diff --git a/pkg/internal/apis/certmanager/validation/certificaterequest.go b/pkg/internal/apis/certmanager/validation/certificaterequest.go index 999d6281b..d1caf923b 100644 --- a/pkg/internal/apis/certmanager/validation/certificaterequest.go +++ b/pkg/internal/apis/certmanager/validation/certificaterequest.go @@ -135,7 +135,7 @@ func patchDuplicateKeyUsage(usages []cmapi.KeyUsage) []cmapi.KeyUsage { newUsages = append(newUsages, cmapi.UsageDigitalSignature) // prevent having 2 UsageDigitalSignature in the slice hasUsageSigning = true - } else { + } else if usage != cmapi.UsageSigning && usage != cmapi.UsageDigitalSignature { newUsages = append(newUsages, usage) } } diff --git a/pkg/internal/apis/certmanager/validation/certificaterequest_test.go b/pkg/internal/apis/certmanager/validation/certificaterequest_test.go index 7e888c7a1..91c9bbb60 100644 --- a/pkg/internal/apis/certmanager/validation/certificaterequest_test.go +++ b/pkg/internal/apis/certmanager/validation/certificaterequest_test.go @@ -117,6 +117,27 @@ func TestValidateCertificateRequestSpec(t *testing.T) { field.Invalid(fldPath.Child("request"), nil, "csr key usages do not match specified usages, these should match if both are set: [[]certmanager.KeyUsage[4] != []certmanager.KeyUsage[2]]"), }, }, + { + name: "Error on cr not having all usages", + crSpec: &cminternal.CertificateRequestSpec{ + Request: mustGenerateCSR(t, gen.Certificate("test", gen.SetCertificateDNSNames("example.com"), gen.SetCertificateKeyUsages(cmapi.UsageDigitalSignature, cmapi.UsageKeyEncipherment, cmapi.UsageServerAuth, cmapi.UsageClientAuth))), + IssuerRef: validIssuerRef, + Usages: []cminternal.KeyUsage{cminternal.UsageAny, cminternal.UsageSigning}, + }, + want: []*field.Error{ + field.Invalid(fldPath.Child("request"), nil, "csr key usages do not match specified usages, these should match if both are set: [[]certmanager.KeyUsage[4] != []certmanager.KeyUsage[2]]"), + }, + }, + { + name: "Test csr with any, signing, digital signature, key encipherment, server and client auth", + crSpec: &cminternal.CertificateRequestSpec{ + Request: mustGenerateCSR(t, gen.Certificate("test", gen.SetCertificateDNSNames("example.com"), gen.SetCertificateKeyUsages(cmapi.UsageAny, cmapi.UsageSigning, cmapi.UsageKeyEncipherment, cmapi.UsageClientAuth, cmapi.UsageServerAuth), gen.SetCertificateIsCA(true))), + IssuerRef: validIssuerRef, + IsCA: true, + Usages: []cminternal.KeyUsage{cminternal.UsageAny, cminternal.UsageSigning, cminternal.UsageKeyEncipherment, cminternal.UsageClientAuth, cminternal.UsageServerAuth}, + }, + want: []*field.Error{}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -156,3 +177,39 @@ func mustGenerateCSR(t *testing.T, crt *cmapi.Certificate) []byte { return csrPEM.Bytes() } + +func Test_patchDuplicateKeyUsage(t *testing.T) { + tests := []struct { + name string + usages []cminternal.KeyUsage + want []cminternal.KeyUsage + }{ + { + name: "Test single KU", + usages: []cminternal.KeyUsage{cminternal.UsageKeyEncipherment}, + want: []cminternal.KeyUsage{cminternal.UsageKeyEncipherment}, + }, + { + name: "Test UsageSigning", + usages: []cminternal.KeyUsage{cminternal.UsageSigning}, + want: []cminternal.KeyUsage{cminternal.UsageDigitalSignature}, + }, + { + name: "Test multiple KU", + usages: []cminternal.KeyUsage{cminternal.UsageDigitalSignature, cminternal.UsageServerAuth, cminternal.UsageClientAuth}, + want: []cminternal.KeyUsage{cminternal.UsageDigitalSignature, cminternal.UsageServerAuth, cminternal.UsageClientAuth}, + }, + { + name: "Test double signing", + usages: []cminternal.KeyUsage{cminternal.UsageSigning, cminternal.UsageDigitalSignature}, + want: []cminternal.KeyUsage{cminternal.UsageDigitalSignature}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := patchDuplicateKeyUsage(tt.usages); !reflect.DeepEqual(got, tt.want) { + t.Errorf("patchDuplicateKeyUsage() = %v, want %v", got, tt.want) + } + }) + } +}