Skip to content

Commit

Permalink
Fix self-signed cert validity on macOS systems (#33157)
Browse files Browse the repository at this point in the history
As per https://support.apple.com/en-in/HT210176:

> TLS server certificates must contain an ExtendedKeyUsage (EKU)
  extension containing the id-kp-serverAuth OID.

We were not specifying this EKU.

Validated by checking with the old self-signed certs:

    $ security verify-cert -c webproxy_cert.pem -p ssl -r webproxy_cert.pem
    Cert Verify Result: Invalid Extended Key Usage for policy

And then repeating the process after this change:

    $ security verify-cert -c webproxy_cert.pem -p ssl -r webproxy_cert.pem
    ...certificate verification successful.

Closes #32531
  • Loading branch information
zmb3 committed Oct 9, 2023
1 parent afbe4c5 commit 4217837
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 6 deletions.
4 changes: 2 additions & 2 deletions lib/teleterm/grpccredentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func createClientTLSConfig(clientKeyPair tls.Certificate, serverCertPath string)
}, nil
}

func generateAndSaveCert(targetPath string) (tls.Certificate, error) {
func generateAndSaveCert(targetPath string, eku ...x509.ExtKeyUsage) (tls.Certificate, error) {
// The cert is first saved under a temp path and then renamed to targetPath. This prevents other
// processes from reading a half-written file.
tempFile, err := os.CreateTemp(filepath.Dir(targetPath), filepath.Base(targetPath))
Expand All @@ -108,7 +108,7 @@ func generateAndSaveCert(targetPath string) (tls.Certificate, error) {
}
defer os.Remove(tempFile.Name())

cert, err := cert.GenerateSelfSignedCert([]string{"localhost"}, nil)
cert, err := cert.GenerateSelfSignedCert([]string{"localhost"}, nil, eku...)
if err != nil {
return tls.Certificate{}, trace.Wrap(err, "failed to generate the certificate")
}
Expand Down
3 changes: 2 additions & 1 deletion lib/teleterm/teleterm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package teleterm
import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"net"
Expand Down Expand Up @@ -207,7 +208,7 @@ func createValidClientTLSConfig(t *testing.T, certsDir string) *tls.Config {
// reach the tsh gRPC server, so we need to use the renderer cert as the client cert.
clientCertPath := filepath.Join(certsDir, rendererCertFileName)
serverCertPath := filepath.Join(certsDir, tshdCertFileName)
clientCert, err := generateAndSaveCert(clientCertPath)
clientCert, err := generateAndSaveCert(clientCertPath, x509.ExtKeyUsageClientAuth)
require.NoError(t, err)

tlsConfig, err := createClientTLSConfig(clientCert, serverCertPath)
Expand Down
15 changes: 12 additions & 3 deletions lib/utils/cert/selfsigned.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import (
// verifier and not in Go.
const macMaxTLSCertValidityPeriod = 825 * 24 * time.Hour

// Credentials keeps the typical 3 components of a proper HTTPS configuration
// Credentials keeps the typical 3 components of a proper TLS configuration
type Credentials struct {
// PublicKey in PEM format
PublicKey []byte
Expand All @@ -49,8 +49,16 @@ type Credentials struct {
}

// GenerateSelfSignedCert generates a self-signed certificate that
// is valid for given domain names and ips, returns PEM-encoded bytes with key and cert
func GenerateSelfSignedCert(hostNames []string, ipAddresses []string) (*Credentials, error) {
// is valid for given domain names and IPs. If extended key usage
// is not specified, the cert will be generated for server auth.
func GenerateSelfSignedCert(hostNames []string, ipAddresses []string, eku ...x509.ExtKeyUsage) (*Credentials, error) {
if len(eku) == 0 {
// if not specified, assume this cert is for server auth,
// which is required for validation on macOS:
// https://support.apple.com/en-in/HT210176
eku = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
}

priv, err := native.GenerateRSAPrivateKey()
if err != nil {
return nil, trace.Wrap(err)
Expand All @@ -77,6 +85,7 @@ func GenerateSelfSignedCert(hostNames []string, ipAddresses []string) (*Credenti
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
ExtKeyUsage: eku,
BasicConstraintsValid: true,
IsCA: true,
}
Expand Down

0 comments on commit 4217837

Please sign in to comment.