mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-02 03:38:42 -07:00
tls: support multiple key/cert pairs, for SNI
This does not add tests or docs, this is to sound out how people feel about the API. Turn the TLS options cert_file and key_file into list-separated paths (so colon-delimited if on Unix, like `$PATH`); the count of entries must match, and the keys and certs should zip together. With this change, TLS SNI works to pick the correct cert to return for a given connection, allowing a NATS server to have multiple identities.
This commit is contained in:
@@ -3715,16 +3715,28 @@ func GenTLSConfig(tc *TLSConfigOpts) (*tls.Config, error) {
|
||||
case tc.CertFile == "" && tc.KeyFile != "":
|
||||
return nil, fmt.Errorf("missing 'cert_file' in TLS configuration")
|
||||
case tc.CertFile != "" && tc.KeyFile != "":
|
||||
// Now load in cert and private key
|
||||
cert, err := tls.LoadX509KeyPair(tc.CertFile, tc.KeyFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing X509 certificate/key pair: %v", err)
|
||||
// To support multiple certs (for SANs) without rearchitecting our
|
||||
// configuration, we accept a list, separated by the platform list
|
||||
// separator; both specs must contain the same count of entries.
|
||||
// (So, colon-separated on Unix, semi-colon on Windows).
|
||||
certFiles := strings.Split(tc.CertFile, string(os.PathListSeparator))
|
||||
keyFiles := strings.Split(tc.KeyFile, string(os.PathListSeparator))
|
||||
if len(certFiles) != len(keyFiles) {
|
||||
return nil, fmt.Errorf("TLS configuration has %d entries in cert_file but %d in key_file", len(certFiles), len(keyFiles))
|
||||
}
|
||||
cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing certificate: %v", err)
|
||||
config.Certificates = make([]tls.Certificate, len(certFiles))
|
||||
// Now load in cert and private keys
|
||||
for i := range certFiles {
|
||||
cert, err := tls.LoadX509KeyPair(certFiles[i], keyFiles[i])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing X509 certificate/key pair: %v", err)
|
||||
}
|
||||
cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing certificate: %v", err)
|
||||
}
|
||||
config.Certificates[i] = cert
|
||||
}
|
||||
config.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
|
||||
// Require client certificates as needed
|
||||
|
||||
Reference in New Issue
Block a user