JWSResult VerifyJWSWithKey()

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;
}