ref: fe1ec8fd63507f3972c7d89ceba694477d570be4
dir: /README/
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); }