diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index 02890b843..34960757e 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -104,7 +104,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #define LF (u_char) '\n' #define CR (u_char) '\r' #define CRLF "\r\n" - +#define ngx_ascii_is_digit(c) (c >= 0x30 && c <= 0x39) #define ngx_abs(value) (((value) >= 0) ? (value) : - (value)) #define ngx_max(val1, val2) ((val1 < val2) ? (val2) : (val1)) diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index a7b389444..307c0ba10 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -5738,96 +5738,166 @@ ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) return NGX_OK; } +ngx_int_t +ngx_ssl_print_time( + BIO *bio, +#if OPENSSL_VERSION_NUMBER > 0x10100000L + const +#endif + ASN1_TIME *tm, long iso8601_format) +{ + ngx_int_t ret; + struct tm stm; + const char period = 0x2E; + int l, f_len; + char *v, *f; + + if (iso8601_format) { + ret = ASN1_TIME_to_tm(tm, &stm); + if (ret != NGX_OK) { + return ret; + } + + l = tm->length; + v = (char *)tm->data; + + if (tm->type == V_ASN1_GENERALIZEDTIME) { + f = NULL; + f_len = 0; + if (tm->length > 15 && v[14] == period) { + f = &v[15]; + while(15 + f_len < l && ngx_ascii_is_digit(f[f_len])) + ++f_len; + } + if (f_len > 0) { + BIO_printf(bio, "%4d-%02d-%02d %02d:%02d:%02d.%.*sZ", + stm.tm_year + 1900, stm.tm_mon + 1, + stm.tm_mday, stm.tm_hour, + stm.tm_min, stm.tm_sec, f_len, f); + return NGX_OK; + } + } + BIO_printf(bio, "%4d-%02d-%02d %02d:%02d:%02dZ", + stm.tm_year + 1900, stm.tm_mon + 1, + stm.tm_mday, stm.tm_hour, + stm.tm_min, stm.tm_sec); + } else { + ASN1_TIME_print(bio, tm); + } + return NGX_OK; +} + +ngx_int_t +ngx_ssl_get_client_v_start_common(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s, long iso8601_format) +{ + BIO *bio; + X509 *cert; + size_t len; + + 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) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed"); + X509_free(cert); + return NGX_ERROR; + } + +#if OPENSSL_VERSION_NUMBER > 0x10100000L + ngx_ssl_print_time(bio, X509_get0_notBefore(cert), iso8601_format); +#else + ngx_ssl_print_time(bio, X509_get_notBefore(cert), iso8601_format); +#endif + + 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; +} + +ngx_int_t +ngx_ssl_get_client_v_end_common(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s, long iso8601_format) +{ + BIO *bio; + X509 *cert; + size_t len; + + 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) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed"); + X509_free(cert); + return NGX_ERROR; + } + +#if OPENSSL_VERSION_NUMBER > 0x10100000L + ngx_ssl_print_time(bio, X509_get0_notAfter(cert), iso8601_format); +#else + ngx_ssl_print_time(bio, X509_get_notAfter(cert), iso8601_format); +#endif + + 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; +} ngx_int_t ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { - BIO *bio; - X509 *cert; - size_t len; - - 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) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed"); - X509_free(cert); - return NGX_ERROR; - } - -#if OPENSSL_VERSION_NUMBER > 0x10100000L - ASN1_TIME_print(bio, X509_get0_notBefore(cert)); -#else - ASN1_TIME_print(bio, X509_get_notBefore(cert)); -#endif - - 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; + return ngx_ssl_get_client_v_start_common(c, pool, s, 0); } +ngx_int_t +ngx_ssl_get_client_v_start_iso8601(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + return ngx_ssl_get_client_v_start_common(c, pool, s, 1); +} ngx_int_t ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { - BIO *bio; - X509 *cert; - size_t len; - - 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) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed"); - X509_free(cert); - return NGX_ERROR; - } - -#if OPENSSL_VERSION_NUMBER > 0x10100000L - ASN1_TIME_print(bio, X509_get0_notAfter(cert)); -#else - ASN1_TIME_print(bio, X509_get_notAfter(cert)); -#endif - - 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; + return ngx_ssl_get_client_v_end_common(c, pool, s, 0); } +ngx_int_t +ngx_ssl_get_client_v_end_iso8601(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + return ngx_ssl_get_client_v_end_common(c, pool, s, 1); +} ngx_int_t ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index 9e68deb44..63ab8b139 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -346,6 +346,10 @@ ngx_int_t ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_client_v_start_iso8601(ngx_connection_t *c, + ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_client_v_end_iso8601(ngx_connection_t *c, + ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index dbfe5c08b..6a34ae48e 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -405,6 +405,12 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = { { ngx_string("ssl_client_v_end"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_client_v_end, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_v_start_iso8601"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_client_v_start_iso8601, NGX_HTTP_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_v_end_iso8601"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_client_v_end_iso8601, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_v_remain"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_client_v_remain, NGX_HTTP_VAR_CHANGEABLE, 0 },