Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions internal/certificate/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func GenerateLeaf(
}

// Sign certificate using CA
_, cert, err := pki.SignCertificate(template, caCert, pk.Public(), caPk)
cert, err := pki.SignCertificate(template, caCert, pk.Public(), caPk)
return cert, pk, err
}

Expand Down Expand Up @@ -94,6 +94,6 @@ func GenerateCA(
}

// self sign the root CA
_, cert, err := pki.SignCertificate(template, template, pk.Public(), pk)
cert, err := pki.SignCertificate(template, template, pk.Public(), pk)
return cert, pk, err
}
25 changes: 0 additions & 25 deletions internal/errors/errors.go

This file was deleted.

23 changes: 8 additions & 15 deletions internal/pki/csr.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ import (
// *x509.Certificate crt and an issuer.
// publicKey is the public key of the signee, and signerKey is the private
// key of the signer.
// It returns a PEM encoded copy of the Certificate as well as a *x509.Certificate
// which can be used for reading the encoded values.
func SignCertificate(template *x509.Certificate, issuerCert *x509.Certificate, publicKey crypto.PublicKey, signerKey any) ([]byte, *x509.Certificate, error) {
// It returns a parsed *x509.Certificate on success.
func SignCertificate(template *x509.Certificate, issuerCert *x509.Certificate, publicKey crypto.PublicKey, signerKey any) (*x509.Certificate, error) {
typedSigner, ok := signerKey.(crypto.Signer)
if !ok {
return nil, nil, fmt.Errorf("didn't get an expected Signer in call to SignCertificate")
return nil, fmt.Errorf("didn't get an expected Signer in call to SignCertificate")
}

var pubKeyAlgo x509.PublicKeyAlgorithm
Expand All @@ -64,32 +63,26 @@ func SignCertificate(template *x509.Certificate, issuerCert *x509.Certificate, p
sigAlgoArg = nil // ignored by signatureAlgorithmFromPublicKey

default:
return nil, nil, fmt.Errorf("unknown public key type on signing certificate: %T", issuerCert.PublicKey)
return nil, fmt.Errorf("unknown public key type on signing certificate: %T", issuerCert.PublicKey)
}

var err error
template.SignatureAlgorithm, err = signatureAlgorithmFromPublicKey(pubKeyAlgo, sigAlgoArg)
if err != nil {
return nil, nil, err
return nil, err
}

derBytes, err := x509.CreateCertificate(rand.Reader, template, issuerCert, publicKey, signerKey)
if err != nil {
return nil, nil, fmt.Errorf("error creating x509 certificate: %s", err.Error())
return nil, fmt.Errorf("error creating x509 certificate: %w", err)
}

cert, err := x509.ParseCertificate(derBytes)
if err != nil {
return nil, nil, fmt.Errorf("error decoding DER certificate bytes: %s", err.Error())
}

pemBytes := bytes.NewBuffer([]byte{})
err = pem.Encode(pemBytes, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
if err != nil {
return nil, nil, fmt.Errorf("error encoding certificate PEM: %s", err.Error())
return nil, fmt.Errorf("error decoding DER certificate bytes: %w", err)
}

return pemBytes.Bytes(), cert, err
return cert, nil
}

// EncodeX509 will encode a single *x509.Certificate into PEM format.
Expand Down
26 changes: 11 additions & 15 deletions internal/pki/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,26 +65,22 @@ func encodePKCS8PrivateKey(pk any) ([]byte, error) {
func encodeECPrivateKey(pk *ecdsa.PrivateKey) ([]byte, error) {
keyBytes, err := x509.MarshalECPrivateKey(pk)
if err != nil {
return nil, fmt.Errorf("error encoding private key: %s", err.Error())
return nil, fmt.Errorf("error encoding private key: %w", err)
}
block := &pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes}

return pem.EncodeToMemory(block), nil
}

// PublicKeysEqual compares two given public keys for equality.
// The definition of "equality" depends on the type of the public keys.
// Returns true if the keys are the same, false if they differ or an error if
// the key type of `a` cannot be determined.
func PublicKeysEqual(a, b crypto.PublicKey) (bool, error) {
switch pub := a.(type) {
case *rsa.PublicKey:
return pub.Equal(b), nil
case *ecdsa.PublicKey:
return pub.Equal(b), nil
case ed25519.PublicKey:
return pub.Equal(b), nil
default:
return false, fmt.Errorf("unrecognised public key type: %T", a)
type publicKeyEqual interface {
Equal(crypto.PublicKey) bool
}

// PublicKeysEqual compares two public keys for equivalence across supported types.
func PublicKeysEqual(a, b any) (bool, error) {
if ak, ok := a.(publicKeyEqual); ok {
return ak.Equal(b), nil
}

return false, fmt.Errorf("unsupported public key type %T", a)
}
21 changes: 10 additions & 11 deletions internal/pki/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ import (
"crypto"
"crypto/x509"
"encoding/pem"

"github.com/cert-manager/webhook-cert-lib/internal/errors"
"fmt"
)

// DecodeX509CertificateBytes will decode a PEM encoded x509 Certificate.
Expand Down Expand Up @@ -50,13 +49,13 @@ func DecodeX509CertificateSetBytes(certBytes []byte) ([]*x509.Certificate, error
// parse the tls certificate
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, errors.NewInvalidData("error parsing TLS certificate: %s", err.Error())
return nil, fmt.Errorf("error parsing TLS certificate: %w", err)
}
certs = append(certs, cert)
}

if len(certs) == 0 {
return nil, errors.NewInvalidData("error decoding certificate PEM block")
return nil, fmt.Errorf("error decoding certificate PEM block")
}

return certs, nil
Expand All @@ -68,40 +67,40 @@ func DecodePrivateKeyBytes(keyBytes []byte) (crypto.Signer, error) {
// decode the private key pem
block, _ := pem.Decode(keyBytes)
if block == nil {
return nil, errors.NewInvalidData("error decoding private key PEM block")
return nil, fmt.Errorf("error decoding private key PEM block")
}

switch block.Type {
case "PRIVATE KEY":
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, errors.NewInvalidData("error parsing pkcs#8 private key: %s", err.Error())
return nil, fmt.Errorf("error parsing pkcs#8 private key: %w", err)
}

signer, ok := key.(crypto.Signer)
if !ok {
return nil, errors.NewInvalidData("error parsing pkcs#8 private key: invalid key type")
return nil, fmt.Errorf("error parsing pkcs#8 private key: invalid key type")
}
return signer, nil
case "EC PRIVATE KEY":
key, err := x509.ParseECPrivateKey(block.Bytes)
if err != nil {
return nil, errors.NewInvalidData("error parsing ecdsa private key: %s", err.Error())
return nil, fmt.Errorf("error parsing ecdsa private key: %w", err)
}

return key, nil
case "RSA PRIVATE KEY":
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, errors.NewInvalidData("error parsing rsa private key: %s", err.Error())
return nil, fmt.Errorf("error parsing rsa private key: %w", err)
}

err = key.Validate()
if err != nil {
return nil, errors.NewInvalidData("rsa private key failed validation: %s", err.Error())
return nil, fmt.Errorf("rsa private key failed validation: %w", err)
}
return key, nil
default:
return nil, errors.NewInvalidData("unknown private key type: %s", block.Type)
return nil, fmt.Errorf("unknown private key type: %s", block.Type)
}
}
1 change: 1 addition & 0 deletions internal/pki/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"crypto/x509"
)

// ToTLSCertificate converts a x509.Certificate and a crypto.Signer to a tls.Certificate.
func ToTLSCertificate(cert *x509.Certificate, pk crypto.Signer) (tls.Certificate, error) {
pkData, err := EncodePrivateKey(pk)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/authority/ca_secret_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func Test__caRequiresRegeneration(t *testing.T) {
if mod != nil {
mod(cert)
}
_, cert, err = pki.SignCertificate(cert, cert, pk.Public(), pk)
cert, err = pki.SignCertificate(cert, cert, pk.Public(), pk)
assert.NoError(t, err)
certBytes, err := pki.EncodeX509(cert)
assert.NoError(t, err)
Expand Down