add backwards compatability for using existing common name or organization if x509name ones are not set

add ability to specify more subject attributes for csr

Signed-off-by: Joshua Mathianas <mathianasj@gmail.com>
This commit is contained in:
Joshua Mathianas 2020-01-15 12:28:00 -05:00
parent 5ee9e6c7aa
commit e33e28c4fd
8 changed files with 316 additions and 8 deletions

View File

@ -190,6 +190,46 @@ spec:
- ocsp signing
- microsoft sgc
- netscape sgc
x509Name:
description: Full X509 name specification (https://golang.org/pkg/crypto/x509/pkix/#Name).
If specified, overrides any other name elements below.
type: object
properties:
commonName:
type: string
country:
description: Country/Region
type: array
items:
type: string
locality:
description: City
type: array
items:
type: string
organization:
type: array
items:
type: string
organizationalUnit:
type: array
items:
type: string
postalCode:
type: array
items:
type: string
province:
description: State/Province
type: array
items:
type: string
serialNumber:
type: string
streetAddress:
type: array
items:
type: string
status:
description: CertificateStatus defines the observed state of Certificate
type: object

View File

@ -381,6 +381,46 @@ spec:
- ocsp signing
- microsoft sgc
- netscape sgc
x509Name:
description: Full X509 name specification (https://golang.org/pkg/crypto/x509/pkix/#Name).
If specified, overrides any other name elements below.
type: object
properties:
commonName:
type: string
country:
description: Country/Region
type: array
items:
type: string
locality:
description: City
type: array
items:
type: string
organization:
type: array
items:
type: string
organizationalUnit:
type: array
items:
type: string
postalCode:
type: array
items:
type: string
province:
description: State/Province
type: array
items:
type: string
serialNumber:
type: string
streetAddress:
type: array
items:
type: string
status:
description: CertificateStatus defines the observed state of Certificate
type: object

View File

@ -72,6 +72,11 @@ const (
// A valid Certificate requires at least one of a CommonName, DNSName, or
// URISAN to be valid.
type CertificateSpec struct {
// Full X509 name specification (https://golang.org/pkg/crypto/x509/pkix/#Name).
// If specified, overrides any other name elements below.
// +optional
X509Name *X509DistinguishedName `json:"x509Name,omitempty"`
// CommonName is a common name to be used on the Certificate.
// The CommonName should have a length of 64 characters or fewer to avoid
// generating invalid CSRs.
@ -145,6 +150,21 @@ type CertificateSpec struct {
KeyEncoding KeyEncoding `json:"keyEncoding,omitempty"`
}
type X509DistinguishedName struct {
// Country/Region
Country []string `json:"country,omitempty"`
Organization []string `json:"organization,omitempty"`
OrganizationalUnit []string `json:"organizationalUnit,omitempty"`
// City
Locality []string `json:"locality,omitempty"`
// State/Province
Province []string `json:"province,omitempty"`
StreetAddress []string `json:"streetAddress,omitempty"`
PostalCode []string `json:"postalCode,omitempty"`
SerialNumber string `json:"serialNumber,omitempty"`
CommonName string `json:"commonName,omitempty"`
}
// CertificateStatus defines the observed state of Certificate
type CertificateStatus struct {
// +optional

View File

@ -277,6 +277,11 @@ func (in *CertificateRequestStatus) DeepCopy() *CertificateRequestStatus {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CertificateSpec) DeepCopyInto(out *CertificateSpec) {
*out = *in
if in.X509Name != nil {
in, out := &in.X509Name, &out.X509Name
*out = new(X509DistinguishedName)
(*in).DeepCopyInto(*out)
}
if in.Organization != nil {
in, out := &in.Organization, &out.Organization
*out = make([]string, len(*in))
@ -752,3 +757,54 @@ func (in *VenafiTPP) DeepCopy() *VenafiTPP {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *X509DistinguishedName) DeepCopyInto(out *X509DistinguishedName) {
*out = *in
if in.Country != nil {
in, out := &in.Country, &out.Country
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Organization != nil {
in, out := &in.Organization, &out.Organization
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.OrganizationalUnit != nil {
in, out := &in.OrganizationalUnit, &out.OrganizationalUnit
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Locality != nil {
in, out := &in.Locality, &out.Locality
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Province != nil {
in, out := &in.Province, &out.Province
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.StreetAddress != nil {
in, out := &in.StreetAddress, &out.StreetAddress
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.PostalCode != nil {
in, out := &in.PostalCode, &out.PostalCode
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new X509DistinguishedName.
func (in *X509DistinguishedName) DeepCopy() *X509DistinguishedName {
if in == nil {
return nil
}
out := new(X509DistinguishedName)
in.DeepCopyInto(out)
return out
}

View File

@ -59,6 +59,11 @@ const (
// CertificateSpec defines the desired state of Certificate
type CertificateSpec struct {
// Full X509 name specification (https://golang.org/pkg/crypto/x509/pkix/#Name).
// If specified, overrides any other name elements below.
// +optional
X509Name *X509DistinguishedName `json:"x509Name,omitempty"`
// A valid Certificate requires at least one of a CommonName, DNSName, or
// URISAN to be valid.
@ -135,6 +140,21 @@ type CertificateSpec struct {
KeyEncoding KeyEncoding `json:"keyEncoding,omitempty"`
}
type X509DistinguishedName struct {
// Country/Region
Country []string `json:"country,omitempty"`
Organization []string `json:"organization,omitempty"`
OrganizationalUnit []string `json:"organizationalUnit,omitempty"`
// City
Locality []string `json:"locality,omitempty"`
// State/Province
Province []string `json:"province,omitempty"`
StreetAddress []string `json:"streetAddress,omitempty"`
PostalCode []string `json:"postalCode,omitempty"`
SerialNumber string `json:"serialNumber,omitempty"`
CommonName string `json:"commonName,omitempty"`
}
// CertificateStatus defines the observed state of Certificate
type CertificateStatus struct {
// +optional

View File

@ -311,6 +311,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*v1alpha2.X509DistinguishedName)(nil), (*certmanager.X509DistinguishedName)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha2_X509DistinguishedName_To_certmanager_X509DistinguishedName(a.(*v1alpha2.X509DistinguishedName), b.(*certmanager.X509DistinguishedName), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*certmanager.X509DistinguishedName)(nil), (*v1alpha2.X509DistinguishedName)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_certmanager_X509DistinguishedName_To_v1alpha2_X509DistinguishedName(a.(*certmanager.X509DistinguishedName), b.(*v1alpha2.X509DistinguishedName), scope)
}); err != nil {
return err
}
return nil
}
@ -559,6 +569,7 @@ func Convert_certmanager_CertificateRequestStatus_To_v1alpha2_CertificateRequest
}
func autoConvert_v1alpha2_CertificateSpec_To_certmanager_CertificateSpec(in *v1alpha2.CertificateSpec, out *certmanager.CertificateSpec, s conversion.Scope) error {
out.X509Name = (*certmanager.X509DistinguishedName)(unsafe.Pointer(in.X509Name))
out.CommonName = in.CommonName
out.Organization = *(*[]string)(unsafe.Pointer(&in.Organization))
out.Duration = (*v1.Duration)(unsafe.Pointer(in.Duration))
@ -585,6 +596,7 @@ func Convert_v1alpha2_CertificateSpec_To_certmanager_CertificateSpec(in *v1alpha
}
func autoConvert_certmanager_CertificateSpec_To_v1alpha2_CertificateSpec(in *certmanager.CertificateSpec, out *v1alpha2.CertificateSpec, s conversion.Scope) error {
out.X509Name = (*v1alpha2.X509DistinguishedName)(unsafe.Pointer(in.X509Name))
out.CommonName = in.CommonName
out.Organization = *(*[]string)(unsafe.Pointer(&in.Organization))
out.Duration = (*v1.Duration)(unsafe.Pointer(in.Duration))
@ -1057,3 +1069,39 @@ func autoConvert_certmanager_VenafiTPP_To_v1alpha2_VenafiTPP(in *certmanager.Ven
func Convert_certmanager_VenafiTPP_To_v1alpha2_VenafiTPP(in *certmanager.VenafiTPP, out *v1alpha2.VenafiTPP, s conversion.Scope) error {
return autoConvert_certmanager_VenafiTPP_To_v1alpha2_VenafiTPP(in, out, s)
}
func autoConvert_v1alpha2_X509DistinguishedName_To_certmanager_X509DistinguishedName(in *v1alpha2.X509DistinguishedName, out *certmanager.X509DistinguishedName, s conversion.Scope) error {
out.Country = *(*[]string)(unsafe.Pointer(&in.Country))
out.Organization = *(*[]string)(unsafe.Pointer(&in.Organization))
out.OrganizationalUnit = *(*[]string)(unsafe.Pointer(&in.OrganizationalUnit))
out.Locality = *(*[]string)(unsafe.Pointer(&in.Locality))
out.Province = *(*[]string)(unsafe.Pointer(&in.Province))
out.StreetAddress = *(*[]string)(unsafe.Pointer(&in.StreetAddress))
out.PostalCode = *(*[]string)(unsafe.Pointer(&in.PostalCode))
out.SerialNumber = in.SerialNumber
out.CommonName = in.CommonName
return nil
}
// Convert_v1alpha2_X509DistinguishedName_To_certmanager_X509DistinguishedName is an autogenerated conversion function.
func Convert_v1alpha2_X509DistinguishedName_To_certmanager_X509DistinguishedName(in *v1alpha2.X509DistinguishedName, out *certmanager.X509DistinguishedName, s conversion.Scope) error {
return autoConvert_v1alpha2_X509DistinguishedName_To_certmanager_X509DistinguishedName(in, out, s)
}
func autoConvert_certmanager_X509DistinguishedName_To_v1alpha2_X509DistinguishedName(in *certmanager.X509DistinguishedName, out *v1alpha2.X509DistinguishedName, s conversion.Scope) error {
out.Country = *(*[]string)(unsafe.Pointer(&in.Country))
out.Organization = *(*[]string)(unsafe.Pointer(&in.Organization))
out.OrganizationalUnit = *(*[]string)(unsafe.Pointer(&in.OrganizationalUnit))
out.Locality = *(*[]string)(unsafe.Pointer(&in.Locality))
out.Province = *(*[]string)(unsafe.Pointer(&in.Province))
out.StreetAddress = *(*[]string)(unsafe.Pointer(&in.StreetAddress))
out.PostalCode = *(*[]string)(unsafe.Pointer(&in.PostalCode))
out.SerialNumber = in.SerialNumber
out.CommonName = in.CommonName
return nil
}
// Convert_certmanager_X509DistinguishedName_To_v1alpha2_X509DistinguishedName is an autogenerated conversion function.
func Convert_certmanager_X509DistinguishedName_To_v1alpha2_X509DistinguishedName(in *certmanager.X509DistinguishedName, out *v1alpha2.X509DistinguishedName, s conversion.Scope) error {
return autoConvert_certmanager_X509DistinguishedName_To_v1alpha2_X509DistinguishedName(in, out, s)
}

View File

@ -277,6 +277,11 @@ func (in *CertificateRequestStatus) DeepCopy() *CertificateRequestStatus {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CertificateSpec) DeepCopyInto(out *CertificateSpec) {
*out = *in
if in.X509Name != nil {
in, out := &in.X509Name, &out.X509Name
*out = new(X509DistinguishedName)
(*in).DeepCopyInto(*out)
}
if in.Organization != nil {
in, out := &in.Organization, &out.Organization
*out = make([]string, len(*in))
@ -752,3 +757,54 @@ func (in *VenafiTPP) DeepCopy() *VenafiTPP {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *X509DistinguishedName) DeepCopyInto(out *X509DistinguishedName) {
*out = *in
if in.Country != nil {
in, out := &in.Country, &out.Country
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Organization != nil {
in, out := &in.Organization, &out.Organization
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.OrganizationalUnit != nil {
in, out := &in.OrganizationalUnit, &out.OrganizationalUnit
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Locality != nil {
in, out := &in.Locality, &out.Locality
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Province != nil {
in, out := &in.Province, &out.Province
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.StreetAddress != nil {
in, out := &in.StreetAddress, &out.StreetAddress
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.PostalCode != nil {
in, out := &in.PostalCode, &out.PostalCode
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new X509DistinguishedName.
func (in *X509DistinguishedName) DeepCopy() *X509DistinguishedName {
if in == nil {
return nil
}
out := new(X509DistinguishedName)
in.DeepCopyInto(out)
return out
}

View File

@ -124,14 +124,28 @@ Outer:
const defaultOrganization = "cert-manager"
// OrganizationForCertificate will return the Organization to set for the
// Certificate resource.
// Certificate resource or if X509Name.Organization is set will return that
// If an Organization is not specifically set, a default will be used.
func OrganizationForCertificate(crt *v1alpha2.Certificate) []string {
if len(crt.Spec.Organization) == 0 {
if len(crt.Spec.Organization) == 0 && len(crt.Spec.X509Name.Organization) == 0 {
return []string{defaultOrganization}
}
return crt.Spec.Organization
if len(crt.Spec.X509Name.Organization) == 0 {
return crt.Spec.Organization
}
return crt.Spec.X509Name.Organization
}
// CommonNameForCertificate will return the CommonName to set for the
// Certificate resource or if X509Name.CommonName is set will return that
func CommonNameForCertificate(crt *v1alpha2.Certificate) string {
if len(crt.Spec.X509Name.CommonName) == 0 {
return crt.Spec.CommonName
}
return crt.Spec.X509Name.CommonName
}
var serialNumberLimit = new(big.Int).Lsh(big.NewInt(1), 128)
@ -164,9 +178,16 @@ func BuildKeyUsages(usages []v1alpha2.KeyUsage, isCA bool) (ku x509.KeyUsage, ek
// The CSR will not be signed, and should be passed to either EncodeCSR or
// to the x509.CreateCertificateRequest function.
func GenerateCSR(crt *v1alpha2.Certificate) (*x509.CertificateRequest, error) {
commonName := crt.Spec.CommonName
iPAddresses := IPAddressesForCertificate(crt)
country := crt.Spec.X509Name.Country
organization := OrganizationForCertificate(crt)
organizationalUnit := crt.Spec.X509Name.OrganizationalUnit
locality := crt.Spec.X509Name.Locality
province := crt.Spec.X509Name.Province
streetAddress := crt.Spec.X509Name.StreetAddress
postalCode := crt.Spec.X509Name.PostalCode
serialNumber := crt.Spec.X509Name.SerialNumber
commonName := CommonNameForCertificate(crt)
iPAddresses := IPAddressesForCertificate(crt)
dnsNames, err := DNSNamesForCertificate(crt)
if err != nil {
@ -192,8 +213,15 @@ func GenerateCSR(crt *v1alpha2.Certificate) (*x509.CertificateRequest, error) {
SignatureAlgorithm: sigAlgo,
PublicKeyAlgorithm: pubKeyAlgo,
Subject: pkix.Name{
Organization: organization,
CommonName: commonName,
Country: country,
Organization: organization,
OrganizationalUnit: organizationalUnit,
Locality: locality,
Province: province,
StreetAddress: streetAddress,
PostalCode: postalCode,
SerialNumber: serialNumber,
CommonName: commonName,
},
DNSNames: dnsNames,
IPAddresses: iPAddresses,
@ -208,7 +236,7 @@ func GenerateCSR(crt *v1alpha2.Certificate) (*x509.CertificateRequest, error) {
// generated by GenerateCSR.
// The PublicKey field must be populated by the caller.
func GenerateTemplate(crt *v1alpha2.Certificate) (*x509.Certificate, error) {
commonName := crt.Spec.CommonName
commonName := CommonNameForCertificate(crt)
dnsNames := crt.Spec.DNSNames
ipAddresses := IPAddressesForCertificate(crt)
organization := OrganizationForCertificate(crt)