Add tests for pemDecodeCertificateChain and pemDecodeCertificate

This commit is contained in:
Herman Slatman 2025-11-05 01:49:11 +01:00
parent 80eb3e81e5
commit 1869b038f4
No known key found for this signature in database
GPG key ID: A23461006C2BEE0F
3 changed files with 147 additions and 3 deletions

View file

@ -286,7 +286,7 @@ func (ca CA) loadOrGenRoot() (rootCert *x509.Certificate, rootKey crypto.Signer,
} }
if rootCert == nil { if rootCert == nil {
rootCert, err = pemDecodeSingleCert(rootCertPEM) rootCert, err = pemDecodeCertificate(rootCertPEM)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("parsing root certificate PEM: %v", err) return nil, nil, fmt.Errorf("parsing root certificate PEM: %v", err)
} }

View file

@ -30,7 +30,7 @@ import (
"go.step.sm/crypto/pemutil" "go.step.sm/crypto/pemutil"
) )
func pemDecodeSingleCert(pemDER []byte) (*x509.Certificate, error) { func pemDecodeCertificate(pemDER []byte) (*x509.Certificate, error) {
pemBlock, remaining := pem.Decode(pemDER) pemBlock, remaining := pem.Decode(pemDER)
if pemBlock == nil { if pemBlock == nil {
return nil, fmt.Errorf("no PEM block found") return nil, fmt.Errorf("no PEM block found")

View file

@ -144,7 +144,7 @@ func TestKeyPair_Load(t *testing.T) {
t.Fatalf("Failed loading KeyPair: %v", err) t.Fatalf("Failed loading KeyPair: %v", err)
} }
if len(chain) != 2 { if len(chain) != 2 {
t.Errorf("Expected 1 certificate in chain; got %d", len(chain)) t.Errorf("Expected 2 certificates in chain; got %d", len(chain))
} }
if signer == nil { if signer == nil {
t.Error("Expected signer to be returned") t.Error("Expected signer to be returned")
@ -168,3 +168,147 @@ func TestKeyPair_Load(t *testing.T) {
} }
}) })
} }
func Test_pemDecodeCertificate(t *testing.T) {
signer, err := keyutil.GenerateDefaultSigner()
if err != nil {
t.Fatalf("Failed creating signer: %v", err)
}
tmpl := &x509.Certificate{
Subject: pkix.Name{CommonName: "test-cert"},
IsCA: true,
MaxPathLen: 3,
}
derBytes, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, signer.Public(), signer)
if err != nil {
t.Fatalf("Creating root certificate failed: %v", err)
}
cert, err := x509.ParseCertificate(derBytes)
if err != nil {
t.Fatalf("Parsing root certificate failed: %v", err)
}
pemBlock, err := pemutil.Serialize(cert)
if err != nil {
t.Fatalf("Failed serializing certificate: %v", err)
}
pemData := pem.EncodeToMemory(pemBlock)
t.Run("ok", func(t *testing.T) {
cert, err := pemDecodeCertificate(pemData)
if err != nil {
t.Fatalf("Failed decoding PEM data: %v", err)
}
if cert == nil {
t.Errorf("Expected a certificate in PEM data")
}
})
t.Run("fail/no-pem-data", func(t *testing.T) {
cert, err := pemDecodeCertificate(nil)
if err == nil {
t.Fatalf("Expected pemDecodeCertificate to return an error")
}
if cert != nil {
t.Errorf("Expected pemDecodeCertificate to return nil")
}
})
t.Run("fail/multiple", func(t *testing.T) {
multiplePEMData := append(pemData, pemData...)
cert, err := pemDecodeCertificate(multiplePEMData)
if err == nil {
t.Fatalf("Expected pemDecodeCertificate to return an error")
}
if cert != nil {
t.Errorf("Expected pemDecodeCertificate to return nil")
}
})
t.Run("fail/no-pem-certificate", func(t *testing.T) {
pkData := pem.EncodeToMemory(&pem.Block{
Type: "PRIVATE KEY",
Bytes: []byte("some-bogus-private-key"),
})
cert, err := pemDecodeCertificate(pkData)
if err == nil {
t.Fatalf("Expected pemDecodeCertificate to return an error")
}
if cert != nil {
t.Errorf("Expected pemDecodeCertificate to return nil")
}
})
}
func Test_pemDecodeCertificateChain(t *testing.T) {
signer, err := keyutil.GenerateDefaultSigner()
if err != nil {
t.Fatalf("Failed creating signer: %v", err)
}
tmpl := &x509.Certificate{
Subject: pkix.Name{CommonName: "test-cert"},
IsCA: true,
MaxPathLen: 3,
}
derBytes, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, signer.Public(), signer)
if err != nil {
t.Fatalf("Creating root certificate failed: %v", err)
}
cert, err := x509.ParseCertificate(derBytes)
if err != nil {
t.Fatalf("Parsing root certificate failed: %v", err)
}
pemBlock, err := pemutil.Serialize(cert)
if err != nil {
t.Fatalf("Failed serializing certificate: %v", err)
}
pemData := pem.EncodeToMemory(pemBlock)
t.Run("ok/single", func(t *testing.T) {
certs, err := pemDecodeCertificateChain(pemData)
if err != nil {
t.Fatalf("Failed decoding PEM data: %v", err)
}
if len(certs) != 1 {
t.Errorf("Expected 1 certificate in PEM data; got %d", len(certs))
}
})
t.Run("ok/multiple", func(t *testing.T) {
multiplePEMData := append(pemData, pemData...)
certs, err := pemDecodeCertificateChain(multiplePEMData)
if err != nil {
t.Fatalf("Failed decoding PEM data: %v", err)
}
if len(certs) != 2 {
t.Errorf("Expected 2 certificates in PEM data; got %d", len(certs))
}
})
t.Run("fail/no-pem-certificate", func(t *testing.T) {
pkData := pem.EncodeToMemory(&pem.Block{
Type: "PRIVATE KEY",
Bytes: []byte("some-bogus-private-key"),
})
certs, err := pemDecodeCertificateChain(pkData)
if err == nil {
t.Fatalf("Expected pemDecodeCertificateChain to return an error")
}
if len(certs) != 0 {
t.Errorf("Expected 0 certificates in PEM data; got %d", len(certs))
}
})
t.Run("fail/no-der-certificate", func(t *testing.T) {
certs, err := pemDecodeCertificateChain([]byte("invalid-der-data"))
if err == nil {
t.Fatalf("Expected pemDecodeCertificateChain to return an error")
}
if len(certs) != 0 {
t.Errorf("Expected 0 certificates in PEM data; got %d", len(certs))
}
})
}