diff --git a/internal/config/files.go b/internal/config/files.go new file mode 100644 index 0000000..d016afe --- /dev/null +++ b/internal/config/files.go @@ -0,0 +1,26 @@ +package config + +import ( + "os" + "path/filepath" +) + +var ( + CAFile = configFile("ca.pem") + ServerCertFile = configFile("server.pem") + ServerKeyFile = configFile("server-key.pem") + ClientCertFile = configFile("client.pem") + ClientKeyFile = configFile("client-key.pem") +) + +func configFile(filename string) string { + if dir := os.Getenv("CONFIG_DIR"); dir != "" { + return filepath.Join(dir, filename) + } + + homeDir, err := os.UserHomeDir() + if err != nil { + panic(err) + } + return filepath.Join(homeDir, ".proglog", filename) +} diff --git a/internal/config/tls.go b/internal/config/tls.go new file mode 100644 index 0000000..c3b963c --- /dev/null +++ b/internal/config/tls.go @@ -0,0 +1,59 @@ +package config + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "io/ioutil" +) + +func SetupTLSConfig(cfg TLSConfig) (*tls.Config, error) { + var err error + tlsConfig := &tls.Config{} + // Load key pair for the server. + if cfg.CertFile != "" && cfg.KeyFile != "" { + tlsConfig.Certificates = make([]tls.Certificate, 1) + tlsConfig.Certificates[0], err = tls.LoadX509KeyPair( + cfg.CertFile, + cfg.KeyFile, + ) + if err != nil { + return nil, err + } + } + + if cfg.CAFile != "" { + b, err := ioutil.ReadFile(cfg.CAFile) + if err != nil { + return nil, err + } + ca := x509.NewCertPool() + ok := ca.AppendCertsFromPEM(b) + if !ok { + return nil, fmt.Errorf( + "failed to parse root certificate: %q", + cfg.CAFile, + ) + } + if cfg.Server { + tlsConfig.ClientCAs = ca + tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert + } else { + tlsConfig.RootCAs = ca + } + tlsConfig.ServerName = cfg.ServerAddress + } + + return tlsConfig, nil + +} + +type TLSConfig struct { + CertFile string + KeyFile string + CAFile string + ServerAddress string + // If this is true, the server validates the authenticity of client certificates. + // Meaning we can use mutual TLS authentication. + Server bool +}