#342 closed enhancement (wontfix)
ssl hash of subject and issuer dn
Reported by: | Alfred Reibenschuh | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | |
Component: | nginx-module | Version: | |
Keywords: | ssl | Cc: | |
uname -a: | Linux NMFMQ1 2.6.32-042stab053.5 #1 SMP Tue Mar 27 11:42:17 MSD 2012 x86_64 x86_64 x86_64 GNU/Linux | ||
nginx -V: | nginx version: nginx/1.4.0 |
Description
the following patch enable to have the (open)ssl hash of issuer and subject in addition to the normal dn available as variables
diff -ur nginx-1.4.0/src/event/ngx_event_openssl.c nginx-1.4.0.patched/src/event/ngx_event_openssl.c
--- nginx-1.4.0/src/event/ngx_event_openssl.c 2013-02-23 12:54:25.000000000 +0100
+++ nginx-1.4.0.patched/src/event/ngx_event_openssl.c 2013-04-26 15:14:16.506854085 +0200
@@ -2391,6 +2391,41 @@
ngx_int_t
+ngx_ssl_get_subject_hash(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
+{
+ size_t len;
+ X509 *cert;
+ X509_NAME *name;
+
+ s->len = 0;
+
+ cert = SSL_get_peer_certificate(c->ssl->connection);
+ if (cert == NULL) {
+ return NGX_OK;
+ }
+
+ name = X509_get_subject_name(cert);
+ if (name == NULL) {
+ X509_free(cert);
+ return NGX_ERROR;
+ }
+
+ s->len = 16;
+ s->data = ngx_pnalloc(pool, 16);
+ if (s->data == NULL) {
+ X509_free(cert);
+ return NGX_ERROR;
+ }
+
+ len = sprintf((char*)s->data, "%08lX", X509_NAME_hash(name));
+
+ X509_free(cert);
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
{
char *p;
@@ -2431,6 +2466,40 @@
return NGX_OK;
}
+ngx_int_t
+ngx_ssl_get_issuer_hash(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
+{
+ size_t len;
+ X509 *cert;
+ X509_NAME *name;
+
+ s->len = 0;
+
+ cert = SSL_get_peer_certificate(c->ssl->connection);
+ if (cert == NULL) {
+ return NGX_OK;
+ }
+
+ name = X509_get_issuer_name(cert);
+ if (name == NULL) {
+ X509_free(cert);
+ return NGX_ERROR;
+ }
+
+ s->len = 16;
+ s->data = ngx_pnalloc(pool, 16);
+ if (s->data == NULL) {
+ X509_free(cert);
+ return NGX_ERROR;
+ }
+
+ len = sprintf((char*)s->data, "%08lX", X509_NAME_hash(name));
+
+ X509_free(cert);
+
+ return NGX_OK;
+}
+
ngx_int_t
ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
diff -ur nginx-1.4.0/src/event/ngx_event_openssl.h nginx-1.4.0.patched/src/event/ngx_event_openssl.h
--- nginx-1.4.0/src/event/ngx_event_openssl.h 2012-10-03 17:24:08.000000000 +0200
+++ nginx-1.4.0.patched/src/event/ngx_event_openssl.h 2013-04-26 15:11:49.966886008 +0200
@@ -145,10 +145,10 @@
ngx_str_t *s);
ngx_int_t ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
-ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
-ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
+ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s);
+ngx_int_t ngx_ssl_get_subject_hash(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s);
+ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s);
+ngx_int_t ngx_ssl_get_issuer_hash(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s);
ngx_int_t ngx_ssl_get_serial_number(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,
diff -ur nginx-1.4.0/src/http/modules/ngx_http_ssl_module.c nginx-1.4.0.patched/src/http/modules/ngx_http_ssl_module.c
--- nginx-1.4.0/src/http/modules/ngx_http_ssl_module.c 2013-03-20 11:36:57.000000000 +0100
+++ nginx-1.4.0.patched/src/http/modules/ngx_http_ssl_module.c 2013-04-26 14:57:00.796853986 +0200
@@ -254,6 +254,12 @@
{ ngx_string("ssl_client_i_dn"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
+ { ngx_string("ssl_client_s_hash"), NULL, ngx_http_ssl_variable,
+ (uintptr_t) ngx_ssl_get_subject_hash, NGX_HTTP_VAR_CHANGEABLE, 0 },
+
+ { ngx_string("ssl_client_i_hash"), NULL, ngx_http_ssl_variable,
+ (uintptr_t) ngx_ssl_get_issuer_hash, NGX_HTTP_VAR_CHANGEABLE, 0 },
+
{ ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
Change History (8)
comment:1 by , 12 years ago
comment:2 by , 12 years ago
unfortionately nginx uses an non-standad reprensentation of certificate issuer und subject dn.
openssl dn hashes are used primarely to lookup ca and/or issuer certificates.
the intended use is for a (mobile device management) application to provision nginx to whitelist particular sub-ca-issuers and/or subjects with root-ca-certs in ca-bundle.pem for service access outside of normal crl management and in the absense of more powerful methods.
http://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslrequire
vs
comment:3 by , 12 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Hashes provided are not something expected to be unique, and use of such variables for access control is bad idea. Use $ssl_client_i_dn/$ssl_client_s_dn instead.
Representation used for $ssl_client_i_dn/$ssl_client_s_dn is the same as used by OpenSSL (as produced with X509_NAME_oneline() function and/or show by "openssl x509 -issuer -noout -in <cert>" command). If you think there is a better representation - please suggest one.
comment:4 by , 12 years ago
- the documentation for X509_NAME_oneline() states:
"The functions X509_NAME_oneline() and X509_NAME_print() are legacy functions which produce a non standard output form, they don't handle multi character fields and have various quirks and inconsistencies. Their use is strongly discouraged in new applications."
- use X509_NAME_print_ex() with flag |XN_FLAG_RFC2253| to produce $ssl_client_?_dn.
- check with "keytool -printcert -file <cert> |grep Issuer:"
comment:5 by , 12 years ago
you might also want to read:
http://www.gossamer-threads.com/lists/apache/dev/274045?do=post_view_threaded
comment:6 by , 12 years ago
hmm, if you worry about ssl performance of having more variables to fill -- than you have a point
comment:7 by , 12 years ago
how about an option (ssl_extended_certificate_variables on/off) that produces the intended variables dynamically if set to on (default off) ?
comment:8 by , 12 years ago
It looks like Apache switched to a new format since 2.3.11, see LegacyDNStringFormat option. We might consider a switch as well, probably with an additional option to control format used.
Just for record, here is how to query names in RFC2253 using openssl itself:
openssl x509 -issuer -nameopt RFC2253 -noout -in <cert>
What's the expected use of the variables introduced?