1package main
2
3import (
4	"crypto/tls"
5
6	"github.com/mwitkow/go-conntrack/connhelpers"
7	logrus "github.com/sirupsen/logrus"
8	"github.com/spf13/pflag"
9
10	"crypto/x509"
11	"io/ioutil"
12)
13
14var (
15	flagTlsServerCert = pflag.String(
16		"server_tls_cert_file",
17		"",
18		"Path to the PEM certificate for server use.")
19
20	flagTlsServerKey = pflag.String(
21		"server_tls_key_file",
22		"../misc/localhost.key",
23		"Path to the PEM key for the certificate for the server use.")
24
25	flagTlsServerClientCertVerification = pflag.String(
26		"server_tls_client_cert_verification",
27		"none",
28		"Controls whether a client certificate is on. Values: none, verify_if_given, require.")
29
30	flagTlsServerClientCAFiles = pflag.StringSlice(
31		"server_tls_client_ca_files",
32		[]string{},
33		"Paths (comma separated) to PEM certificate chains used for client-side verification. If empty, host CA chain will be used.",
34	)
35)
36
37func buildServerTlsOrFail() *tls.Config {
38	if *flagTlsServerCert == "" || *flagTlsServerKey == "" {
39		logrus.Fatalf("flags server_tls_cert_file and server_tls_key_file must be set")
40	}
41	tlsConfig, err := connhelpers.TlsConfigForServerCerts(*flagTlsServerCert, *flagTlsServerKey)
42	if err != nil {
43		logrus.Fatalf("failed reading TLS server keys: %v", err)
44	}
45	tlsConfig.MinVersion = tls.VersionTLS12
46	switch *flagTlsServerClientCertVerification {
47	case "none":
48		tlsConfig.ClientAuth = tls.NoClientCert
49	case "verify_if_given":
50		tlsConfig.ClientAuth = tls.VerifyClientCertIfGiven
51	case "require":
52		tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
53	default:
54		logrus.Fatalf("Uknown value '%v' for server_tls_client_cert_verification", *flagTlsServerClientCertVerification)
55	}
56	if tlsConfig.ClientAuth != tls.NoClientCert {
57		if len(*flagTlsServerClientCAFiles) > 0 {
58			tlsConfig.ClientCAs = x509.NewCertPool()
59			for _, path := range *flagTlsServerClientCAFiles {
60				data, err := ioutil.ReadFile(path)
61				if err != nil {
62					logrus.Fatalf("failed reading client CA file %v: %v", path, err)
63				}
64				if ok := tlsConfig.ClientCAs.AppendCertsFromPEM(data); !ok {
65					logrus.Fatalf("failed processing client CA file %v", path)
66				}
67			}
68		} else {
69			var err error
70			tlsConfig.ClientCAs, err = x509.SystemCertPool()
71			if err != nil {
72				logrus.Fatalf("no client CA files specified, fallback to system CA chain failed: %v", err)
73			}
74		}
75
76	}
77	tlsConfig, err = connhelpers.TlsConfigWithHttp2Enabled(tlsConfig)
78	if err != nil {
79		logrus.Fatalf("can't configure h2 handling: %v", err)
80	}
81	return tlsConfig
82}
83