introduce gen.CSRForCertificate and gen.CSRWithSignerForCertificate and use it to deduplicate test code

Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com>
This commit is contained in:
Tim Ramlot 2024-06-14 15:28:21 +02:00
parent 255d954106
commit e0cdfd37bf
No known key found for this signature in database
GPG Key ID: 47428728E0C2878D
7 changed files with 95 additions and 190 deletions

View File

@ -17,11 +17,9 @@ limitations under the License.
package validation package validation
import ( import (
"bytes"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
"encoding/asn1" "encoding/asn1"
"encoding/pem"
"reflect" "reflect"
"testing" "testing"
@ -32,7 +30,6 @@ import (
cminternal "github.com/cert-manager/cert-manager/internal/apis/certmanager" cminternal "github.com/cert-manager/cert-manager/internal/apis/certmanager"
cminternalmeta "github.com/cert-manager/cert-manager/internal/apis/meta" cminternalmeta "github.com/cert-manager/cert-manager/internal/apis/meta"
cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
"github.com/cert-manager/cert-manager/pkg/util/pki"
utilpki "github.com/cert-manager/cert-manager/pkg/util/pki" utilpki "github.com/cert-manager/cert-manager/pkg/util/pki"
"github.com/cert-manager/cert-manager/test/unit/gen" "github.com/cert-manager/cert-manager/test/unit/gen"
) )
@ -572,10 +569,12 @@ func TestValidateCertificateRequest(t *testing.T) {
cr: &cminternal.CertificateRequest{ cr: &cminternal.CertificateRequest{
Spec: cminternal.CertificateRequestSpec{ Spec: cminternal.CertificateRequestSpec{
// mustGenerateCSR will set the default usages for us // mustGenerateCSR will set the default usages for us
Request: mustGenerateCSR(t, gen.Certificate("test", gen.SetCertificateDNSNames("example.com")), func(cr *x509.CertificateRequest) { Request: mustGenerateCSR(t, gen.Certificate("test", gen.SetCertificateDNSNames("example.com")), func(cr *x509.CertificateRequest) error {
// manually remove extensions that encode default usages // manually remove extensions that encode default usages
cr.Extensions = nil cr.Extensions = nil
cr.ExtraExtensions = nil cr.ExtraExtensions = nil
return nil
}), }),
IssuerRef: validIssuerRef, IssuerRef: validIssuerRef,
Usages: []cminternal.KeyUsage{cminternal.UsageKeyEncipherment, cminternal.UsageDigitalSignature}, Usages: []cminternal.KeyUsage{cminternal.UsageKeyEncipherment, cminternal.UsageDigitalSignature},
@ -588,12 +587,12 @@ func TestValidateCertificateRequest(t *testing.T) {
cr: &cminternal.CertificateRequest{ cr: &cminternal.CertificateRequest{
Spec: cminternal.CertificateRequestSpec{ Spec: cminternal.CertificateRequestSpec{
// mustGenerateCSR will set the default usages for us // mustGenerateCSR will set the default usages for us
Request: mustGenerateCSR(t, gen.Certificate("test", gen.SetCertificateDNSNames("example.com")), func(cr *x509.CertificateRequest) { Request: mustGenerateCSR(t, gen.Certificate("test", gen.SetCertificateDNSNames("example.com")), func(cr *x509.CertificateRequest) error {
// manually remove extensions that encode default usages // manually remove extensions that encode default usages
cr.Extensions = nil cr.Extensions = nil
cr.ExtraExtensions = []pkix.Extension{ cr.ExtraExtensions = []pkix.Extension{
{ {
Id: pki.OIDExtensionKeyUsage, Id: utilpki.OIDExtensionKeyUsage,
Critical: false, Critical: false,
Value: func(t *testing.T) []byte { Value: func(t *testing.T) []byte {
asn1KeyUsage, err := asn1.Marshal(asn1.BitString{Bytes: []byte{}, BitLength: 0}) asn1KeyUsage, err := asn1.Marshal(asn1.BitString{Bytes: []byte{}, BitLength: 0})
@ -605,6 +604,8 @@ func TestValidateCertificateRequest(t *testing.T) {
}(t), }(t),
}, },
} }
return nil
}), }),
IssuerRef: validIssuerRef, IssuerRef: validIssuerRef,
Usages: []cminternal.KeyUsage{cminternal.UsageKeyEncipherment, cminternal.UsageDigitalSignature}, Usages: []cminternal.KeyUsage{cminternal.UsageKeyEncipherment, cminternal.UsageDigitalSignature},
@ -877,30 +878,10 @@ func TestValidateCertificateRequest(t *testing.T) {
} }
} }
func mustGenerateCSR(t *testing.T, crt *cmapi.Certificate, modifiers ...func(*x509.CertificateRequest)) []byte { func mustGenerateCSR(t *testing.T, crt *cmapi.Certificate, modifiers ...gen.CSRModifier) []byte {
// Create a new private key csrPEM, _, err := gen.CSRForCertificate(crt, modifiers...)
pk, err := utilpki.GenerateRSAPrivateKey(2048)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
return csrPEM
x509CSR, err := utilpki.GenerateCSR(crt)
if err != nil {
t.Fatal(err)
}
for _, modifier := range modifiers {
modifier(x509CSR)
}
csrDER, err := utilpki.EncodeCSR(x509CSR, pk)
if err != nil {
t.Fatal(err)
}
csrPEM := bytes.NewBuffer([]byte{})
err = pem.Encode(csrPEM, &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrDER})
if err != nil {
t.Fatal(err)
}
return csrPEM.Bytes()
} }

View File

@ -19,7 +19,6 @@ package requestmanager
import ( import (
"crypto" "crypto"
"crypto/x509" "crypto/x509"
"encoding/pem"
"testing" "testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -77,7 +76,7 @@ func createCryptoBundle(originalCert *cmapi.Certificate) (*cryptoBundle, error)
return nil, err return nil, err
} }
privateKey, err := pki.GeneratePrivateKeyForCertificate(crt) csrPEM, privateKey, err := gen.CSRForCertificate(crt)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -87,11 +86,6 @@ func createCryptoBundle(originalCert *cmapi.Certificate) (*cryptoBundle, error)
return nil, err return nil, err
} }
csrPEM, err := generateCSRImpl(crt, privateKeyBytes)
if err != nil {
return nil, err
}
csr, err := pki.DecodeX509CertificateRequestBytes(csrPEM) csr, err := pki.DecodeX509CertificateRequestBytes(csrPEM)
if err != nil { if err != nil {
return nil, err return nil, err
@ -173,26 +167,3 @@ func createCryptoBundle(originalCert *cmapi.Certificate) (*cryptoBundle, error)
certBytes: certBytes, certBytes: certBytes,
}, nil }, nil
} }
func generateCSRImpl(crt *cmapi.Certificate, pk []byte) ([]byte, error) {
csr, err := pki.GenerateCSR(crt)
if err != nil {
return nil, err
}
signer, err := pki.DecodePrivateKeyBytes(pk)
if err != nil {
return nil, err
}
csrDER, err := pki.EncodeCSR(csr, signer)
if err != nil {
return nil, err
}
csrPEM := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE REQUEST", Bytes: csrDER,
})
return csrPEM, nil
}

View File

@ -14,14 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package pki package pki_test
import ( import (
"bytes"
"crypto" "crypto"
"crypto/x509" "crypto/x509"
"encoding/asn1" "encoding/asn1"
"encoding/pem"
"reflect" "reflect"
"testing" "testing"
@ -29,10 +27,12 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
"github.com/cert-manager/cert-manager/pkg/util/pki"
"github.com/cert-manager/cert-manager/test/unit/gen"
) )
func mustGenerateRSA(t *testing.T, keySize int) crypto.PrivateKey { func mustGenerateRSA(t *testing.T, keySize int) crypto.PrivateKey {
pk, err := GenerateRSAPrivateKey(keySize) pk, err := pki.GenerateRSAPrivateKey(keySize)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -40,7 +40,7 @@ func mustGenerateRSA(t *testing.T, keySize int) crypto.PrivateKey {
} }
func mustGenerateECDSA(t *testing.T, keySize int) crypto.PrivateKey { func mustGenerateECDSA(t *testing.T, keySize int) crypto.PrivateKey {
pk, err := GenerateECPrivateKey(keySize) pk, err := pki.GenerateECPrivateKey(keySize)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -48,7 +48,7 @@ func mustGenerateECDSA(t *testing.T, keySize int) crypto.PrivateKey {
} }
func mustGenerateEd25519(t *testing.T) crypto.PrivateKey { func mustGenerateEd25519(t *testing.T) crypto.PrivateKey {
pk, err := GenerateEd25519PrivateKey() pk, err := pki.GenerateEd25519PrivateKey()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -75,18 +75,18 @@ func TestPrivateKeyMatchesSpec(t *testing.T) {
violations: []string{"spec.privateKey.size"}, violations: []string{"spec.privateKey.size"},
}, },
"should match if keySize and algorithm are correct (ECDSA)": { "should match if keySize and algorithm are correct (ECDSA)": {
key: mustGenerateECDSA(t, ECCurve256), key: mustGenerateECDSA(t, pki.ECCurve256),
expectedAlgo: cmapi.ECDSAKeyAlgorithm, expectedAlgo: cmapi.ECDSAKeyAlgorithm,
expectedSize: 256, expectedSize: 256,
}, },
"should not match if ECDSA keySize is incorrect": { "should not match if ECDSA keySize is incorrect": {
key: mustGenerateECDSA(t, ECCurve256), key: mustGenerateECDSA(t, pki.ECCurve256),
expectedAlgo: cmapi.ECDSAKeyAlgorithm, expectedAlgo: cmapi.ECDSAKeyAlgorithm,
expectedSize: ECCurve521, expectedSize: pki.ECCurve521,
violations: []string{"spec.privateKey.size"}, violations: []string{"spec.privateKey.size"},
}, },
"should not match if keyAlgorithm is incorrect": { "should not match if keyAlgorithm is incorrect": {
key: mustGenerateECDSA(t, ECCurve256), key: mustGenerateECDSA(t, pki.ECCurve256),
expectedAlgo: cmapi.RSAKeyAlgorithm, expectedAlgo: cmapi.RSAKeyAlgorithm,
expectedSize: 2048, expectedSize: 2048,
violations: []string{"spec.privateKey.algorithm"}, violations: []string{"spec.privateKey.algorithm"},
@ -98,7 +98,7 @@ func TestPrivateKeyMatchesSpec(t *testing.T) {
} }
for name, test := range tests { for name, test := range tests {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
violations, err := PrivateKeyMatchesSpec( violations, err := pki.PrivateKeyMatchesSpec(
test.key, test.key,
cmapi.CertificateSpec{ cmapi.CertificateSpec{
PrivateKey: &cmapi.CertificatePrivateKey{ PrivateKey: &cmapi.CertificatePrivateKey{
@ -132,7 +132,7 @@ func TestCertificateRequestOtherNamesMatchSpec(t *testing.T) {
violations []string violations []string
}{ }{
"should not report any violation if Certificate otherName(s) match the CertificateRequest's": { "should not report any violation if Certificate otherName(s) match the CertificateRequest's": {
crSpec: MustBuildCertificateRequest(&cmapi.Certificate{Spec: cmapi.CertificateSpec{ crSpec: mustBuildCertificateRequest(t, &cmapi.Certificate{Spec: cmapi.CertificateSpec{
CommonName: "cn", CommonName: "cn",
OtherNames: []cmapi.OtherName{ OtherNames: []cmapi.OtherName{
{ {
@ -140,7 +140,7 @@ func TestCertificateRequestOtherNamesMatchSpec(t *testing.T) {
UTF8Value: "upn@testdomain.local", UTF8Value: "upn@testdomain.local",
}, },
}, },
}}, t), }}),
certSpec: cmapi.CertificateSpec{ certSpec: cmapi.CertificateSpec{
CommonName: "cn", CommonName: "cn",
OtherNames: []cmapi.OtherName{ OtherNames: []cmapi.OtherName{
@ -153,7 +153,7 @@ func TestCertificateRequestOtherNamesMatchSpec(t *testing.T) {
err: "", err: "",
}, },
"should report violation if Certificate otherName(s) mismatch the CertificateRequest's": { "should report violation if Certificate otherName(s) mismatch the CertificateRequest's": {
crSpec: MustBuildCertificateRequest(&cmapi.Certificate{Spec: cmapi.CertificateSpec{ crSpec: mustBuildCertificateRequest(t, &cmapi.Certificate{Spec: cmapi.CertificateSpec{
CommonName: "cn", CommonName: "cn",
OtherNames: []cmapi.OtherName{ OtherNames: []cmapi.OtherName{
{ {
@ -161,7 +161,7 @@ func TestCertificateRequestOtherNamesMatchSpec(t *testing.T) {
UTF8Value: "upn@testdomain.local", UTF8Value: "upn@testdomain.local",
}, },
}, },
}}, t), }}),
certSpec: cmapi.CertificateSpec{ certSpec: cmapi.CertificateSpec{
CommonName: "cn", CommonName: "cn",
OtherNames: []cmapi.OtherName{ OtherNames: []cmapi.OtherName{
@ -177,7 +177,7 @@ func TestCertificateRequestOtherNamesMatchSpec(t *testing.T) {
}, },
}, },
"should not report violation if Certificate otherName(s) match the CertificateRequest's (with different order)": { "should not report violation if Certificate otherName(s) match the CertificateRequest's (with different order)": {
crSpec: MustBuildCertificateRequest(&cmapi.Certificate{Spec: cmapi.CertificateSpec{ crSpec: mustBuildCertificateRequest(t, &cmapi.Certificate{Spec: cmapi.CertificateSpec{
CommonName: "cn", CommonName: "cn",
OtherNames: []cmapi.OtherName{ OtherNames: []cmapi.OtherName{
{ {
@ -189,7 +189,7 @@ func TestCertificateRequestOtherNamesMatchSpec(t *testing.T) {
UTF8Value: "upn@testdomain.local", UTF8Value: "upn@testdomain.local",
}, },
}, },
}}, t), }}),
certSpec: cmapi.CertificateSpec{ certSpec: cmapi.CertificateSpec{
CommonName: "cn", CommonName: "cn",
OtherNames: []cmapi.OtherName{ OtherNames: []cmapi.OtherName{
@ -208,7 +208,7 @@ func TestCertificateRequestOtherNamesMatchSpec(t *testing.T) {
} }
for name, test := range tests { for name, test := range tests {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
violations, err := RequestMatchesSpec(test.crSpec, test.certSpec) violations, err := pki.RequestMatchesSpec(test.crSpec, test.certSpec)
if err != nil { if err != nil {
if test.err == "" { if test.err == "" {
t.Errorf("Unexpected error: %s", err.Error()) t.Errorf("Unexpected error: %s", err.Error())
@ -226,12 +226,7 @@ func TestCertificateRequestOtherNamesMatchSpec(t *testing.T) {
func TestRequestMatchesSpecSubject(t *testing.T) { func TestRequestMatchesSpecSubject(t *testing.T) {
createCSRBlob := func(literalSubject string) []byte { createCSRBlob := func(literalSubject string) []byte {
pk, err := GenerateRSAPrivateKey(2048) seq, err := pki.UnmarshalSubjectStringToRDNSequence(literalSubject)
if err != nil {
t.Fatal(err)
}
seq, err := UnmarshalSubjectStringToRDNSequence(literalSubject)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -241,16 +236,15 @@ func TestRequestMatchesSpecSubject(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
csr := &x509.CertificateRequest{ pemBytes, _, err := gen.CSR(x509.Ed25519, func(cr *x509.CertificateRequest) error {
RawSubject: asn1Seq, cr.RawSubject = asn1Seq
} return nil
})
csrBytes, err := x509.CreateCertificateRequest(bytes.NewBuffer(nil), csr, pk)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrBytes}) return pemBytes
} }
tests := []struct { tests := []struct {
@ -282,7 +276,7 @@ func TestRequestMatchesSpecSubject(t *testing.T) {
for _, test := range tests { for _, test := range tests {
test := test test := test
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
violations, err := RequestMatchesSpec( violations, err := pki.RequestMatchesSpec(
&cmapi.CertificateRequest{ &cmapi.CertificateRequest{
Spec: cmapi.CertificateRequestSpec{ Spec: cmapi.CertificateRequestSpec{
Request: test.x509CSR, Request: test.x509CSR,
@ -442,7 +436,7 @@ func TestSecretDataAltNamesMatchSpec(t *testing.T) {
} }
for name, test := range tests { for name, test := range tests {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
violations, err := SecretDataAltNamesMatchSpec(&corev1.Secret{Data: map[string][]byte{corev1.TLSCertKey: test.data}}, test.spec) violations, err := pki.SecretDataAltNamesMatchSpec(&corev1.Secret{Data: map[string][]byte{corev1.TLSCertKey: test.data}}, test.spec)
switch { switch {
case err != nil: case err != nil:
if test.err != err.Error() { if test.err != err.Error() {
@ -461,17 +455,17 @@ func TestSecretDataAltNamesMatchSpec(t *testing.T) {
} }
func selfSignCertificate(t *testing.T, spec cmapi.CertificateSpec) []byte { func selfSignCertificate(t *testing.T, spec cmapi.CertificateSpec) []byte {
pk, err := GenerateRSAPrivateKey(2048) pk, err := pki.GenerateRSAPrivateKey(2048)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
template, err := CertificateTemplateFromCertificate(&cmapi.Certificate{Spec: spec}) template, err := pki.CertificateTemplateFromCertificate(&cmapi.Certificate{Spec: spec})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
pemData, _, err := SignCertificate(template, template, pk.Public(), pk) pemData, _, err := pki.SignCertificate(template, template, pk.Public(), pk)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -479,23 +473,12 @@ func selfSignCertificate(t *testing.T, spec cmapi.CertificateSpec) []byte {
return pemData return pemData
} }
func MustBuildCertificateRequest(crt *cmapi.Certificate, t *testing.T) *cmapi.CertificateRequest { func mustBuildCertificateRequest(t *testing.T, crt *cmapi.Certificate) *cmapi.CertificateRequest {
pk, err := GenerateRSAPrivateKey(2048) pemData, _, err := gen.CSRForCertificate(crt)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
csrTemplate, err := GenerateCSR(crt, WithOtherNames(true))
if err != nil {
t.Fatal(err)
}
var buffer bytes.Buffer
csr, err := x509.CreateCertificateRequest(&buffer, csrTemplate, pk)
if err != nil {
t.Fatal(err)
}
pemData := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csr})
cr := &cmapi.CertificateRequest{ cr := &cmapi.CertificateRequest{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: t.Name(), Name: t.Name(),

View File

@ -148,22 +148,11 @@ func TestIssuingController(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// Create x509 CSR from Certificate csrPEM, err := gen.CSRWithSignerForCertificate(crt, sk)
csr, err := utilpki.GenerateCSR(crt)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Encode CSR
csrDER, err := utilpki.EncodeCSR(csr, sk)
if err != nil {
t.Fatal(err)
}
csrPEM := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE REQUEST", Bytes: csrDER,
})
// Sign Certificate // Sign Certificate
certTemplate, err := utilpki.CertificateTemplateFromCertificate(crt) certTemplate, err := utilpki.CertificateTemplateFromCertificate(crt)
if err != nil { if err != nil {
@ -371,22 +360,11 @@ func TestIssuingController_PKCS8_PrivateKey(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// Create x509 CSR from Certificate csrPEM, err := gen.CSRWithSignerForCertificate(crt, sk)
csr, err := utilpki.GenerateCSR(crt)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Encode CSR
csrDER, err := utilpki.EncodeCSR(csr, sk)
if err != nil {
t.Fatal(err)
}
csrPEM := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE REQUEST", Bytes: csrDER,
})
// Sign Certificate // Sign Certificate
certTemplate, err := utilpki.CertificateTemplateFromCertificate(crt) certTemplate, err := utilpki.CertificateTemplateFromCertificate(crt)
if err != nil { if err != nil {
@ -589,22 +567,11 @@ func Test_IssuingController_SecretTemplate(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// Create x509 CSR from Certificate csrPEM, err := gen.CSRWithSignerForCertificate(crt, sk)
csr, err := utilpki.GenerateCSR(crt)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Encode CSR
csrDER, err := utilpki.EncodeCSR(csr, sk)
if err != nil {
t.Fatal(err)
}
csrPEM := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE REQUEST", Bytes: csrDER,
})
// Sign Certificate // Sign Certificate
certTemplate, err := utilpki.CertificateTemplateFromCertificate(crt) certTemplate, err := utilpki.CertificateTemplateFromCertificate(crt)
if err != nil { if err != nil {
@ -836,22 +803,11 @@ func Test_IssuingController_AdditionalOutputFormats(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// Create x509 CSR from Certificate csrPEM, err := gen.CSRWithSignerForCertificate(crt, pk)
csr, err := utilpki.GenerateCSR(crt)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Encode CSR
csrDER, err := utilpki.EncodeCSR(csr, pk)
if err != nil {
t.Fatal(err)
}
csrPEM := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE REQUEST", Bytes: csrDER,
})
// Sign Certificate // Sign Certificate
certTemplate, err := utilpki.CertificateTemplateFromCertificate(crt) certTemplate, err := utilpki.CertificateTemplateFromCertificate(crt)
if err != nil { if err != nil {

View File

@ -18,7 +18,6 @@ package certificates
import ( import (
"context" "context"
"encoding/pem"
"strconv" "strconv"
"testing" "testing"
"time" "time"
@ -36,7 +35,6 @@ import (
"github.com/cert-manager/cert-manager/pkg/controller/certificates/revisionmanager" "github.com/cert-manager/cert-manager/pkg/controller/certificates/revisionmanager"
logf "github.com/cert-manager/cert-manager/pkg/logs" logf "github.com/cert-manager/cert-manager/pkg/logs"
"github.com/cert-manager/cert-manager/pkg/metrics" "github.com/cert-manager/cert-manager/pkg/metrics"
utilpki "github.com/cert-manager/cert-manager/pkg/util/pki"
"github.com/cert-manager/cert-manager/test/unit/gen" "github.com/cert-manager/cert-manager/test/unit/gen"
) )
@ -107,27 +105,11 @@ func TestRevisionManagerController(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// Create a new private key csrPEM, _, err := gen.CSRForCertificate(crt)
sk, err := utilpki.GenerateRSAPrivateKey(2048)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
csr, err := utilpki.GenerateCSR(crt)
if err != nil {
t.Fatal(err)
}
// Encode CSR
csrDER, err := utilpki.EncodeCSR(csr, sk)
if err != nil {
t.Fatal(err)
}
csrPEM := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE REQUEST", Bytes: csrDER,
})
// Create 6 CertificateRequests which are owned by this Certificate // Create 6 CertificateRequests which are owned by this Certificate
for i := 0; i < 6; i++ { for i := 0; i < 6; i++ {
_, err = cmCl.CertmanagerV1().CertificateRequests(namespace).Create(ctx, &cmapi.CertificateRequest{ _, err = cmCl.CertmanagerV1().CertificateRequests(namespace).Create(ctx, &cmapi.CertificateRequest{

View File

@ -18,7 +18,6 @@ package validation
import ( import (
"context" "context"
"encoding/pem"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -33,7 +32,7 @@ import (
"github.com/cert-manager/cert-manager/pkg/api" "github.com/cert-manager/cert-manager/pkg/api"
cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1"
"github.com/cert-manager/cert-manager/pkg/util/pki" "github.com/cert-manager/cert-manager/test/unit/gen"
) )
var certGVK = schema.GroupVersionKind{ var certGVK = schema.GroupVersionKind{
@ -200,22 +199,9 @@ func TestValidationCertificateRequests(t *testing.T) {
} }
func mustGenerateCSR(t *testing.T, cert *cmapi.Certificate) []byte { func mustGenerateCSR(t *testing.T, cert *cmapi.Certificate) []byte {
request, err := pki.GenerateCSR(cert) csr, _, err := gen.CSRForCertificate(cert)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
sk, err := pki.GenerateRSAPrivateKey(2048)
if err != nil {
t.Fatal(err)
}
csrBytes, err := pki.EncodeCSR(request, sk)
if err != nil {
t.Fatal(err)
}
csr := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE REQUEST", Bytes: csrBytes,
})
return csr return csr
} }

View File

@ -28,11 +28,57 @@ import (
"net" "net"
"net/url" "net/url"
v1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
"github.com/cert-manager/cert-manager/pkg/util/pki" "github.com/cert-manager/cert-manager/pkg/util/pki"
) )
type CSRModifier func(*x509.CertificateRequest) error type CSRModifier func(*x509.CertificateRequest) error
var defaultGenerateCSROptions = []pki.GenerateCSROption{
pki.WithEncodeBasicConstraintsInRequest(true),
pki.WithNameConstraints(true),
pki.WithOtherNames(true),
pki.WithUseLiteralSubject(true),
}
func CSRForCertificate(crt *v1.Certificate, mods ...CSRModifier) (csr []byte, sk crypto.Signer, err error) {
cr, err := pki.GenerateCSR(crt, defaultGenerateCSROptions...)
if err != nil {
return nil, nil, err
}
modifiers := []CSRModifier{}
modifiers = append(modifiers, func(c *x509.CertificateRequest) error {
*c = *cr
return nil
})
modifiers = append(modifiers, mods...)
return CSR(cr.PublicKeyAlgorithm, modifiers...)
}
func CSRWithSignerForCertificate(crt *v1.Certificate, sk crypto.Signer, mods ...CSRModifier) (csr []byte, err error) {
cr, err := pki.GenerateCSR(crt, defaultGenerateCSROptions...)
if err != nil {
return nil, err
}
modifiers := []CSRModifier{}
modifiers = append(modifiers, func(c *x509.CertificateRequest) error {
if c.PublicKeyAlgorithm != cr.PublicKeyAlgorithm {
return fmt.Errorf("public key algorithm mismatch: %s != %s", c.PublicKeyAlgorithm, cr.PublicKeyAlgorithm)
}
if c.SignatureAlgorithm != cr.SignatureAlgorithm {
return fmt.Errorf("signature algorithm mismatch: %s != %s", c.SignatureAlgorithm, cr.SignatureAlgorithm)
}
*c = *cr
return nil
})
modifiers = append(modifiers, mods...)
return CSRWithSigner(sk, modifiers...)
}
func CSR(keyAlgorithm x509.PublicKeyAlgorithm, mods ...CSRModifier) (csr []byte, sk crypto.Signer, err error) { func CSR(keyAlgorithm x509.PublicKeyAlgorithm, mods ...CSRModifier) (csr []byte, sk crypto.Signer, err error) {
switch keyAlgorithm { switch keyAlgorithm {
case x509.RSA: case x509.RSA: