/* * perform compact serialization on a JWT and return the resulting string */ char *oidc_jwt_serialize(apr_pool_t *pool, oidc_jwt_t *jwt, oidc_jose_error_t *err) { cjose_err cjose_err; const char *cser = NULL; if (strcmp(jwt->header.alg, "none") != 0) { if (cjose_jws_export(jwt->cjose_jws, &cser, &cjose_err) == FALSE) { oidc_jose_error(err, "cjose_jws_export failed: %s", oidc_cjose_e2s(pool, cjose_err)); return NULL; } } else { char *s_payload = json_dumps(jwt->payload.value.json, JSON_PRESERVE_ORDER | JSON_COMPACT); char *out = NULL; size_t out_len; if (cjose_base64url_encode((const uint8_t *)s_payload, strlen(s_payload), &out, &out_len, &cjose_err) == FALSE) return FALSE; cser = apr_pstrndup(pool, out, out_len); cjose_get_dealloc()(out); free(s_payload); cser = apr_psprintf(pool, "eyJhbGciOiJub25lIn0.%s.", cser); } return apr_pstrdup(pool, cser); }
END_TEST START_TEST(test_cjose_jws_import_export_compare) { cjose_err err; // import the common key cjose_jwk_t *jwk = cjose_jwk_import(JWK_COMMON, strlen(JWK_COMMON), &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); // import the jws created with the common key cjose_jws_t *jws = cjose_jws_import(JWS_COMMON, strlen(JWS_COMMON), &err); ck_assert_msg(NULL != jws, "cjose_jws_import failed: " "%s, file: %s, function: %s, line: %ld", err.message, err.file, err.function, err.line); // re-export the jws object const char *cser = NULL; ck_assert_msg(cjose_jws_export(jws, &cser, &err), "re-export of imported JWS faied: " "%s, file: %s, function: %s, line: %ld", err.message, err.file, err.function, err.line); // compare the re-export to the original serialization ck_assert_msg(strncmp(JWS_COMMON, cser, strlen(JWS_COMMON)) == 0, "export of imported JWS doesn't match original"); cjose_jwk_release(jwk); cjose_jws_release(jws); }
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); }