connect: strip port from DNS SANs for ingress gateway leaf cert (#15320)

* connect: strip port from DNS SANs for ingress gateway leaf cert

* connect: format DNS SANs in CreateCSR

* connect: Test wildcard case when formatting SANs
This commit is contained in:
Kyle Havlovitz 2022-11-14 10:27:03 -08:00 committed by GitHub
parent 95d5f4de69
commit 7be442ee63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 1 deletions

3
.changelog/15320.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
connect: strip port from DNS SANs for ingress gateway leaf certificate to avoid an invalid hostname error when using the Vault provider.
```

View File

@ -12,6 +12,7 @@ import (
"fmt" "fmt"
"net" "net"
"net/url" "net/url"
"strings"
) )
// SigAlgoForKey returns the preferred x509.SignatureAlgorithm for a given key // SigAlgoForKey returns the preferred x509.SignatureAlgorithm for a given key
@ -47,11 +48,28 @@ func SigAlgoForKeyType(keyType string) x509.SignatureAlgorithm {
// along with the PEM-encoded private key for this certificate. // along with the PEM-encoded private key for this certificate.
func CreateCSR(uri CertURI, privateKey crypto.Signer, func CreateCSR(uri CertURI, privateKey crypto.Signer,
dnsNames []string, ipAddresses []net.IP, extensions ...pkix.Extension) (string, error) { dnsNames []string, ipAddresses []net.IP, extensions ...pkix.Extension) (string, error) {
// Drop everything after the ':' from the name when constructing the DNS SANs.
uniqueNames := make(map[string]struct{})
formattedDNSNames := make([]string, 0)
for _, host := range dnsNames {
hostSegments := strings.Split(host, ":")
if len(hostSegments) == 0 || hostSegments[0] == "" {
continue
}
formattedHost := hostSegments[0]
if _, ok := uniqueNames[formattedHost]; !ok {
formattedDNSNames = append(formattedDNSNames, formattedHost)
uniqueNames[formattedHost] = struct{}{}
}
}
template := &x509.CertificateRequest{ template := &x509.CertificateRequest{
URIs: []*url.URL{uri.URI()}, URIs: []*url.URL{uri.URI()},
SignatureAlgorithm: SigAlgoForKey(privateKey), SignatureAlgorithm: SigAlgoForKey(privateKey),
ExtraExtensions: extensions, ExtraExtensions: extensions,
DNSNames: dnsNames, DNSNames: formattedDNSNames,
IPAddresses: ipAddresses, IPAddresses: ipAddresses,
} }
HackSANExtensionForCSR(template) HackSANExtensionForCSR(template)

36
agent/connect/csr_test.go Normal file
View File

@ -0,0 +1,36 @@
package connect
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestCreateCSR_FormatDNSSANs(t *testing.T) {
pk, _, err := GeneratePrivateKey()
require.NoError(t, err)
spiffeID := &SpiffeIDService{
Host: "7528f42f-92e5-4db4-b84c-3405c3ca91e6",
Service: "srv1",
Datacenter: "dc1",
}
csr, err := CreateCSR(spiffeID, pk, []string{
"foo.example.com",
"foo.example.com:8080",
"bar.example.com",
"*.example.com",
":8080",
"",
}, nil)
require.NoError(t, err)
req, err := ParseCSR(csr)
require.NoError(t, err)
require.Len(t, req.URIs, 1)
require.Equal(t, spiffeID.URI(), req.URIs[0])
require.Equal(t, []string{
"foo.example.com",
"bar.example.com",
"*.example.com",
}, req.DNSNames)
}