diff -uNr /root/nginx-0.7.67/src/event/ngx_event_openssl.c ./src/event/ngx_event_openssl.c --- /root/nginx-0.7.67/src/event/ngx_event_openssl.c 2010-06-07 19:55:20.000000000 +0800 +++ ./src/event/ngx_event_openssl.c 2010-08-13 11:52:45.000000000 +0800 @@ -2146,6 +2146,109 @@ return NGX_OK; } +time_t +Asn1ToTime(ASN1_TIME *tm) +{ + struct tm t; + int i; + char *v = (char *)tm->data; + time_t timer; + //damn code from openssl crypto/asn1/t_x509.c + if(tm->type == V_ASN1_UTCTIME) + { + if (tm->length < 10) + return 0; + for (i=0; i<10; i++) + if ((v[i] > '9') || (v[i] < '0')) return 0; + t.tm_year= (v[0]-'0')*10+(v[1]-'0'); + if (t.tm_year < 50) t.tm_year+=100; //2050 is judgment day? + t.tm_mon= (v[2]-'0')*10+(v[3]-'0') - 1; + if ((t.tm_mon > 11) || (t.tm_mon < 0)) return 0; + t.tm_mday= (v[4]-'0')*10+(v[5]-'0'); + t.tm_hour= (v[6]-'0')*10+(v[7]-'0'); + t.tm_min= (v[8]-'0')*10+(v[9]-'0'); + if (tm->length >=12 && + (v[10] >= '0') && (v[10] <= '9') && + (v[11] >= '0') && (v[11] <= '9')) + t.tm_sec= (v[10]-'0')*10+(v[11]-'0'); + } + else if(tm->type == V_ASN1_GENERALIZEDTIME) + { + if (tm->length < 12) + return 0; + for (i=0; i<12; i++) + if ((v[i] > '9') || (v[i] < '0')) return 0; + t.tm_year= (v[0]-'0')*1000+(v[1]-'0')*100 + (v[2]-'0')*10+(v[3]-'0') - 1900; + t.tm_mon= (v[4]-'0')*10+(v[5]-'0') - 1; + if ((t.tm_mon > 11) || (t.tm_mon < 0)) return 0; + t.tm_mday= (v[6]-'0')*10+(v[7]-'0'); + t.tm_hour= (v[8]-'0')*10+(v[9]-'0'); + t.tm_min= (v[10]-'0')*10+(v[11]-'0'); + if (tm->length >= 14 && + (v[12] >= '0') && (v[12] <= '9') && + (v[13] >= '0') && (v[13] <= '9')) + t.tm_sec= (v[12]-'0')*10+(v[13]-'0'); + } + else + return 0; + + if (v[tm->length-1] == 'Z') + { + time(&timer); + return (mktime(&t) + mktime(localtime(&timer)) - mktime(gmtime(&timer))); + } + else + return mktime(&t); + + +} + +ngx_int_t +ngx_ssl_get_notafter_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + X509 *cert; + ASN1_TIME *t; + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + return NGX_OK; + } + t = X509_get_notAfter(cert); + s->len = 10; + s->data = ngx_pnalloc(pool, 10); + if (s->data == NULL) { + X509_free(cert); + return NGX_ERROR; + } + sprintf((char *)s->data, "%ld", (long) Asn1ToTime(t)); + + X509_free(cert); + + return NGX_OK; +} + +ngx_int_t +ngx_ssl_get_notbefore_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + X509 *cert; + ASN1_TIME *t; + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + return NGX_OK; + } + t = X509_get_notBefore(cert); + s->len = 10; + s->data = ngx_pnalloc(pool, 10); + if (s->data == NULL) { + X509_free(cert); + return NGX_ERROR; + } + sprintf((char *)s->data, "%ld", (long) Asn1ToTime(t)); + + 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) diff -uNr /root/nginx-0.7.67/src/event/ngx_event_openssl.h ./src/event/ngx_event_openssl.h --- /root/nginx-0.7.67/src/event/ngx_event_openssl.h 2010-06-07 18:09:14.000000000 +0800 +++ ./src/event/ngx_event_openssl.h 2010-08-12 16:47:49.000000000 +0800 @@ -134,7 +134,11 @@ ngx_str_t *s); ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); - +time_t Asn1ToTime(ASN1_TIME *tm); +ngx_int_t ngx_ssl_get_notafter_dn(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); +ngx_int_t ngx_ssl_get_notbefore_dn(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size); diff -uNr /root/nginx-0.7.67/src/http/modules/ngx_http_ssl_module.c ./src/http/modules/ngx_http_ssl_module.c --- /root/nginx-0.7.67/src/http/modules/ngx_http_ssl_module.c 2010-02-01 22:39:16.000000000 +0800 +++ ./src/http/modules/ngx_http_ssl_module.c 2010-08-11 17:31:24.000000000 +0800 @@ -206,6 +206,12 @@ { 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_notafter"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_notafter_dn, NGX_HTTP_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_notbefore"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_notbefore_dn, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } };