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

Commit

Permalink
add support for OAuth 2.0 Client Certificate Bound Access Tokens
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
zandbelt committed Oct 24, 2018
1 parent 26b3549 commit e7fe401
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
5 changes: 5 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
10/24/2018
- add support for draft https://www.ietf.org/id/draft-ietf-oauth-mtls-12.txt:
OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound Access Tokens
- version 1.1.0

10/9/2018
- update to RFC8471 and RFC8472
- version 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
AC_INIT([mod_token_binding],[1.0.0],[[email protected]])
AC_INIT([mod_token_binding],[1.1.0],[[email protected]])

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

Expand Down
60 changes: 59 additions & 1 deletion src/mod_token_binding.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ module AP_MODULE_DECLARE_DATA token_binding_module;
#define TB_CFG_PROVIDED_ENV_VAR_DEFAULT TB_CFG_PROVIDED_TBID_HDR_NAME
#define TB_CFG_REFERRED_ENV_VAR_DEFAULT TB_CFG_REFERRED_TBID_HDR_NAME
#define TB_CFG_CONTEXT_ENV_VAR_DEFAULT TB_CFG_TB_CONTEXT_HDR_NAME
#define TB_CFG_FINGERPRINT_ENV_VAR_DEFAULT "TB_SSL_CLIENT_CERT_FINGERPRINT"

#define TB_CFG_PASS_VAR_PROVIDED_STR "provided"
#define TB_CFG_PASS_VAR_REFERRED_STR "referred"
Expand Down Expand Up @@ -216,6 +217,59 @@ static int tb_ssl_pre_handshake(conn_rec *c, SSL * ssl, int is_proxy) {
return 0;
}

static void tb_draft_ietf_oauth_mtls(request_rec *r) {
char *fingerprint = NULL;
X509 *x509 = NULL;
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int md_len;
size_t len;
tb_conn_config *conn_cfg = NULL;

tb_debug(r, "enter");

conn_cfg = tb_get_conn_config(r->connection);

if ((conn_cfg == NULL) || (conn_cfg->ssl == NULL)
|| (r->subprocess_env == NULL))
goto end;

x509 = SSL_get_peer_certificate(conn_cfg->ssl);
if (x509 == NULL) {
tb_error(r, "SSL_get_peer_certificate failed");
goto end;
}

if (!X509_digest(x509, EVP_sha256(), md, &md_len)) {
tb_error(r, "X509_digest failed");
goto end;
}

len = CalculateBase64EscapedLen(md_len, false);
fingerprint = apr_pcalloc(r->pool, len + 1);
WebSafeBase64Escape((const char *) md, md_len, fingerprint, len,
false);

apr_table_set(r->subprocess_env, TB_CFG_FINGERPRINT_ENV_VAR_DEFAULT,
fingerprint);

tb_debug(r, "set environment variable %s to %s",
TB_CFG_FINGERPRINT_ENV_VAR_DEFAULT, fingerprint);

end:

if (x509)
X509_free(x509);

tb_debug(r, "leave");

return;
}

static int tb_check_access_handler(request_rec *r) {
tb_draft_ietf_oauth_mtls(r);
return 0;
}

static void tb_set_var(request_rec *r, const char *env_var_name,
const char *header_name, uint8_t* tokbind_id, size_t tokbind_id_len) {

Expand Down Expand Up @@ -548,12 +602,16 @@ static int tb_post_config_handler(apr_pool_t *pool, apr_pool_t *p1,
}

static void tb_register_hooks(apr_pool_t *p) {
static const char *aszPre[] = { "mod_ssl.c", NULL };
static const char *aszSucc[] = { "mod_auth_openidc.c", NULL };
ap_hook_post_config(tb_post_config_handler, NULL, NULL, APR_HOOK_LAST);
ap_hook_post_read_request(tb_post_read_request, NULL, NULL, APR_HOOK_LAST);
ap_hook_post_read_request(tb_post_read_request, aszPre, aszSucc, APR_HOOK_LAST);
APR_OPTIONAL_HOOK(ssl, init_server, tb_ssl_init_server, NULL, NULL,
APR_HOOK_MIDDLE);
APR_OPTIONAL_HOOK(ssl, pre_handshake, tb_ssl_pre_handshake, NULL, NULL,
APR_HOOK_MIDDLE);
// need the access hook because only then SSL_get_peer_certificate succeeds...
ap_hook_check_access(tb_check_access_handler, aszPre, aszSucc, APR_HOOK_FIRST, AP_AUTH_INTERNAL_PER_CONF);
}

static const command_rec tb_cmds[] = {
Expand Down

0 comments on commit e7fe401

Please sign in to comment.