1
0
Fork 0
mirror of https://repo.or.cz/socat.git synced 2025-07-07 13:26:33 +00:00

Added SNI support to OPENSSL-CONNECT, with options no-sni, snihost

This commit is contained in:
Gerhard Rieger 2020-12-31 14:30:04 +01:00
parent d109e3131b
commit aa2b9c00b2
9 changed files with 179 additions and 2 deletions

View file

@ -131,6 +131,10 @@ const struct optdesc opt_openssl_compress = { "openssl-compress", "compress
const struct optdesc opt_openssl_fips = { "openssl-fips", "fips", OPT_OPENSSL_FIPS, GROUP_OPENSSL, PH_SPEC, TYPE_BOOL, OFUNC_SPEC };
#endif
const struct optdesc opt_openssl_commonname = { "openssl-commonname", "cn", OPT_OPENSSL_COMMONNAME, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC };
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
const struct optdesc opt_openssl_no_sni = { "openssl-no-sni", "nosni", OPT_OPENSSL_NO_SNI, GROUP_OPENSSL, PH_SPEC, TYPE_BOOL, OFUNC_SPEC };
const struct optdesc opt_openssl_snihost = { "openssl-snihost", "snihost", OPT_OPENSSL_SNIHOST, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC };
#endif
/* If FIPS is compiled in, we need to track if the user asked for FIPS mode.
@ -220,6 +224,8 @@ static int
bool opt_ver = true; /* verify peer certificate */
char *opt_cert = NULL; /* file name of client certificate */
const char *opt_commonname = NULL; /* for checking peer certificate */
bool opt_no_sni;
const char *opt_snihost = NULL; /* for SNI host */
int result;
if (!(xioflags & XIO_MAYCONVERT)) {
@ -249,11 +255,27 @@ static int
retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname);
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
retropt_bool(opts, OPT_OPENSSL_NO_SNI, &opt_no_sni);
retropt_string(opts, OPT_OPENSSL_SNIHOST, (char **)&opt_snihost);
#endif
if (opt_commonname == NULL) {
opt_commonname = hostname;
opt_commonname = strdup(hostname);
if (opt_commonname == NULL) {
Error1("strdup("F_Zu"): out of memory", strlen(hostname)+1);
}
}
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
if (opt_snihost == NULL) {
opt_snihost = strdup(opt_commonname);
if (opt_snihost == NULL) {
Error1("strdup("F_Zu"): out of memory", strlen(opt_commonname)+1);
}
}
#endif
result =
_xioopen_openssl_prepare(opts, xfd, false, &opt_ver, opt_cert, &ctx, (bool *)&use_dtls);
if (result != STAT_OK) return STAT_NORETRY;
@ -319,7 +341,8 @@ static int
return result;
}
result = _xioopen_openssl_connect(xfd, opt_ver, opt_commonname, ctx, level);
result = _xioopen_openssl_connect(xfd, opt_ver, opt_commonname,
opt_no_sni, opt_snihost, ctx, level);
switch (result) {
case STAT_OK: break;
#if WITH_RETRY
@ -376,6 +399,9 @@ static int
openssl_conn_loginfo(xfd->para.openssl.ssl);
free((void *)opt_commonname);
free((void *)opt_snihost);
/* fill in the fd structure */
return STAT_OK;
}
@ -388,6 +414,8 @@ static int
int _xioopen_openssl_connect(struct single *xfd,
bool opt_ver,
const char *opt_commonname,
bool no_sni,
const char *snihost,
SSL_CTX *ctx,
int level) {
SSL *ssl;
@ -412,6 +440,17 @@ int _xioopen_openssl_connect(struct single *xfd,
return result;
}
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
if (!no_sni) {
if (!SSL_set_tlsext_host_name(ssl, snihost)) {
Error1("Failed to set SNI host \"%s\"", snihost);
sycSSL_free(xfd->para.openssl.ssl);
xfd->para.openssl.ssl = NULL;
return STAT_NORETRY;
}
}
#endif
result = xioSSL_connect(xfd, opt_commonname, opt_ver, level);
if (result != STAT_OK) {
sycSSL_free(xfd->para.openssl.ssl);