2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2021-06-25 18:00:00 +00:00
|
|
|
package connect
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
"crypto/rsa"
|
|
|
|
"crypto/x509"
|
|
|
|
"encoding/pem"
|
|
|
|
"math/big"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
var testPrivateKey_x509 *rsa.PrivateKey
|
|
|
|
|
|
|
|
func TestX509_EmptySubject(t *testing.T) {
|
|
|
|
// NOTE: this test is lifted straight out of the stdlib with no changes. to
|
|
|
|
// show that the cert-only workflow is fine.
|
|
|
|
|
|
|
|
template := x509.Certificate{
|
|
|
|
SerialNumber: big.NewInt(1),
|
|
|
|
DNSNames: []string{"example.com"},
|
|
|
|
}
|
|
|
|
|
|
|
|
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &testPrivateKey_x509.PublicKey, testPrivateKey_x509)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to create certificate: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
cert, err := x509.ParseCertificate(derBytes)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to parse certificate: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, ext := range cert.Extensions {
|
|
|
|
if ext.Id.Equal(x509_oidExtensionSubjectAltName) {
|
|
|
|
if !ext.Critical {
|
|
|
|
t.Fatal("SAN extension is not critical")
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Fatal("SAN extension is missing")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestX509_EmptySubjectInCSR(t *testing.T) {
|
|
|
|
// NOTE: the CSR-only workflow is flawed so we hack around it
|
|
|
|
|
|
|
|
for _, tc := range []struct {
|
|
|
|
name string
|
|
|
|
hack bool
|
|
|
|
expectCritical bool
|
|
|
|
}{
|
|
|
|
{name: "unmodified stdlib",
|
|
|
|
hack: false,
|
|
|
|
expectCritical: false,
|
|
|
|
},
|
|
|
|
{name: "hacked stdlib",
|
|
|
|
hack: true,
|
|
|
|
expectCritical: true,
|
|
|
|
},
|
|
|
|
} {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
template := x509.CertificateRequest{
|
|
|
|
DNSNames: []string{"example.com"},
|
|
|
|
}
|
|
|
|
if tc.hack {
|
|
|
|
HackSANExtensionForCSR(&template)
|
|
|
|
}
|
|
|
|
|
|
|
|
derBytes, err := x509.CreateCertificateRequest(rand.Reader, &template, testPrivateKey_x509)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to create certificate request: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
csr, err := x509.ParseCertificateRequest(derBytes)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to parse certificate request: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, ext := range csr.Extensions {
|
|
|
|
if ext.Id.Equal(x509_oidExtensionSubjectAltName) {
|
|
|
|
if tc.expectCritical {
|
|
|
|
if !ext.Critical {
|
|
|
|
t.Fatal("SAN extension is not critical")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ext.Critical {
|
|
|
|
t.Fatal("SAN extension is critical now; maybe we don't need the hack anymore with this version of Go?")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Fatal("SAN extension is missing")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
block, _ := pem.Decode([]byte(pemPrivateKey_x509))
|
|
|
|
|
|
|
|
var err error
|
|
|
|
testPrivateKey_x509, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var pemPrivateKey_x509 = `
|
|
|
|
-----BEGIN RSA PRIVATE KEY-----
|
|
|
|
MIICXAIBAAKBgQCxoeCUW5KJxNPxMp+KmCxKLc1Zv9Ny+4CFqcUXVUYH69L3mQ7v
|
|
|
|
IWrJ9GBfcaA7BPQqUlWxWM+OCEQZH1EZNIuqRMNQVuIGCbz5UQ8w6tS0gcgdeGX7
|
|
|
|
J7jgCQ4RK3F/PuCM38QBLaHx988qG8NMc6VKErBjctCXFHQt14lerd5KpQIDAQAB
|
|
|
|
AoGAYrf6Hbk+mT5AI33k2Jt1kcweodBP7UkExkPxeuQzRVe0KVJw0EkcFhywKpr1
|
|
|
|
V5eLMrILWcJnpyHE5slWwtFHBG6a5fLaNtsBBtcAIfqTQ0Vfj5c6SzVaJv0Z5rOd
|
|
|
|
7gQF6isy3t3w9IF3We9wXQKzT6q5ypPGdm6fciKQ8RnzREkCQQDZwppKATqQ41/R
|
|
|
|
vhSj90fFifrGE6aVKC1hgSpxGQa4oIdsYYHwMzyhBmWW9Xv/R+fPyr8ZwPxp2c12
|
|
|
|
33QwOLPLAkEA0NNUb+z4ebVVHyvSwF5jhfJxigim+s49KuzJ1+A2RaSApGyBZiwS
|
|
|
|
rWvWkB471POAKUYt5ykIWVZ83zcceQiNTwJBAMJUFQZX5GDqWFc/zwGoKkeR49Yi
|
|
|
|
MTXIvf7Wmv6E++eFcnT461FlGAUHRV+bQQXGsItR/opIG7mGogIkVXa3E1MCQARX
|
|
|
|
AAA7eoZ9AEHflUeuLn9QJI/r0hyQQLEtrpwv6rDT1GCWaLII5HJ6NUFVf4TTcqxo
|
|
|
|
6vdM4QGKTJoO+SaCyP0CQFdpcxSAuzpFcKv0IlJ8XzS/cy+mweCMwyJ1PFEc4FX6
|
|
|
|
wg/HcAJWY60xZTJDFN+Qfx8ZQvBEin6c2/h+zZi5IVY=
|
|
|
|
-----END RSA PRIVATE KEY-----
|
|
|
|
`
|