envoyconfig: add virtual host domains for certificates in addition to routes (#3593)

* envoyconfig: add virtual host domains for certificates in addition to routes

* Update pkg/cryptutil/certificates.go

Co-authored-by: bobby <1544881+desimone@users.noreply.github.com>

* Update pkg/cryptutil/tls.go

Co-authored-by: bobby <1544881+desimone@users.noreply.github.com>

* comments

Co-authored-by: bobby <1544881+desimone@users.noreply.github.com>
This commit is contained in:
Caleb Doxsey 2022-08-31 10:35:45 -06:00 committed by GitHub
parent 23c42da8ec
commit 33794ff316
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 99 additions and 14 deletions

View file

@ -219,6 +219,21 @@ func GenerateSelfSignedCertificate(domain string, configure ...func(*x509.Certif
return &cert, nil
}
// EncodeCertificate encodes a TLS certificate into PEM compatible byte slices.
// Returns `nil`, `nil` if there is an error marshaling the PKCS8 private key.
func EncodeCertificate(cert *tls.Certificate) (pemCertificateBytes, pemKeyBytes []byte, err error) {
if cert == nil || len(cert.Certificate) == 0 {
return nil, nil, nil
}
publicKeyBytes := cert.Certificate[0]
privateKeyBytes, err := x509.MarshalPKCS8PrivateKey(cert.PrivateKey)
if err != nil {
return nil, nil, err
}
return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: publicKeyBytes}),
pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateKeyBytes}), nil
}
// ParsePEMCertificate parses a PEM encoded certificate block.
func ParsePEMCertificate(raw []byte) (*x509.Certificate, error) {
data := raw

View file

@ -165,3 +165,18 @@ func TestPrivateKeyMarshaling(t *testing.T) {
t.Fatal("private key encoding did not match")
}
}
func TestEncodeCertificate(t *testing.T) {
t.Run("nil", func(t *testing.T) {
cert, key, err := EncodeCertificate(nil)
assert.NoError(t, err)
assert.Nil(t, cert)
assert.Nil(t, key)
})
t.Run("empty certificate", func(t *testing.T) {
cert, key, err := EncodeCertificate(&tls.Certificate{})
assert.NoError(t, err)
assert.Nil(t, cert)
assert.Nil(t, key)
})
}

View file

@ -63,6 +63,30 @@ func GetCertificateForDomain(certificates []tls.Certificate, domain string) (*tl
return GenerateSelfSignedCertificate(domain)
}
// GetCertificateDomains gets all the certificate's matching domain names.
// Will return an empty slice if certificate is nil, empty, or x509 parsing fails.
func GetCertificateDomains(cert *tls.Certificate) []string {
if cert == nil || len(cert.Certificate) == 0 {
return nil
}
xcert, err := x509.ParseCertificate(cert.Certificate[0])
if err != nil {
return nil
}
var domains []string
if xcert.Subject.CommonName != "" {
domains = append(domains, xcert.Subject.CommonName)
}
for _, dnsName := range xcert.DNSNames {
if dnsName != "" {
domains = append(domains, dnsName)
}
}
return domains
}
func matchesDomain(cert *tls.Certificate, domain string) bool {
if cert == nil || len(cert.Certificate) == 0 {
return false

View file

@ -5,6 +5,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetCertificateForDomain(t *testing.T) {
@ -62,3 +63,9 @@ func TestGetCertificateForDomain(t *testing.T) {
assert.NotNil(t, found)
})
}
func TestGetCertificateDomains(t *testing.T) {
cert, err := GenerateSelfSignedCertificate("www.example.com")
require.NoError(t, err)
assert.Equal(t, []string{"www.example.com"}, GetCertificateDomains(cert))
}