Add x509 v3 CA Issuers Extension
Signed-off-by: Jeremy Campbell <jeremy.campbell@okta.com>
This commit is contained in:
parent
b0ed333413
commit
dc876fef16
@ -1081,6 +1081,11 @@ spec:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
issuingCertificateURLs:
|
||||
description: IssuingCertificateURLs is a list of URLs which this issuer should embed into certificates it creates. See https://www.rfc-editor.org/rfc/rfc5280#section-4.2.2.1 for more details. As an example, such a URL might be "http://ca.domain.com/ca.crt".
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
ocspServers:
|
||||
description: The OCSP server list is an X.509 v3 extension that defines a list of URLs of OCSP responders. The OCSP responders can be queried for the revocation status of an issued certificate. If not set, the certificate will be issued with no OCSP servers set. For example, an OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org".
|
||||
type: array
|
||||
|
||||
@ -1081,6 +1081,11 @@ spec:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
issuingCertificateURLs:
|
||||
description: IssuingCertificateURLs is a list of URLs which this issuer should embed into certificates it creates. See https://www.rfc-editor.org/rfc/rfc5280#section-4.2.2.1 for more details. As an example, such a URL might be "http://ca.domain.com/ca.crt".
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
ocspServers:
|
||||
description: The OCSP server list is an X.509 v3 extension that defines a list of URLs of OCSP responders. The OCSP responders can be queried for the revocation status of an issued certificate. If not set, the certificate will be issued with no OCSP servers set. For example, an OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org".
|
||||
type: array
|
||||
|
||||
@ -292,6 +292,12 @@ type CAIssuer struct {
|
||||
// certificate will be issued with no OCSP servers set. For example, an
|
||||
// OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org".
|
||||
OCSPServers []string
|
||||
|
||||
// IssuingCertificateURLs is a list of URLs which this issuer should embed into certificates
|
||||
// it creates. See https://www.rfc-editor.org/rfc/rfc5280#section-4.2.2.1 for more details.
|
||||
// As an example, such a URL might be "http://ca.domain.com/ca.crt".
|
||||
// +optional
|
||||
IssuingCertificateURLs []string `json:"issuingCertificateURLs,omitempty"`
|
||||
}
|
||||
|
||||
// IssuerStatus contains status information about an Issuer
|
||||
|
||||
@ -401,6 +401,7 @@ func autoConvert_v1_CAIssuer_To_certmanager_CAIssuer(in *v1.CAIssuer, out *certm
|
||||
out.SecretName = in.SecretName
|
||||
out.CRLDistributionPoints = *(*[]string)(unsafe.Pointer(&in.CRLDistributionPoints))
|
||||
out.OCSPServers = *(*[]string)(unsafe.Pointer(&in.OCSPServers))
|
||||
out.IssuingCertificateURLs = *(*[]string)(unsafe.Pointer(&in.IssuingCertificateURLs))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -413,6 +414,7 @@ func autoConvert_certmanager_CAIssuer_To_v1_CAIssuer(in *certmanager.CAIssuer, o
|
||||
out.SecretName = in.SecretName
|
||||
out.CRLDistributionPoints = *(*[]string)(unsafe.Pointer(&in.CRLDistributionPoints))
|
||||
out.OCSPServers = *(*[]string)(unsafe.Pointer(&in.OCSPServers))
|
||||
out.IssuingCertificateURLs = *(*[]string)(unsafe.Pointer(&in.IssuingCertificateURLs))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -309,6 +309,12 @@ type CAIssuer struct {
|
||||
// OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org".
|
||||
// +optional
|
||||
OCSPServers []string `json:"ocspServers,omitempty"`
|
||||
|
||||
// IssuingCertificateURLs is a list of URLs which this issuer should embed into certificates
|
||||
// it creates. See https://www.rfc-editor.org/rfc/rfc5280#section-4.2.2.1 for more details.
|
||||
// As an example, such a URL might be "http://ca.domain.com/ca.crt".
|
||||
// +optional
|
||||
IssuingCertificateURLs []string `json:"issuingCertificateURLs,omitempty"`
|
||||
}
|
||||
|
||||
// IssuerStatus contains status information about an Issuer
|
||||
|
||||
@ -399,6 +399,7 @@ func autoConvert_v1alpha2_CAIssuer_To_certmanager_CAIssuer(in *CAIssuer, out *ce
|
||||
out.SecretName = in.SecretName
|
||||
out.CRLDistributionPoints = *(*[]string)(unsafe.Pointer(&in.CRLDistributionPoints))
|
||||
out.OCSPServers = *(*[]string)(unsafe.Pointer(&in.OCSPServers))
|
||||
out.IssuingCertificateURLs = *(*[]string)(unsafe.Pointer(&in.IssuingCertificateURLs))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -411,6 +412,7 @@ func autoConvert_certmanager_CAIssuer_To_v1alpha2_CAIssuer(in *certmanager.CAIss
|
||||
out.SecretName = in.SecretName
|
||||
out.CRLDistributionPoints = *(*[]string)(unsafe.Pointer(&in.CRLDistributionPoints))
|
||||
out.OCSPServers = *(*[]string)(unsafe.Pointer(&in.OCSPServers))
|
||||
out.IssuingCertificateURLs = *(*[]string)(unsafe.Pointer(&in.IssuingCertificateURLs))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +41,11 @@ func (in *CAIssuer) DeepCopyInto(out *CAIssuer) {
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.IssuingCertificateURLs != nil {
|
||||
in, out := &in.IssuingCertificateURLs, &out.IssuingCertificateURLs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -309,6 +309,12 @@ type CAIssuer struct {
|
||||
// OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org".
|
||||
// +optional
|
||||
OCSPServers []string `json:"ocspServers,omitempty"`
|
||||
|
||||
// IssuingCertificateURLs is a list of URLs which this issuer should embed into certificates
|
||||
// it creates. See https://www.rfc-editor.org/rfc/rfc5280#section-4.2.2.1 for more details.
|
||||
// As an example, such a URL might be "http://ca.domain.com/ca.crt".
|
||||
// +optional
|
||||
IssuingCertificateURLs []string `json:"issuingCertificateURLs,omitempty"`
|
||||
}
|
||||
|
||||
// IssuerStatus contains status information about an Issuer
|
||||
|
||||
@ -399,6 +399,7 @@ func autoConvert_v1alpha3_CAIssuer_To_certmanager_CAIssuer(in *CAIssuer, out *ce
|
||||
out.SecretName = in.SecretName
|
||||
out.CRLDistributionPoints = *(*[]string)(unsafe.Pointer(&in.CRLDistributionPoints))
|
||||
out.OCSPServers = *(*[]string)(unsafe.Pointer(&in.OCSPServers))
|
||||
out.IssuingCertificateURLs = *(*[]string)(unsafe.Pointer(&in.IssuingCertificateURLs))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -411,6 +412,7 @@ func autoConvert_certmanager_CAIssuer_To_v1alpha3_CAIssuer(in *certmanager.CAIss
|
||||
out.SecretName = in.SecretName
|
||||
out.CRLDistributionPoints = *(*[]string)(unsafe.Pointer(&in.CRLDistributionPoints))
|
||||
out.OCSPServers = *(*[]string)(unsafe.Pointer(&in.OCSPServers))
|
||||
out.IssuingCertificateURLs = *(*[]string)(unsafe.Pointer(&in.IssuingCertificateURLs))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +41,11 @@ func (in *CAIssuer) DeepCopyInto(out *CAIssuer) {
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.IssuingCertificateURLs != nil {
|
||||
in, out := &in.IssuingCertificateURLs, &out.IssuingCertificateURLs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -311,6 +311,12 @@ type CAIssuer struct {
|
||||
// OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org".
|
||||
// +optional
|
||||
OCSPServers []string `json:"ocspServers,omitempty"`
|
||||
|
||||
// IssuingCertificateURLs is a list of URLs which this issuer should embed into certificates
|
||||
// it creates. See https://www.rfc-editor.org/rfc/rfc5280#section-4.2.2.1 for more details.
|
||||
// As an example, such a URL might be "http://ca.domain.com/ca.crt".
|
||||
// +optional
|
||||
IssuingCertificateURLs []string `json:"issuingCertificateURLs,omitempty"`
|
||||
}
|
||||
|
||||
// IssuerStatus contains status information about an Issuer
|
||||
|
||||
@ -399,6 +399,7 @@ func autoConvert_v1beta1_CAIssuer_To_certmanager_CAIssuer(in *CAIssuer, out *cer
|
||||
out.SecretName = in.SecretName
|
||||
out.CRLDistributionPoints = *(*[]string)(unsafe.Pointer(&in.CRLDistributionPoints))
|
||||
out.OCSPServers = *(*[]string)(unsafe.Pointer(&in.OCSPServers))
|
||||
out.IssuingCertificateURLs = *(*[]string)(unsafe.Pointer(&in.IssuingCertificateURLs))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -411,6 +412,7 @@ func autoConvert_certmanager_CAIssuer_To_v1beta1_CAIssuer(in *certmanager.CAIssu
|
||||
out.SecretName = in.SecretName
|
||||
out.CRLDistributionPoints = *(*[]string)(unsafe.Pointer(&in.CRLDistributionPoints))
|
||||
out.OCSPServers = *(*[]string)(unsafe.Pointer(&in.OCSPServers))
|
||||
out.IssuingCertificateURLs = *(*[]string)(unsafe.Pointer(&in.IssuingCertificateURLs))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +41,11 @@ func (in *CAIssuer) DeepCopyInto(out *CAIssuer) {
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.IssuingCertificateURLs != nil {
|
||||
in, out := &in.IssuingCertificateURLs, &out.IssuingCertificateURLs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -244,6 +244,11 @@ func ValidateCAIssuerConfig(iss *certmanager.CAIssuer, fldPath *field.Path) fiel
|
||||
el = append(el, field.Invalid(fldPath.Child("ocspServer").Index(i), ocspURL, "must be a valid URL, e.g., http://ocsp.int-x3.letsencrypt.org"))
|
||||
}
|
||||
}
|
||||
for i, issuerURL := range iss.IssuingCertificateURLs {
|
||||
if issuerURL == "" {
|
||||
el = append(el, field.Invalid(fldPath.Child("issuingCertificateURLs").Index(i), issuerURL, "must be a valid URL"))
|
||||
}
|
||||
}
|
||||
return el
|
||||
}
|
||||
|
||||
|
||||
@ -737,6 +737,30 @@ func TestValidateIssuerSpec(t *testing.T) {
|
||||
field.Invalid(fldPath.Child("ca", "ocspServer").Index(0), "", `must be a valid URL, e.g., http://ocsp.int-x3.letsencrypt.org`),
|
||||
},
|
||||
},
|
||||
"valid IssuingCertificateURLs": {
|
||||
spec: &cmapi.IssuerSpec{
|
||||
IssuerConfig: cmapi.IssuerConfig{
|
||||
CA: &cmapi.CAIssuer{
|
||||
SecretName: "valid",
|
||||
IssuingCertificateURLs: []string{"http://ca.example.com/ca.crt"},
|
||||
},
|
||||
},
|
||||
},
|
||||
errs: []*field.Error{},
|
||||
},
|
||||
"invalid IssuingCertificateURLs": {
|
||||
spec: &cmapi.IssuerSpec{
|
||||
IssuerConfig: cmapi.IssuerConfig{
|
||||
CA: &cmapi.CAIssuer{
|
||||
SecretName: "valid",
|
||||
IssuingCertificateURLs: []string{""},
|
||||
},
|
||||
},
|
||||
},
|
||||
errs: []*field.Error{
|
||||
field.Invalid(fldPath.Child("ca", "issuingCertificateURLs").Index(0), "", `must be a valid URL`),
|
||||
},
|
||||
},
|
||||
}
|
||||
for n, s := range scenarios {
|
||||
t.Run(n, func(t *testing.T) {
|
||||
|
||||
@ -41,6 +41,11 @@ func (in *CAIssuer) DeepCopyInto(out *CAIssuer) {
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.IssuingCertificateURLs != nil {
|
||||
in, out := &in.IssuingCertificateURLs, &out.IssuingCertificateURLs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -314,6 +314,12 @@ type CAIssuer struct {
|
||||
// OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org".
|
||||
// +optional
|
||||
OCSPServers []string `json:"ocspServers,omitempty"`
|
||||
|
||||
// IssuingCertificateURLs is a list of URLs which this issuer should embed into certificates
|
||||
// it creates. See https://www.rfc-editor.org/rfc/rfc5280#section-4.2.2.1 for more details.
|
||||
// As an example, such a URL might be "http://ca.domain.com/ca.crt".
|
||||
// +optional
|
||||
IssuingCertificateURLs []string `json:"issuingCertificateURLs,omitempty"`
|
||||
}
|
||||
|
||||
// IssuerStatus contains status information about an Issuer
|
||||
|
||||
@ -41,6 +41,11 @@ func (in *CAIssuer) DeepCopyInto(out *CAIssuer) {
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.IssuingCertificateURLs != nil {
|
||||
in, out := &in.IssuingCertificateURLs, &out.IssuingCertificateURLs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -128,6 +128,7 @@ func (c *CA) Sign(ctx context.Context, cr *cmapi.CertificateRequest, issuerObj c
|
||||
|
||||
template.CRLDistributionPoints = issuerObj.GetSpec().CA.CRLDistributionPoints
|
||||
template.OCSPServer = issuerObj.GetSpec().CA.OCSPServers
|
||||
template.IssuingCertificateURL = issuerObj.GetSpec().CA.IssuingCertificateURLs
|
||||
|
||||
bundle, err := c.signingFn(caCerts, caKey, template)
|
||||
if err != nil {
|
||||
|
||||
@ -552,6 +552,24 @@ func TestCA_Sign(t *testing.T) {
|
||||
assert.Equal(t, []string{"http://ocsp-v3.example.org"}, got.OCSPServer)
|
||||
},
|
||||
},
|
||||
"when the Issuer has IssuingCertificateURL set, it should appear on the signed ca": {
|
||||
givenCASecret: gen.SecretFrom(gen.Secret("secret-1"), gen.SetSecretNamespace("default"), gen.SetSecretData(secretDataFor(t, rootPK, rootCert))),
|
||||
givenCAIssuer: gen.Issuer("issuer-1", gen.SetIssuerCA(cmapi.CAIssuer{
|
||||
SecretName: "secret-1",
|
||||
IssuingCertificateURLs: []string{"http://ca.letsencrypt.org/ca.crt"},
|
||||
})),
|
||||
givenCR: gen.CertificateRequest("cr-1",
|
||||
gen.SetCertificateRequestCSR(testCSR),
|
||||
gen.SetCertificateRequestIssuer(cmmeta.ObjectReference{
|
||||
Name: "issuer-1",
|
||||
Group: certmanager.GroupName,
|
||||
Kind: "Issuer",
|
||||
}),
|
||||
),
|
||||
assertSignedCert: func(t *testing.T, got *x509.Certificate) {
|
||||
assert.Equal(t, []string{"http://ca.letsencrypt.org/ca.crt"}, got.IssuingCertificateURL)
|
||||
},
|
||||
},
|
||||
"when the Issuer has crlDistributionPoints set, it should appear on the signed ca ": {
|
||||
givenCASecret: gen.SecretFrom(gen.Secret("secret-1"), gen.SetSecretNamespace("default"), gen.SetSecretData(secretDataFor(t, rootPK, rootCert))),
|
||||
givenCAIssuer: gen.Issuer("issuer-1", gen.SetIssuerCA(cmapi.CAIssuer{
|
||||
|
||||
@ -129,6 +129,7 @@ func (c *CA) Sign(ctx context.Context, csr *certificatesv1.CertificateSigningReq
|
||||
|
||||
template.CRLDistributionPoints = issuerObj.GetSpec().CA.CRLDistributionPoints
|
||||
template.OCSPServer = issuerObj.GetSpec().CA.OCSPServers
|
||||
template.IssuingCertificateURL = issuerObj.GetSpec().CA.IssuingCertificateURLs
|
||||
|
||||
bundle, err := c.signingFn(caCerts, caKey, template)
|
||||
if err != nil {
|
||||
|
||||
@ -705,6 +705,20 @@ func TestCA_Sign(t *testing.T) {
|
||||
assert.Equal(t, []string{"http://ocsp-v3.example.org"}, got.OCSPServer)
|
||||
},
|
||||
},
|
||||
"when the Issuer has issuingCertificateURLs set, it should appear on the signed ca": {
|
||||
givenCASecret: gen.SecretFrom(gen.Secret("secret-1"), gen.SetSecretNamespace("default"), gen.SetSecretData(secretDataFor(t, rootPK, rootCert))),
|
||||
givenCAIssuer: gen.Issuer("issuer-1", gen.SetIssuerCA(cmapi.CAIssuer{
|
||||
SecretName: "secret-1",
|
||||
IssuingCertificateURLs: []string{"http://ca.example.com/ca.crt"},
|
||||
})),
|
||||
givenCSR: gen.CertificateSigningRequest("cr-1",
|
||||
gen.SetCertificateSigningRequestRequest(testCSR),
|
||||
gen.SetCertificateSigningRequestSignerName("issuers.cert-manager.io/"+gen.DefaultTestNamespace+".issuer-1"),
|
||||
),
|
||||
assertSignedCert: func(t *testing.T, got *x509.Certificate) {
|
||||
assert.Equal(t, []string{"http://ca.example.com/ca.crt"}, got.IssuingCertificateURL)
|
||||
},
|
||||
},
|
||||
"when the Issuer has crlDistributionPoints set, it should appear on the signed ca ": {
|
||||
givenCASecret: gen.SecretFrom(gen.Secret("secret-1"), gen.SetSecretNamespace("default"), gen.SetSecretData(secretDataFor(t, rootPK, rootCert))),
|
||||
givenCAIssuer: gen.Issuer("issuer-1", gen.SetIssuerCA(cmapi.CAIssuer{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user