Beispiel #1
0
/*
 * encrypt JWT
 */
apr_byte_t oidc_jwt_encrypt(apr_pool_t *pool, oidc_jwt_t *jwe, oidc_jwk_t *jwk,
		const char *payload, char **serialized, oidc_jose_error_t *err) {

	cjose_header_t *hdr = (cjose_header_t *)jwe->header.value.json;

	if (jwe->header.alg)
		oidc_jwt_hdr_set(jwe, CJOSE_HDR_ALG, jwe->header.alg);
	if (jwe->header.kid)
		oidc_jwt_hdr_set(jwe, CJOSE_HDR_KID, jwe->header.kid);
	if (jwe->header.enc)
		oidc_jwt_hdr_set(jwe, CJOSE_HDR_ENC, jwe->header.enc);

	cjose_err cjose_err;
	cjose_jwe_t *cjose_jwe = cjose_jwe_encrypt(jwk->cjose_jwk, hdr,
			(const uint8_t *) payload, strlen(payload), &cjose_err);
	if (cjose_jwe == NULL) {
		oidc_jose_error(err, "cjose_jwe_encrypt failed: %s",
				oidc_cjose_e2s(pool, cjose_err));
		return FALSE;
	}

	char *cser = cjose_jwe_export(cjose_jwe, &cjose_err);
	if (cser == NULL) {
		oidc_jose_error(err, "cjose_jwe_export failed: %s",
				oidc_cjose_e2s(pool, cjose_err));
		return FALSE;
	}

	*serialized = apr_pstrdup(pool, cser);
	cjose_get_dealloc()(cser);
	cjose_jwe_release(cjose_jwe);

	return TRUE;
}
Beispiel #2
0
/*
 * decrypt a JSON Web Token
 */
apr_byte_t oidc_jwe_decrypt(apr_pool_t *pool, const char *input_json,
		apr_hash_t *keys, char **s_json, oidc_jose_error_t *err, apr_byte_t import_must_succeed) {
	cjose_err cjose_err;
	cjose_jwe_t *jwe = cjose_jwe_import(input_json, strlen(input_json),
			&cjose_err);
	if (jwe != NULL) {
		size_t content_len = 0;
		uint8_t *decrypted = oidc_jwe_decrypt_impl(pool, jwe, keys, &content_len,
				err);
		if (decrypted != NULL) {
			decrypted[content_len] = '\0';
			*s_json = apr_pstrdup(pool, (const char *) decrypted);
			cjose_get_dealloc()(decrypted);
		}
		cjose_jwe_release(jwe);
	} else if (import_must_succeed == FALSE) {
		*s_json = apr_pstrdup(pool, input_json);
	} else {
		oidc_jose_error(err, "cjose_jwe_import failed: %s",
				oidc_cjose_e2s(pool, cjose_err));
	}
	return (*s_json != NULL);
}
Beispiel #3
0
cjose_jwe_t *cjose_jwe_import(
        const char *cser,
        size_t cser_len,
        cjose_err *err)
{
    cjose_jwe_t *jwe = NULL;

    if (NULL == cser)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }

    // allocate and initialize a new JWE object
    if (!_cjose_jwe_malloc(sizeof(cjose_jwe_t), false, (uint8_t **)&jwe, err))
    {
        return NULL;
    }

    // import each part of the compact serialization
    int part = 0;
    int idx = 0;
    int start_idx = 0;
    while (idx <= cser_len && part < 5)
    {
        if ((idx == cser_len) || (cser[idx] == '.'))
        {
            if (!_cjose_jwe_import_part(
                    jwe, part++, cser + start_idx, idx - start_idx, err))
            {
                cjose_jwe_release(jwe);
                return NULL;                
            }
            start_idx = idx + 1;
        }
        if (part < 5) ++idx;
    }

    // fail if we didn't find enough parts
    if (part != 5)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        cjose_jwe_release(jwe);
        return NULL;
    }

    // fail if we finished early (e.g. more than 5 parts)
    if (idx != cser_len)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        cjose_jwe_release(jwe);
        return NULL;        
    }

    // deserialize JSON header
    jwe->hdr = json_loadb(
               (const char *)jwe->part[0].raw, jwe->part[0].raw_len, 0, NULL);
    if (NULL == jwe->hdr)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        cjose_jwe_release(jwe);
        return NULL;
    }

    // validate the JSON header
    if (!_cjose_jwe_validate_hdr(jwe, jwe->hdr, err))
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        cjose_jwe_release(jwe);
        return NULL;        
    }

    return jwe;
}
Beispiel #4
0
cjose_jwe_t *cjose_jwe_encrypt(
        const cjose_jwk_t *jwk,
        cjose_header_t *protected_header,
        const uint8_t *plaintext,
        size_t plaintext_len,
        cjose_err *err)
{
    cjose_jwe_t *jwe = NULL;

    if (NULL == jwk || NULL == protected_header)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }

    // if not already set, add kid header to JWE to match that of JWK
    const char *kid = cjose_jwk_get_kid(jwk, err);
    if (NULL != kid) {
        if (!cjose_header_set(protected_header, CJOSE_HDR_KID, kid, err)) 
        {
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_STATE);
            return false;
        }
    }

    // allocate and initialize a new JWE object
    if (!_cjose_jwe_malloc(sizeof(cjose_jwe_t), false, (uint8_t **)&jwe, err))
    {
        return NULL;
    }

    // validate JWE header
    if (!_cjose_jwe_validate_hdr(jwe, protected_header, err))
    {
        cjose_jwe_release(jwe);
        return NULL;
    }

    // build JWE header
    if (!_cjose_jwe_build_hdr(jwe, protected_header, err))
    {
        cjose_jwe_release(jwe);
        return NULL;
    }

    // build JWE content-encryption key and encrypted key
    if (!jwe->fns.encrypt_ek(jwe, jwk, err))
    {
        cjose_jwe_release(jwe);
        return NULL;
    }

    // build JWE initialization vector
    if (!jwe->fns.set_iv(jwe, err))
    {
        cjose_jwe_release(jwe);
        return NULL;
    }

    // build JWE encrypted data and authentication tag
    if (!jwe->fns.encrypt_dat(jwe, plaintext, plaintext_len, err))
    {
        cjose_jwe_release(jwe);
        return NULL;
    }

    return jwe;
}