diff options
author | tjpcc <tjp@ctrl-c.club> | 2023-10-30 12:02:11 -0600 |
---|---|---|
committer | tjpcc <tjp@ctrl-c.club> | 2023-10-30 12:02:41 -0600 |
commit | 87189fafa7134f70dcdd51f1d508686573a91979 (patch) | |
tree | c4bcf2c979c37de7554392bc505067f13d51a044 | |
parent | f85930d875494c043fc5ac3ddcf843ddfac14ec9 (diff) |
multitls support for virtualhosting with SNI
fixes #15
-rw-r--r-- | gemini/tls.go | 32 |
1 files changed, 31 insertions, 1 deletions
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 +} |