diff --git a/docs/generated/reference/output/reference/api-docs/index.html b/docs/generated/reference/output/reference/api-docs/index.html index 605c204cb..be63fdbdb 100755 --- a/docs/generated/reference/output/reference/api-docs/index.html +++ b/docs/generated/reference/output/reference/api-docs/index.html @@ -97,6 +97,10 @@ Appears In: DNSNames is a list of subject alt names to be used on the Certificate +isCA
boolean +IsCA will mark this Certificate as valid for signing. This implies that the 'signing' usage is set + + issuerRef
ObjectReference IssuerRef is a reference to the issuer for this certificate. If the 'kind' field is not set, or set to 'Issuer', an Issuer resource with the given name in the same namespace as the Certificate will be used. If the 'kind' field is set to 'ClusterIssuer', a ClusterIssuer with the provided name will be used. The 'name' field in this stanza is required at all times. diff --git a/pkg/apis/certmanager/v1alpha1/types_certificate.go b/pkg/apis/certmanager/v1alpha1/types_certificate.go index bdd5ded01..05201866c 100644 --- a/pkg/apis/certmanager/v1alpha1/types_certificate.go +++ b/pkg/apis/certmanager/v1alpha1/types_certificate.go @@ -68,6 +68,10 @@ type CertificateSpec struct { // The 'name' field in this stanza is required at all times. IssuerRef ObjectReference `json:"issuerRef"` + // IsCA will mark this Certificate as valid for signing. + // This implies that the 'signing' usage is set + IsCA bool `json:"isCA,omitempty"` + // ACME contains configuration specific to ACME Certificates. // Notably, this contains details on how the domain names listed on this // Certificate resource should be 'solved', i.e. mapping HTTP01 and DNS01 diff --git a/pkg/apis/certmanager/validation/certificate_for_issuer.go b/pkg/apis/certmanager/validation/certificate_for_issuer.go index 36ddc9aca..be236b31a 100644 --- a/pkg/apis/certmanager/validation/certificate_for_issuer.go +++ b/pkg/apis/certmanager/validation/certificate_for_issuer.go @@ -55,6 +55,10 @@ func ValidateCertificateForACMEIssuer(crt *v1alpha1.CertificateSpec, issuer *v1a el = append(el, field.Invalid(specPath.Child("keyAlgorithm"), crt.KeyAlgorithm, "ACME key algorithm must be RSA")) } + if crt.IsCA { + el = append(el, field.Invalid(specPath.Child("isCA"), crt.KeyAlgorithm, "ACME does not support CA certificates")) + } + return el } @@ -67,6 +71,10 @@ func ValidateCertificateForCAIssuer(crt *v1alpha1.CertificateSpec, issuer *v1alp func ValidateCertificateForVaultIssuer(crt *v1alpha1.CertificateSpec, issuer *v1alpha1.IssuerSpec, specPath *field.Path) field.ErrorList { el := field.ErrorList{} + if crt.IsCA { + el = append(el, field.Invalid(specPath.Child("isCA"), crt.KeyAlgorithm, "Vault issuer does not currently support CA certificates")) + } + return el } diff --git a/pkg/util/pki/csr.go b/pkg/util/pki/csr.go index ab16bba3d..8e3a577f6 100644 --- a/pkg/util/pki/csr.go +++ b/pkg/util/pki/csr.go @@ -107,11 +107,16 @@ func GenerateTemplate(issuer v1alpha1.GenericIssuer, crt *v1alpha1.Certificate, return nil, err } + keyUsages := x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment + if crt.Spec.IsCA { + keyUsages |= x509.KeyUsageCertSign + } return &x509.Certificate{ Version: 3, BasicConstraintsValid: true, SerialNumber: serialNumber, SignatureAlgorithm: sigAlgo, + IsCA: crt.Spec.IsCA, Subject: pkix.Name{ Organization: []string{defaultOrganization}, CommonName: commonName, @@ -119,7 +124,7 @@ func GenerateTemplate(issuer v1alpha1.GenericIssuer, crt *v1alpha1.Certificate, NotBefore: time.Now(), NotAfter: time.Now().Add(defaultNotAfter), // see http://golang.org/pkg/crypto/x509/#KeyUsage - KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, + KeyUsage: keyUsages, DNSNames: dnsNames, }, nil }