91 lines
3.4 KiB
Go
91 lines
3.4 KiB
Go
package tlsreload
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/pem"
|
|
"math/big"
|
|
"net/url"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestResolveSPIFFEIdentityUsesExactRoleSpecificURI(t *testing.T) {
|
|
certificatePath, keyPath := writeWorkloadCertificate(t, "gateway-a", "spiffe://proxy-pool.local/production/worker/gateway-a")
|
|
identity, err := ResolveSPIFFEIdentity(certificatePath, keyPath, "proxy-pool.local", "production", "worker")
|
|
if err != nil || identity != "gateway-a" {
|
|
t.Fatalf("ResolveSPIFFEIdentity() = (%q, %v), want (gateway-a, nil)", identity, err)
|
|
}
|
|
if _, err := ResolveSPIFFEIdentity(certificatePath, keyPath, "proxy-pool.local", "production", "checker"); err == nil {
|
|
t.Fatal("ResolveSPIFFEIdentity(checker) error = nil")
|
|
}
|
|
}
|
|
|
|
func TestResolveSPIFFEIdentityRejectsMultipleMatchingURIs(t *testing.T) {
|
|
certificatePath, keyPath := writeWorkloadCertificate(t, "gateway-a",
|
|
"spiffe://proxy-pool.local/production/worker/gateway-a",
|
|
"spiffe://proxy-pool.local/production/worker/gateway-b",
|
|
)
|
|
if _, err := ResolveSPIFFEIdentity(certificatePath, keyPath, "proxy-pool.local", "production", "worker"); err == nil {
|
|
t.Fatal("ResolveSPIFFEIdentity(multiple identities) error = nil")
|
|
}
|
|
}
|
|
|
|
func TestResolveSPIFFEIdentityRejectsMultipleURISANsAcrossRoles(t *testing.T) {
|
|
certificatePath, keyPath := writeWorkloadCertificate(t, "gateway-a",
|
|
"spiffe://proxy-pool.local/production/worker/gateway-a",
|
|
"spiffe://proxy-pool.local/production/checker/checker-a",
|
|
)
|
|
if _, err := ResolveSPIFFEIdentity(certificatePath, keyPath, "proxy-pool.local", "production", "worker"); err == nil {
|
|
t.Fatal("ResolveSPIFFEIdentity(multiple URI SANs) error = nil")
|
|
}
|
|
}
|
|
|
|
func writeWorkloadCertificate(t *testing.T, commonName string, identityURIs ...string) (string, string) {
|
|
t.Helper()
|
|
directory := t.TempDir()
|
|
certificatePath := filepath.Join(directory, "tls.crt")
|
|
keyPath := filepath.Join(directory, "tls.key")
|
|
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
if err != nil {
|
|
t.Fatalf("generate workload key: %v", err)
|
|
}
|
|
identities := make([]*url.URL, 0, len(identityURIs))
|
|
for _, raw := range identityURIs {
|
|
identity, parseErr := url.Parse(raw)
|
|
if parseErr != nil {
|
|
t.Fatalf("parse workload identity: %v", parseErr)
|
|
}
|
|
identities = append(identities, identity)
|
|
}
|
|
now := time.Now()
|
|
template := &x509.Certificate{
|
|
SerialNumber: big.NewInt(now.UnixNano()), Subject: pkix.Name{CommonName: commonName},
|
|
URIs: identities, NotBefore: now.Add(-time.Minute), NotAfter: now.Add(time.Hour),
|
|
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
|
}
|
|
der, err := x509.CreateCertificate(rand.Reader, template, template, &privateKey.PublicKey, privateKey)
|
|
if err != nil {
|
|
t.Fatalf("create workload certificate: %v", err)
|
|
}
|
|
certificate := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: der})
|
|
privateDER, err := x509.MarshalPKCS8PrivateKey(privateKey)
|
|
if err != nil {
|
|
t.Fatalf("marshal workload key: %v", err)
|
|
}
|
|
key := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateDER})
|
|
if err := os.WriteFile(certificatePath, certificate, 0o600); err != nil {
|
|
t.Fatalf("write workload certificate: %v", err)
|
|
}
|
|
if err := os.WriteFile(keyPath, key, 0o600); err != nil {
|
|
t.Fatalf("write workload key: %v", err)
|
|
}
|
|
return certificatePath, keyPath
|
|
}
|