mirror of
https://github.com/nginx/nginx.git
synced 2025-06-06 00:42:40 +08:00
SSL: support ALPN (IETF's successor to NPN).
Signed-off-by: Piotr Sikora <piotr@cloudflare.com>
This commit is contained in:
parent
d3e0bf306b
commit
4ae889c9f2
@ -17,6 +17,14 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
|
||||
#define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5"
|
||||
#define NGX_DEFAULT_ECDH_CURVE "prime256v1"
|
||||
|
||||
#define NGX_HTTP_NPN_ADVERTISE "\x08http/1.1"
|
||||
|
||||
|
||||
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||
static int ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn,
|
||||
const unsigned char **out, unsigned char *outlen,
|
||||
const unsigned char *in, unsigned int inlen, void *arg);
|
||||
#endif
|
||||
|
||||
#ifdef TLSEXT_TYPE_next_proto_neg
|
||||
static int ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
|
||||
@ -288,9 +296,65 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
|
||||
static ngx_str_t ngx_http_ssl_sess_id_ctx = ngx_string("HTTP");
|
||||
|
||||
|
||||
#ifdef TLSEXT_TYPE_next_proto_neg
|
||||
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||
|
||||
#define NGX_HTTP_NPN_ADVERTISE "\x08http/1.1"
|
||||
static int
|
||||
ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
|
||||
unsigned char *outlen, const unsigned char *in, unsigned int inlen,
|
||||
void *arg)
|
||||
{
|
||||
unsigned int srvlen;
|
||||
unsigned char *srv;
|
||||
#if (NGX_DEBUG)
|
||||
unsigned int i;
|
||||
#endif
|
||||
#if (NGX_HTTP_SPDY)
|
||||
ngx_http_connection_t *hc;
|
||||
#endif
|
||||
#if (NGX_HTTP_SPDY || NGX_DEBUG)
|
||||
ngx_connection_t *c;
|
||||
|
||||
c = ngx_ssl_get_connection(ssl_conn);
|
||||
#endif
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
for (i = 0; i < inlen; i += in[i] + 1) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"SSL ALPN supported by client: %*s", in[i], &in[i + 1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_SPDY)
|
||||
hc = c->data;
|
||||
|
||||
if (hc->addr_conf->spdy) {
|
||||
srv = (unsigned char *) NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE;
|
||||
srvlen = sizeof(NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1;
|
||||
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
srv = (unsigned char *) NGX_HTTP_NPN_ADVERTISE;
|
||||
srvlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1;
|
||||
}
|
||||
|
||||
if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen,
|
||||
in, inlen)
|
||||
!= OPENSSL_NPN_NEGOTIATED)
|
||||
{
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"SSL ALPN selected: %*s", *outlen, *out);
|
||||
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TLSEXT_TYPE_next_proto_neg
|
||||
|
||||
static int
|
||||
ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
|
||||
@ -561,6 +625,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||
SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_http_ssl_alpn_select, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef TLSEXT_TYPE_next_proto_neg
|
||||
SSL_CTX_set_next_protos_advertised_cb(conf->ssl.ctx,
|
||||
ngx_http_ssl_npn_advertised, NULL);
|
||||
|
@ -1349,11 +1349,13 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||
}
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_SPDY && NGX_HTTP_SSL && !defined TLSEXT_TYPE_next_proto_neg)
|
||||
#if (NGX_HTTP_SPDY && NGX_HTTP_SSL \
|
||||
&& !defined TLSEXT_TYPE_application_layer_protocol_negotiation \
|
||||
&& !defined TLSEXT_TYPE_next_proto_neg)
|
||||
if (lsopt->spdy && lsopt->ssl) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"nginx was built without OpenSSL NPN support, "
|
||||
"SPDY is not enabled for %s", lsopt->addr);
|
||||
"nginx was built without OpenSSL ALPN or NPN "
|
||||
"support, SPDY is not enabled for %s", lsopt->addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -705,13 +705,25 @@ ngx_http_ssl_handshake_handler(ngx_connection_t *c)
|
||||
|
||||
c->ssl->no_wait_shutdown = 1;
|
||||
|
||||
#if (NGX_HTTP_SPDY && defined TLSEXT_TYPE_next_proto_neg)
|
||||
#if (NGX_HTTP_SPDY \
|
||||
&& (defined TLSEXT_TYPE_application_layer_protocol_negotiation \
|
||||
|| defined TLSEXT_TYPE_next_proto_neg))
|
||||
{
|
||||
unsigned int len;
|
||||
const unsigned char *data;
|
||||
static const ngx_str_t spdy = ngx_string(NGX_SPDY_NPN_NEGOTIATED);
|
||||
|
||||
SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
|
||||
len = 0;
|
||||
|
||||
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||
SSL_get0_alpn_selected(c->ssl->connection, &data, &len);
|
||||
#endif
|
||||
|
||||
#ifdef TLSEXT_TYPE_next_proto_neg
|
||||
if (len == 0) {
|
||||
SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (len == spdy.len && ngx_strncmp(data, spdy.data, spdy.len) == 0) {
|
||||
ngx_http_spdy_init(c->read);
|
||||
|
@ -17,10 +17,8 @@
|
||||
|
||||
#define NGX_SPDY_VERSION 2
|
||||
|
||||
#ifdef TLSEXT_TYPE_next_proto_neg
|
||||
#define NGX_SPDY_NPN_ADVERTISE "\x06spdy/2"
|
||||
#define NGX_SPDY_NPN_NEGOTIATED "spdy/2"
|
||||
#endif
|
||||
|
||||
#define NGX_SPDY_STATE_BUFFER_SIZE 16
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user