mirror of
https://github.com/moparisthebest/socat
synced 2024-12-21 14:38:48 -05:00
Add OpenSSL snihost option for TLS SNI extension
This commit is contained in:
parent
8fda559e8d
commit
268432bf42
@ -502,13 +502,15 @@ label(ADDRESS_OPENSSL_CONNECT)dit(bf(tt(OPENSSL:<host>:<port>)))
|
|||||||
link(openssl-commonname)(OPTION_OPENSSL_COMMONNAME) option.
|
link(openssl-commonname)(OPTION_OPENSSL_COMMONNAME) option.
|
||||||
Socat tries to match it against the certificates subject commonName,
|
Socat tries to match it against the certificates subject commonName,
|
||||||
and the certifications extension subjectAltName DNS names. Wildcards in the
|
and the certifications extension subjectAltName DNS names. Wildcards in the
|
||||||
certificate are supported.nl()
|
certificate are supported. To specify the TLS SNI hostname to set use the
|
||||||
|
link(snihost)(OPTION_OPENSSL_SNIHOST) option.nl()
|
||||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(OPENSSL)(GROUP_OPENSSL),link(RETRY)(GROUP_RETRY) nl()
|
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(OPENSSL)(GROUP_OPENSSL),link(RETRY)(GROUP_RETRY) nl()
|
||||||
Useful options:
|
Useful options:
|
||||||
link(cipher)(OPTION_OPENSSL_CIPHERLIST),
|
link(cipher)(OPTION_OPENSSL_CIPHERLIST),
|
||||||
link(method)(OPTION_OPENSSL_METHOD),
|
link(method)(OPTION_OPENSSL_METHOD),
|
||||||
link(verify)(OPTION_OPENSSL_VERIFY),
|
link(verify)(OPTION_OPENSSL_VERIFY),
|
||||||
link(commonname)(OPTION_OPENSSL_COMMONNAME)
|
link(commonname)(OPTION_OPENSSL_COMMONNAME),
|
||||||
|
link(snihost)(OPTION_OPENSSL_SNIHOST),
|
||||||
link(cafile)(OPTION_OPENSSL_CAFILE),
|
link(cafile)(OPTION_OPENSSL_CAFILE),
|
||||||
link(capath)(OPTION_OPENSSL_CAPATH),
|
link(capath)(OPTION_OPENSSL_CAPATH),
|
||||||
link(certificate)(OPTION_OPENSSL_CERTIFICATE),
|
link(certificate)(OPTION_OPENSSL_CERTIFICATE),
|
||||||
@ -2700,6 +2702,9 @@ label(OPTION_OPENSSL_COMMONNAME)dit(bf(tt(commonname=<string>)))
|
|||||||
certificates commonname. This option has only meaning when option
|
certificates commonname. This option has only meaning when option
|
||||||
link(verify)(OPTION_OPENSSL_VERIFY) is not disabled and the choosen cipher
|
link(verify)(OPTION_OPENSSL_VERIFY) is not disabled and the choosen cipher
|
||||||
provides a peer certificate.
|
provides a peer certificate.
|
||||||
|
label(OPTION_OPENSSL_SNIHOST)dit(bf(tt(snihost=<string>)))
|
||||||
|
Specify the SNI hostname for the TLS request. The server can use this TLS
|
||||||
|
extension to choose which certificate to send.
|
||||||
label(OPTION_OPENSSL_FIPS)dit(bf(tt(fips)))
|
label(OPTION_OPENSSL_FIPS)dit(bf(tt(fips)))
|
||||||
Enables FIPS mode if compiled in. For info about the FIPS encryption
|
Enables FIPS mode if compiled in. For info about the FIPS encryption
|
||||||
implementation standard see lurl(http://oss-institute.org/fips-faq.html).
|
implementation standard see lurl(http://oss-institute.org/fips-faq.html).
|
||||||
|
@ -117,6 +117,7 @@ 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 };
|
const struct optdesc opt_openssl_fips = { "openssl-fips", "fips", OPT_OPENSSL_FIPS, GROUP_OPENSSL, PH_SPEC, TYPE_BOOL, OFUNC_SPEC };
|
||||||
#endif
|
#endif
|
||||||
const struct optdesc opt_openssl_commonname = { "openssl-commonname", "cn", OPT_OPENSSL_COMMONNAME, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC };
|
const struct optdesc opt_openssl_commonname = { "openssl-commonname", "cn", OPT_OPENSSL_COMMONNAME, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC };
|
||||||
|
const struct optdesc opt_openssl_snihost = { "openssl-snihost", "snihost", OPT_OPENSSL_SNIHOST, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC };
|
||||||
|
|
||||||
|
|
||||||
/* If FIPS is compiled in, we need to track if the user asked for FIPS mode.
|
/* If FIPS is compiled in, we need to track if the user asked for FIPS mode.
|
||||||
@ -197,6 +198,7 @@ static int
|
|||||||
bool opt_ver = true; /* verify peer certificate */
|
bool opt_ver = true; /* verify peer certificate */
|
||||||
char *opt_cert = NULL; /* file name of client certificate */
|
char *opt_cert = NULL; /* file name of client certificate */
|
||||||
const char *opt_commonname = NULL; /* for checking peer certificate */
|
const char *opt_commonname = NULL; /* for checking peer certificate */
|
||||||
|
const char *opt_snihost = NULL; /* for sni host */
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (!(xioflags & XIO_MAYCONVERT)) {
|
if (!(xioflags & XIO_MAYCONVERT)) {
|
||||||
@ -226,10 +228,15 @@ static int
|
|||||||
|
|
||||||
retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
|
retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
|
||||||
retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname);
|
retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname);
|
||||||
|
retropt_string(opts, OPT_OPENSSL_SNIHOST, (char **)&opt_snihost);
|
||||||
|
|
||||||
if (opt_commonname == NULL) {
|
if (opt_commonname == NULL) {
|
||||||
opt_commonname = hostname;
|
opt_commonname = hostname;
|
||||||
}
|
}
|
||||||
|
/* could do this, but might not be desired?
|
||||||
|
if (opt_snihost == NULL) {
|
||||||
|
opt_snihost = hostname;
|
||||||
|
} */
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_openssl_prepare(opts, xfd, false, &opt_ver, opt_cert, &ctx);
|
_xioopen_openssl_prepare(opts, xfd, false, &opt_ver, opt_cert, &ctx);
|
||||||
@ -289,7 +296,7 @@ static int
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = _xioopen_openssl_connect(xfd, opt_ver, opt_commonname, ctx, level);
|
result = _xioopen_openssl_connect(xfd, opt_ver, opt_commonname, opt_snihost, ctx, level);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case STAT_OK: break;
|
case STAT_OK: break;
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
@ -358,6 +365,7 @@ static int
|
|||||||
int _xioopen_openssl_connect(struct single *xfd,
|
int _xioopen_openssl_connect(struct single *xfd,
|
||||||
bool opt_ver,
|
bool opt_ver,
|
||||||
const char *opt_commonname,
|
const char *opt_commonname,
|
||||||
|
const char *opt_snihost,
|
||||||
SSL_CTX *ctx,
|
SSL_CTX *ctx,
|
||||||
int level) {
|
int level) {
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
@ -382,6 +390,12 @@ int _xioopen_openssl_connect(struct single *xfd,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt_snihost && !SSL_set_tlsext_host_name(ssl, opt_snihost)) {
|
||||||
|
sycSSL_free(xfd->para.openssl.ssl);
|
||||||
|
xfd->para.openssl.ssl = NULL;
|
||||||
|
return STAT_NORETRY;
|
||||||
|
}
|
||||||
|
|
||||||
result = xioSSL_connect(xfd, opt_commonname, opt_ver, level);
|
result = xioSSL_connect(xfd, opt_commonname, opt_ver, level);
|
||||||
if (result != STAT_OK) {
|
if (result != STAT_OK) {
|
||||||
sycSSL_free(xfd->para.openssl.ssl);
|
sycSSL_free(xfd->para.openssl.ssl);
|
||||||
|
@ -30,6 +30,7 @@ extern const struct optdesc opt_openssl_compress;
|
|||||||
extern const struct optdesc opt_openssl_fips;
|
extern const struct optdesc opt_openssl_fips;
|
||||||
#endif
|
#endif
|
||||||
extern const struct optdesc opt_openssl_commonname;
|
extern const struct optdesc opt_openssl_commonname;
|
||||||
|
extern const struct optdesc opt_openssl_snihost;
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
_xioopen_openssl_prepare(struct opt *opts, struct single *xfd,
|
_xioopen_openssl_prepare(struct opt *opts, struct single *xfd,
|
||||||
@ -38,6 +39,7 @@ extern int
|
|||||||
extern int
|
extern int
|
||||||
_xioopen_openssl_connect(struct single *xfd, bool opt_ver,
|
_xioopen_openssl_connect(struct single *xfd, bool opt_ver,
|
||||||
const char *opt_commonname,
|
const char *opt_commonname,
|
||||||
|
const char *opt_snihost,
|
||||||
SSL_CTX *ctx, int level);
|
SSL_CTX *ctx, int level);
|
||||||
extern int
|
extern int
|
||||||
_xioopen_openssl_listen(struct single *xfd, bool opt_ver,
|
_xioopen_openssl_listen(struct single *xfd, bool opt_ver,
|
||||||
|
@ -1109,6 +1109,7 @@ const struct optname optionnames[] = {
|
|||||||
IF_OPENSSL("openssl-key", &opt_openssl_key)
|
IF_OPENSSL("openssl-key", &opt_openssl_key)
|
||||||
IF_OPENSSL("openssl-method", &opt_openssl_method)
|
IF_OPENSSL("openssl-method", &opt_openssl_method)
|
||||||
IF_OPENSSL("openssl-pseudo", &opt_openssl_pseudo)
|
IF_OPENSSL("openssl-pseudo", &opt_openssl_pseudo)
|
||||||
|
IF_OPENSSL("openssl-snihost", &opt_openssl_snihost)
|
||||||
IF_OPENSSL("openssl-verify", &opt_openssl_verify)
|
IF_OPENSSL("openssl-verify", &opt_openssl_verify)
|
||||||
IF_TERMIOS("opost", &opt_opost)
|
IF_TERMIOS("opost", &opt_opost)
|
||||||
#if defined(HAVE_TERMIOS_ISPEED) && defined(OSPEED_OFFSET) && (OSPEED_OFFSET != -1)
|
#if defined(HAVE_TERMIOS_ISPEED) && defined(OSPEED_OFFSET) && (OSPEED_OFFSET != -1)
|
||||||
@ -1377,6 +1378,7 @@ const struct optname optionnames[] = {
|
|||||||
#ifdef SO_SNDTIMEO
|
#ifdef SO_SNDTIMEO
|
||||||
IF_SOCKET ("sndtimeo", &opt_so_sndtimeo)
|
IF_SOCKET ("sndtimeo", &opt_so_sndtimeo)
|
||||||
#endif
|
#endif
|
||||||
|
IF_OPENSSL("snihost", &opt_openssl_snihost)
|
||||||
#ifdef SO_ACCEPTCONN /* AIX433 */
|
#ifdef SO_ACCEPTCONN /* AIX433 */
|
||||||
IF_SOCKET ("so-acceptconn", &opt_so_acceptconn)
|
IF_SOCKET ("so-acceptconn", &opt_so_acceptconn)
|
||||||
#endif /* SO_ACCEPTCONN */
|
#endif /* SO_ACCEPTCONN */
|
||||||
|
@ -483,6 +483,7 @@ enum e_optcode {
|
|||||||
OPT_OPENSSL_KEY,
|
OPT_OPENSSL_KEY,
|
||||||
OPT_OPENSSL_METHOD,
|
OPT_OPENSSL_METHOD,
|
||||||
OPT_OPENSSL_PSEUDO,
|
OPT_OPENSSL_PSEUDO,
|
||||||
|
OPT_OPENSSL_SNIHOST,
|
||||||
OPT_OPENSSL_VERIFY,
|
OPT_OPENSSL_VERIFY,
|
||||||
OPT_OPOST, /* termios.c_oflag */
|
OPT_OPOST, /* termios.c_oflag */
|
||||||
OPT_OSPEED, /* termios.c_ospeed */
|
OPT_OSPEED, /* termios.c_ospeed */
|
||||||
|
Loading…
Reference in New Issue
Block a user