proxy-pool/internal/controlplane/tlsreload/identity_test.go

81 lines
2.9 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 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
}