JWSResult VerifySJWK()

in src/utils/jws_utils/src/jws_utils.c [316:460]


JWSResult VerifySJWK(const char* sjwk)
{
    JWSResult retval = JWSResult_Failed;
    JWSResult jwsResultIsSigningKeyDisallowed = JWSResult_Failed;
    JWSResult jwsResultVerifyJwtSignature = JWSResult_Failed;
    ADUC_Result result = { ADUC_GeneralResult_Failure, 0 };
    ADUC_Result resultGetDisabledSigningKeys = { ADUC_GeneralResult_Failure, 0 };
    VECTOR_HANDLE signingKeyDisallowed = NULL;

    char* header = NULL;
    char* payload = NULL;
    char* signature = NULL;

    char* jsonHeader = NULL;
    char* jsonPayload = NULL;
    char* kid = NULL;
    void* rootKey = NULL;

    if (!ExtractJWSSections(sjwk, &header, &payload, &signature))
    {
        Log_Error("bad jws section structure");
        retval = JWSResult_BadStructure;
        goto done;
    }

    jsonHeader = Base64URLDecodeToString(header);

    if (jsonHeader == NULL)
    {
        Log_Error("base64url decode failed");
        retval = JWSResult_Failed;
        goto done;
    }

    kid = GetStringValueFromJSON(jsonHeader, "kid");

    if (kid == NULL)
    {
        Log_Error("NULL 'kid'");
        retval = JWSResult_Failed;
        goto done;
    }

    result = RootKeyUtility_GetKeyForKid(&rootKey, kid);

    if (IsAducResultCodeFailure(result.ResultCode))
    {
        if (result.ExtendedResultCode == ADUC_ERC_UTILITIES_ROOTKEYUTIL_SIGNING_ROOTKEY_IS_DISABLED)
        {
            Log_Error("disallowed root kid: '%s'", kid);
            retval = JWSResult_DisallowedRootKid;
        }
        else if (result.ExtendedResultCode == ADUC_ERC_UTILITIES_ROOTKEYUTIL_NO_ROOTKEY_FOUND_FOR_KEYID)
        {
            Log_Error("missing root kid: '%s'", kid);
            retval = JWSResult_MissingRootKid;
        }
        else
        {
            Log_Error("invalid or unknown error for root kid: '%s'", kid);
            retval = JWSResult_InvalidRootKid;
        }
        goto done;
    }

    // First verify JWT structure and signature
    jwsResultVerifyJwtSignature = VerifyJWSWithKey(sjwk, rootKey);
    if (jwsResultVerifyJwtSignature != JWSResult_Success)
    {
        Log_Error("sjwk failed verification for rootKey");
        retval = jwsResultVerifyJwtSignature;
        goto done;
    }

    // Now, verify that signing key is not on the rootkey packages's Disallowed
    resultGetDisabledSigningKeys = RootKeyUtility_GetDisabledSigningKeys(&signingKeyDisallowed);
    if (IsAducResultCodeFailure(resultGetDisabledSigningKeys.ResultCode))
    {
        Log_Error("sjwk failed to get disabled signing keys");
        retval = JWSResult_FailedGetDisabledSigningKeys;
        goto done;
    }

    jsonPayload = Base64URLDecodeToString(payload);

    if (jsonPayload == NULL)
    {
        Log_Error("failed base64url decode");
        retval = JWSResult_Failed;
        goto done;
    }

    jwsResultIsSigningKeyDisallowed = IsSigningKeyDisallowed(jsonPayload, signingKeyDisallowed);
    if (jwsResultIsSigningKeyDisallowed != JWSResult_Success)
    {
        Log_Error("failed disallowed");
        retval = jwsResultIsSigningKeyDisallowed;
        goto done;
    }

    retval = JWSResult_Success;

done:
    if (signingKeyDisallowed != NULL)
    {
        VECTOR_destroy(signingKeyDisallowed);
    }

    if (header != NULL)
    {
        free(header);
    }

    if (payload != NULL)
    {
        free(payload);
    }

    if (signature != NULL)
    {
        free(signature);
    }

    if (kid != NULL)
    {
        free(kid);
    }

    if (jsonHeader != NULL)
    {
        free(jsonHeader);
    }

    if (jsonPayload != NULL)
    {
        free(jsonPayload);
    }

    if (rootKey != NULL)
    {
        CryptoUtils_FreeCryptoKeyHandle(rootKey);
    }

    return retval;
}