Bug#926332: socat: please support SNI

2021-02-01 Thread Vagrant Cascadian
On 2019-04-03, Benjamin Barenblat wrote:
> socat does not support the TLS Server Name Indication extension. This
> extension has become pretty widely deployed at this point, and socat’s
> TLS support could be substantially more useful if it sent SNI.

I believe this is supported in version 1.7.4, according to the man page:

   snihost=

  Set the client side Server Name Indication (SNI) host name
  different from the addressed server name or common name. This
  might be useful when the server certificate has multiple host
  names or wildcard names because the SNI host name is passed in
  cleartext to the server and might be eavesdropped; with this
  option a mock name of the desired certificate may be transferred.


live well,
  vagrant


signature.asc
Description: PGP signature


Bug#926332: socat: please support SNI

2019-04-03 Thread Benjamin Barenblat
Package: socat
Version: 1.7.3.2-2
Severity: wishlist
Tags: upstream

socat does not support the TLS Server Name Indication extension. This
extension has become pretty widely deployed at this point, and socat’s
TLS support could be substantially more useful if it sent SNI.

A patch against 1.7.3.0 is available [1]; I’ve also attached it here for
convenience. I haven’t tested or reviewed it, though, so its inclusion
should not be treated as an endorsement. :)

[1] 
https://github.com/moparisthebest/socat/commit/268432bf4220502535dbd373344b60b8fd10e3ce
>From 268432bf4220502535dbd373344b60b8fd10e3ce Mon Sep 17 00:00:00 2001
From: moparisthebest 
Date: Fri, 17 Jul 2015 22:08:00 -0400
Subject: [PATCH 1/1] Add OpenSSL snihost option for TLS SNI extension

---
 doc/socat.yo  |  9 +++--
 xio-openssl.c | 16 +++-
 xio-openssl.h |  2 ++
 xioopts.c |  2 ++
 xioopts.h |  1 +
 5 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/doc/socat.yo b/doc/socat.yo
index 65e9894..18269da 100644
--- a/doc/socat.yo
+++ b/doc/socat.yo
@@ -502,13 +502,15 @@ label(ADDRESS_OPENSSL_CONNECT)dit(bf(tt(OPENSSL::)))
link(openssl-commonname)(OPTION_OPENSSL_COMMONNAME) option.
Socat tries to match it against the certificates subject commonName,
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()
Useful options:
link(cipher)(OPTION_OPENSSL_CIPHERLIST),
link(method)(OPTION_OPENSSL_METHOD),
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(capath)(OPTION_OPENSSL_CAPATH),
link(certificate)(OPTION_OPENSSL_CERTIFICATE),
@@ -2700,6 +2702,9 @@ label(OPTION_OPENSSL_COMMONNAME)dit(bf(tt(commonname=)))
certificates commonname. This option has only meaning when option
link(verify)(OPTION_OPENSSL_VERIFY) is not disabled and the choosen cipher
provides a peer certificate.
+label(OPTION_OPENSSL_SNIHOST)dit(bf(tt(snihost=)))
+   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)))
Enables FIPS mode if compiled in. For info about the FIPS encryption
implementation standard see lurl(http://oss-institute.org/fips-faq.html). 
diff --git a/xio-openssl.c b/xio-openssl.c
index 665430d..a04e5bf 100644
--- a/xio-openssl.c
+++ b/xio-openssl.c
@@ -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 };
 #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_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.
@@ -197,6 +198,7 @@ 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 */
+   const char *opt_snihost = NULL;   /* for sni host */
int result;
 
if (!(xioflags & XIO_MAYCONVERT)) {
@@ -226,10 +228,15 @@ static int
 
retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname);
+   retropt_string(opts, OPT_OPENSSL_SNIHOST, (char **)&opt_snihost);

if (opt_commonname == NULL) {
   opt_commonname = hostname;
}
+   /* could do this, but might not be desired?
+   if (opt_snihost == NULL) {
+  opt_snihost = hostname;
+   } */
 
result =
   _xioopen_openssl_prepare(opts, xfd, false, &opt_ver, opt_cert, &ctx);
@@ -289,7 +296,7 @@ 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_snihost, ctx, level);
   switch (result) {
   case STAT_OK: break;
 #if WITH_RETRY
@@ -358,6 +365,7 @@ static int
 int _xioopen_openssl_connect(struct single *xfd,
 			 bool opt_ver,
 			 const char *opt_commonname,
+			 const char *opt_snihost,
 			 SSL_CTX *ctx,
 			 int level) {
SSL *ssl;
@@ -382,6 +390,12 @@ int _xioope