1 /* 2 * Copyright 2023, Andrew Lindesay <apl@lindesay.co.nz>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "JwtTokenHelper.h" 8 9 #include "DataIOUtils.h" 10 #include "Json.h" 11 #include "JsonMessageWriter.h" 12 13 #include <ctype.h> 14 15 16 /*static*/ bool 17 JwtTokenHelper::IsValid(const BString& value) 18 { 19 int countDots = 0; 20 21 for (int i = 0; i < value.Length(); i++) { 22 char ch = value[i]; 23 24 if ('.' == ch) 25 countDots++; 26 else { 27 if (!_IsBase64(ch)) 28 return false; 29 } 30 } 31 32 return 2 == countDots; 33 } 34 35 36 /*! A JWT token is split into three parts separated by a '.' character. The 37 middle section is a base-64 encoded string and within the string is JSON 38 structured data. The JSON data contains key-value pairs which carry data 39 about the token. This method will take a JWT token, will find the middle 40 section and will parse the claims into the supplied 'message' parameter. 41 */ 42 43 /*static*/ status_t 44 JwtTokenHelper::ParseClaims(const BString& token, BMessage& message) 45 { 46 int firstDot = token.FindFirst('.'); 47 48 if (firstDot == B_ERROR) 49 return B_BAD_VALUE; 50 51 // find the end of the first section by looking for the next dot. 52 53 int secondDot = token.FindFirst('.', firstDot + 1); 54 55 if (secondDot == B_ERROR) 56 return B_BAD_VALUE; 57 58 BMemoryIO memoryIo(&(token.String())[firstDot + 1], (secondDot - firstDot) - 1); 59 Base64DecodingDataIO base64DecodingIo(&memoryIo, '-', '_'); 60 BJsonMessageWriter writer(message); 61 BJson::Parse(&base64DecodingIo, &writer); 62 63 return writer.ErrorStatus(); 64 } 65 66 67 /*! Note this is base64 "url" standard that disallows "/" and "+" and instead 68 uses "-" and "_". 69 */ 70 71 /*static*/ bool 72 JwtTokenHelper::_IsBase64(char ch) 73 { 74 return isalnum(ch) 75 || '=' == ch 76 || '-' == ch 77 || '_' == ch; 78 } 79