@@ -707,13 +707,15 @@ void oauth2_jose_jwk_list_free(oauth2_log_t *log, oauth2_jose_jwk_list_t *keys)
707707
708708static oauth2_jose_jwk_list_t *
709709oauth2_jose_jwks_list_resolve (oauth2_log_t * , oauth2_jose_jwks_provider_t * ,
710- bool * );
710+ bool * , cjose_header_t * );
711711static oauth2_jose_jwk_list_t *
712712oauth2_jose_jwks_uri_resolve (oauth2_log_t * , oauth2_jose_jwks_provider_t * ,
713- bool * );
713+ bool * , cjose_header_t * );
714+ static oauth2_jose_jwk_list_t * oauth2_jose_jwks_eckey_url_resolve (
715+ oauth2_log_t * , oauth2_jose_jwks_provider_t * , bool * , cjose_header_t * );
714716static oauth2_jose_jwk_list_t *
715- oauth2_jose_jwks_eckey_url_resolve (oauth2_log_t * ,
716- oauth2_jose_jwks_provider_t * , bool * );
717+ oauth2_jose_jwks_aws_alb_resolve (oauth2_log_t * , oauth2_jose_jwks_provider_t * ,
718+ bool * , cjose_header_t * );
717719
718720static oauth2_jose_jwks_provider_t *
719721_oauth2_jose_jwks_provider_init (oauth2_log_t * log ,
@@ -737,6 +739,12 @@ _oauth2_jose_jwks_provider_init(oauth2_log_t *log,
737739 provider -> jwks_uri = oauth2_uri_ctx_init (log );
738740 provider -> resolve = oauth2_jose_jwks_eckey_url_resolve ;
739741 break ;
742+ case OAUTH2_JOSE_JWKS_PROVIDER_AWS_ALB :
743+ provider -> jwks_uri = oauth2_uri_ctx_init (log );
744+ provider -> resolve = oauth2_jose_jwks_aws_alb_resolve ;
745+ provider -> alb_arn = NULL ;
746+ provider -> alb_base_url = NULL ;
747+ break ;
740748 }
741749
742750 return provider ;
@@ -765,6 +773,11 @@ _oauth2_jose_jwks_provider_clone(oauth2_log_t *log,
765773 case OAUTH2_JOSE_JWKS_PROVIDER_ECKEY_URI :
766774 dst -> jwks_uri = oauth2_uri_ctx_clone (log , src -> jwks_uri );
767775 break ;
776+ case OAUTH2_JOSE_JWKS_PROVIDER_AWS_ALB :
777+ dst -> jwks_uri = oauth2_uri_ctx_clone (log , src -> jwks_uri );
778+ dst -> alb_arn = oauth2_strdup (src -> alb_arn );
779+ dst -> alb_base_url = oauth2_strdup (src -> alb_base_url );
780+ break ;
768781 }
769782
770783end :
@@ -790,6 +803,14 @@ _oauth2_jose_jwks_provider_free(oauth2_log_t *log,
790803 if (provider -> jwks_uri )
791804 oauth2_uri_ctx_free (log , provider -> jwks_uri );
792805 break ;
806+ case OAUTH2_JOSE_JWKS_PROVIDER_AWS_ALB :
807+ if (provider -> jwks_uri )
808+ oauth2_uri_ctx_free (log , provider -> jwks_uri );
809+ if (provider -> alb_arn )
810+ oauth2_mem_free (provider -> alb_arn );
811+ if (provider -> alb_base_url )
812+ oauth2_mem_free (provider -> alb_base_url );
813+ break ;
793814 }
794815
795816 oauth2_mem_free (provider );
@@ -1292,7 +1313,7 @@ bool oauth2_jose_jwt_verify(oauth2_log_t *log,
12921313 if (jwt_verify_ctx ) {
12931314
12941315 keys = jwt_verify_ctx -> jwks_provider -> resolve (
1295- log , jwt_verify_ctx -> jwks_provider , & refresh );
1316+ log , jwt_verify_ctx -> jwks_provider , & refresh , hdr );
12961317
12971318 ctx .jws = jws ;
12981319 ctx .kid = cjose_header_get (hdr , "kid" , & err );
@@ -1309,7 +1330,7 @@ bool oauth2_jose_jwt_verify(oauth2_log_t *log,
13091330 if (keys )
13101331 oauth2_jose_jwk_list_free (log , keys );
13111332 keys = jwt_verify_ctx -> jwks_provider -> resolve (
1312- log , jwt_verify_ctx -> jwks_provider , & refresh );
1333+ log , jwt_verify_ctx -> jwks_provider , & refresh , hdr );
13131334 _oauth2_jose_verification_keys_loop (
13141335 log , keys , _oauth2_jose_jwt_verify_jwk , & ctx );
13151336
@@ -1846,8 +1867,46 @@ _OAUTH_CFG_CTX_CALLBACK(oauth2_jose_verify_options_jwk_set_eckey_uri)
18461867 "eckey_uri" );
18471868}
18481869
1849- static oauth2_jose_jwk_list_t * oauth2_jose_jwks_list_resolve (
1850- oauth2_log_t * log , oauth2_jose_jwks_provider_t * provider , bool * refresh )
1870+ _OAUTH_CFG_CTX_CALLBACK (oauth2_jose_verify_options_jwk_set_aws_alb )
1871+ {
1872+ char * rv = NULL ;
1873+ oauth2_cfg_token_verify_t * verify = (oauth2_cfg_token_verify_t * )ctx ;
1874+ const char * alb_base_url = NULL ;
1875+
1876+ oauth2_debug (log , "enter" );
1877+
1878+ rv = _oauth2_jose_verify_options_jwk_set_url (
1879+ log , value , params , verify , OAUTH2_JOSE_JWKS_PROVIDER_AWS_ALB ,
1880+ "aws_alb" );
1881+ if (rv != NULL )
1882+ goto end ;
1883+
1884+ oauth2_jose_jwt_verify_ctx_t * ptr = verify -> ctx -> ptr ;
1885+
1886+ // this is going to be set dynamically
1887+ if (ptr -> jwks_provider -> jwks_uri -> endpoint -> url ) {
1888+ oauth2_mem_free (ptr -> jwks_provider -> jwks_uri -> endpoint -> url );
1889+ ptr -> jwks_provider -> jwks_uri -> endpoint -> url = NULL ;
1890+ }
1891+
1892+ ptr -> jwks_provider -> alb_arn = oauth2_strdup (value );
1893+
1894+ alb_base_url = oauth2_nv_list_get (log , params , "alb_base_url" );
1895+ if (alb_base_url ) {
1896+ ptr -> jwks_provider -> alb_base_url = oauth2_strdup (alb_base_url );
1897+ }
1898+
1899+ end :
1900+
1901+ oauth2_debug (log , "leave: %s" , rv );
1902+
1903+ return rv ;
1904+ }
1905+
1906+ static oauth2_jose_jwk_list_t *
1907+ oauth2_jose_jwks_list_resolve (oauth2_log_t * log ,
1908+ oauth2_jose_jwks_provider_t * provider ,
1909+ bool * refresh , cjose_header_t * hdr )
18511910{
18521911 * refresh = false;
18531912 return oauth2_jose_jwk_list_clone (log , provider -> jwks );
@@ -2171,22 +2230,107 @@ static oauth2_jose_jwk_list_t *_oauth2_jose_jwks_resolve_from_uri(
21712230 return dst ;
21722231}
21732232
2174- static oauth2_jose_jwk_list_t * oauth2_jose_jwks_uri_resolve (
2175- oauth2_log_t * log , oauth2_jose_jwks_provider_t * provider , bool * refresh )
2233+ static oauth2_jose_jwk_list_t *
2234+ oauth2_jose_jwks_uri_resolve (oauth2_log_t * log ,
2235+ oauth2_jose_jwks_provider_t * provider ,
2236+ bool * refresh , cjose_header_t * hdr )
21762237{
21772238 return _oauth2_jose_jwks_resolve_from_uri (
21782239 log , provider , refresh ,
21792240 _oauth2_jose_jwks_uri_resolve_response_callback );
21802241}
21812242
2182- static oauth2_jose_jwk_list_t * oauth2_jose_jwks_eckey_url_resolve (
2183- oauth2_log_t * log , oauth2_jose_jwks_provider_t * provider , bool * refresh )
2243+ static oauth2_jose_jwk_list_t *
2244+ oauth2_jose_jwks_eckey_url_resolve (oauth2_log_t * log ,
2245+ oauth2_jose_jwks_provider_t * provider ,
2246+ bool * refresh , cjose_header_t * hdr )
21842247{
21852248 return _oauth2_jose_jwks_resolve_from_uri (
21862249 log , provider , refresh ,
21872250 _oauth2_jose_jwks_eckey_url_resolve_response_callback );
21882251}
21892252
2253+ static const char * _oauth2_jose_jwks_aws_alb_region (const char * arn )
2254+ {
2255+ if (!arn )
2256+ return NULL ;
2257+
2258+ char * arn_copy = oauth2_strdup (arn );
2259+ if (!arn_copy )
2260+ return NULL ;
2261+
2262+ char * token = strtok (arn_copy , ":" );
2263+ int count = 0 ;
2264+ const char * region = NULL ;
2265+
2266+ while (token ) {
2267+ if (count == 3 ) {
2268+ region = oauth2_strdup (token );
2269+ break ;
2270+ }
2271+ token = strtok (NULL , ":" );
2272+ count ++ ;
2273+ }
2274+
2275+ oauth2_mem_free (arn_copy );
2276+ return region ;
2277+ }
2278+
2279+ static oauth2_jose_jwk_list_t *
2280+ oauth2_jose_jwks_aws_alb_resolve (oauth2_log_t * log ,
2281+ oauth2_jose_jwks_provider_t * provider ,
2282+ bool * refresh , cjose_header_t * hdr )
2283+ {
2284+ cjose_err err ;
2285+ char * url = NULL ;
2286+ const char * region = NULL ;
2287+
2288+ const char * signer = cjose_header_get (hdr , "signer" , & err );
2289+ const char * kid = cjose_header_get (hdr , "kid" , & err );
2290+
2291+ if (!signer || !kid ) {
2292+ oauth2_error (log ,
2293+ "missing 'signer' or 'kid' in JWT header: "
2294+ "signer=%s, kid=%s" ,
2295+ signer , kid );
2296+ return NULL ;
2297+ }
2298+
2299+ if (strcmp (signer , provider -> alb_arn ) != 0 ) {
2300+ oauth2_error (
2301+ log ,
2302+ "signer does not match configured ARN: signer=%s, arn=%s" ,
2303+ signer , provider -> alb_arn );
2304+ return NULL ;
2305+ }
2306+
2307+ if (provider -> alb_base_url == NULL ) {
2308+ region = _oauth2_jose_jwks_aws_alb_region (provider -> alb_arn );
2309+ if (!region ) {
2310+ oauth2_error (
2311+ log , "failed to extract region from ARN: arn=%s" ,
2312+ provider -> alb_arn );
2313+ return NULL ;
2314+ }
2315+ url = _oauth2_stradd4 (NULL , "https://public-keys.auth.elb." ,
2316+ region , ".amazonaws.com/" , kid );
2317+ } else {
2318+ url = oauth2_stradd (NULL , provider -> alb_base_url , kid , NULL );
2319+ }
2320+ oauth2_debug (log , "constructed ALB JWKs URL: %s" , url );
2321+
2322+ provider -> jwks_uri -> endpoint -> url = url ;
2323+
2324+ oauth2_jose_jwk_list_t * result = _oauth2_jose_jwks_resolve_from_uri (
2325+ log , provider , refresh ,
2326+ _oauth2_jose_jwks_eckey_url_resolve_response_callback );
2327+
2328+ provider -> jwks_uri -> endpoint -> url = NULL ;
2329+ oauth2_mem_free (url );
2330+
2331+ return result ;
2332+ }
2333+
21902334/*
21912335oauth2_jose_jwk_list_t *
21922336oauth2_jose_jwks_resolve(oauth2_log_t *log, oauth2_cfg_token_verify_t *verify,
0 commit comments