@@ -2236,33 +2236,78 @@ oauth2_jose_jwks_eckey_url_resolve(oauth2_log_t *log,
22362236 _oauth2_jose_jwks_eckey_url_resolve_response_callback );
22372237}
22382238
2239+ static const char * _oauth2_jose_jwks_aws_alb_region (const char * arn ) {
2240+ if (!arn ) return NULL ;
2241+
2242+ char * arn_copy = oauth2_strdup (arn );
2243+ if (!arn_copy ) return NULL ;
2244+
2245+ char * token = strtok (arn_copy , ":" );
2246+ int count = 0 ;
2247+ const char * region = NULL ;
2248+
2249+ while (token ) {
2250+ if (count == 3 ) {
2251+ region = oauth2_strdup (token );
2252+ break ;
2253+ }
2254+ token = strtok (NULL , ":" );
2255+ count ++ ;
2256+ }
2257+
2258+ oauth2_mem_free (arn_copy );
2259+ return region ;
2260+ }
2261+
22392262static oauth2_jose_jwk_list_t *
22402263oauth2_jose_jwks_aws_alb_resolve (oauth2_log_t * log ,
22412264 oauth2_jose_jwks_provider_t * provider ,
22422265 bool * refresh , const cjose_header_t * hdr )
22432266{
2244- /*
2245- * 1. pull the 'signer' and `kid` claims from the header (a typedef-ed
2246- * JSON object)
2247- * 2. check it against the configured provider->arb_arn value, and if
2248- * they match:
2249- * 3. construct the EC keys URL:
2250- * https://public-keys.auth.elb.<region from
2251- * ALB_ARN>.amazonaws.com/<kid>
2252- * TODO: make the base URL configurable in
2253- * oauth2_jose_verify_options_jwk_set_aws_alb and add a member
2254- * alb_arn_base_url to oauth2_jose_jwks_provider_t
2255- * 4. construct a temporary provider->jwks_uri
2256- * 5. call:
2257- * _oauth2_jose_jwks_resolve_from_uri(log, provider, refresh,
2258- * oauth2_jose_jwks_eckey_url_resolve_response_callback);
2259- * and save the result (oauth2_jose_jwk_list_t *)
2260- * 6. free the temporary provider->jwks_uri (TODO: caching?)
2261- * 7. return the result
2262- *
2263- * add unit tests
2264- */
2265- return NULL ;
2267+ cjose_err err ;
2268+
2269+ // TODO - error here, issue with const cjose_header_t *hdr
2270+ const char * signer = cjose_header_get (hdr , "signer" , & err );
2271+ const char * kid = cjose_header_get (hdr , "kid" , & err );
2272+
2273+ if (!signer || !kid ) {
2274+ oauth2_error (log , "missing 'signer' or 'kid' in JWT header: signer=%s, kid=%s" , signer , kid );
2275+ return NULL ;
2276+ }
2277+
2278+ // TODO - determine if theres a better place for this?
2279+ // TODO - maybe needed? timing safe compare?
2280+ if (strcmp (signer , provider -> alb_arn ) != 0 ) {
2281+ oauth2_error (log , "signer does not match configured ARN: signer=%s, arn=%s" , signer , provider -> alb_arn );
2282+ return NULL ;
2283+ }
2284+
2285+ const char * region = _oauth2_jose_jwks_aws_alb_region (provider -> alb_arn );
2286+ if (!region ) {
2287+ oauth2_error (log , "failed to extract region from ARN: arn=%s" , provider -> alb_arn );
2288+ return NULL ;
2289+ }
2290+
2291+ size_t url_len = strlen ("https://public-keys.auth.elb." ) + strlen (region ) + strlen (".amazonaws.com/" ) + strlen (kid ) + 1 ;
2292+ char * url = oauth2_mem_alloc (url_len );
2293+ if (!url ) {
2294+ oauth2_error (log , "oauth2_mem_alloc failed for JWKS URL" );
2295+ return NULL ;
2296+ }
2297+
2298+ oauth2_snprintf (url , url_len , "https://public-keys.auth.elb.%s.amazonaws.com/%s" , region , kid );
2299+ oauth2_debug (log , "constructed JWKS URL: %s" , url );
2300+
2301+ // TODO - should probably be a copy of provider?
2302+ oauth2_cfg_endpoint_set_url (provider -> jwks_uri -> endpoint , url );
2303+
2304+ oauth2_jose_jwk_list_t * result = _oauth2_jose_jwks_resolve_from_uri (
2305+ log , provider , refresh , oauth2_jose_jwks_eckey_url_resolve_response_callback
2306+ );
2307+
2308+ oauth2_mem_free (url );
2309+
2310+ return result ;
22662311}
22672312
22682313/*
0 commit comments