Exemplo n.º 1
0
/*
 * parse and (optionally) decrypt a JSON Web Token
 */
apr_byte_t oidc_jwt_parse(apr_pool_t *pool, const char *input_json,
		oidc_jwt_t **j_jwt, apr_hash_t *keys, oidc_jose_error_t *err) {

	cjose_err cjose_err;
	char *s_json = NULL;

	if (oidc_jwe_decrypt(pool, input_json, keys, &s_json, err, FALSE) == FALSE)
		return FALSE;

	*j_jwt = oidc_jwt_new(pool, FALSE, FALSE);
	oidc_jwt_t *jwt = *j_jwt;

	jwt->cjose_jws = cjose_jws_import(s_json, strlen(s_json), &cjose_err);
	if (jwt->cjose_jws == NULL) {
		oidc_jose_error(err, "cjose_jws_import failed: %s",
				oidc_cjose_e2s(pool, cjose_err));
		oidc_jwt_destroy(jwt);
		*j_jwt = NULL;
		return FALSE;
	}

	cjose_header_t *hdr = cjose_jws_get_protected(jwt->cjose_jws);
	jwt->header.value.json = json_deep_copy((json_t *)hdr);
	char *str = json_dumps(jwt->header.value.json,
			JSON_PRESERVE_ORDER | JSON_COMPACT);
	jwt->header.value.str = apr_pstrdup(pool, str);
	free(str);

	jwt->header.alg = apr_pstrdup(pool,
			cjose_header_get(hdr, CJOSE_HDR_ALG, &cjose_err));
	jwt->header.enc = apr_pstrdup(pool,
			cjose_header_get(hdr, CJOSE_HDR_ENC, &cjose_err));
	jwt->header.kid = apr_pstrdup(pool,
			cjose_header_get(hdr, CJOSE_HDR_KID, &cjose_err));

	uint8_t *plaintext = NULL;
	size_t plaintext_len = 0;
	if (cjose_jws_get_plaintext(jwt->cjose_jws, &plaintext, &plaintext_len,
			&cjose_err) == FALSE) {
		oidc_jose_error(err, "cjose_jws_get_plaintext failed: %s",
				oidc_cjose_e2s(pool, cjose_err));
		return FALSE;
	}

	if (oidc_jose_parse_payload(pool, (const char *) plaintext, plaintext_len,
			&jwt->payload, err) == FALSE) {
		oidc_jwt_destroy(jwt);
		*j_jwt = NULL;
	}

	return TRUE;
}
Exemplo n.º 2
0
/*
 * get a header value from a JWT
 */
const char *oidc_jwt_hdr_get(oidc_jwt_t *jwt, const char *key) {
	cjose_err cjose_err;
	cjose_header_t *hdr = cjose_jws_get_protected(jwt->cjose_jws);
	return hdr ? cjose_header_get(hdr, key, &cjose_err) : NULL;
}
Exemplo n.º 3
0
static void _self_sign_self_verify(const char *plain1, const char *alg, cjose_err *err)
{
    const char *s_jwk = _self_get_jwk_by_alg(alg);
    cjose_jwk_t *jwk = cjose_jwk_import(s_jwk, strlen(s_jwk), err);

    ck_assert_msg(NULL != jwk, "cjose_jwk_import failed: "
                               "%s, file: %s, function: %s, line: %ld",
                  err->message, err->file, err->function, err->line);

    // set header for JWS
    cjose_header_t *hdr = cjose_header_new(err);
    ck_assert_msg(cjose_header_set(hdr, CJOSE_HDR_ALG, alg, err), "cjose_header_set failed: "
                                                                  "%s, file: %s, function: %s, line: %ld",
                  err->message, err->file, err->function, err->line);

    // create the JWS
    size_t plain1_len = strlen(plain1);
    cjose_jws_t *jws1 = cjose_jws_sign(jwk, hdr, plain1, plain1_len, err);
    ck_assert_msg(NULL != jws1, "cjose_jws_sign failed: "
                                "%s, file: %s, function: %s, line: %ld",
                  err->message, err->file, err->function, err->line);
    ck_assert(hdr == cjose_jws_get_protected(jws1));

    // get the compact serialization of JWS
    const char *compact = NULL;
    ck_assert_msg(cjose_jws_export(jws1, &compact, err), "cjose_jws_export failed: "
                                                         "%s, file: %s, function: %s, line: %ld",
                  err->message, err->file, err->function, err->line);

    // deserialize the compact representation to a new JWS
    cjose_jws_t *jws2 = cjose_jws_import(compact, strlen(compact), err);
    ck_assert_msg(NULL != jws2, "cjose_jws_import failed: "
                                "%s, file: %s, function: %s, line: %ld",
                  err->message, err->file, err->function, err->line);

    // verify the deserialized JWS
    ck_assert_msg(cjose_jws_verify(jws2, jwk, err), "cjose_jws_verify failed: "
                                                    "%s, file: %s, function: %s, line: %ld",
                  err->message, err->file, err->function, err->line);

    // get the verified plaintext
    uint8_t *plain2 = NULL;
    size_t plain2_len = 0;
    ck_assert_msg(cjose_jws_get_plaintext(jws2, &plain2, &plain2_len, err), "cjose_jws_get_plaintext failed: "
                                                                            "%s, file: %s, function: %s, line: %ld",
                  err->message, err->file, err->function, err->line);

    // confirm equal headers
    ck_assert(json_equal((json_t *)cjose_jws_get_protected(jws1), (json_t *)cjose_jws_get_protected(jws2)));

    // confirm plain2 == plain1
    ck_assert_msg(plain2_len == strlen(plain1), "length of verified plaintext does not match length of original, "
                                                "expected: %lu, found: %lu",
                  strlen(plain1), plain2_len);
    ck_assert_msg(strncmp(plain1, plain2, plain2_len) == 0, "verified plaintext does not match signed plaintext");

    cjose_header_release(hdr);
    cjose_jws_release(jws1);
    cjose_jws_release(jws2);
    cjose_jwk_release(jwk);
}