@@ -89,6 +89,7 @@ module AP_MODULE_DECLARE_DATA token_binding_module;
8989#define TB_CFG_PROVIDED_ENV_VAR_DEFAULT TB_CFG_PROVIDED_TBID_HDR_NAME
9090#define TB_CFG_REFERRED_ENV_VAR_DEFAULT TB_CFG_REFERRED_TBID_HDR_NAME
9191#define TB_CFG_CONTEXT_ENV_VAR_DEFAULT TB_CFG_TB_CONTEXT_HDR_NAME
92+ #define TB_CFG_FINGERPRINT_ENV_VAR_DEFAULT "TB_SSL_CLIENT_CERT_FINGERPRINT"
9293
9394#define TB_CFG_PASS_VAR_PROVIDED_STR "provided"
9495#define TB_CFG_PASS_VAR_REFERRED_STR "referred"
@@ -216,6 +217,59 @@ static int tb_ssl_pre_handshake(conn_rec *c, SSL * ssl, int is_proxy) {
216217 return 0 ;
217218}
218219
220+ static void tb_draft_ietf_oauth_mtls (request_rec * r ) {
221+ char * fingerprint = NULL ;
222+ X509 * x509 = NULL ;
223+ unsigned char md [EVP_MAX_MD_SIZE ];
224+ unsigned int md_len ;
225+ size_t len ;
226+ tb_conn_config * conn_cfg = NULL ;
227+
228+ tb_debug (r , "enter" );
229+
230+ conn_cfg = tb_get_conn_config (r -> connection );
231+
232+ if ((conn_cfg == NULL ) || (conn_cfg -> ssl == NULL )
233+ || (r -> subprocess_env == NULL ))
234+ goto end ;
235+
236+ x509 = SSL_get_peer_certificate (conn_cfg -> ssl );
237+ if (x509 == NULL ) {
238+ tb_error (r , "SSL_get_peer_certificate failed" );
239+ goto end ;
240+ }
241+
242+ if (!X509_digest (x509 , EVP_sha256 (), md , & md_len )) {
243+ tb_error (r , "X509_digest failed" );
244+ goto end ;
245+ }
246+
247+ len = CalculateBase64EscapedLen (md_len , false);
248+ fingerprint = apr_pcalloc (r -> pool , len + 1 );
249+ WebSafeBase64Escape ((const char * ) md , md_len , fingerprint , len ,
250+ false);
251+
252+ apr_table_set (r -> subprocess_env , TB_CFG_FINGERPRINT_ENV_VAR_DEFAULT ,
253+ fingerprint );
254+
255+ tb_debug (r , "set environment variable %s to %s" ,
256+ TB_CFG_FINGERPRINT_ENV_VAR_DEFAULT , fingerprint );
257+
258+ end :
259+
260+ if (x509 )
261+ X509_free (x509 );
262+
263+ tb_debug (r , "leave" );
264+
265+ return ;
266+ }
267+
268+ static int tb_check_access_handler (request_rec * r ) {
269+ tb_draft_ietf_oauth_mtls (r );
270+ return 0 ;
271+ }
272+
219273static void tb_set_var (request_rec * r , const char * env_var_name ,
220274 const char * header_name , uint8_t * tokbind_id , size_t tokbind_id_len ) {
221275
@@ -548,12 +602,16 @@ static int tb_post_config_handler(apr_pool_t *pool, apr_pool_t *p1,
548602}
549603
550604static void tb_register_hooks (apr_pool_t * p ) {
605+ static const char * aszPre [] = { "mod_ssl.c" , NULL };
606+ static const char * aszSucc [] = { "mod_auth_openidc.c" , NULL };
551607 ap_hook_post_config (tb_post_config_handler , NULL , NULL , APR_HOOK_LAST );
552- ap_hook_post_read_request (tb_post_read_request , NULL , NULL , APR_HOOK_LAST );
608+ ap_hook_post_read_request (tb_post_read_request , aszPre , aszSucc , APR_HOOK_LAST );
553609 APR_OPTIONAL_HOOK (ssl , init_server , tb_ssl_init_server , NULL , NULL ,
554610 APR_HOOK_MIDDLE );
555611 APR_OPTIONAL_HOOK (ssl , pre_handshake , tb_ssl_pre_handshake , NULL , NULL ,
556612 APR_HOOK_MIDDLE );
613+ // need the access hook because only then SSL_get_peer_certificate succeeds...
614+ ap_hook_check_access (tb_check_access_handler , aszPre , aszSucc , APR_HOOK_FIRST , AP_AUTH_INTERNAL_PER_CONF );
557615}
558616
559617static const command_rec tb_cmds [] = {
0 commit comments