diff --git a/ChangeLog b/ChangeLog index cd0dd43..a33bbe5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +11/08/2023 +- update DPoP support to RFC 9449 +- release 1.5.2 + 08/31/2023 - printout more cjose error details when errors occur verifying JWT access tokens diff --git a/README.md b/README.md index 268668c..55ee61a 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ Generic library to build C-based OAuth 2.x and OpenID Connect servers and client - JWT bearer token validation using JWK, JWKS URI, shared symmetric key, X.509 cert, and RSA public key ([RFC 6750](https://tools.ietf.org/html/rfc6750)) - OAuth 2.0 Authorization Server Metadata ([RFC 8414](https://tools.ietf.org/html/rfc8414)) - Proof Key for Code Exchange (PKCE) by OAuth Public Clients ([RFC 7636](https://tools.ietf.org/html/rfc7636)) -- OAuth 2.0 Mutual-TLS (MTLS) Certificate-Bound Access Tokens ([RFC 8705](https://tools.ietf.org/html/rfc8705)) -- OAuth 2.0 Demonstration of Proof-of-Possession (DPoP) at the Application Layer ([Internet-Draft](https://tools.ietf.org/html/draft-ietf-oauth-dpop)) +- OAuth 2.0 Mutual-TLS (MTLS) Certificate-Bound Access Tokens ([RFC 8705](https://tools.ietf.org/html/rfc8705)) +- OAuth 2.0 Demonstrating Proof of Possession (DPoP) ([RFC9449](https://tools.ietf.org/html/rfc9449)) - Amazon ALB [EC key URL based `x-amzn-oidc-data` JWT verification](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html) - endpoint authentication methods: `client_secret_basic`, `client_secret_post`, [`client_secret_jwt`, `private_key_jwt`](https://tools.ietf.org/html/rfc7523), [TLS client certificate](https://tools.ietf.org/id/draft-ietf-oauth-mtls), and HTTP basic authentication - configurable cache backends: shared memory, file-based, memcache, and Redis diff --git a/configure.ac b/configure.ac index 23f2a22..b29134a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([liboauth2],[1.5.1],[hans.zandbelt@openidc.com]) +AC_INIT([liboauth2],[1.5.2],[hans.zandbelt@openidc.com]) AM_INIT_AUTOMAKE([foreign no-define subdir-objects]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/src/dpop.c b/src/dpop.c index 282bc17..7a5f020 100644 --- a/src/dpop.c +++ b/src/dpop.c @@ -31,6 +31,8 @@ #define OAUTH_DPOP_HDR_JWK "jwk" #define OAUTH_DPOP_CLAIM_HTM "htm" #define OAUTH_DPOP_CLAIM_HTU "htu" +#define OAUTH_DPOP_CLAIM_ATH "ath" +#define OAUTH_DPOP_CLAIM_NONCE "nonce" #define OAUTH_DPOP_HDR_TYP_VALUE "dpop+jwt" static bool _oauth2_dpop_jwt_validate(oauth2_log_t *log, const char *s_dpop, @@ -84,12 +86,13 @@ static bool _oauth2_dpop_claims_validate(oauth2_log_t *log, cjose_header_t *hdr, cjose_jwk_t **jwk, const char **hdr_typ, const char **hdr_alg, char **clm_htm, - char **clm_htu, char **clm_jti) + char **clm_htu, char **clm_jti, + char **clm_ath, char **clm_nonce) { bool rc = false; cjose_err err; char *hdr_jwk = NULL; - json_int_t clm_iat; + json_int_t clm_iat = 0; *hdr_typ = cjose_header_get(hdr, OAUTH2_JOSE_HDR_TYP, &err); if (*hdr_typ == NULL) { @@ -121,38 +124,59 @@ static bool _oauth2_dpop_claims_validate(oauth2_log_t *log, cjose_header_t *hdr, goto end; } - if (oauth2_json_string_get(log, dpop_payload, OAUTH_DPOP_CLAIM_HTU, - clm_htu, NULL) == false) { + if ((oauth2_json_string_get(log, dpop_payload, OAUTH_DPOP_CLAIM_HTU, + clm_htu, NULL) == false) || + (*clm_htu == NULL)) { oauth2_error(log, "required claim \"%s\" not found in DPOP payload", OAUTH_DPOP_CLAIM_HTU); goto end; } - if (oauth2_json_string_get(log, dpop_payload, OAUTH_DPOP_CLAIM_HTM, - clm_htm, NULL) == false) { + if ((oauth2_json_string_get(log, dpop_payload, OAUTH_DPOP_CLAIM_HTM, + clm_htm, NULL) == false) || + (*clm_htm == NULL)) { oauth2_error(log, "required claim \"%s\" not found in DPOP payload", OAUTH_DPOP_CLAIM_HTM); goto end; } - if (oauth2_json_string_get(log, dpop_payload, OAUTH2_CLAIM_JTI, clm_jti, - NULL) == false) { + if ((oauth2_json_string_get(log, dpop_payload, OAUTH2_CLAIM_JTI, + clm_jti, NULL) == false) || + (*clm_jti == NULL)) { oauth2_error(log, "required claim \"%s\" not found in DPOP payload", OAUTH2_CLAIM_JTI); goto end; } - if (oauth2_json_number_get(log, dpop_payload, OAUTH2_CLAIM_IAT, - &clm_iat, 0) == false) { + if ((oauth2_json_number_get(log, dpop_payload, OAUTH2_CLAIM_IAT, + &clm_iat, 0) == false) || + (clm_iat == 0)) { oauth2_error(log, "required claim \"%s\" not found in DPOP payload", OAUTH2_CLAIM_IAT); goto end; } + if ((oauth2_json_string_get(log, dpop_payload, OAUTH_DPOP_CLAIM_ATH, + clm_ath, NULL) == false) || + (*clm_ath == NULL)) { + oauth2_error(log, + "required claim \"%s\" not found in DPOP payload", + OAUTH_DPOP_CLAIM_ATH); + goto end; + } + + if ((oauth2_json_string_get(log, dpop_payload, OAUTH_DPOP_CLAIM_NONCE, + clm_nonce, NULL) == false) || + (*clm_nonce == NULL)) { + oauth2_debug( + log, "(optional) claim \"%s\" not found in DPOP payload", + OAUTH_DPOP_CLAIM_NONCE); + } + rc = true; end: @@ -328,14 +352,99 @@ static bool _oauth2_dpop_jti_validate(oauth2_log_t *log, return rc; } +static bool(_oauth2_dpp_hdr_count)(oauth2_log_t *log, void *rec, + const char *key, const char *value) +{ + int *n = (int *)rec; + if (strcasecmp(key, OAUTH2_HTTP_HDR_DPOP) == 0) + (*n)++; + return true; +} + +static bool _oauth2_dpop_header_count(oauth2_log_t *log, + oauth2_http_request_t *request) +{ + bool rc = false; + int n = 0; + + oauth2_http_request_headers_loop(log, request, _oauth2_dpp_hdr_count, + &n); + + if (n > 1) { + oauth2_error(log, "more than one %s header found", + OAUTH2_HTTP_HDR_DPOP); + goto end; + } + + if (n == 0) { + oauth2_error(log, "no %s header found", OAUTH2_HTTP_HDR_DPOP); + goto end; + } + + rc = true; + +end: + + return rc; +} + +static bool _oauth2_dpop_ath_validate(oauth2_log_t *log, + oauth2_cfg_dpop_verify_t *verify, + const char *clm_ath, + const char *access_token) +{ + bool rc = false; + unsigned char *calc = NULL; + unsigned int calc_len = 0; + uint8_t *dec = NULL; + size_t dec_len = 0; + + if ((clm_ath == NULL) || (access_token == NULL)) + goto end; + + if (oauth2_jose_hash_bytes( + log, "sha256", (const unsigned char *)access_token, + strlen(access_token), &calc, &calc_len) == false) + goto end; + + if (oauth2_base64url_decode(log, clm_ath, &dec, &dec_len) == false) + goto end; + + if ((calc_len != dec_len) || (memcmp(dec, calc, dec_len) != 0)) { + oauth2_error(log, + "provided \"ath\" hash value (%s) does not match " + "the calculated value (dec_len=%d, calc_len=%d)", + clm_ath, dec_len, calc_len); + goto end; + } + + oauth2_debug(log, + "successfully validated the provided \"ath\" hash value " + "(%s) against the calculated value", + clm_ath); + + rc = true; + +end: + + if (dec) + oauth2_mem_free(dec); + if (calc) + oauth2_mem_free(calc); + + return rc; +} + static bool _oauth2_dpop_parse_and_validate(oauth2_log_t *log, oauth2_cfg_dpop_verify_t *verify, oauth2_http_request_t *request, + const char *access_token, cjose_jwk_t **jwk) { bool rc = false; const char *hdr_typ = NULL, *hdr_alg = NULL; - char *clm_htm = NULL, *clm_htu = NULL, *clm_jti = NULL; + char *clm_htm = NULL, *clm_htu = NULL, *clm_jti = NULL, *clm_ath = NULL, + *clm_nonce = NULL; const char *s_dpop = NULL; cjose_jws_t *jws = NULL; cjose_header_t *hdr = NULL; @@ -345,6 +454,12 @@ static bool _oauth2_dpop_parse_and_validate(oauth2_log_t *log, if ((request == NULL) || (verify == NULL) || (jwk == NULL)) goto end; + /* + * 1. that there is not more than one DPoP header in the request, + */ + if (_oauth2_dpop_header_count(log, request) == false) + goto end; + s_dpop = oauth2_http_request_header_get(log, request, OAUTH2_HTTP_HDR_DPOP); if (s_dpop == NULL) @@ -355,71 +470,99 @@ static bool _oauth2_dpop_parse_and_validate(oauth2_log_t *log, oauth2_debug(log, "DPOP header: %s", s_peek); /* - * 1. the string value is a well-formed JWT + * 2. the string value of the header field is a well-formed JWT, */ if (_oauth2_dpop_jwt_validate(log, s_dpop, &jws, &hdr, &dpop_payload) == false) goto end; /* - * 2. all required claims are contained in the JWT, + * 3. all required claims per Section 4.2 are contained in the JWT, */ if (_oauth2_dpop_claims_validate(log, hdr, dpop_payload, jwk, &hdr_typ, - &hdr_alg, &clm_htm, &clm_htu, - &clm_jti) == false) + &hdr_alg, &clm_htm, &clm_htu, &clm_jti, + &clm_ath, &clm_nonce) == false) goto end; /* - * 3. the "typ" field in the header has the value "dpop+jwt", + * 4. the typ field in the header has the value dpop+jwt, */ if (_oauth2_dpop_hdr_typ_validate(log, hdr_typ) == false) goto end; /* - * 4. the algorithm in the header of the JWT indicates an asymmetric - * digital signature algorithm, is not "none", is supported by the - * application, and is deemed secure, + * 5. the algorithm in the header of the JWT indicates an asymmetric + * digital signature algorithm, is not none, is supported by the + * application, and is deemed secure, */ if (_oauth2_dpop_hdr_alg_validate(log, hdr_alg) == false) goto end; /* - * 5. that the JWT is signed using the public key contained in the - * "jwk" header of the JWT, + * 6. the JWT signature verifies with the public key contained in the + * jwk header of the JWT, */ if (_oauth2_dpop_sig_verify(log, jws, *jwk) == false) goto end; /* - * 6. the "htm" claim matches the HTTP method value of the HTTP request - * in which the JWT was received (case-insensitive), + * 7. the jwk header of the JWT does not contain a private key, + */ + // TODO: + + /* + * 8. the htm claim matches the HTTP method value of the HTTP request + * in which the JWT was received, */ if (_oauth2_dpop_htm_validate(log, request, clm_htm) == false) goto end; /* - * 7. the "htu" claims matches the HTTP URI value for the HTTP request - * in which the JWT was received, ignoring any query and fragment - * parts, + * 9. the htu claim matches the HTTPS URI value for the HTTP request + * in which the JWT was received, ignoring any query and fragment + * parts, */ if (_oauth2_dpop_htu_validate(log, request, clm_htu) == false) goto end; /* - * 8. the token was issued within an acceptable timeframe (see - * Section 9.1), and + * 10. if the server provided a nonce value to the client, the nonce + * claim matches the server-provided nonce value, + */ + // TODO: + + /* + * 11. the iat claim value is within an acceptable timeframe and, + * within a reasonable consideration of accuracy and resource + * utilization, a proof JWT with the same jti value has not + * previously been received at the same resource during that time + * period (see Section 11.1), */ if (_oauth2_dpop_iat_validate(log, verify, dpop_payload) == false) goto end; + if (_oauth2_dpop_jti_validate(log, verify, clm_jti, s_dpop) == false) + goto end; + /* - * 9. that, within a reasonable consideration of accuracy and resource - * utilization, a JWT with the same "jti" value has not been - * received previously (see Section 9.1). + * 12. if presented to a protected resource in conjunction with an + * access token, + * + * 1. ensure that the value of the ath claim equals the hash of + * that access token, */ - if (_oauth2_dpop_jti_validate(log, verify, s_dpop, clm_jti) == false) + if (_oauth2_dpop_ath_validate(log, verify, clm_ath, access_token) == + false) goto end; + /* + * 2. confirm that the public key to which the access token is + * bound matches the public key from the DPoP proof. + * + */ + // done in the calling function oauth2_dpop_token_verify with the "jkt" + // claim + rc = true; end: @@ -432,6 +575,10 @@ static bool _oauth2_dpop_parse_and_validate(oauth2_log_t *log, oauth2_mem_free(clm_htm); if (clm_jti) oauth2_mem_free(clm_jti); + if (clm_ath) + oauth2_mem_free(clm_ath); + if (clm_nonce) + oauth2_mem_free(clm_nonce); if (dpop_payload) json_decref(dpop_payload); if (jws) @@ -446,7 +593,7 @@ static bool _oauth2_dpop_parse_and_validate(oauth2_log_t *log, bool oauth2_dpop_token_verify(oauth2_log_t *log, oauth2_cfg_dpop_verify_t *verify, oauth2_http_request_t *request, - json_t *json_payload) + const char *access_token, json_t *json_payload) { bool rc = false; cjose_jwk_t *jwk = NULL; @@ -461,8 +608,8 @@ bool oauth2_dpop_token_verify(oauth2_log_t *log, if ((request == NULL) || (json_payload == NULL)) goto end; - if (_oauth2_dpop_parse_and_validate(log, verify, request, &jwk) == - false) + if (_oauth2_dpop_parse_and_validate(log, verify, request, access_token, + &jwk) == false) goto end; if (oauth2_jose_jwk_thumbprint(log, jwk, &hash_bytes, @@ -490,7 +637,7 @@ bool oauth2_dpop_token_verify(oauth2_log_t *log, (memcmp(hash_bytes, dst, hash_bytes_len)) != 0) { oauth2_error(log, "public key thumbprint in DPOP \"%s\" does not " - "match \"%s\" claim \%s\" in JWT token", + "match \"%s\" claim \%s\" for the access token", calc_thumb, OAUTH_DPOP_CLAIM_CNF_JKT, prov_thumb); goto end; } diff --git a/src/oauth2.c b/src/oauth2.c index 42a3dd8..28481d4 100644 --- a/src/oauth2.c +++ b/src/oauth2.c @@ -888,8 +888,8 @@ bool oauth2_token_verify(oauth2_log_t *log, oauth2_http_request_t *request, if (rc == true) { if (ptr->type == OAUTH2_TOKEN_VERIFY_DPOP) { - rc = oauth2_dpop_token_verify(log, &verify->dpop, - request, *json_payload); + rc = oauth2_dpop_token_verify( + log, &verify->dpop, request, token, *json_payload); } else if (ptr->type == OAUTH2_TOKEN_VERIFY_MTLS) { rc = oauth2_mtls_token_verify(log, &verify->mtls, request, *json_payload); diff --git a/src/oauth2_int.h b/src/oauth2_int.h index 92c74b3..075527c 100644 --- a/src/oauth2_int.h +++ b/src/oauth2_int.h @@ -39,6 +39,6 @@ bool oauth2_auth_basic(oauth2_log_t *log, oauth2_http_call_ctx_t *ctx, bool oauth2_dpop_token_verify(oauth2_log_t *log, oauth2_cfg_dpop_verify_t *verify, oauth2_http_request_t *request, - json_t *json_payload); + const char *access_token, json_t *json_payload); #endif /* _OAUTH2_INT_H_ */ diff --git a/test/check_oauth2.c b/test/check_oauth2.c index ff35ade..1eb9b5a 100644 --- a/test/check_oauth2.c +++ b/test/check_oauth2.c @@ -625,40 +625,49 @@ START_TEST(test_oauth2_verify_jwk_dpop) { bool rc = false; oauth2_cfg_token_verify_t *verify = NULL; - char *jwt = "eyJhbGciOiAiUlMyNTYifQ." - "ewogICJzdWIiOiAic29tZW9uZUBleGFtcGxlLmNvbSIsCiAgImlzcyI6IC" - "JodHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsCiAgImF1ZCI6ICJodHRw" - "czovL3Jlc291cmNlLmV4YW1wbGUub3JnIiwKICAibmJmIjogMTU2MjI2Mj" - "YxMSwKICAiZXhwIjogMTU2MjI2NjIxNiwKICAiY25mIjogewogICAgImpr" - "dCI6ICIwWmNPQ09SWk5ZeS1EV3BxcTMwalp5SkdIVE4wZDJIZ2xCVjN1aW" - "d1QTRJIgogIH0KfQ.o0j8O6PMQX4R-YPyiyNcdywMzHtUV3leeUn8X9w_" - "CHq_M9UQndIbsNrzClKD8wTm3LuSO3v6wMsdxSC7Ypk3iTMKZCWK66fx9-" - "BIo2d4fbJeC32YbL0FkSmZNzuqIPn1xfxoQ3Lx7_P9vS0k-" - "frefuoWWR8NmVDGXuCxVg1INtoC1QUUB3rCe3PnY8cNNfijlSGSArODffQ" - "XRR0CLULDGV87RgAeRZOHzfDc2lQr9ifLC8FfM6wRPBDCgljE5Ygyfc58x" - "FAIEW_GnVJzRV-WN83PMJ-le-DMDHLnk_" - "YvYbjKRG4Awr5OLm8jD8tc5YlwSZKRo7TOE_pGkctSTf1ang"; - char *jwk = "{\"kty\":\"RSA\",\"kid\":\"k1\",\"use\":\"sig\",\"n\":" - "\"ym7jipmB37CgdonwGFVRuZmRfCl3lVh91fmm5CXHcNlUFZNR3D6Q9r63" - "PpGRnfSsX3dOweh8BXd2AJ3mxvcE4z9xH--tA5EaOGI7IVF0Ip_" - "i3flGg85xOADlb8rX3ez1NqkqMVJeeJypKhCCDNfvu_" - "MXSdPLglU969YQF5xKAK8VFRfI6EfxxrZ_3Dvt2CKDV4LTPPJe9KI2_" - "LuLQFBJ3MzlCTVxY6gyaljrWaDq7q5Lt3GB1KYS0Yd8COEQwsclOLm0Tdd" - "hg4cle-DfaTMi7xsTZsPKyac5x17Y4N4isHhZULuWHX7o1bs809xcj-_-" - "YCRq6C61je_mzFhuF4pczw\",\"e\":\"AQAB\"}"; + char *jwt = + "eyJhbGciOiJSUzI1NiIsImtpZCI6ImsxIiwicGkuYXRtIjoiMSJ9." + "eyJzY29wZSI6WyJvcGVuaWQiXSwiYXV0aG9yaXphdGlvbl9kZXRhaWxzIjpbXSwiY2" + "xpZW50X2lkX25hbWUiOiJyb19jbGllbnQiLCJVc2VybmFtZSI6ImpvZSIsIk9yZ05h" + "bWUiOiJQaW5nIElkZW50aXR5IENvcnBvcmF0aW9uIiwiY25mIjp7ImprdCI6InZBcG" + "RWSVBLenNwMXpzSzVjQ25JTmRLOEdKU0Z3VlNSeV9IZ1VFNDBYUGsifSwiZXhwIjox" + "Njk5NDUyNDYzfQ.DihED2HcrAkW9ItLYIAqeweOEyI_" + "qqcCfMVmHNEnIpvz7GeaYFQ6E3edj1AWU09NsUa3W3mV5Ze6-" + "zgeSwXQf9yEs2TVO88Ye6zpv3F1SPlO8Zhue4qGZJpdKtyz_sPCGRd2v_" + "1N6ji9m1IyNzJwiMD32molHWpcIRytke2hG9AZvxzcmJ1lwd0ReVyV8payUmxtVcwN" + "yKzTmX-XNV7kNP6DZsnJTOYFgJ98punDpdorpIMFwjOTcFk8zMFdHO9rdR_" + "jUI4NGXlfmLXtTrS-FdSd3bRDQFuJA5qGdNie-5vS-kfeIUCaAQZFXR6MsD-Dz_" + "xKPhuDQecbDiIj5s726Q"; + char *jwk = + "{\"kty\":\"RSA\",\"kid\":\"k1\",\"use\":\"sig\",\"n\":" + "\"hKvkosOyK33gznaRCNgakMLE2GHS5_7K34oqZRsAWC-7aC420eJNL2z_" + "8Z7ouWXpJNZ2YHQcqxPe4UZGtiDiFYLdDbQPrCDiTpuRYybe1UmZJ3Kk5fBx9yXKU0" + "zbdSKYPEeq1w5Fi7rt46YkZ6qwv3Yixo7eTxbglezJOx_YcS5sfXxcwBU1nYbGU_" + "MgrBXAfy1Hea5tcUSPot-BTMcuj_doHLT_sEm4AZwaZiLhMiqfI-" + "J6Gv5Hg6aBTXpYv50DEdcoZzkabMHxjHICS9w2FGWAzMt_" + "AvW4ISlbAxlBroXhTEXC6GIJwoDTskuPlCO4CVa3axh0s1D49JFJoBYasw\"," + "\"e\":\"AQAB\"}"; char *dpop = - "eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik" - "VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdC" - "R" - "nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1J" - "E" - "QSIsImNydiI6IlAtMjU2In19." - "eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj" - "oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0" - "Z" - "WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOH0." - "lNhmpAX1WwmpBvwhok4E74kWCiGB" - "NdavjLAeevGy32H3dbF0Jbri69Nm2ukkwb-uyUI4AUg1JSskfWIyo4UCbQ"; + "eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IlJTMjU2IiwiandrIjp7Imt0eSI6IlJTQS" + "IsImUiOiJBUUFCIiwibiI6InJiOXZ5ekFJaVFqQUVFdGFTZnJnU2NSVHotVnNEZ2hp" + "b1Z2ajNJNnlZbHJ2TFdaNHFWdEtzUDNQU3Z4dTNVejdWTWRwVFEyODc5WlRGVWh0LV" + "9Cc3M1NHNtOUdJTTZQVGRZY3VDN3dOMHR2N2JHMDNsVGdOUFdvcmZrMzRhSVk1NHh1" + "Tmo5SHNBVnJKRG1NWklWTnBOUGZabXcwcDVheFBVQ19OTEw4YVhUeDJnWFZFV3V4dG" + "NXSjFzbzFHVE5pbXZPMXM1eklTaDZvTXlDVFRhQ1N2el9DYWVwektTeXZfc00yWk9Y" + "VkhUVzZ2SEM4Q0tMY2VwT1NFLWx0UXV3TUF6MWxEU0szQ0hURFRTMVNzdEpVMklKam" + "hobnFwVVgzVHNxQ0E5em9PQlk4aXVRd3hCTDBicFl4T0dVZ21oNXU0Sm90bFlzZkU0" + "T3FMdG1ueGJuSzdydyJ9fQ." + "eyJqdGkiOiIrSmJDS3hrazFUNXQ4bys1IiwiaHRtIjoiR0VUIiwiaHR1IjoiaHR0cH" + "M6Ly9sb2NhbGhvc3Quem1hcnR6b25lLmV1L2FwaS8iLCJpYXQiOjE2OTk0NDUyNjMs" + "ImF0aCI6Ikd6TkR1S1poVHd5dHppN09rd3VXMjhwQ0xTb0paZ2xmN1pNRG94SGQ2dk" + "kifQ.K-" + "xn9siYFnhi3y5gejKwwIEzD2uKmmtfqV0XDbHh7JZ2RNQJfBNpyiEhSUT5dXc5AY8h" + "RzUyWmi4cmE0yW97FKphZdbeumFBGuLiTyMQNVTUWdjMOS7-uWV27bZXj-KaI3C9c_" + "mNHjsuW_Ax5LSK35u8Iw_A25EXrJhezzAP74chiKJN1pw3eq_2EZlUF-" + "ihz7Y045sW56EBf-4SCJUfOhGnrb7rHg3KXMiOcSdEnzFiaTSYOozlMZxFvY-" + "VnaqksBZ17-mGMSi7K_" + "9QdBac7ick7OQ7VecYittd5nmnvrRaGytJdJYOSfB5HDPtoaXFNGj24yaJan3IOr2H" + "bg2t8A"; json_t *json_payload = NULL; oauth2_http_request_t *request = NULL; const char *rv = NULL; @@ -681,9 +690,10 @@ START_TEST(test_oauth2_verify_jwk_dpop) request = oauth2_http_request_init(_log); oauth2_http_request_scheme_set(_log, request, "https"); - oauth2_http_request_hostname_set(_log, request, "resource.example.org"); + oauth2_http_request_hostname_set(_log, request, + "localhost.zmartzone.eu"); // oauth2_http_request_port_set(); - oauth2_http_request_path_set(_log, request, "/protectedresource"); + oauth2_http_request_path_set(_log, request, "/api/"); oauth2_http_request_method_set(_log, request, OAUTH2_HTTP_METHOD_GET); oauth2_http_request_header_set(_log, request, "DPoP", dpop);