static apr_status_t apr_jose_encode_json_jwe()

in jose/apr_jose_encode.c [261:479]


static apr_status_t apr_jose_encode_json_jwe(apr_bucket_brigade *brigade,
        apr_brigade_flush flush, void *ctx, apr_jose_t *jose, apr_jose_cb_t *cb,
        apr_pool_t *p)
{

    apr_json_value_t *json;
    char *buf;
    const char *buf64;
    apr_size_t len;
    apr_size_t len64;

    apr_bucket_brigade *bb = apr_brigade_create(p,
            brigade->bucket_alloc);

    apr_jose_jwe_t *jwe = jose->jose.jwe;

    apr_status_t status = APR_SUCCESS;

    /* create our json */

    json = apr_json_object_create(p);

    /* create protected header */

    if (jwe->encryption) {
        apr_jose_encryption_t *e = jwe->encryption;

        if (e->protected) {

            status = apr_jose_encode_base64_json(bb, flush, ctx,
                    e->protected, p);
            if (APR_SUCCESS != status) {
                return status;
            }

            status = apr_brigade_pflatten(bb, &buf, &len, p);
            if (APR_SUCCESS != status) {
                return status;
            }

            apr_brigade_cleanup(bb);

            apr_json_object_set(json, "protected",
                    APR_JSON_VALUE_STRING,
                    apr_json_string_create(p, buf, len), p);

        }

        /* create unprotected header */

        if (e->unprotected) {

            apr_json_object_set(json, "unprotected",
                    APR_JSON_VALUE_STRING, e->unprotected, p);

        }

        /* create recipient */
        if (jwe->recipient) {

            apr_jose_recipient_t *recip = jwe->recipient;

            /* create the payload */

            status = apr_jose_encode(bb, flush, ctx, jwe->payload, cb, p);
            if (APR_SUCCESS != status) {
                jose->result = jwe->payload->result;
                return status;
            }

            if (cb && cb->encrypt && recip) {
                status = cb->encrypt(bb, jose, recip, e, cb->ctx, p);
                if (APR_SUCCESS != status) {
                    return status;
                }
            }

            apr_brigade_cleanup(bb);

            /* create header */

            apr_json_object_set(json, "header",
                    APR_JSON_VALUE_STRING, recip->header, p);

            apr_brigade_cleanup(bb);

            /* create encrypted key */

            buf64 = apr_pencode_base64_binary(p, recip->ekey.data,
                    recip->ekey.len,
                    APR_ENCODE_BASE64URL, &len64);

            apr_json_object_set(json, "encrypted_key",
                    APR_JSON_VALUE_STRING,
                    apr_json_string_create(p, buf64, len64), p);

        }

        /* create recipients */
        if (jwe->recipients) {

            apr_json_value_t *recips;
            int i;

            /* create recipients element */

            recips = apr_json_array_create(p, jwe->recipients->nelts);
            apr_json_object_set(json, "recipients",
                    APR_JSON_VALUE_STRING, recips, p);

            /* populate each recipient */

            for (i = 0; i < jwe->recipients->nelts; i++) {
                apr_json_value_t *r = apr_json_object_create(p);
                apr_jose_recipient_t *recip = APR_ARRAY_IDX(
                        jwe->recipients, i, apr_jose_recipient_t *);

                if (!recip) {
                    continue;
                }

                apr_json_array_add(recips, r);

                /* create the payload */

                status = apr_jose_encode(bb, flush, ctx, jwe->payload, cb, p);
                if (APR_SUCCESS != status) {
                    jose->result = jwe->payload->result;
                    return status;
                }

                if (cb && cb->encrypt && recip) {
                    status = cb->encrypt(bb, jose, recip, e, cb->ctx, p);
                    if (APR_SUCCESS != status) {
                        return status;
                    }
                }

                apr_brigade_cleanup(bb);

                /* create header */

                apr_json_object_set(r, "header",
                        APR_JSON_VALUE_STRING, recip->header, p);

                apr_brigade_cleanup(bb);

                /* create encrypted key */

                buf64 = apr_pencode_base64_binary(p, recip->ekey.data,
                        recip->ekey.len,
                        APR_ENCODE_BASE64URL, &len64);

                apr_json_object_set(r, "encrypted_key",
                        APR_JSON_VALUE_STRING,
                        apr_json_string_create(p, buf64, len64), p);

            }
            if (APR_SUCCESS != status) {
                return status;
            }

        }

        /* create iv */

        if (e->iv.len) {

            buf64 = apr_pencode_base64_binary(p, e->iv.data, e->iv.len,
                    APR_ENCODE_BASE64URL, &len64);

            apr_json_object_set(json, "iv", APR_JSON_VALUE_STRING,
                    apr_json_string_create(p, buf64, len64), p);
        }

        /* create aad */

        if (e->aad.len) {

            buf64 = apr_pencode_base64_binary(p, e->aad.data, e->aad.len,
                    APR_ENCODE_BASE64URL, &len64);

            apr_json_object_set(json, "aad", APR_JSON_VALUE_STRING,
                    apr_json_string_create(p, buf64, len64), p);
        }

        /* create ciphertext */

        if (e->cipher.len) {

            buf64 = apr_pencode_base64_binary(p, e->cipher.data, e->cipher.len,
                    APR_ENCODE_BASE64URL, &len64);

            apr_json_object_set(json, "ciphertext", APR_JSON_VALUE_STRING,
                    apr_json_string_create(p, buf64, len64), p);
        }

        /* create tag */

        if (e->tag.len) {

            buf64 = apr_pencode_base64_binary(p, e->tag.data, e->tag.len,
                    APR_ENCODE_BASE64URL, &len64);

            apr_json_object_set(json, "tag", APR_JSON_VALUE_STRING,
                    apr_json_string_create(p, buf64, len64), p);
        }

    }

    /* write out our final result */

    if (json) {
        status = apr_json_encode(brigade, flush, ctx, json,
                APR_JSON_FLAGS_WHITESPACE, p);
    }

    return status;
}