[multiple] allow TLS ALPN "h2" if "server.h2proto"

This commit is contained in:
Glenn Strauss 2020-07-21 19:53:26 -04:00
parent a8f8d5edc0
commit bbcc2f229a
4 changed files with 35 additions and 19 deletions

View File

@ -51,6 +51,7 @@ GNUTLS_SKIP_GLOBAL_INIT
#include "base.h"
#include "fdevent.h"
#include "http_header.h"
#include "http_kv.h"
#include "log.h"
#include "plugin.h"
@ -1313,14 +1314,13 @@ mod_gnutls_alpn_select_cb (gnutls_session_t ssl, handler_ctx *hctx)
const int n = (int)d.size;
switch (n) {
#if 0
case 2: /* "h2" */
if (in[i] == 'h' && in[i+1] == '2') {
proto = MOD_GNUTLS_ALPN_H2;
hctx->r->http_version = HTTP_VERSION_2;
break;
}
return 0;
#endif
case 8: /* "http/1.1" "http/1.0" */
if (0 == memcmp(in+i, "http/1.", 7)) {
if (in[i+7] == '1') {
@ -1451,13 +1451,19 @@ mod_gnutls_client_hello_hook(gnutls_session_t ssl, unsigned int htype,
#if GNUTLS_VERSION_NUMBER >= 0x030200
/* https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids */
static const gnutls_datum_t alpn_protos_http_acme[] = {
{ (unsigned char *)CONST_STR_LEN("http/1.1") }
{ (unsigned char *)CONST_STR_LEN("h2") }
,{ (unsigned char *)CONST_STR_LEN("http/1.1") }
,{ (unsigned char *)CONST_STR_LEN("http/1.0") }
,{ (unsigned char *)CONST_STR_LEN("acme-tls/1") }
};
unsigned int n = !buffer_string_is_empty(hctx->conf.ssl_acme_tls_1) ? 3 : 2;
unsigned int n = !buffer_string_is_empty(hctx->conf.ssl_acme_tls_1) ? 4 : 3;
const gnutls_datum_t *alpn_protos = alpn_protos_http_acme;
if (!hctx->r->conf.h2proto) {
++alpn_protos;
--n;
}
/*unsigned int flags = GNUTLS_ALPN_SERVER_PRECEDENCE;*/
rc = gnutls_alpn_set_protocols(hctx->ssl, alpn_protos_http_acme, n, 0);
rc = gnutls_alpn_set_protocols(hctx->ssl, alpn_protos, n, 0);
if (rc < 0) {
log_error_st *errh = hctx->r->conf.errh;
elog(errh, __FILE__, __LINE__, rc, "gnutls_alpn_set_protocols()");
@ -2392,6 +2398,7 @@ connection_write_cq_ssl (connection *con, chunkqueue *cq, off_t max_bytes)
{
handler_ctx *hctx = con->plugin_ctx[plugin_data_singleton->id];
gnutls_session_t ssl = hctx->ssl;
if (!hctx->handshake) return 0;
if (hctx->pending_write) {
int wr = gnutls_record_send(ssl, NULL, 0);

View File

@ -85,6 +85,7 @@
#include "base.h"
#include "fdevent.h"
#include "http_header.h"
#include "http_kv.h"
#include "log.h"
#include "plugin.h"
#include "safe_memclear.h"
@ -965,14 +966,13 @@ mod_mbedtls_alpn_select_cb (handler_ctx *hctx, const char *in)
unsigned short proto;
switch (n) {
#if 0
case 2: /* "h2" */
if (in[i] == 'h' && in[i+1] == '2') {
proto = MOD_MBEDTLS_ALPN_H2;
hctx->r->http_version = HTTP_VERSION_2;
break;
}
return 0;
#endif
case 8: /* "http/1.1" "http/1.0" */
if (0 == memcmp(in+i, "http/1.", 7)) {
if (in[i+7] == '1') {
@ -1194,19 +1194,22 @@ network_init_ssl (server *srv, plugin_config_socket *s, plugin_data *p)
#ifdef MBEDTLS_SSL_ALPN
/* https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids */
static const char *alpn_protos_http_acme[] = {
"http/1.1"
"h2"
,"http/1.1"
,"http/1.0"
,"acme-tls/1"
,NULL
};
static const char *alpn_protos_http[] = {
"http/1.1"
"h2"
,"http/1.1"
,"http/1.0"
,NULL
};
const char **alpn_protos = (!buffer_string_is_empty(s->ssl_acme_tls_1))
? alpn_protos_http_acme
: alpn_protos_http;
if (!srv->srvconf.h2proto) ++alpn_protos;
rc = mbedtls_ssl_conf_alpn_protocols(s->ssl_ctx, alpn_protos);
if (0 != rc) {
elog(srv->errh, __FILE__, __LINE__, rc, "error setting ALPN protocols");
@ -1909,11 +1912,9 @@ mod_mbedtls_ssl_handshake (handler_ctx *hctx)
}
if (0 == rc && hctx->ssl.state == MBEDTLS_SSL_SERVER_HELLO) {
#ifdef MBEDTLS_SSL_ALPN
if (!buffer_string_is_empty(hctx->conf.ssl_acme_tls_1)) {
const char *alpn = mbedtls_ssl_get_alpn_protocol(&hctx->ssl);
if (NULL != alpn)
rc = mod_mbedtls_alpn_select_cb(hctx, alpn);
}
const char *alpn = mbedtls_ssl_get_alpn_protocol(&hctx->ssl);
if (NULL != alpn)
rc = mod_mbedtls_alpn_select_cb(hctx, alpn);
#endif
}
}

View File

@ -104,6 +104,7 @@
#include "base.h"
#include "fdevent.h"
#include "http_header.h"
#include "http_kv.h"
#include "log.h"
#include "plugin.h"
#include "safe_memclear.h"
@ -1270,7 +1271,8 @@ mod_nss_alpn_select_cb (void *arg, PRFileDesc *ssl,
{
/* https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids */
static const SECItem alpn[] = {
{ 0, (unsigned char *)CONST_STR_LEN("http/1.1") }
{ 0, (unsigned char *)CONST_STR_LEN("h2") }
,{ 0, (unsigned char *)CONST_STR_LEN("http/1.1") }
,{ 0, (unsigned char *)CONST_STR_LEN("http/1.0") }
,{ 0, (unsigned char *)CONST_STR_LEN("acme-tls/1") }
};
@ -1289,12 +1291,17 @@ mod_nss_alpn_select_cb (void *arg, PRFileDesc *ssl,
handler_ctx *hctx = arg;
switch (j) { /*(must match SECItem alpn[] above)*/
case 0:
hctx->alpn = MOD_NSS_ALPN_HTTP11;
if (!hctx->r->conf.h2proto) continue;
hctx->alpn = MOD_NSS_ALPN_H2;
hctx->r->http_version = HTTP_VERSION_2;
break;
case 1:
hctx->alpn = MOD_NSS_ALPN_HTTP10;
hctx->alpn = MOD_NSS_ALPN_HTTP11;
break;
case 2:
hctx->alpn = MOD_NSS_ALPN_HTTP10;
break;
case 3:
if (buffer_string_is_empty(hctx->conf.ssl_acme_tls_1))
continue;
if (0 == mod_nss_acme_tls_1(hctx))

View File

@ -153,6 +153,7 @@ WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( WOLF_STACK_OF
#include "base.h"
#include "fdevent.h"
#include "http_header.h"
#include "http_kv.h"
#include "log.h"
#include "plugin.h"
#include "safe_memclear.h"
@ -2400,14 +2401,14 @@ mod_openssl_alpn_select_cb (SSL *ssl, const unsigned char **out, unsigned char *
n = in[i++];
if (i+n > inlen || 0 == n) break;
switch (n) {
#if 0
case 2: /* "h2" */
if (in[i] == 'h' && in[i+1] == '2') {
if (!hctx->r->conf.h2proto) continue;
proto = MOD_OPENSSL_ALPN_H2;
hctx->r->http_version = HTTP_VERSION_2;
break;
}
continue;
#endif
case 8: /* "http/1.1" "http/1.0" */
if (0 == memcmp(in+i, "http/1.", 7)) {
if (in[i+7] == '1') {