in src/utils/jws_utils/src/jws_utils.c [632:739]
JWSResult VerifyJWSWithKey(const char* blob, CryptoKeyHandle key)
{
JWSResult result = JWSResult_Failed;
// Check for structure
char* header = NULL;
char* payload = NULL;
char* signature = NULL;
char* headerJson = NULL;
char* alg = NULL;
char* headerPlusPayload = NULL;
uint8_t* decodedSignature = NULL;
if (!ExtractJWSSections(blob, &header, &payload, &signature))
{
Log_Error("bad structure extracting JWS sections");
result = JWSResult_BadStructure;
goto done;
}
headerJson = Base64URLDecodeToString(header);
if (headerJson == NULL)
{
Log_Error("failed base64 url decode for hdr");
result = JWSResult_Failed;
goto done;
}
alg = GetStringValueFromJSON(headerJson, "alg");
if (alg == NULL)
{
Log_Error("failed to get 'alg' value from hdr");
result = JWSResult_BadStructure;
goto done;
}
// Note: The +2 is for the "." between the header and the payload
// and the null terminator at the end of the string.
size_t headerLen = strlen(header);
size_t payloadLen = strlen(payload);
size_t hppSize = headerLen + payloadLen + 2;
headerPlusPayload = (char*)calloc(1, hppSize);
if (headerPlusPayload == NULL)
{
result = JWSResult_Failed;
goto done;
}
memcpy(headerPlusPayload, header, headerLen);
headerPlusPayload[headerLen] = '.';
memcpy(headerPlusPayload + headerLen + 1, payload, payloadLen);
headerPlusPayload[headerLen + payloadLen + 1] = '\0';
size_t decodedSignatureLen = Base64URLDecode(signature, &decodedSignature);
if (!CryptoUtils_IsValidSignature(
alg, decodedSignature, decodedSignatureLen, (uint8_t*)headerPlusPayload, strlen(headerPlusPayload), key))
{
Log_Error("Signature is invalid");
result = JWSResult_InvalidSignature;
}
else
{
result = JWSResult_Success;
}
done:
if (header != NULL)
{
free(header);
}
if (payload != NULL)
{
free(payload);
}
if (signature != NULL)
{
free(signature);
}
if (headerJson != NULL)
{
free(headerJson);
}
if (alg != NULL)
{
free(alg);
}
if (headerPlusPayload != NULL)
{
free(headerPlusPayload);
}
if (decodedSignature != NULL)
{
free(decodedSignature);
}
return result;
}