Hello, Please find attached patch, that add ssl_client_EKU nginx variable.
Variable contains coma-separated list of OIDs, presented in client's certificate (if any). If EKU extension is absent, empty line will be returned. Dot-separated form of OID choosen rather than human-readable short name, as EKU may contains values OpenSSL not aware of, and we receive "UNDEF" only in this case. Purpose is to use in LUA scripts, or let backend server know the list of EKU's, as it can contains lot more that just 'TLS Client Authentication'. (for those who read in Russain: http://www.infotrust.ru/data/Docs/InfoTrustCP.pdf page 37, as an example) For example directive proxy_set_header X-ClientCert-EKU $ssl_client_EKU; will result in following in proxied header: X-ClientCert-EKU: 1.3.6.1.5.5.7.3.2,1.2.643.3.34.2.6,1.2.643.3.34.2.1 Tested on 1.8.0, 1.9.4 Best wishes, Andrey
From 9c15ddb5825030c8d6bab0699dc03a164f015fa1 Mon Sep 17 00:00:00 2001 From: Andrey Kulikov <[email protected]> Date: Wed, 9 Sep 2015 02:29:39 +0300 Subject: [PATCH] Add ssl_client_EKU nginx variable. Variable contains coma-separated list of OIDs, presented in client's certificate (if any). We choose dot-separated form of OID, rather than human-readable short name, as EKU may contains values OpenSSL not aware of, and we receive "UNDEF" only in this case. Purpose is to use in LUA scripts, or let backend server know the list of EKU's, as it can contains lot more that just 'TLS Client Authentication'. --- src/event/ngx_event_openssl.c | 63 ++++++++++++++++++++++++++++++++ src/event/ngx_event_openssl.h | 2 + src/http/modules/ngx_http_ssl_module.c | 3 ++ 3 files changed, 68 insertions(+) diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 1b789e6..334c56a 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -3457,6 +3457,69 @@ ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) } +ngx_int_t +ngx_ssl_get_client_EKU(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + size_t len; + X509 *cert; + BIO *bio; + int i; + int first_element = 1; + char oid_buff[128]; + + s->len = 0; + + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + return NGX_OK; + } + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + X509_free(cert); + return NGX_ERROR; + } + + EXTENDED_KEY_USAGE *extusage; + extusage = (EXTENDED_KEY_USAGE *)X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL); + if (extusage) { + for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { + ASN1_OBJECT *asn = sk_ASN1_OBJECT_value(extusage, i); + /* 1 means that we need dot-separated form of OID, rather than + * human-readable short name, as EKU may contains values + * OpenSSL not aware of, and we receive "UNDEF" only in this case. + */ + OBJ_obj2txt(oid_buff, 1024, asn, 1); + + if (first_element) { + first_element = 0; + } else { + BIO_write(bio, ",", 1); + } + + BIO_write(bio, oid_buff, strnlen(oid_buff, sizeof(oid_buff))); + } + } /* if(extusage) */ + sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); + + len = BIO_pending(bio); + + s->len = len; + s->data = ngx_pnalloc(pool, len); + if (s->data == NULL) { + BIO_free(bio); + X509_free(cert); + return NGX_ERROR; + } + + BIO_read(bio, s->data, len); + BIO_free(bio); + X509_free(cert); + + return NGX_OK; +} + + static void * ngx_openssl_create_conf(ngx_cycle_t *cycle) { diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index 08eff64..0f59053 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -189,6 +189,8 @@ ngx_int_t ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_client_EKU(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index 275febe..8584176 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -307,6 +307,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = { { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_EKU"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_client_EKU, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; -- 1.7.10.4
_______________________________________________ nginx-devel mailing list [email protected] http://mailman.nginx.org/mailman/listinfo/nginx-devel
