diff --git a/docs/TLS.md b/docs/TLS.md index 47bd4e35cadae..354b5209202fc 100644 --- a/docs/TLS.md +++ b/docs/TLS.md @@ -20,10 +20,15 @@ For client TLS support we have the following options: ## The public and private keypairs for the client encoded in PEM format. May ## contain intermediate certificates. +## Configuration for separate cert and key files # tls_cert = "/etc/telegraf/cert.pem" # tls_key = "/etc/telegraf/key.pem" # passphrase for encrypted private key, if it is in PKCS#8 format. Encrypted PKCS#1 private keys are not supported. # tls_key_pwd = "changeme" +## Configuration for single file containing both cert and key +# tls_cert_key = "/etc/telegraf/client.pem" +## For encrypted key files, supply a password for decryption +# tls_key_password = "***" ## Skip TLS verification. # insecure_skip_verify = false ## Send the specified TLS server name via SNI. @@ -47,10 +52,15 @@ The server TLS configuration provides support for TLS mutual authentication: # tls_allowed_dns_names = ["client.example.org"] ## Add service certificate and key. +## Configuration for separate cert and key files # tls_cert = "/etc/telegraf/cert.pem" # tls_key = "/etc/telegraf/key.pem" # passphrase for encrypted private key, if it is in PKCS#8 format. Encrypted PKCS#1 private keys are not supported. # tls_key_pwd = "changeme" +## Configuration for single file containing both cert and key +# tls_cert_key = "/etc/telegraf/client.pem" +## For encrypted key files, supply a password for decryption +# tls_key_password = "***" ``` #### Advanced Configuration diff --git a/plugins/common/tls/config.go b/plugins/common/tls/config.go index 2b65ccb721302..287821b3b4130 100644 --- a/plugins/common/tls/config.go +++ b/plugins/common/tls/config.go @@ -1,17 +1,13 @@ package tls import ( - "crypto/rsa" "crypto/tls" "crypto/x509" - "encoding/pem" - "errors" "fmt" "os" "strings" "github.com/influxdata/telegraf/internal/choice" - "github.com/youmark/pkcs8" ) const TLSMinVersionDefault = tls.VersionTLS12 @@ -21,7 +17,9 @@ type ClientConfig struct { TLSCA string `toml:"tls_ca"` TLSCert string `toml:"tls_cert"` TLSKey string `toml:"tls_key"` - TLSKeyPwd string `toml:"tls_key_pwd"` + TLSCertAndKey string `toml:"tls_cert_key"` + TLSKeyPwd string `toml:"tls_key_pwd" deprecated:"1.22.0;use 'tls_key_password' instead"` + TLSKeyPassword string `toml:"tls_key_password"` TLSMinVersion string `toml:"tls_min_version"` InsecureSkipVerify bool `toml:"insecure_skip_verify"` ServerName string `toml:"tls_server_name"` @@ -37,7 +35,9 @@ type ClientConfig struct { type ServerConfig struct { TLSCert string `toml:"tls_cert"` TLSKey string `toml:"tls_key"` - TLSKeyPwd string `toml:"tls_key_pwd"` + TLSCertAndKey string `toml:"tls_cert_key"` + TLSKeyPwd string `toml:"tls_key_pwd" deprecated:"1.22.0;use 'tls_key_password' instead"` + TLSKeyPassword string `toml:"tls_key_password"` TLSAllowedCACerts []string `toml:"tls_allowed_cacerts"` TLSCipherSuites []string `toml:"tls_cipher_suites"` TLSMinVersion string `toml:"tls_min_version"` @@ -72,7 +72,7 @@ func (c *ClientConfig) TLSConfig() (*tls.Config, error) { // * disabled security, // * an SNI server name, or // * empty/never renegotiation method - empty := c.TLSCA == "" && c.TLSKey == "" && c.TLSCert == "" + empty := c.TLSCA == "" && c.TLSKey == "" && c.TLSCert == "" && c.TLSCertAndKey == "" empty = empty && !c.InsecureSkipVerify && c.ServerName == "" empty = empty && (c.RenegotiationMethod == "" || c.RenegotiationMethod == "never") @@ -111,6 +111,11 @@ func (c *ClientConfig) TLSConfig() (*tls.Config, error) { tlsConfig.RootCAs = pool } + if c.TLSCertAndKey != "" { + c.TLSCert = c.TLSCertAndKey + c.TLSKey = c.TLSCertAndKey + } + if c.TLSCert != "" && c.TLSKey != "" { err := loadCertificate(tlsConfig, c.TLSCert, c.TLSKey, c.TLSKeyPwd) if err != nil { @@ -141,7 +146,7 @@ func (c *ClientConfig) TLSConfig() (*tls.Config, error) { // TLSConfig returns a tls.Config, may be nil without error if TLS is not // configured. func (c *ServerConfig) TLSConfig() (*tls.Config, error) { - if c.TLSCert == "" && c.TLSKey == "" && len(c.TLSAllowedCACerts) == 0 { + if c.TLSCert == "" && c.TLSKey == "" && c.TLSCertAndKey == "" && len(c.TLSAllowedCACerts) == 0 { return nil, nil } @@ -156,6 +161,11 @@ func (c *ServerConfig) TLSConfig() (*tls.Config, error) { tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert } + if c.TLSCertAndKey != "" { + c.TLSCert = c.TLSCertAndKey + c.TLSKey = c.TLSCertAndKey + } + if c.TLSCert != "" && c.TLSKey != "" { err := loadCertificate(tlsConfig, c.TLSCert, c.TLSKey, c.TLSKeyPwd) if err != nil { @@ -222,44 +232,16 @@ func makeCertPool(certFiles []string) (*x509.CertPool, error) { } func loadCertificate(config *tls.Config, certFile, keyFile, privateKeyPassphrase string) error { - certBytes, err := os.ReadFile(certFile) - if err != nil { - return fmt.Errorf("could not load certificate %q: %w", certFile, err) - } - - keyBytes, err := os.ReadFile(keyFile) - if err != nil { - return fmt.Errorf("could not load private key %q: %w", keyFile, err) - } - - keyPEMBlock, _ := pem.Decode(keyBytes) - if keyPEMBlock == nil { - return errors.New("failed to decode private key: no PEM data found") - } - var cert tls.Certificate - if keyPEMBlock.Type == "ENCRYPTED PRIVATE KEY" { - if privateKeyPassphrase == "" { - return errors.New("missing password for PKCS#8 encrypted private key") - } - var decryptedKey *rsa.PrivateKey - decryptedKey, err = pkcs8.ParsePKCS8PrivateKeyRSA(keyPEMBlock.Bytes, []byte(privateKeyPassphrase)) - if err != nil { - return fmt.Errorf("failed to parse encrypted PKCS#8 private key: %w", err) - } - cert, err = tls.X509KeyPair(certBytes, pem.EncodeToMemory(&pem.Block{Type: keyPEMBlock.Type, Bytes: x509.MarshalPKCS1PrivateKey(decryptedKey)})) - if err != nil { - return fmt.Errorf("failed to load cert/key pair: %w", err) - } - } else if keyPEMBlock.Headers["Proc-Type"] == "4,ENCRYPTED" { - // The key is an encrypted private key with the DEK-Info header. - // This is currently unsupported because of the deprecation of x509.IsEncryptedPEMBlock and x509.DecryptPEMBlock. - return fmt.Errorf("password-protected keys in pkcs#1 format are not supported") + var err error + if privateKeyPassphrase != "" { + cert, err = tls.X509KeyPair([]byte(ReadCertificate(certFile)), []byte(ReadKey(keyFile, privateKeyPassphrase))) } else { - cert, err = tls.X509KeyPair(certBytes, keyBytes) - if err != nil { - return fmt.Errorf("failed to load cert/key pair: %w", err) - } + cert, err = tls.LoadX509KeyPair(certFile, keyFile) + } + if err != nil { + return fmt.Errorf( + "could not load keypair %s:%s: %v", certFile, keyFile, err) } config.Certificates = []tls.Certificate{cert} return nil diff --git a/plugins/common/tls/config_test.go b/plugins/common/tls/config_test.go index 03bbb9b828d77..5e1684ff2faf2 100644 --- a/plugins/common/tls/config_test.go +++ b/plugins/common/tls/config_test.go @@ -38,10 +38,10 @@ func TestClientConfig(t *testing.T) { { name: "success with tls key password set", client: tls.ClientConfig{ - TLSCA: pki.CACertPath(), - TLSCert: pki.ClientCertPath(), - TLSKey: pki.ClientKeyPath(), - TLSKeyPwd: "", + TLSCA: pki.CACertPath(), + TLSCert: pki.ClientCertPath(), + TLSKey: pki.ClientKeyPath(), + TLSKeyPassword: "", }, }, { @@ -93,7 +93,6 @@ func TestClientConfig(t *testing.T) { expNil: true, expErr: true, }, - { name: "invalid ca", client: tls.ClientConfig{ @@ -203,7 +202,17 @@ func TestServerConfig(t *testing.T) { server: tls.ServerConfig{ TLSCert: pki.ServerCertPath(), TLSKey: pki.ServerKeyPath(), - TLSKeyPwd: "", + TLSKeyPassword: "", + TLSAllowedCACerts: []string{pki.CACertPath()}, + TLSCipherSuites: []string{pki.CipherSuite()}, + TLSMinVersion: pki.TLSMinVersion(), + TLSMaxVersion: pki.TLSMaxVersion(), + }, + }, + { + name: "success with cert and key", + server: tls.ServerConfig{ + TLSCertAndKey: pki.ServerCertAndKeyPath(), TLSAllowedCACerts: []string{pki.CACertPath()}, TLSCipherSuites: []string{pki.CipherSuite()}, TLSMinVersion: pki.TLSMinVersion(), diff --git a/plugins/common/tls/utils.go b/plugins/common/tls/utils.go index 25ef4a543f232..34a21446146b8 100644 --- a/plugins/common/tls/utils.go +++ b/plugins/common/tls/utils.go @@ -1,9 +1,16 @@ package tls import ( + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" "fmt" + "os" "sort" "strings" + + "github.com/youmark/pkcs8" ) // ParseCiphers returns a `[]uint16` by received `[]string` key that represents ciphers from crypto/tls. @@ -36,3 +43,58 @@ func ParseTLSVersion(version string) (uint16, error) { sort.Strings(available) return 0, fmt.Errorf("unsupported version %q (available: %s)", version, strings.Join(available, ",")) } + +func readFile(filename string) []byte { + octets, err := os.ReadFile(filename) + if err != nil { + panic(fmt.Sprintf("reading %q: %v", filename, err)) + } + return octets +} + +func ReadCertificate(filename string) string { + octets := readFile(filename) + return string(octets) +} + +func ReadKey(filename string, password string) string { + keyBytes := readFile(filename) + currentBlock, remainingBlocks := pem.Decode(keyBytes) + if currentBlock == nil { + panic(errors.New("failed to decode private key: no PEM data found")) + } + var allBlocks string + for { + if currentBlock.Type == "ENCRYPTED PRIVATE KEY" { + if password == "" { + panic(errors.New("missing password for PKCS#8 encrypted private key")) + } + var decryptedKey *rsa.PrivateKey + decryptedKey, err := pkcs8.ParsePKCS8PrivateKeyRSA(currentBlock.Bytes, []byte(password)) + if err != nil { + panic(fmt.Errorf("failed to parse encrypted PKCS#8 private key: %w", err)) + } + pemBlock := string(pem.EncodeToMemory(&pem.Block{Type: currentBlock.Type, Bytes: x509.MarshalPKCS1PrivateKey(decryptedKey)})) + allBlocks += pemBlock + } else if currentBlock.Headers["Proc-Type"] == "4,ENCRYPTED" { + decryptedKeyDER, err := x509.DecryptPEMBlock(currentBlock, []byte(password)) + if err != nil { + panic(fmt.Errorf("failed to parse encrypted private key %w", err)) + } + decryptedKey, err := x509.ParsePKCS1PrivateKey(decryptedKeyDER) + if err != nil { + panic(fmt.Errorf("unable to convert from DER to PEM format: %w", err)) + } + pemBlock := string(pem.EncodeToMemory(&pem.Block{Type: currentBlock.Type, Bytes: x509.MarshalPKCS1PrivateKey(decryptedKey)})) + allBlocks += pemBlock + } else { + pemBlock := string(pem.EncodeToMemory(&pem.Block{Type: currentBlock.Type, Bytes: currentBlock.Bytes})) + allBlocks += pemBlock + } + currentBlock, remainingBlocks = pem.Decode(remainingBlocks) + if currentBlock == nil { + break + } + } + return allBlocks +} diff --git a/plugins/outputs/mongodb/README.md b/plugins/outputs/mongodb/README.md index f4062c886142a..1ba9f2bb87773 100644 --- a/plugins/outputs/mongodb/README.md +++ b/plugins/outputs/mongodb/README.md @@ -46,7 +46,7 @@ to use them. # authentication = "X509" # tls_ca = "ca.pem" # tls_key = "client.pem" - # # tls_key_pwd = "changeme" # required for encrypted tls_key + # # tls_key_password = "changeme" # required for encrypted tls_key # insecure_skip_verify = false # database to store measurements and time series collections diff --git a/plugins/outputs/mongodb/mongodb.go b/plugins/outputs/mongodb/mongodb.go index 9034b724d3c70..6e5a785d79d43 100644 --- a/plugins/outputs/mongodb/mongodb.go +++ b/plugins/outputs/mongodb/mongodb.go @@ -136,6 +136,9 @@ func (s *MongoDB) Init() error { if s.TLSKeyPwd != "" { q.Set("sslClientCertificateKeyPassword", s.TLSKeyPwd) } + if s.TLSKeyPassword != "" { + q.Set("sslClientCertificateKeyPassword", s.TLSKeyPassword) + } newConnectionString.RawQuery = q.Encode() s.Dsn = newConnectionString.String() // always auth source $external diff --git a/testutil/pki/serverenc.pem b/testutil/pki/serverenc.pem new file mode 100644 index 0000000000000..a8d21aa9ce6de --- /dev/null +++ b/testutil/pki/serverenc.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIB+TCCAWKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBBUZWxl +Z3JhZiBUZXN0IENBMB4XDTE4MDUwMzAxMDUyOVoXDTI4MDQzMDAxMDUyOVowHTEb +MBkGA1UEAwwSc2VydmVyLmxvY2FsZG9tYWluMIGfMA0GCSqGSIb3DQEBAQUAA4GN +ADCBiQKBgQDTBmLJ0pBFUxnPkkx38sBnOKvs+OinVqxTnVcc1iCyQJQleB37uY6D +L55mSsPvnad/oDpyGpHt4RVtrhmyC6ptSrWLyk7mraeAo30Cooqr5tA9A+6yj0ij +ySLlYimTMQy8tbnVNWLwKbxgT9N4NlUzwyqxLWUMfRzLfmefqzk5bQIDAQABo0sw +STAJBgNVHRMEAjAAMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATALBgNVHQ8E +BAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADgYEATNnM +ol0s29lJ+WkP+HUFtKaXxQ+kXLADqfhsk2G1/kZAVRHsYUDlJ+GkHnWIHlg/ggIP +JS+z44iwMPOtzJQI7MvAFYVKpYAEdIFTjXf6GafLjUfoXYi0vwHoVJHtQu3Kpm9L +Ugm02h0ycIadN8RdWAAFUf6XpVKUJa0YYLuyaXY= +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,D380549EA9DF81C470A9DB93CBB21B66 + +tVa+a2cCBl7rggevzh7zp8i0YJgoe5yCQe76jZ3/LA5E/Th7KWc+aRm7H1NClhVc +5Ny4ChXyiyL8nmCWaaVl7s2AMckdQOEsTRb7FR3hq8tmfQIr2Vy/yaBeCaU7+cCK +R4KofgNM5W83IjIuKhXf0nE1vMAMpzftLCThtpDyAyZ1AHau5XllmRsqvSM0UR5p +N0OVPnTZJkggIb/alaGFGE+6frTkI0RQmeHc5CfUeO8PxBdWZUeWx+vrnAn3LuyF +j5G9gMnEKDWKonyd114JcrDjobm9pErCFGTwiGPulRVvMKXLYhzvfnYxxLZT4Jf+ +vOZ8SUufliWbXcoPRd3KXQeTDPgkb9VtJgqL2PuOF3/H4X0InjF/qDnf4gFGoELY +Ctbce9EvcQh0+zYI1PJIqhy1zqxNpBnI9QtCjjwPXixQYy8BSgd5IUaXWkZ8g38E +7saH/8nCvAI0EuELb0p/3+Vr6/4HvuBaL7X8yff5RUHIXPafuqnF5X2MkXFr9DUw +7tVRispVadPxQ+NP62LYaJsgycGlYHGvWAYrlWylL8mH3dGGsxGm3qnQCDPsWhkW ++DRFFTPLkgSIj+HEjATIk8IkLS+5I5/TXw8h3WuhghOXED+7BDSPCRk8zY/8Sfmz +C63vWy5FWOrrbYqwfnfn91IQdaxy03IDaUD1xMQK1rCkZJlY10eE/Zwz5Ne0hexa +whM2gjfp7l9Ktvw2jY7R+YXvKusY8FLytZoq+gkqr5HnjkWQVgHipHcBukf6Yq2U +WWr61Bgx5jHjLYGBu/s8RY7u1qZ+uPbsOXFTIqGyvmHRUqVxnt01+KtB7s3AD0HH +-----END RSA PRIVATE KEY----- diff --git a/testutil/pki/serverenckey.pem b/testutil/pki/serverenckey.pem new file mode 100644 index 0000000000000..fd6afb8ec5883 --- /dev/null +++ b/testutil/pki/serverenckey.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,D380549EA9DF81C470A9DB93CBB21B66 + +tVa+a2cCBl7rggevzh7zp8i0YJgoe5yCQe76jZ3/LA5E/Th7KWc+aRm7H1NClhVc +5Ny4ChXyiyL8nmCWaaVl7s2AMckdQOEsTRb7FR3hq8tmfQIr2Vy/yaBeCaU7+cCK +R4KofgNM5W83IjIuKhXf0nE1vMAMpzftLCThtpDyAyZ1AHau5XllmRsqvSM0UR5p +N0OVPnTZJkggIb/alaGFGE+6frTkI0RQmeHc5CfUeO8PxBdWZUeWx+vrnAn3LuyF +j5G9gMnEKDWKonyd114JcrDjobm9pErCFGTwiGPulRVvMKXLYhzvfnYxxLZT4Jf+ +vOZ8SUufliWbXcoPRd3KXQeTDPgkb9VtJgqL2PuOF3/H4X0InjF/qDnf4gFGoELY +Ctbce9EvcQh0+zYI1PJIqhy1zqxNpBnI9QtCjjwPXixQYy8BSgd5IUaXWkZ8g38E +7saH/8nCvAI0EuELb0p/3+Vr6/4HvuBaL7X8yff5RUHIXPafuqnF5X2MkXFr9DUw +7tVRispVadPxQ+NP62LYaJsgycGlYHGvWAYrlWylL8mH3dGGsxGm3qnQCDPsWhkW ++DRFFTPLkgSIj+HEjATIk8IkLS+5I5/TXw8h3WuhghOXED+7BDSPCRk8zY/8Sfmz +C63vWy5FWOrrbYqwfnfn91IQdaxy03IDaUD1xMQK1rCkZJlY10eE/Zwz5Ne0hexa +whM2gjfp7l9Ktvw2jY7R+YXvKusY8FLytZoq+gkqr5HnjkWQVgHipHcBukf6Yq2U +WWr61Bgx5jHjLYGBu/s8RY7u1qZ+uPbsOXFTIqGyvmHRUqVxnt01+KtB7s3AD0HH +-----END RSA PRIVATE KEY----- diff --git a/testutil/pki/tls-certs.sh b/testutil/pki/tls-certs.sh index 67cd0cfa6eaec..01e64f9e23697 100644 --- a/testutil/pki/tls-certs.sh +++ b/testutil/pki/tls-certs.sh @@ -71,7 +71,9 @@ openssl req -x509 -config ./openssl.conf -days 3650 -newkey rsa:2048 -out ./cert openssl genrsa -out ./private/serverkey.pem 2048 && openssl req -new -key ./private/serverkey.pem -out ./certs/servercsr.pem -outform PEM -subj "/CN=$(cat /proc/sys/kernel/hostname)/O=server/" && openssl ca -config ./openssl.conf -in ./certs/servercsr.pem -out ./certs/servercert.pem -notext -batch -extensions server_ca_extensions && -openssl ca -config ./openssl.conf -in ./certs/servercsr.pem -out ./certs/servercertexp.pem -startdate "$(date +%y%m%d%H%M00 --date='-5 minutes')Z" -enddate "$(date +%y%m%d%H%M00 --date='5 minutes')Z" -notext -batch -extensions server_ca_extensions && +openssl ca -config ./openssl.conf -in ./certs/servercsr.pem -out ./certs/servercertexp.pem -startdate $(date +%y%m%d%H%M00 --date='-5 minutes')'Z' -enddate $(date +%y%m%d%H%M00 --date='5 minutes')'Z' -notext -batch -extensions server_ca_extensions && +cp ./private/serverkey.pem ./private/serverkeyenc.pem && +ssh-keygen -p -f ./private/serverkeyenc.pem -m PEM -N 'changeme' && # Create client and client encrypted keypair openssl genrsa -out ./private/clientkey.pem 2048 && @@ -79,12 +81,14 @@ openssl req -new -key ./private/clientkey.pem -out ./certs/clientcsr.pem -outfor openssl ca -config ./openssl.conf -in ./certs/clientcsr.pem -out ./certs/clientcert.pem -notext -batch -extensions client_ca_extensions && cp ./private/clientkey.pem ./private/clientenckey.pem && ssh-keygen -p -f ./private/clientenckey.pem -m PEM -N 'changeme' && + # Generate a pkcs#8 encrypted private key using pkcs#5 v2.0 algorithm openssl pkcs8 -topk8 -v2 des3 -in ./private/clientkey.pem -out ./private/clientenckey.pkcs8.pem -passout pass:changeme && openssl pkcs8 -topk8 -in clientenckey.pem -passin pass:changeme -nocrypt -out clientkey.pkcs8.pem && +ssh-keygen -p -f ./private/clientenckey.pem -m PEM -N 'changeme' && # Combine crt and key to create pem formatted keyfile cat ./certs/clientcert.pem ./private/clientkey.pem > ./private/client.pem && -cat ./certs/clientcert.pem ./private/clientkeyenc.pem > ./private/clientenc.pem && +cat ./certs/clientcert.pem ./private/clientenckey.pem > ./private/clientenc.pem && cat ./certs/servercert.pem ./private/serverkey.pem > ./private/server.pem && cat ./certs/servercertexp.pem ./private/serverkey.pem > ./private/serverexp.pem diff --git a/testutil/tls.go b/testutil/tls.go index 30cfd114f4f3a..f7f8a6e4a639b 100644 --- a/testutil/tls.go +++ b/testutil/tls.go @@ -1,9 +1,6 @@ package testutil import ( - "fmt" - "io" - "os" "path" "path/filepath" @@ -45,7 +42,7 @@ func (p *pki) TLSServerConfig() *tls.ServerConfig { } func (p *pki) ReadCACert() string { - return readCertificate(p.CACertPath()) + return tls.ReadCertificate(p.CACertPath()) } func (p *pki) CACertPath() string { @@ -65,7 +62,7 @@ func (p *pki) TLSMaxVersion() string { } func (p *pki) ReadClientCert() string { - return readCertificate(p.ClientCertPath()) + return tls.ReadCertificate(p.ClientCertPath()) } func (p *pki) ClientCertPath() string { @@ -73,17 +70,25 @@ func (p *pki) ClientCertPath() string { } func (p *pki) ReadClientKey() string { - return readCertificate(p.ClientKeyPath()) + return tls.ReadKey(p.ClientKeyPath(), "") } func (p *pki) ClientKeyPath() string { return path.Join(p.keyPath, "clientkey.pem") } +func (p *pki) ReadClientCertAndKey() string { + return tls.ReadKey(p.ClientCertAndKeyPath(), "") +} + func (p *pki) ClientCertAndKeyPath() string { return path.Join(p.keyPath, "client.pem") } +func (p *pki) ReadClientEncKey() string { + return tls.ReadKey(p.ClientEncKeyPath(), "") +} + func (p *pki) ClientEncKeyPath() string { return path.Join(p.keyPath, "clientenckey.pem") } @@ -96,12 +101,16 @@ func (p *pki) ClientEncPKCS8KeyPath() string { return path.Join(p.keyPath, "clientenckey.pkcs8.pem") } +func (p *pki) ReadClientCertAndEncKey() string { + return tls.ReadKey(p.ClientCertAndEncKeyPath(), "") +} + func (p *pki) ClientCertAndEncKeyPath() string { return path.Join(p.keyPath, "clientenc.pem") } func (p *pki) ReadServerCert() string { - return readCertificate(p.ServerCertPath()) + return tls.ReadCertificate(p.ServerCertPath()) } func (p *pki) ServerCertPath() string { @@ -109,13 +118,17 @@ func (p *pki) ServerCertPath() string { } func (p *pki) ReadServerKey() string { - return readCertificate(p.ServerKeyPath()) + return tls.ReadKey(p.ServerKeyPath(), "") } func (p *pki) ServerKeyPath() string { return path.Join(p.keyPath, "serverkey.pem") } +func (p *pki) ReadServerCertAndKey() string { + return tls.ReadKey(p.ServerCertAndKeyPath(), "") +} + func (p *pki) ServerCertAndKeyPath() string { return path.Join(p.keyPath, "server.pem") } @@ -145,15 +158,3 @@ func (p *pki) AbsolutePaths() (*PKIPaths, error) { ClientCert: cert, }, nil } - -func readCertificate(filename string) string { - file, err := os.Open(filename) - if err != nil { - panic(fmt.Sprintf("opening %q: %v", filename, err)) - } - octets, err := io.ReadAll(file) - if err != nil { - panic(fmt.Sprintf("reading %q: %v", filename, err)) - } - return string(octets) -}