Skip to content
This repository was archived by the owner on Jan 23, 2024. It is now read-only.

Commit e7fe401

Browse files
committed
add support for OAuth 2.0 Client Certificate Bound Access Tokens
see: https://www.ietf.org/id/draft-ietf-oauth-mtls-12.txt: setting an environment variable TB_SSL_CLIENT_CERT_FINGERPRINT with the base64url encoded value of the SHA256 hash of the DER representation of the certificate Signed-off-by: Hans Zandbelt <[email protected]>
1 parent 26b3549 commit e7fe401

3 files changed

Lines changed: 65 additions & 2 deletions

File tree

ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
10/24/2018
2+
- add support for draft https://www.ietf.org/id/draft-ietf-oauth-mtls-12.txt:
3+
OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound Access Tokens
4+
- version 1.1.0
5+
16
10/9/2018
27
- update to RFC8471 and RFC8472
38
- version 1.0.0

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AC_INIT([mod_token_binding],[1.0.0],[[email protected]])
1+
AC_INIT([mod_token_binding],[1.1.0],[[email protected]])
22

33
AC_SUBST(NAMEVER, AC_PACKAGE_TARNAME()-AC_PACKAGE_VERSION())
44

src/mod_token_binding.c

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
219273
static 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

550604
static 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

559617
static const command_rec tb_cmds[] = {

0 commit comments

Comments
 (0)