@@ -2236,33 +2236,78 @@ oauth2_jose_jwks_eckey_url_resolve(oauth2_log_t *log,
2236
2236
_oauth2_jose_jwks_eckey_url_resolve_response_callback );
2237
2237
}
2238
2238
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
+
2239
2262
static oauth2_jose_jwk_list_t *
2240
2263
oauth2_jose_jwks_aws_alb_resolve (oauth2_log_t * log ,
2241
2264
oauth2_jose_jwks_provider_t * provider ,
2242
2265
bool * refresh , const cjose_header_t * hdr )
2243
2266
{
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 ;
2266
2311
}
2267
2312
2268
2313
/*
0 commit comments