mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-20 22:15:40 +00:00
MINOR: ssl: support Openssl 1.1.1 early callback for switchctx
Use Openssl-1.1.1 SSL_CTX_set_client_hello_cb to mimic BoringSSL early callback. Native multi certificate and SSL/TLS method per certificate is now supported by Openssl >= 1.1.1.
This commit is contained in:
parent
48e8755639
commit
84e417d859
@ -10399,8 +10399,9 @@ crt <cert>
|
|||||||
to use both RSA and ECDSA cipher suites. Users connecting with an SNI of
|
to use both RSA and ECDSA cipher suites. Users connecting with an SNI of
|
||||||
"rsa.example.com" will only be able to use RSA cipher suites, and users
|
"rsa.example.com" will only be able to use RSA cipher suites, and users
|
||||||
connecting with "ecdsa.example.com" will only be able to use ECDSA cipher
|
connecting with "ecdsa.example.com" will only be able to use ECDSA cipher
|
||||||
suites. With BoringSSL multi-cert is natively supported, no need to bundle
|
suites. With BoringSSL and Openssl >= 1.1.1 multi-cert is natively supported,
|
||||||
certificates. ECDSA certificate will be preferred if client support it.
|
no need to bundle certificates. ECDSA certificate will be preferred if client
|
||||||
|
support it.
|
||||||
|
|
||||||
If a directory name is given as the <cert> argument, haproxy will
|
If a directory name is given as the <cert> argument, haproxy will
|
||||||
automatically search and load bundled files in that directory.
|
automatically search and load bundled files in that directory.
|
||||||
@ -10424,7 +10425,7 @@ crt-list <file>
|
|||||||
|
|
||||||
sslbindconf support "npn", "alpn", "verify", "ca-file", "no-ca-names",
|
sslbindconf support "npn", "alpn", "verify", "ca-file", "no-ca-names",
|
||||||
crl-file", "ecdhe", "curves", "ciphers" configuration. With BoringSSL
|
crl-file", "ecdhe", "curves", "ciphers" configuration. With BoringSSL
|
||||||
"ssl-min-ver" and "ssl-max-ver" are also supported.
|
and Openssl >= 1.1.1 "ssl-min-ver" and "ssl-max-ver" are also supported.
|
||||||
It override the configuration set in bind line for the certificate.
|
It override the configuration set in bind line for the certificate.
|
||||||
|
|
||||||
Wildcards are supported in the SNI filter. Negative filter are also supported,
|
Wildcards are supported in the SNI filter. Negative filter are also supported,
|
||||||
@ -10438,9 +10439,9 @@ crt-list <file>
|
|||||||
|
|
||||||
Multi-cert bundling (see "crt") is supported with crt-list, as long as only
|
Multi-cert bundling (see "crt") is supported with crt-list, as long as only
|
||||||
the base name is given in the crt-list. SNI filter will do the same work on
|
the base name is given in the crt-list. SNI filter will do the same work on
|
||||||
all bundled certificates. With BoringSSL multi-cert is natively supported,
|
all bundled certificates. With BoringSSL and Openssl >= 1.1.1 multi-cert is
|
||||||
avoid multi-cert bundling. RSA and ECDSA certificates can be declared in a
|
natively supported, avoid multi-cert bundling. RSA and ECDSA certificates can
|
||||||
row, and set different ssl and filter parameter.
|
be declared in a row, and set different ssl and filter parameter.
|
||||||
|
|
||||||
crt-list file example:
|
crt-list file example:
|
||||||
cert1.pem
|
cert1.pem
|
||||||
|
@ -1828,7 +1828,7 @@ ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_con
|
|||||||
#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
|
#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
|
||||||
#define SSL_OP_NO_TLSv1_2 0
|
#define SSL_OP_NO_TLSv1_2 0
|
||||||
#endif
|
#endif
|
||||||
#ifndef SSL_OP_NO_TLSv1_3 /* dev */
|
#ifndef SSL_OP_NO_TLSv1_3 /* needs OpenSSL >= 1.1.1 */
|
||||||
#define SSL_OP_NO_TLSv1_3 0
|
#define SSL_OP_NO_TLSv1_3 0
|
||||||
#endif
|
#endif
|
||||||
#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
|
#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
|
||||||
@ -1951,7 +1951,7 @@ static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
|
|||||||
SSL_set_SSL_CTX(ssl, ctx);
|
SSL_set_SSL_CTX(ssl, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) || defined(OPENSSL_IS_BORINGSSL)
|
||||||
|
|
||||||
static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
|
static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
|
||||||
{
|
{
|
||||||
@ -1963,9 +1963,14 @@ static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
|
|||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
|
static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
|
||||||
{
|
{
|
||||||
SSL *ssl = ctx->ssl;
|
SSL *ssl = ctx->ssl;
|
||||||
|
#else
|
||||||
|
static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
|
||||||
|
{
|
||||||
|
#endif
|
||||||
struct connection *conn;
|
struct connection *conn;
|
||||||
struct bind_conf *s;
|
struct bind_conf *s;
|
||||||
const uint8_t *extension_data;
|
const uint8_t *extension_data;
|
||||||
@ -1981,8 +1986,12 @@ static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
|
|||||||
conn = SSL_get_app_data(ssl);
|
conn = SSL_get_app_data(ssl);
|
||||||
s = objt_listener(conn->target)->bind_conf;
|
s = objt_listener(conn->target)->bind_conf;
|
||||||
|
|
||||||
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
|
if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
|
||||||
&extension_data, &extension_len)) {
|
&extension_data, &extension_len)) {
|
||||||
|
#else
|
||||||
|
if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &extension_data, &extension_len)) {
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* The server_name extension was given too much extensibility when it
|
* The server_name extension was given too much extensibility when it
|
||||||
* was written, so parsing the normal case is a bit complex.
|
* was written, so parsing the normal case is a bit complex.
|
||||||
@ -2022,7 +2031,11 @@ static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* extract/check clientHello informations */
|
/* extract/check clientHello informations */
|
||||||
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
|
if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
|
||||||
|
#else
|
||||||
|
if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
|
||||||
|
#endif
|
||||||
uint8_t sign;
|
uint8_t sign;
|
||||||
size_t len;
|
size_t len;
|
||||||
if (extension_len < 2)
|
if (extension_len < 2)
|
||||||
@ -2057,13 +2070,21 @@ static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
|
|||||||
const SSL_CIPHER *cipher;
|
const SSL_CIPHER *cipher;
|
||||||
size_t len;
|
size_t len;
|
||||||
const uint8_t *cipher_suites;
|
const uint8_t *cipher_suites;
|
||||||
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
len = ctx->cipher_suites_len;
|
len = ctx->cipher_suites_len;
|
||||||
cipher_suites = ctx->cipher_suites;
|
cipher_suites = ctx->cipher_suites;
|
||||||
|
#else
|
||||||
|
len = SSL_client_hello_get0_ciphers(ssl, &cipher_suites);
|
||||||
|
#endif
|
||||||
if (len % 2 != 0)
|
if (len % 2 != 0)
|
||||||
goto abort;
|
goto abort;
|
||||||
for (; len != 0; len -= 2, cipher_suites += 2) {
|
for (; len != 0; len -= 2, cipher_suites += 2) {
|
||||||
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
uint16_t cipher_suite = (cipher_suites[0] << 8) | cipher_suites[1];
|
uint16_t cipher_suite = (cipher_suites[0] << 8) | cipher_suites[1];
|
||||||
cipher = SSL_get_cipher_by_value(cipher_suite);
|
cipher = SSL_get_cipher_by_value(cipher_suite);
|
||||||
|
#else
|
||||||
|
cipher = SSL_CIPHER_find(ssl, cipher_suites);
|
||||||
|
#endif
|
||||||
if (cipher && SSL_CIPHER_get_auth_nid(cipher) == NID_auth_ecdsa) {
|
if (cipher && SSL_CIPHER_get_auth_nid(cipher) == NID_auth_ecdsa) {
|
||||||
has_ecdsa = 1;
|
has_ecdsa = 1;
|
||||||
break;
|
break;
|
||||||
@ -2152,7 +2173,12 @@ static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
|
|||||||
abort:
|
abort:
|
||||||
/* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
|
/* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
|
||||||
conn->err_code = CO_ER_SSL_HANDSHAKE;
|
conn->err_code = CO_ER_SSL_HANDSHAKE;
|
||||||
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
return ssl_select_cert_error;
|
return ssl_select_cert_error;
|
||||||
|
#else
|
||||||
|
*al = SSL_AD_UNRECOGNIZED_NAME;
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* OPENSSL_IS_BORINGSSL */
|
#else /* OPENSSL_IS_BORINGSSL */
|
||||||
@ -3647,6 +3673,9 @@ ssl_sock_initial_ctx(struct bind_conf *bind_conf)
|
|||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
|
SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
|
||||||
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
|
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
|
||||||
|
#elif (OPENSSL_VERSION_NUMBER >= 0x10101000L)
|
||||||
|
SSL_CTX_set_client_hello_cb(ctx, ssl_sock_switchctx_cbk, NULL);
|
||||||
|
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
|
||||||
#else
|
#else
|
||||||
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
|
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
|
||||||
SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
|
SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
|
||||||
@ -6773,7 +6802,7 @@ static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_
|
|||||||
|
|
||||||
static int ssl_bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
|
static int ssl_bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
|
||||||
{
|
{
|
||||||
#if !defined(OPENSSL_IS_BORINGSSL)
|
#if (OPENSSL_VERSION_NUMBER < 0x10101000L) || !defined(OPENSSL_IS_BORINGSSL)
|
||||||
Warning("crt-list: ssl-min-ver and ssl-max-ver are not supported with this Openssl version (skipped).\n");
|
Warning("crt-list: ssl-min-ver and ssl-max-ver are not supported with this Openssl version (skipped).\n");
|
||||||
#endif
|
#endif
|
||||||
return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
|
return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
|
||||||
|
Loading…
Reference in New Issue
Block a user