From 87189fafa7134f70dcdd51f1d508686573a91979 Mon Sep 17 00:00:00 2001 From: tjpcc Date: Mon, 30 Oct 2023 12:02:11 -0600 Subject: multitls support for virtualhosting with SNI fixes #15 --- gemini/tls.go | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'gemini/tls.go') diff --git a/gemini/tls.go b/gemini/tls.go index 5b35fb6..1ea0f3c 100644 --- a/gemini/tls.go +++ b/gemini/tls.go @@ -1,6 +1,9 @@ package gemini -import "crypto/tls" +import ( + "crypto/tls" + "errors" +) // FileTLS builds a TLS configuration from paths to a certificate and key file. // @@ -17,3 +20,30 @@ func FileTLS(certfile string, keyfile string) (*tls.Config, error) { ClientAuth: tls.RequestClientCert, }, nil } + +// MultiTLS returns a *tls.Config usable for virtual hosting multiple domains. +// +// The provided configs map should be keyed on domain names, and the fallback will +// be used if the client does not support SNI, or if the requested domain isn't found. +func MultiTLS(configs map[string]*tls.Config, fallback *tls.Config) *tls.Config { + multi := &tls.Config{ + MinVersion: tls.VersionTLS12, + ClientAuth: tls.RequestClientCert, + GetConfigForClient: func(info *tls.ClientHelloInfo) (*tls.Config, error) { + conf, ok := configs[info.ServerName] + if !ok { + if fallback == nil { + return nil, errors.New("no TLS config found") + } + conf = fallback + } + return conf, nil + }, + } + + if fallback != nil { + multi.Certificates = fallback.Certificates + } + + return multi +} -- cgit v1.2.3