feat: possibly read custom CA certs to create tls.Config

pull/5672/head
Pavel Zavora 2021-02-24 07:55:34 +01:00
parent a11dc5b173
commit bc03575561
2 changed files with 59 additions and 0 deletions

View File

@ -2,8 +2,11 @@ package server
import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io/ioutil"
"os"
"sort"
"strings"
)
@ -19,6 +22,8 @@ type tlsOptions struct {
MinVersion string
// MaxVersion of TLS to be negotiated with the client, no value means no maximum.
MaxVersion string
// CACerts contains Path to CA certificates
CACerts string
}
var ciphersMap = map[string]uint16{
@ -75,6 +80,26 @@ func createTLSConfig(o tlsOptions) (out *tls.Config, err error) {
out = new(tls.Config)
out.Certificates = []tls.Certificate{cert}
// CA certs
if o.CACerts != "" {
f, err := os.Open(o.CACerts)
if err != nil {
return nil, err
}
defer f.Close()
certPool := x509.NewCertPool()
certs, err := ioutil.ReadAll(f)
if err != nil {
return nil, fmt.Errorf("error reading CA certificates: %s", err.Error())
}
ok := certPool.AppendCertsFromPEM(certs)
if !ok {
return nil, fmt.Errorf("error appending CA certificates from %s", o.CACerts)
}
out.RootCAs = certPool
}
// ciphers
if len(o.Ciphers) > 0 {
for _, name := range o.Ciphers {

View File

@ -2,6 +2,7 @@ package server
import (
"crypto/tls"
"crypto/x509"
"fmt"
"testing"
@ -112,6 +113,33 @@ func Test_createTLSConfig(t *testing.T) {
},
err: `unknown maximum TLS version: "f1". available versions: 1.0, `, // + + other versions follow
},
{
name: "custom ca certs",
in: tlsOptions{
Cert: "tls_options_test.cert",
Key: "tls_options_test.key",
CACerts: "tls_options_test.cert",
},
out: &tls.Config{}, // certificates are compared
},
{
name: "unknown ca certs",
in: tlsOptions{
Cert: "tls_options_test.cert",
Key: "tls_options_test.key",
CACerts: "tls_options_test2.cert",
},
err: "open tls_options_test2.cert: no such file or directory",
},
{
name: "unsupported ca certs",
in: tlsOptions{
Cert: "tls_options_test.cert",
Key: "tls_options_test.key",
CACerts: "tls_options_test.key",
},
err: "error appending CA certificates from tls_options_test.key",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
@ -119,7 +147,13 @@ func Test_createTLSConfig(t *testing.T) {
if test.err == "" {
require.Nil(t, err)
require.NotNil(t, config.Certificates)
if test.in.CACerts != "" {
require.NotNil(t, config.RootCAs)
x509Cert, _ := x509.ParseCertificate(config.Certificates[0].Certificate[0])
require.Equal(t, config.RootCAs.Subjects()[0], x509Cert.RawSubject)
}
config.Certificates = nil // we don't want to compare certificates
config.RootCAs = nil // and also root CA certs
require.Equal(t, test.out, config)
} else {
require.NotNil(t, err)