Skip to content

Commit

Permalink
Changes with nginx 1.7.0 24 Apr 2014
Browse files Browse the repository at this point in the history
  • Loading branch information
nginx authored and kolbyjack committed Apr 24, 2014
1 parent ea2dabd commit 7a8cd93
Show file tree
Hide file tree
Showing 12 changed files with 615 additions and 43 deletions.
10 changes: 8 additions & 2 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@

Changes with nginx 1.6.0 24 Apr 2014
Changes with nginx 1.7.0 24 Apr 2014

*) 1.6.x stable branch.
*) Feature: backend SSL certificate verification.

*) Feature: support for SNI while working with SSL backends.

*) Feature: the $ssl_server_name variable.

*) Feature: the "if" parameter of the "access_log" directive.


Changes with nginx 1.5.13 08 Apr 2014
Expand Down
10 changes: 8 additions & 2 deletions CHANGES.ru
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@

Изменения в nginx 1.6.0 24.04.2014
Изменения в nginx 1.7.0 24.04.2014

*) Стабильная ветка 1.6.x.
*) Добавление: проверка SSL-сертификатов бэкендов.

*) Добавление: поддержка SNI при работе с бэкендами по SSL.

*) Добавление: переменная $ssl_server_name.

*) Добавление: параметр if директивы access_log.


Изменения в nginx 1.5.13 08.04.2014
Expand Down
4 changes: 2 additions & 2 deletions src/core/nginx.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_


#define nginx_version 1006000
#define NGINX_VERSION "1.6.0"
#define nginx_version 1007000
#define NGINX_VERSION "1.7.0"
#define NGINX_VER "nginx/" NGINX_VERSION

#define NGINX_VAR "NGINX"
Expand Down
201 changes: 198 additions & 3 deletions src/event/ngx_event_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ static int ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
HMAC_CTX *hctx, int enc);
#endif

#if OPENSSL_VERSION_NUMBER < 0x10002001L
static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str);
#endif

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);
Expand Down Expand Up @@ -2418,7 +2422,7 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
if (enc == 1) {
/* encrypt session ticket */

ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"ssl session ticket encrypt, key: \"%*s\" (%s session)",
ngx_hex_dump(buf, key[0].name, 16) - buf, buf,
SSL_session_reused(ssl_conn) ? "reused" : "new");
Expand All @@ -2440,15 +2444,15 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
}
}

ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"ssl session ticket decrypt, key: \"%*s\" not found",
ngx_hex_dump(buf, name, 16) - buf, buf);

return 0;

found:

ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"ssl session ticket decrypt, key: \"%*s\"%s",
ngx_hex_dump(buf, key[i].name, 16) - buf, buf,
(i == 0) ? " (default)" : "");
Expand Down Expand Up @@ -2486,6 +2490,175 @@ ngx_ssl_cleanup_ctx(void *data)
}


ngx_int_t
ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name)
{
X509 *cert;

cert = SSL_get_peer_certificate(c->ssl->connection);
if (cert == NULL) {
return NGX_ERROR;
}

#if OPENSSL_VERSION_NUMBER >= 0x10002001L

/* X509_check_host() is only available in OpenSSL 1.0.2+ */

if (name->len == 0) {
goto failed;
}

if (X509_check_host(cert, name->data, name->len, 0) != 1) {
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
"X509_check_host(): no match");
goto failed;
}

ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
"X509_check_host(): match");

goto found;

#else
{
int n, i;
X509_NAME *sname;
ASN1_STRING *str;
X509_NAME_ENTRY *entry;
GENERAL_NAME *altname;
STACK_OF(GENERAL_NAME) *altnames;

/*
* As per RFC6125 and RFC2818, we check subjectAltName extension,
* and if it's not present - commonName in Subject is checked.
*/

altnames = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);

if (altnames) {
n = sk_GENERAL_NAME_num(altnames);

for (i = 0; i < n; i++) {
altname = sk_GENERAL_NAME_value(altnames, i);

if (altname->type != GEN_DNS) {
continue;
}

str = altname->d.dNSName;

ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL subjectAltName: \"%*s\"",
ASN1_STRING_length(str), ASN1_STRING_data(str));

if (ngx_ssl_check_name(name, str) == NGX_OK) {
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL subjectAltName: match");
GENERAL_NAMES_free(altnames);
goto found;
}
}

ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL subjectAltName: no match");

GENERAL_NAMES_free(altnames);
goto failed;
}

/*
* If there is no subjectAltName extension, check commonName
* in Subject. While RFC2818 requires to only check "most specific"
* CN, both Apache and OpenSSL check all CNs, and so do we.
*/

sname = X509_get_subject_name(cert);

if (sname == NULL) {
goto failed;
}

i = -1;
for ( ;; ) {
i = X509_NAME_get_index_by_NID(sname, NID_commonName, i);

if (i < 0) {
break;
}

entry = X509_NAME_get_entry(sname, i);
str = X509_NAME_ENTRY_get_data(entry);

ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL commonName: \"%*s\"",
ASN1_STRING_length(str), ASN1_STRING_data(str));

if (ngx_ssl_check_name(name, str) == NGX_OK) {
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL commonName: match");
goto found;
}
}

ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL commonName: no match");
}
#endif

failed:

X509_free(cert);
return NGX_ERROR;

found:

X509_free(cert);
return NGX_OK;
}


#if OPENSSL_VERSION_NUMBER < 0x10002001L

static ngx_int_t
ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern)
{
u_char *s, *p, *end;
size_t slen, plen;

s = name->data;
slen = name->len;

p = ASN1_STRING_data(pattern);
plen = ASN1_STRING_length(pattern);

if (slen == plen && ngx_strncasecmp(s, p, plen) == 0) {
return NGX_OK;
}

if (plen > 2 && p[0] == '*' && p[1] == '.') {
plen -= 1;
p += 1;

end = s + slen;
s = ngx_strlchr(s, end, '.');

if (s == NULL) {
return NGX_ERROR;
}

slen = end - s;

if (plen == slen && ngx_strncasecmp(s, p, plen) == 0) {
return NGX_OK;
}
}

return NGX_ERROR;
}

#endif


ngx_int_t
ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
{
Expand Down Expand Up @@ -2544,6 +2717,28 @@ ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
}


ngx_int_t
ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
{
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

const char *servername;

servername = SSL_get_servername(c->ssl->connection,
TLSEXT_NAMETYPE_host_name);
if (servername) {
s->data = (u_char *) servername;
s->len = ngx_strlen(servername);
return NGX_OK;
}

#endif

s->len = 0;
return NGX_OK;
}


ngx_int_t
ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
{
Expand Down
4 changes: 4 additions & 0 deletions src/event/ngx_event_openssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ ngx_int_t ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session);
|| n == X509_V_ERR_CERT_UNTRUSTED \
|| n == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)

ngx_int_t ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name);


ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
Expand All @@ -159,6 +161,8 @@ ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool,
Expand Down
Loading

0 comments on commit 7a8cd93

Please sign in to comment.