Skip to content

Commit

Permalink
remove obsolete support for Token Binding RFC 8471
Browse files Browse the repository at this point in the history
Signed-off-by: Hans Zandbelt <[email protected]>
  • Loading branch information
zandbelt committed Oct 31, 2023
1 parent 167acb2 commit f9a5250
Show file tree
Hide file tree
Showing 13 changed files with 9 additions and 432 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
10/31/2023
- add capability to seamlessly rollover OIDCCryptoPassphrase using a (temporary) 2nd value that holds the old one
- bump to 2.4.15rc1
- remove obsolete support for Token Binding https://www.rfc-editor.org/rfc/rfc8471.html (id_token, access_token, session cookie)

10/30/2023
- do not apply logout_on_error and authenticate_on_error when a parallel refresh token request is detected
Expand Down
19 changes: 0 additions & 19 deletions auth_openidc.conf
Original file line number Diff line number Diff line change
Expand Up @@ -301,15 +301,6 @@
# NB: this can be overridden on a per-OP basis in the .conf file using the key: pkce_method
#OIDCPKCEMethod [plain|S256|referred_tb]

# The OpenID Connect Bound Authentication policy used,
# see: http://openid.net/specs/openid-connect-token-bound-authentication-1_0.html
# "disabled": no referred token binding will be requested from the User Agent upon redirection to the OP
# "optional": referred token binding will be requested, the "cnf["tbh"]" claim is optional on return
# "required": referred token binding will be requested, the "cnf["tbh"]" claim must be present when the Client supports Token Binding
# "enforced": referred token binding will be requested, the "cnf["tbh"]" claim must be present and the User Agent must support Token Binding
# When not defined the default is "optional".
#OIDCTokenBindingPolicy [disabled|optional|required|enforced]

# (used only in dynamic client registration)
# Define the Client JWKs URL (e.g. https://localhost/protected/?jwks=rsa)") that will be
# used during client registration to point to the JWK set with public keys for this client.
Expand Down Expand Up @@ -496,16 +487,6 @@
# When not defined the default "header" is used.
#OIDCOAuthAcceptTokenAs [header|post|query|cookie[:<cookie-name>|basic]+

# The Token Binding policy used for OAuth 2.0 Access Tokens
# see: https://tools.ietf.org/html/draft-ietf-oauth-token-binding
# "disabled": no token binding ID will be verified in the access token, present or not
# "optional": the "cnf["tbh"]" claim is optional in the introspection result or the JWT access token, if it is present it will be verified
# "required": the "cnf["tbh"]" claim must be present when the Client supports Token Binding
# "enforced": the "cnf["tbh"]" claim must be present and the Client must support Token Binding
# When not defined the default is "optional".
#OIDCOAuthAccessTokenBindingPolicy [disabled|optional|required|enforced]


########################################################################################
#
# Cookie Settings
Expand Down
51 changes: 0 additions & 51 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,6 @@
#define OIDC_DEFAULT_UNAUTZ_ACTION OIDC_UNAUTZ_RETURN403
/* defines for how long provider metadata will be cached */
#define OIDC_DEFAULT_PROVIDER_METADATA_REFRESH_INTERVAL 0
/* defines the default token binding policy for a provider */
#define OIDC_DEFAULT_PROVIDER_TOKEN_BINDING_POLICY OIDC_TOKEN_BINDING_POLICY_OPTIONAL
/* defines the default token binding policy for OAuth 2.0 access tokens */
#define OIDC_DEFAULT_OAUTH_ACCESS_TOKEN_BINDING_POLICY OIDC_TOKEN_BINDING_POLICY_OPTIONAL
/* define the default HTTP method used to send the authentication request to the provider */
#define OIDC_DEFAULT_AUTH_REQUEST_METHOD OIDC_AUTH_REQUEST_METHOD_GET
/* define whether the issuer will be added to the redirect uri by default to mitigate the IDP mixup attack */
Expand Down Expand Up @@ -205,7 +201,6 @@
#define OIDCUserInfoEncryptedResponseAlg "OIDCUserInfoEncryptedResponseAlg"
#define OIDCUserInfoEncryptedResponseEnc "OIDCUserInfoEncryptedResponseEnc"
#define OIDCUserInfoTokenMethod "OIDCUserInfoTokenMethod"
#define OIDCTokenBindingPolicy "OIDCTokenBindingPolicy"
#define OIDCSSLValidateServer "OIDCSSLValidateServer"
#define OIDCValidateIssuer "OIDCValidateIssuer"
#define OIDCClientName "OIDCClientName"
Expand Down Expand Up @@ -284,7 +279,6 @@
#define OIDCProviderAuthRequestMethod "OIDCProviderAuthRequestMethod"
#define OIDCBlackListedClaims "OIDCBlackListedClaims"
#define OIDCOAuthServerMetadataURL "OIDCOAuthServerMetadataURL"
#define OIDCOAuthAccessTokenBindingPolicy "OIDCOAuthAccessTokenBindingPolicy"
#define OIDCRefreshAccessTokenBeforeExpiry "OIDCRefreshAccessTokenBeforeExpiry"
#define OIDCStateInputHeaders "OIDCStateInputHeaders"
#define OIDCRedirectURLsAllowed "OIDCRedirectURLsAllowed"
Expand Down Expand Up @@ -777,8 +771,6 @@ const char* oidc_parse_pkce_type(apr_pool_t *pool, const char *arg,
*type = &oidc_pkce_plain;
} else if (_oidc_strcmp(arg, OIDC_PKCE_METHOD_S256) == 0) {
*type = &oidc_pkce_s256;
} else if (_oidc_strcmp(arg, OIDC_PKCE_METHOD_REFERRED_TB) == 0) {
*type = &oidc_pkce_referred_tb;
}

return NULL;
Expand Down Expand Up @@ -1291,20 +1283,6 @@ static const char* oidc_set_filtered_claims(cmd_parms *cmd, void *m,
return NULL;
}

/*
* set the token binding policy
*/
static const char* oidc_set_token_binding_policy(cmd_parms *cmd,
void *struct_ptr, const char *arg) {
oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
&auth_openidc_module);
int offset = (int) (long) cmd->info;
int *token_binding_policy = (int*) ((char*) cfg + offset);
const char *rv = oidc_parse_token_binding_policy(cmd->pool, arg,
token_binding_policy);
return OIDC_CONFIG_DIR_RV(cmd, rv);
}

/*
* set the claim prefix
*/
Expand Down Expand Up @@ -1772,11 +1750,6 @@ static void oidc_merge_provider_config(apr_pool_t *pool, oidc_provider_t *dst,
add->request_object != NULL ?
add->request_object : base->request_object;

dst->token_binding_policy =
add->token_binding_policy
!= OIDC_DEFAULT_PROVIDER_TOKEN_BINDING_POLICY ?
add->token_binding_policy : base->token_binding_policy;

dst->issuer_specific_redirect_uri =
add->issuer_specific_redirect_uri
!= OIDC_DEFAULT_PROVIDER_ISSUER_SPECIFIC_REDIRECT_URI ?
Expand Down Expand Up @@ -1850,9 +1823,6 @@ void* oidc_create_server_config(apr_pool_t *pool, server_rec *svr) {
c->oauth.verify_public_keys = NULL;
c->oauth.verify_shared_keys = NULL;

c->oauth.access_token_binding_policy =
OIDC_DEFAULT_OAUTH_ACCESS_TOKEN_BINDING_POLICY;

c->cache = &oidc_cache_shm;
c->cache_cfg = NULL;
c->cache_encrypt = OIDC_CONFIG_POS_INT_UNSET;
Expand Down Expand Up @@ -1925,9 +1895,6 @@ void* oidc_create_server_config(apr_pool_t *pool, server_rec *svr) {
c->provider_metadata_refresh_interval =
OIDC_DEFAULT_PROVIDER_METADATA_REFRESH_INTERVAL;

c->provider.token_binding_policy =
OIDC_DEFAULT_PROVIDER_TOKEN_BINDING_POLICY;

c->info_hook_data = NULL;
c->black_listed_claims = NULL;
c->white_listed_claims = NULL;
Expand Down Expand Up @@ -2068,12 +2035,6 @@ void* oidc_merge_server_config(apr_pool_t *pool, void *BASE, void *ADD) {
add->oauth.verify_shared_keys :
base->oauth.verify_shared_keys;

c->oauth.access_token_binding_policy =
add->oauth.access_token_binding_policy
!= OIDC_DEFAULT_OAUTH_ACCESS_TOKEN_BINDING_POLICY ?
add->oauth.access_token_binding_policy :
base->oauth.access_token_binding_policy;

c->http_timeout_long.request_timeout =
add->http_timeout_long.request_timeout != OIDC_DEFAULT_HTTP_REQUEST_TIMEOUT_LONG ?
add->http_timeout_long.request_timeout :
Expand Down Expand Up @@ -3397,12 +3358,6 @@ const command_rec oidc_config_cmds[] = {
(void *)APR_OFFSETOF(oidc_cfg, provider.userinfo_token_method),
RSRC_CONF,
"The method that is used to present the access token to the userinfo endpoint; must be one of [authz_header|post_param]"),
AP_INIT_TAKE1(OIDCTokenBindingPolicy,
oidc_set_token_binding_policy,
(void *)APR_OFFSETOF(oidc_cfg, provider.token_binding_policy),
RSRC_CONF,
"The token binding policy used with the provider; must be one of [disabled|optional|required|enforced]"),

AP_INIT_TAKE1(OIDCSSLValidateServer,
oidc_set_ssl_validate_slot,
(void*)APR_OFFSETOF(oidc_cfg, provider.ssl_validate_server),
Expand Down Expand Up @@ -3893,12 +3848,6 @@ const command_rec oidc_config_cmds[] = {
(void*)APR_OFFSETOF(oidc_cfg, oauth.metadata_url),
RSRC_CONF,
"Authorization Server metadata URL."),
AP_INIT_TAKE1(OIDCOAuthAccessTokenBindingPolicy,
oidc_set_token_binding_policy,
(void *)APR_OFFSETOF(oidc_cfg, oauth.access_token_binding_policy),
RSRC_CONF,
"The token binding policy used for access tokens; must be one of [disabled|optional|required|enforced]"),

AP_INIT_TAKE12(OIDCRefreshAccessTokenBeforeExpiry,
oidc_set_refresh_access_token_before_expiry,
(void *)APR_OFFSETOF(oidc_dir_cfg, refresh_access_token_before_expiry),
Expand Down
22 changes: 1 addition & 21 deletions src/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ extern module AP_MODULE_DECLARE_DATA auth_openidc_module;
#define OIDC_METADATA_FRONTCHANNEL_LOGOUT_URI "frontchannel_logout_uri"
#define OIDC_METADATA_BACKCHANNEL_LOGOUT_URI "backchannel_logout_uri"
#define OIDC_METADATA_POST_LOGOUT_REDIRECT_URIS "post_logout_redirect_uris"
#define OIDC_METADATA_IDTOKEN_BINDING_CNF "id_token_token_binding_cnf"
#define OIDC_METADATA_SSL_VALIDATE_SERVER "ssl_validate_server"
#define OIDC_METADATA_VALIDATE_ISSUER "validate_issuer"
#define OIDC_METADATA_SCOPE "scope"
Expand All @@ -115,7 +114,6 @@ extern module AP_MODULE_DECLARE_DATA auth_openidc_module;
#define OIDC_METADATA_TOKEN_ENDPOINT_TLS_CLIENT_KEY_PWD "token_endpoint_tls_client_key_pwd"
#define OIDC_METADATA_REQUEST_OBJECT "request_object"
#define OIDC_METADATA_USERINFO_TOKEN_METHOD "userinfo_token_method"
#define OIDC_METADATA_TOKEN_BINDING_POLICY "token_binding_policy"
#define OIDC_METADATA_AUTH_REQUEST_METHOD "auth_request_method"
#define OIDC_METADATA_ISSUER_SPECIFIC_REDIRECT_URI "issuer_specific_redirect_uri"

Expand Down Expand Up @@ -580,11 +578,6 @@ static apr_byte_t oidc_metadata_client_register(request_rec *r, oidc_cfg *cfg,
OIDC_REDIRECT_URI_REQUEST_LOGOUT,
OIDC_BACKCHANNEL_STYLE_LOGOUT_PARAM_VALUE)));

if (provider->token_binding_policy > OIDC_TOKEN_BINDING_POLICY_DISABLED) {
json_object_set_new(data, OIDC_METADATA_IDTOKEN_BINDING_CNF,
json_string(OIDC_CLAIM_CNF_TBH));
}

if (cfg->default_slo_url != NULL) {
json_object_set_new(data, OIDC_METADATA_POST_LOGOUT_REDIRECT_URIS,
json_pack("[s]",
Expand Down Expand Up @@ -667,8 +660,7 @@ static apr_byte_t oidc_metadata_jwks_retrieve_and_cache(request_rec *r,
}

// TODO: add issuer?
if (oidc_proto_validate_jwt(r, jwt, NULL, TRUE, FALSE, -1,
OIDC_TOKEN_BINDING_POLICY_DISABLED) == FALSE)
if (oidc_proto_validate_jwt(r, jwt, NULL, TRUE, FALSE, -1) == FALSE)
return FALSE;

oidc_debug(r, "successfully verified and validated JWKs JWT");
Expand Down Expand Up @@ -1417,18 +1409,6 @@ apr_byte_t oidc_metadata_conf_parse(request_rec *r, oidc_cfg *cfg,
else
provider->userinfo_token_method = OIDC_USER_INFO_TOKEN_METHOD_HEADER;

/* see if we've got a custom token binding policy */
char *policy = NULL;
oidc_metadata_get_valid_string(r, j_conf,
OIDC_METADATA_TOKEN_BINDING_POLICY, oidc_valid_token_binding_policy,
&policy,
NULL);
if (policy != NULL)
oidc_parse_token_binding_policy(r->pool, policy,
&provider->token_binding_policy);
else
provider->token_binding_policy = cfg->provider.token_binding_policy;

/* see if we've got a custom HTTP method for passing the auth request */
oidc_metadata_get_valid_string(r, j_conf, OIDC_METADATA_AUTH_REQUEST_METHOD,
oidc_valid_auth_request_method, &method,
Expand Down
13 changes: 1 addition & 12 deletions src/mod_auth_openidc.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,6 @@ static char* oidc_get_browser_state_hash(request_rec *r, oidc_cfg *c,
/* concat the nonce parameter to the hash input */
apr_sha1_update(&sha1, nonce, _oidc_strlen(nonce));

/* concat the token binding ID if present */
value = oidc_util_get_provided_token_binding_id(r);
if (value != NULL) {
oidc_debug(r,
"Provided Token Binding ID environment variable found; adding its value to the state");
apr_sha1_update(&sha1, value, _oidc_strlen(value));
}

/* finalize the hash input and calculate the resulting hash output */
unsigned char hash[OIDC_SHA1_LEN];
apr_sha1_final(hash, &sha1);
Expand Down Expand Up @@ -3431,12 +3423,9 @@ static int oidc_handle_logout_backchannel(request_rec *r, oidc_cfg *cfg) {
goto out;
}

// oidc_proto_validate_idtoken would try and require a token binding cnf
// if the policy is set to "required", so don't use that here
if (oidc_proto_validate_jwt(r, jwt,
provider->validate_issuer ? provider->issuer : NULL, FALSE, FALSE,
provider->idtoken_iat_slack,
OIDC_TOKEN_BINDING_POLICY_DISABLED) == FALSE)
provider->idtoken_iat_slack) == FALSE)
goto out;

/* verify the "aud" and "azp" values */
Expand Down
16 changes: 1 addition & 15 deletions src/mod_auth_openidc.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,6 @@ APLOG_USE_MODULE(auth_openidc);
/* https://www.ietf.org/id/draft-ietf-oauth-mtls-12 */
#define OIDC_TB_CFG_FINGERPRINT_ENV_VAR "TB_SSL_CLIENT_CERT_FINGERPRINT"

#define OIDC_TOKEN_BINDING_POLICY_DISABLED 0
#define OIDC_TOKEN_BINDING_POLICY_OPTIONAL 1
#define OIDC_TOKEN_BINDING_POLICY_REQUIRED 2
#define OIDC_TOKEN_BINDING_POLICY_ENFORCED 3

#define OIDC_STATE_INPUT_HEADERS_USER_AGENT 1
#define OIDC_STATE_INPUT_HEADERS_X_FORWARDED_FOR 2

Expand All @@ -293,7 +288,6 @@ typedef struct oidc_proto_pkce_t {

extern oidc_proto_pkce_t oidc_pkce_plain;
extern oidc_proto_pkce_t oidc_pkce_s256;
extern oidc_proto_pkce_t oidc_pkce_referred_tb;

typedef struct oidc_jwks_uri_t {
char *uri;
Expand Down Expand Up @@ -350,7 +344,6 @@ typedef struct oidc_provider_t {
int userinfo_token_method;
char *request_object;
int auth_request_method;
int token_binding_policy;

int issuer_specific_redirect_uri;
} oidc_provider_t ;
Expand Down Expand Up @@ -389,7 +382,6 @@ typedef struct oidc_oauth_t {
apr_hash_t *verify_shared_keys;
char *verify_jwks_uri;
apr_array_header_t *verify_public_keys;
int access_token_binding_policy;
} oidc_oauth_t;

typedef struct oidc_outgoing_proxy_t {
Expand Down Expand Up @@ -637,9 +629,6 @@ apr_byte_t oidc_oauth_get_bearer_token(request_rec *r, const char **access_token
#define OIDC_CLAIM_C_HASH "c_hash"
#define OIDC_CLAIM_RFP "rfp"
#define OIDC_CLAIM_TARGET_LINK_URI "target_link_uri"
#define OIDC_CLAIM_CNF "cnf"
#define OIDC_CLAIM_CNF_TBH "tbh"
#define OIDC_CLAIM_CNF_X5T_S256 "x5t#S256"
#define OIDC_CLAIM_SID "sid"
#define OIDC_CLAIM_EVENTS "events"

Expand Down Expand Up @@ -747,7 +736,7 @@ apr_array_header_t *oidc_proto_supported_flows(apr_pool_t *pool);
apr_byte_t oidc_proto_flow_is_supported(apr_pool_t *pool, const char *flow);
apr_byte_t oidc_proto_validate_authorization_response(request_rec *r, const char *response_type, const char *requested_response_mode, char **code, char **id_token, char **access_token, char **token_type, const char *used_response_mode);
apr_byte_t oidc_proto_jwt_verify(request_rec *r, oidc_cfg *cfg, oidc_jwt_t *jwt, const oidc_jwks_uri_t *jwks_uri, int ssl_validate_server, apr_hash_t *symmetric_keys, const char *alg);
apr_byte_t oidc_proto_validate_jwt(request_rec *r, oidc_jwt_t *jwt, const char *iss, apr_byte_t exp_is_mandatory, apr_byte_t iat_is_mandatory, int iat_slack, int token_binding_policy);
apr_byte_t oidc_proto_validate_jwt(request_rec *r, oidc_jwt_t *jwt, const char *iss, apr_byte_t exp_is_mandatory, apr_byte_t iat_is_mandatory, int iat_slack);
apr_byte_t oidc_proto_generate_nonce(request_rec *r, char **nonce, int len);
apr_byte_t oidc_proto_validate_aud_and_azp(request_rec *r, oidc_cfg *cfg, oidc_provider_t *provider, oidc_jwt_payload_t *id_token_payload);

Expand Down Expand Up @@ -903,7 +892,6 @@ char *oidc_util_get_chunked_cookie(request_rec *r, const char *cookieName, int c
void oidc_util_set_chunked_cookie(request_rec *r, const char *cookieName, const char *cookieValue, apr_time_t expires, int chunkSize, const char *ext);
apr_byte_t oidc_util_create_symmetric_key(request_rec *r, const char *client_secret, unsigned int r_key_len, const char *hash_algo, apr_byte_t set_kid, oidc_jwk_t **jwk);
apr_hash_t * oidc_util_merge_symmetric_key(apr_pool_t *pool, const apr_array_header_t *keys, oidc_jwk_t *jwk);
const char *oidc_util_get_provided_token_binding_id(const request_rec *r);
char *oidc_util_http_query_encoded_url(request_rec *r, const char *url, const apr_table_t *params);
char *oidc_util_get_full_path(apr_pool_t *pool, const char *abs_or_rel_filename);
apr_byte_t oidc_enabled(request_rec *r);
Expand Down Expand Up @@ -938,7 +926,6 @@ const char *oidc_util_apr_expr_exec(request_rec *r, const oidc_apr_expr_t *expr,
#define OIDC_HTTP_HDR_EXPIRES "Expires"
#define OIDC_HTTP_HDR_X_FRAME_OPTIONS "X-Frame-Options"
#define OIDC_HTTP_HDR_WWW_AUTHENTICATE "WWW-Authenticate"
#define OIDC_HTTP_HDR_INCLUDE_REFERRED_TOKEN_BINDING_ID "Include-Referred-Token-Binding-ID"

#define OIDC_HTTP_HDR_VAL_XML_HTTP_REQUEST "XMLHttpRequest"
#define OIDC_HTTP_HDR_VAL_NAVIGATE "navigate"
Expand All @@ -965,7 +952,6 @@ void oidc_util_hdr_out_location_set(const request_rec *r, const char *value);
const char *oidc_util_hdr_out_location_get(const request_rec *r);
void oidc_util_hdr_err_out_add(const request_rec *r, const char *name, const char *value);
apr_byte_t oidc_util_hdr_in_accept_contains(const request_rec *r, const char *needle);
apr_byte_t oidc_util_json_validate_cnf(request_rec *r, json_t *jwt, int token_binding_policy);
apr_byte_t oidc_util_html_send_in_template(request_rec *r, const char *filename, char **static_template_content, const char *arg1, int arg1_esc, const char *arg2, int arg2_esc, int status_code);

// oidc_metadata.c
Expand Down
8 changes: 1 addition & 7 deletions src/oauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,11 +458,6 @@ static apr_byte_t oidc_oauth_resolve_access_token(request_rec *r, oidc_cfg *c,
if (oidc_util_decode_json_and_check_error(r, s_json, &result) == FALSE)
return FALSE;

/* check the token binding ID in the introspection result */
if (oidc_util_json_validate_cnf(r, result,
c->oauth.access_token_binding_policy) == FALSE)
return FALSE;

json_t *active = json_object_get(result, OIDC_PROTO_ACTIVE);
apr_time_t cache_until = apr_time_now() + apr_time_from_sec(60);
if (active != NULL) {
Expand Down Expand Up @@ -601,8 +596,7 @@ static apr_byte_t oidc_oauth_validate_jwt_access_token(request_rec *r,
* validate the access token JWT by validating the (optional) exp claim
* don't enforce anything around iat since it doesn't make much sense for access tokens
*/
if (oidc_proto_validate_jwt(r, jwt, NULL, FALSE, FALSE, -1,
c->oauth.access_token_binding_policy) == FALSE) {
if (oidc_proto_validate_jwt(r, jwt, NULL, FALSE, FALSE, -1) == FALSE) {
oidc_jwt_destroy(jwt);
return FALSE;
}
Expand Down
Loading

0 comments on commit f9a5250

Please sign in to comment.