Simplify e2e test fixture for otherName

* Fix Bug in critical on empty subject logic

Signed-off-by: SpectralHiss <houssem.elfekih@jetstack.io>
This commit is contained in:
SpectralHiss 2023-12-21 17:48:50 +00:00
parent ae4249b9e2
commit c59037a19b
3 changed files with 98 additions and 108 deletions

View File

@ -324,7 +324,7 @@ func GenerateCSR(crt *v1.Certificate, optFuncs ...GenerateCSROption) (*x509.Cert
// just an empty SEQUENCE.
var emptyASN1Subject = []byte{0x30, 0}
sanExtension, err := MarshalSANs(sans, bytes.Equal(asn1Subject, emptyASN1Subject))
sanExtension, err := MarshalSANs(sans, !bytes.Equal(asn1Subject, emptyASN1Subject))
if err != nil {
return nil, err
}

View File

@ -20,8 +20,8 @@ import (
"context"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"fmt"
"time"
"github.com/cert-manager/cert-manager/e2e-tests/framework"
@ -37,25 +37,32 @@ import (
var _ = framework.CertManagerDescribe("othername san processing", func() {
const (
testName = "test-othername-san-processing"
issuerName = "certificate-othername-san-processing"
secretName = testName
nameTypeEmail = 1
testName = "test-othername-san-processing"
issuerName = "certificate-othername-san-processing"
secretName = testName
)
var (
oidExtensionSubjectAltName = asn1.ObjectIdentifier{2, 5, 29, 17}
emailAddresses = []string{"email@domain.com"}
oidExtensionSubjectAltName = []int{2, 5, 29, 17}
emailAddresses = []string{"email@domain.test"}
)
// StringValueLikeType type for asn1 encoding. This will hold
// our utf-8 encoded string.
type StringValueLikeType struct {
A string `asn1:"utf8"`
}
type OtherName struct {
OID asn1.ObjectIdentifier
Value StringValueLikeType `asn1:"tag:0"`
extractSANsFromCertificate := func(certDER string) pkix.Extension {
block, rest := pem.Decode([]byte(certDER))
fmt.Printf("block: %v, rest: %+v", block, rest)
Expect(len(rest)).To(Equal(0))
cert, err := x509.ParseCertificate(block.Bytes)
Expect(err).NotTo(HaveOccurred())
for _, extension := range cert.Extensions {
if extension.Id.Equal(oidExtensionSubjectAltName) {
return extension
}
}
Fail("Could not find SANs in certificate")
return pkix.Extension{}
}
f := framework.NewDefaultFramework("certificate-othername-san-processing")
@ -73,6 +80,7 @@ var _ = framework.CertManagerDescribe("othername san processing", func() {
},
OtherNames: OtherNames,
EmailAddresses: emailAddresses,
CommonName: "SOMECN",
},
}
By("creating Certificate with OtherNames")
@ -96,15 +104,11 @@ var _ = framework.CertManagerDescribe("othername san processing", func() {
Expect(f.CertManagerClientSet.CertmanagerV1().Issuers(f.Namespace.Name).Delete(context.Background(), issuerName, metav1.DeleteOptions{})).NotTo(HaveOccurred())
})
It("Should create a certificate with the supplied otherName SAN values and emailAddresses included", func() {
It("Should create a certificate with the supplied otherName SAN value and emailAddress included", func() {
crt, err := createCertificate(f, []cmapi.OtherName{
{
OID: "1.3.6.1.4.1.311.20.2.3",
UTF8Value: "userprincipal@domain.com",
},
{
OID: "1.2.840.113556.1.4.221", // this is the legacy samAccountName but could be any oid
UTF8Value: "user@example.org",
UTF8Value: "upn@domain.test",
},
})
Expect(err).NotTo(HaveOccurred())
@ -119,42 +123,33 @@ var _ = framework.CertManagerDescribe("othername san processing", func() {
cert, err := x509.ParseCertificate(pemBlock.Bytes)
Expect(err).To(BeNil())
By("Including the supplied RFC822 email Address")
Expect(cert.EmailAddresses).To(Equal(emailAddresses))
By("Including the appropriate GeneralNames ( RFC822 email Address and OtherName) in generated Certificate")
By("Including the supplied otherName values in SAN Extension")
/* openssl req -nodes -newkey rsa:2048 -subj "/CN=someCN" \
-addext 'subjectAltName=email:email@domain.test,otherName:msUPN;UTF8:upn@domain.test' -x509 -out server.crt
*/
expectedSanExtension := extractSANsFromCertificate(`-----BEGIN CERTIFICATE-----
MIIDRDCCAiygAwIBAgIUdotGup0k8gdZ+irmcuvLeJDm5wkwDQYJKoZIhvcNAQEL
BQAwETEPMA0GA1UEAwwGc29tZUNOMB4XDTIzMTIyMTE2NDQyOFoXDTI0MDEyMDE2
NDQyOFowETEPMA0GA1UEAwwGc29tZUNOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAyIIWkA1mNi0ZpdwkGeBjmZKZD9J8D9NlpYpOTzoxRLstuJdUNOb0
BgsRk9FWr6rzg6SdSL7NxUS9ZJc0X0P8gn7bPUVtaF7vbj2apz1W2fhx2ifmBRaT
n7ZbpO1aapzr0kiPEZKc82X4jualnFW2YMjjQMc6YuMykcaTQnpv9R4/mzM0kzal
gpKp82tnUogG7EC79cO6xubk0kgIxBFwpH+H6EPLtRY12wW5fONmw9smRgsfleIs
lMSHNuJvUMqyktb8YzAX/XCz3Idumu1UA4ZCFRNCZ019JnmaFF9McGqaC6zrPwnl
aONLw1x9tD+D9bwi6idHNbq/PmQwfs7zzQIDAQABo4GTMIGQMB0GA1UdDgQWBBRm
myeY1slW3mXcGLZs7uciGpfCQzAfBgNVHSMEGDAWgBRmmyeY1slW3mXcGLZs7uci
GpfCQzAPBgNVHRMBAf8EBTADAQH/MD0GA1UdEQQ2MDSBEWVtYWlsQGRvbWFpbi50
ZXN0oB8GCisGAQQBgjcUAgOgEQwPdXBuQGRvbWFpbi50ZXN0MA0GCSqGSIb3DQEB
CwUAA4IBAQCgpAMWkSqA0jV+Bd6UEw7phROTkan5IWTXqYT56RI3AS+LZ83cVglS
FP0UKUssQjLKmubcJWo84T83woxfZVSj15x8X+ohzSvSK8wIe2uobKKNl8F0yW8X
3267YrKGnY6eDqsmNZT8P1isSyYF0PUP3EIDlO6D1YICMawvZItnE+tf9QR+5IIH
3dEzwc2wJsUVYLQ6fgZ4KMfY+fMThY7EDQPsR2M7YFW3p4+3GPQMGBGCOQZysuVh
4uvQbrc9rUWzLMmmJrbb2/xwMm1iCoJfRyLKOGqQV8O6NfnYz5n0/vYzXUCvEbfl
YH0ROM05IRf2nOI6KInaiz4POk6JvdTb
-----END CERTIFICATE-----
`)
otherNameSANRawVal := func(expectedOID asn1.ObjectIdentifier, value string) asn1.RawValue {
otherNameDer, err := asn1.MarshalWithParams(OtherName{
OID: expectedOID, // UPN OID
Value: StringValueLikeType{
A: value,
}}, "tag:0")
Expect(err).To(BeNil())
rawVal := asn1.RawValue{
FullBytes: otherNameDer,
}
return rawVal
}
asn1otherNameUpnSANRawVal := otherNameSANRawVal(asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 20, 2, 3}, "userprincipal@domain.com") // UPN OID
asn1otherNamesAMAAccountNameRawVal := otherNameSANRawVal(asn1.ObjectIdentifier{1, 2, 840, 113556, 1, 4, 221}, "user@example.org") // sAMAccountName OID
mustMarshalSAN := func(generalNames []asn1.RawValue) pkix.Extension {
val, err := asn1.Marshal(generalNames)
Expect(err).To(BeNil())
return pkix.Extension{
Id: oidExtensionSubjectAltName,
Value: val,
Critical: true,
}
}
expectedSanExtension := mustMarshalSAN([]asn1.RawValue{
{Tag: nameTypeEmail, Class: 2, Bytes: []byte("email@domain.com")},
asn1otherNameUpnSANRawVal,
asn1otherNamesAMAAccountNameRawVal,
})
Expect(cert.Extensions).To(ContainElement(expectedSanExtension))
})

View File

@ -229,10 +229,6 @@ func (s *Suite) Define() {
OID: "1.3.6.1.4.1.311.20.2.3",
UTF8Value: "userprincipal@domain.com",
},
{
OID: "1.2.840.113556.1.4.221", // this is the legacy samAccountName but could be any oid
UTF8Value: "user@example.org",
},
}
testCertificate := &cmapi.Certificate{
@ -266,59 +262,38 @@ func (s *Suite) Define() {
cert, err := x509.ParseCertificate(pemBlock.Bytes)
Expect(err).To(BeNil())
By("Including the supplied RFC822 email Address")
Expect(cert.EmailAddresses).To(Equal(emailAddresses))
By("Including the appropriate GeneralNames ( RFC822 email Address and OtherName) in generated Certificate")
By("Including the supplied otherName values in SAN Extension")
oidExtensionSubjectAltName := asn1.ObjectIdentifier{2, 5, 29, 17}
/* openssl req -nodes -newkey rsa:2048 -subj "/CN=someCN" \
-addext 'subjectAltName=email:email@domain.test,otherName:msUPN;UTF8:upn@domain.test' -x509 -out server.crt
*/
expectedSanExtension := extractSANsFromCertificate(`-----BEGIN CERTIFICATE-----
MIIDRDCCAiygAwIBAgIUdotGup0k8gdZ+irmcuvLeJDm5wkwDQYJKoZIhvcNAQEL
BQAwETEPMA0GA1UEAwwGc29tZUNOMB4XDTIzMTIyMTE2NDQyOFoXDTI0MDEyMDE2
NDQyOFowETEPMA0GA1UEAwwGc29tZUNOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAyIIWkA1mNi0ZpdwkGeBjmZKZD9J8D9NlpYpOTzoxRLstuJdUNOb0
BgsRk9FWr6rzg6SdSL7NxUS9ZJc0X0P8gn7bPUVtaF7vbj2apz1W2fhx2ifmBRaT
n7ZbpO1aapzr0kiPEZKc82X4jualnFW2YMjjQMc6YuMykcaTQnpv9R4/mzM0kzal
gpKp82tnUogG7EC79cO6xubk0kgIxBFwpH+H6EPLtRY12wW5fONmw9smRgsfleIs
lMSHNuJvUMqyktb8YzAX/XCz3Idumu1UA4ZCFRNCZ019JnmaFF9McGqaC6zrPwnl
aONLw1x9tD+D9bwi6idHNbq/PmQwfs7zzQIDAQABo4GTMIGQMB0GA1UdDgQWBBRm
myeY1slW3mXcGLZs7uciGpfCQzAfBgNVHSMEGDAWgBRmmyeY1slW3mXcGLZs7uci
GpfCQzAPBgNVHRMBAf8EBTADAQH/MD0GA1UdEQQ2MDSBEWVtYWlsQGRvbWFpbi50
ZXN0oB8GCisGAQQBgjcUAgOgEQwPdXBuQGRvbWFpbi50ZXN0MA0GCSqGSIb3DQEB
CwUAA4IBAQCgpAMWkSqA0jV+Bd6UEw7phROTkan5IWTXqYT56RI3AS+LZ83cVglS
FP0UKUssQjLKmubcJWo84T83woxfZVSj15x8X+ohzSvSK8wIe2uobKKNl8F0yW8X
3267YrKGnY6eDqsmNZT8P1isSyYF0PUP3EIDlO6D1YICMawvZItnE+tf9QR+5IIH
3dEzwc2wJsUVYLQ6fgZ4KMfY+fMThY7EDQPsR2M7YFW3p4+3GPQMGBGCOQZysuVh
4uvQbrc9rUWzLMmmJrbb2/xwMm1iCoJfRyLKOGqQV8O6NfnYz5n0/vYzXUCvEbfl
YH0ROM05IRf2nOI6KInaiz4POk6JvdTb
-----END CERTIFICATE-----
`)
otherNameSANRawVal := func(expectedOID asn1.ObjectIdentifier, value string) asn1.RawValue {
// StringValueLikeType type for asn1 encoding. This will hold
// our utf-8 encoded string.
type StringValueLikeType struct {
A string `asn1:"utf8"`
}
type OtherName struct {
OID asn1.ObjectIdentifier
Value StringValueLikeType `asn1:"tag:0"`
}
otherNameDer, err := asn1.MarshalWithParams(OtherName{
OID: expectedOID, // UPN OID
Value: StringValueLikeType{
A: value,
}}, "tag:0")
Expect(err).To(BeNil())
rawVal := asn1.RawValue{
FullBytes: otherNameDer,
}
return rawVal
}
asn1otherNameUpnSANRawVal := otherNameSANRawVal(asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 20, 2, 3}, "userprincipal@domain.com") // UPN OID
asn1otherNamesAMAAccountNameRawVal := otherNameSANRawVal(asn1.ObjectIdentifier{1, 2, 840, 113556, 1, 4, 221}, "user@example.org") // sAMAccountName OID
mustMarshalSAN := func(generalNames []asn1.RawValue) pkix.Extension {
val, err := asn1.Marshal(generalNames)
Expect(err).To(BeNil())
return pkix.Extension{
Id: oidExtensionSubjectAltName,
Value: val,
Critical: true, // Since there is no subject the SAN extension is critical
}
}
nameTypeEmail := 1
expectedSanExtension := mustMarshalSAN([]asn1.RawValue{
{Tag: nameTypeEmail, Class: 2, Bytes: []byte("email@domain.com")},
asn1otherNameUpnSANRawVal,
asn1otherNamesAMAAccountNameRawVal,
})
Expect(cert.Extensions).To(ContainElement(expectedSanExtension))
Fail("check")
return nil
}
By("Validating the issued Certificate...")
err = f.Helper().ValidateCertificate(testCertificate, valFunc)
@ -1139,3 +1114,23 @@ func (s *Suite) Define() {
}, featureset.WildcardsFeature, featureset.OnlySAN)
})
}
var oidExtensionSubjectAltName = []int{2, 5, 29, 17}
func extractSANsFromCertificate(certDER string) pkix.Extension {
block, rest := pem.Decode([]byte(certDER))
fmt.Printf("block: %v, rest: %+v", block, rest)
Expect(len(rest)).To(Equal(0))
cert, err := x509.ParseCertificate(block.Bytes)
Expect(err).NotTo(HaveOccurred())
for _, extension := range cert.Extensions {
if extension.Id.Equal(oidExtensionSubjectAltName) {
return extension
}
}
Fail("Could not find SANs in certificate")
return pkix.Extension{}
}