Clone
clone: git://shithub.us/igor/tlssrv.sni gits://shithub.us/igor/tlssrv.sni
push: hjgit://shithub.us/igor/tlssrv.sni
patches to: igor@9lab.org
Last commit
fe1ec8fd
– igor <igor@mux>
authored
on 2023/01/28 19:25
Describe the top level goal...
About
This is WIP attempting to extend tlssrv to support the Server Name
Identifier (SNI) extension. With this extension it is possible to use
multiple SSL certificates with a single IP address.
# Key Functions
tlshand.c:/^tlsClientExtensions
tlshand.c:/^checkClientExtensions
tlshand.c:/^tlsConnectionFree
# Data Types
tlshand.c:/^typedef struct TlsConnection
/sys/include/libsec.h:/^typedef struct TLSconn
# Approach
The function tlshand.c:/^checkClientExtensions must
be extended to decode the server name indication. For this
the 'tlshand.c:/^typedef struct TlsConnection' needs to
be extended to hold the server name.
tlshand.c:/^tlsConnectionFree needs to free any potential
`TlsConnection.serverName`.
We are going to allow multiple certificates to be specified
to tlssrv. A certificate encodes its domain in its subject:
% auth/pemdecode 'CERTIFICATE' /sys/lib/tls/acmed/mux.9lab.org.crt | auth/x5092pub
key proto=rsa size=2048 ek=10001 n=BEF7549C333817BBE366CD58B2A60D3D2E3C1924ADF9E9B6BDB7FB74B5FF0CF1FF5A4D7A6F7202B7155D854396E925ADEAAF27AF8A118E0360470D6FD01BBF710051B02A53ECBFA8A8BB0FADCD4C7E320296CC6E82DE71B3B9D0378B982DB0359E4C8FD2AF9CB9BC3B6CBC0931E6638F74E716AA7B7AAF9E0873DDA676073B9C4F499EE57D96BAD2C2FB156CC25C289EAAC962CE785C82D2CFD78CC2A493B0965224EAFE94AB0A14441EF0CE4BBC0BF1E4034CAD051131A08120221F56E7000CAAF2244D5B111F7764CF04BE1A4BC866721FC4F8C9BD35F4EB71BFF33982F7BEAB3246794610666896C01D572D674E9A27B2CBD2D2D9311DAD675BAF230B82BF subject=mux.9lab.org
Sample code that shows how to extract the domain from the
subject can be found in /sys/src/cmd/auth/acmed.c:/^getcert
static void
getcert(char *csrpath)
{
char *csr, *dom[64], subj[2048];
uchar *der;
int nder, ndom, fd;
RSApub *rsa;
Hdr loc = { "location" };
JSON *o;
if((fd = open(csrpath, OREAD|OCEXEC)) == -1)
sysfatal("open %s: %r", csrpath);
if((der = slurp(fd, &nder)) == nil)
sysfatal("read %s: %r", csrpath);
close(fd);
if((rsa = X509reqtoRSApub(der, nder, subj, sizeof(subj))) == nil)
sysfatal("decode csr: %r");
rsapubfree(rsa);
if((csr = encurl64(der, nder)) == nil)
sysfatal("encode %s: %r", csrpath);
free(der);
dprint("subject: %s\n", subj);
if((ndom = getfields(subj, dom, nelem(dom), 1, ", ")) == nelem(dom))
sysfatal("too man domains");
if((o = submitorder(dom, ndom, &loc)) == nil)
sysfatal("order: %r");
if(dochallenges(dom, ndom, o) == -1)
sysfatal("challenge: %r");
if(submitcsr(o, csr) == -1)
sysfatal("signing cert: %r");
if(fetchcert(loc.val) == -1)
sysfatal("saving cert: %r");
free(csr);
}