apr_status_t apr_jose_decode_compact_jwe()

in jose/apr_jose_decode.c [498:643]


apr_status_t apr_jose_decode_compact_jwe(apr_jose_t **jose, const char *left,
        const char *right, apr_json_value_t *ph, apr_json_value_t *enc,
        const char *typ, const char *cty, apr_jose_text_t *ph64,
        apr_jose_cb_t *cb, int level, int flags, apr_pool_t *pool,
        apr_bucket_brigade *bb)
{
    const char *dot;
    apr_jose_jwe_t *jwe;
    apr_jose_text_t aad64;
    apr_status_t status;
    int dflags = APR_JOSE_FLAG_NONE;

    if (!cb || !cb->decrypt) {
        apr_errprintf(&(*jose)->result, pool, NULL, 0,
                "Decryption failed: no decrypt callback provided");
        return APR_EINIT;
    }

    *jose = apr_jose_jwe_make(*jose, NULL, NULL, NULL, NULL, pool);
    if (!*jose) {
        return APR_ENOMEM;
    }
    jwe = (*jose)->jose.jwe;

    jwe->encryption = apr_jose_encryption_make(NULL, NULL,
            NULL, pool);
    if (!jwe->encryption) {
        return APR_ENOMEM;
    }

    jwe->recipient = apr_jose_recipient_make(NULL, NULL, NULL, pool);
    if (!jwe->recipient) {
        return APR_ENOMEM;
    }

    /*
     * Parse the JWE representation to extract the serialized values
     * for the components of the JWE.  When using the JWE Compact
     * Serialization, these components are the base64url-encoded
     * representations of the JWE Protected Header, the JWE Encrypted
     * Key, the JWE Initialization Vector, the JWE Ciphertext, and the
     * JWE Authentication Tag, and when using the JWE JSON
     * Serialization, these components also include the base64url-
     * encoded representation of the JWE AAD and the unencoded JWE
     * Shared Unprotected Header and JWE Per-Recipient Unprotected
     * Header values.  When using the JWE Compact Serialization, the
     * JWE Protected Header, the JWE Encrypted Key, the JWE
     * Initialization Vector, the JWE Ciphertext, and the JWE
     * Authentication Tag are represented as base64url-encoded values
     * in that order, with each value being separated from the next by
     * a single period ('.') character, resulting in exactly four
     * delimiting period characters being used.  The JWE JSON
     * Serialization is described in Section 7.2.
     */

    /* protected header */
    if (ph) {
        jwe->encryption->protected = ph;
    }

    /* encrypted key */
    dot = memchr(left, '.', right - left);
    if (!dot) {
        apr_errprintf(&(*jose)->result, pool, NULL, 0,
                "Syntax error: compact JWE decoding failed: one lonely dot");
        return APR_BADCH;
    }

    jwe->recipient->ekey.data = apr_pdecode_base64_binary(pool, left,
            dot - left, APR_ENCODE_BASE64URL, &jwe->recipient->ekey.len);
    if (!jwe->recipient->ekey.data) {
        apr_errprintf(&(*jose)->result, pool, NULL, 0,
                "Syntax error: JWE ekey base64url decoding failed at %" APR_SIZE_T_FMT "",
                jwe->recipient->ekey.len);
        return APR_BADCH;
    }

    left = dot + 1;

    /* iv */
    dot = memchr(left, '.', right - left);
    if (!dot) {
        apr_errprintf(&(*jose)->result, pool, NULL, 0,
                "Syntax error: JWE compact decoding failed: only two dots");
        return APR_BADCH;
    }

    jwe->encryption->iv.data = apr_pdecode_base64_binary(pool, left,
            dot - left, APR_ENCODE_BASE64URL, &jwe->encryption->iv.len);
    if (!jwe->encryption->iv.data) {
        apr_errprintf(&(*jose)->result, pool, NULL, 0,
                "Syntax error: JWE iv base64url decoding failed at %" APR_SIZE_T_FMT "",
                                        jwe->encryption->iv.len);
        return APR_BADCH;
    }

    left = dot + 1;

    /* ciphertext */
    dot = memchr(left, '.', right - left);
    if (!dot) {
        apr_errprintf(&(*jose)->result, pool, NULL, 0,
                "Syntax error: JOSE compact JWE decoding failed: only three dots");

        return APR_BADCH;
    }

    jwe->encryption->cipher.data = apr_pdecode_base64_binary(pool, left,
            dot - left, APR_ENCODE_BASE64URL, &jwe->encryption->cipher.len);
    if (!jwe->encryption->cipher.data) {
        apr_errprintf(&(*jose)->result, pool, NULL, 0,
                "Syntax error: JWE ciphertext base64url decoding failed at %" APR_SIZE_T_FMT "",
                jwe->encryption->cipher.len);

        return APR_BADCH;
    }

    left = dot + 1;

    /* tag */
    jwe->encryption->tag.data = apr_pdecode_base64_binary(pool, left,
            dot - left, APR_ENCODE_BASE64URL, &jwe->encryption->tag.len);
    if (!jwe->encryption->tag.data) {
        apr_errprintf(&(*jose)->result, pool, NULL, 0,
                "Syntax error: JWE tag base64url decoding failed at %" APR_SIZE_T_FMT "",
                jwe->encryption->tag.len);

        return APR_BADCH;
    }

    /* aad is the empty string in compact serialisation */
    memset(&aad64, 0, sizeof(apr_jose_text_t));

    status = apr_jose_decode_jwe_recipient(jose,
            bb, jwe->recipient, jwe->encryption, typ, cty, ph64, &aad64, cb,
            level, &dflags, pool);

    if (APR_SUCCESS != status) {
        apr_errprintf(&(*jose)->result, pool, NULL, 0,
                "Decryption failed: JWE decryption failed");

        return status;
    }

    return APR_SUCCESS;
}