[nginx] SSL: $ssl_client_v_start, $ssl_client_v_end, $ssl_client_v_remain.
Maxim Dounin
mdounin at mdounin.ru
Mon Dec 5 20:01:59 UTC 2016
details: http://hg.nginx.org/nginx/rev/2d15fff64e3c
branches:
changeset: 6815:2d15fff64e3c
user: Maxim Dounin <mdounin at mdounin.ru>
date: Mon Dec 05 22:23:23 2016 +0300
description:
SSL: $ssl_client_v_start, $ssl_client_v_end, $ssl_client_v_remain.
diffstat:
src/event/ngx_event_openssl.c | 178 +++++++++++++++++++++++++++++++++
src/event/ngx_event_openssl.h | 6 +
src/http/modules/ngx_http_ssl_module.c | 9 +
3 files changed, 193 insertions(+), 0 deletions(-)
diffs (230 lines):
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -59,6 +59,12 @@ static int ngx_ssl_session_ticket_key_ca
static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str);
#endif
+static time_t ngx_ssl_parse_time(
+#if OPENSSL_VERSION_NUMBER > 0x10100000L
+ const
+#endif
+ ASN1_TIME *asn1time);
+
static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static void ngx_openssl_exit(ngx_cycle_t *cycle);
@@ -3749,6 +3755,178 @@ ngx_ssl_get_client_verify(ngx_connection
}
+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) {
+ 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;
+}
+
+
+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) {
+ 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;
+}
+
+
+ngx_int_t
+ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
+{
+ X509 *cert;
+ time_t now, end;
+
+ s->len = 0;
+
+ cert = SSL_get_peer_certificate(c->ssl->connection);
+ if (cert == NULL) {
+ return NGX_OK;
+ }
+
+#if OPENSSL_VERSION_NUMBER > 0x10100000L
+ end = ngx_ssl_parse_time(X509_get0_notAfter(cert));
+#else
+ end = ngx_ssl_parse_time(X509_get_notAfter(cert));
+#endif
+
+ if (end == (time_t) NGX_ERROR) {
+ X509_free(cert);
+ return NGX_OK;
+ }
+
+ now = ngx_time();
+
+ if (end < now + 86400) {
+ ngx_str_set(s, "0");
+ X509_free(cert);
+ return NGX_OK;
+ }
+
+ s->data = ngx_pnalloc(pool, NGX_TIME_T_LEN);
+ if (s->data == NULL) {
+ X509_free(cert);
+ return NGX_ERROR;
+ }
+
+ s->len = ngx_sprintf(s->data, "%T", (end - now) / 86400) - s->data;
+
+ X509_free(cert);
+
+ return NGX_OK;
+}
+
+
+static time_t
+ngx_ssl_parse_time(
+#if OPENSSL_VERSION_NUMBER > 0x10100000L
+ const
+#endif
+ ASN1_TIME *asn1time)
+{
+ BIO *bio;
+ u_char *value;
+ size_t len;
+ time_t time;
+
+ /*
+ * OpenSSL doesn't provide a way to convert ASN1_TIME
+ * into time_t. To do this, we use ASN1_TIME_print(),
+ * which uses the "MMM DD HH:MM:SS YYYY [GMT]" format (e.g.,
+ * "Feb 3 00:55:52 2015 GMT"), and parse the result.
+ */
+
+ bio = BIO_new(BIO_s_mem());
+ if (bio == NULL) {
+ return NGX_ERROR;
+ }
+
+ /* fake weekday prepended to match C asctime() format */
+
+ BIO_write(bio, "Tue ", sizeof("Tue ") - 1);
+ ASN1_TIME_print(bio, asn1time);
+ len = BIO_get_mem_data(bio, &value);
+
+ time = ngx_parse_http_time(value, len);
+
+ BIO_free(bio);
+
+ return time;
+}
+
+
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
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -215,6 +215,12 @@ ngx_int_t ngx_ssl_get_fingerprint(ngx_co
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_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_remain(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
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -313,6 +313,15 @@ static ngx_http_variable_t ngx_http_ssl
{ 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_v_start"), NULL, ngx_http_ssl_variable,
+ (uintptr_t) ngx_ssl_get_client_v_start, NGX_HTTP_VAR_CHANGEABLE, 0 },
+
+ { 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_remain"), NULL, ngx_http_ssl_variable,
+ (uintptr_t) ngx_ssl_get_client_v_remain, NGX_HTTP_VAR_CHANGEABLE, 0 },
+
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};
More information about the nginx-devel
mailing list