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