From ce463a563f4af467a489ddd89900f736c53509e8 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Fri, 16 Feb 2018 11:06:37 -0500 Subject: [PATCH] Add Locality, Province, and other fields to roles (will be set as-is) and CA generation/signing endpoints. --- builtin/logical/pki/ca_util.go | 7 +++++ builtin/logical/pki/cert_util.go | 43 +++++++++------------------ builtin/logical/pki/fields.go | 42 ++++++++++++++++++++++++++ builtin/logical/pki/path_roles.go | 49 +++++++++++++++++++++++++++++-- builtin/logical/pki/path_root.go | 7 +++++ 5 files changed, 117 insertions(+), 31 deletions(-) diff --git a/builtin/logical/pki/ca_util.go b/builtin/logical/pki/ca_util.go index f0024a84cc57..384f440d8bf5 100644 --- a/builtin/logical/pki/ca_util.go +++ b/builtin/logical/pki/ca_util.go @@ -36,6 +36,13 @@ func (b *backend) getGenerationParams( AllowAnyName: true, AllowIPSANs: true, EnforceHostnames: false, + OU: data.Get("ou").([]string), + Organization: data.Get("organization").([]string), + Country: data.Get("country").([]string), + Locality: data.Get("locality").([]string), + Province: data.Get("province").([]string), + StreetAddress: data.Get("street_address").([]string), + PostalCode: data.Get("postal_code").([]string), } if role.KeyType == "rsa" && role.KeyBits < 2048 { diff --git a/builtin/logical/pki/cert_util.go b/builtin/logical/pki/cert_util.go index 85d6ede1a200..4e548b026670 100644 --- a/builtin/logical/pki/cert_util.go +++ b/builtin/logical/pki/cert_util.go @@ -52,9 +52,7 @@ type dataBundle struct { } type creationParameters struct { - CommonName string - OU []string - Organization []string + Subject pkix.Name DNSNames []string EmailAddresses []string IPAddresses []net.IP @@ -839,10 +837,15 @@ func generateCreationBundle(b *backend, data *dataBundle) error { } } - // Set OU (organizationalUnit) values if specified in the role - ou := strutil.RemoveDuplicates(data.role.OU, false) - // Set O (organization) values if specified in the role - organization := strutil.RemoveDuplicates(data.role.Organization, false) + subject := pkix.Name{ + Country: strutil.RemoveDuplicates(data.role.Country, false), + Organization: strutil.RemoveDuplicates(data.role.Organization, false), + OrganizationalUnit: strutil.RemoveDuplicates(data.role.OU, false), + Locality: strutil.RemoveDuplicates(data.role.Locality, false), + Province: strutil.RemoveDuplicates(data.role.Province, false), + StreetAddress: strutil.RemoveDuplicates(data.role.StreetAddress, false), + PostalCode: strutil.RemoveDuplicates(data.role.PostalCode, false), + } // Get the TTL and verify it against the max allowed var ttl time.Duration @@ -909,9 +912,7 @@ func generateCreationBundle(b *backend, data *dataBundle) error { } data.params = &creationParameters{ - CommonName: cn, - OU: ou, - Organization: organization, + Subject: subject, DNSNames: dnsNames, EmailAddresses: emailAddresses, IPAddresses: ipAddresses, @@ -1001,19 +1002,13 @@ func createCertificate(data *dataBundle) (*certutil.ParsedCertBundle, error) { return nil, errutil.InternalError{Err: fmt.Sprintf("error getting subject key ID: %s", err)} } - subject := pkix.Name{ - CommonName: data.params.CommonName, - OrganizationalUnit: data.params.OU, - Organization: data.params.Organization, - } - certTemplate := &x509.Certificate{ SerialNumber: serialNumber, - Subject: subject, NotBefore: time.Now().Add(-30 * time.Second), NotAfter: data.params.NotAfter, IsCA: false, SubjectKeyId: subjKeyID, + Subject: data.params.Subject, DNSNames: data.params.DNSNames, EmailAddresses: data.params.EmailAddresses, IPAddresses: data.params.IPAddresses, @@ -1119,12 +1114,8 @@ func createCSR(data *dataBundle) (*certutil.ParsedCSRBundle, error) { } // Like many root CAs, other information is ignored - subject := pkix.Name{ - CommonName: data.params.CommonName, - } - csrTemplate := &x509.CertificateRequest{ - Subject: subject, + Subject: data.params.Subject, DNSNames: data.params.DNSNames, EmailAddresses: data.params.EmailAddresses, IPAddresses: data.params.IPAddresses, @@ -1189,15 +1180,9 @@ func signCertificate(data *dataBundle) (*certutil.ParsedCertBundle, error) { caCert := data.signingBundle.Certificate - subject := pkix.Name{ - CommonName: data.params.CommonName, - OrganizationalUnit: data.params.OU, - Organization: data.params.Organization, - } - certTemplate := &x509.Certificate{ SerialNumber: serialNumber, - Subject: subject, + Subject: data.params.Subject, NotBefore: time.Now().Add(-30 * time.Second), NotAfter: data.params.NotAfter, SubjectKeyId: subjKeyID[:], diff --git a/builtin/logical/pki/fields.go b/builtin/logical/pki/fields.go index 5ef83060cc37..a236a1d05389 100644 --- a/builtin/logical/pki/fields.go +++ b/builtin/logical/pki/fields.go @@ -120,6 +120,48 @@ a CA cert or signing a CA cert, not when generating a CSR for an intermediate CA.`, } + fields["ou"] = &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, OU (OrganizationalUnit) will be set to +this value.`, + } + + fields["organization"] = &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, O (Organization) will be set to +this value.`, + } + + fields["country"] = &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, Country will be set to +this value.`, + } + + fields["locality"] = &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, Locality will be set to +this value.`, + } + + fields["province"] = &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, Province will be set to +this value.`, + } + + fields["street_address"] = &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, Street Address will be set to +this value.`, + } + + fields["postal_code"] = &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, Postal Code will be set to +this value.`, + } + return fields } diff --git a/builtin/logical/pki/path_roles.go b/builtin/logical/pki/path_roles.go index 1ed1774fe40f..be33be9298c6 100644 --- a/builtin/logical/pki/path_roles.go +++ b/builtin/logical/pki/path_roles.go @@ -193,13 +193,43 @@ include the Common Name (cn). Defaults to true.`, "ou": &framework.FieldSchema{ Type: framework.TypeCommaStringSlice, - Description: `If set, the OU (OrganizationalUnit) will be set to + Description: `If set, OU (OrganizationalUnit) will be set to this value in certificates issued by this role.`, }, "organization": &framework.FieldSchema{ Type: framework.TypeCommaStringSlice, - Description: `If set, the O (Organization) will be set to + Description: `If set, O (Organization) will be set to +this value in certificates issued by this role.`, + }, + + "country": &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, Country will be set to +this value in certificates issued by this role.`, + }, + + "locality": &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, Locality will be set to +this value in certificates issued by this role.`, + }, + + "province": &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, Province will be set to +this value in certificates issued by this role.`, + }, + + "street_address": &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, Street Address will be set to +this value in certificates issued by this role.`, + }, + + "postal_code": &framework.FieldSchema{ + Type: framework.TypeCommaStringSlice, + Description: `If set, Postal Code will be set to this value in certificates issued by this role.`, }, @@ -420,6 +450,11 @@ func (b *backend) pathRoleCreate(ctx context.Context, req *logical.Request, data KeyUsage: data.Get("key_usage").([]string), OU: data.Get("ou").([]string), Organization: data.Get("organization").([]string), + Country: data.Get("country").([]string), + Locality: data.Get("locality").([]string), + Province: data.Get("province").([]string), + StreetAddress: data.Get("street_address").([]string), + PostalCode: data.Get("postal_code").([]string), GenerateLease: new(bool), NoStore: data.Get("no_store").(bool), RequireCN: data.Get("require_cn").(bool), @@ -560,6 +595,11 @@ type roleEntry struct { OU []string `json:"ou_list" mapstructure:"ou"` OrganizationOld string `json:"organization,omitempty"` Organization []string `json:"organization_list" mapstructure:"organization"` + Country []string `json:"country" mapstructure:"country"` + Locality []string `json:"locality" mapstructure:"locality"` + Province []string `json:"province" mapstructure:"province"` + StreetAddress []string `json:"street_address" mapstructure:"street_address"` + PostalCode []string `json:"postal_code" mapstructure:"postal_code"` GenerateLease *bool `json:"generate_lease,omitempty"` NoStore bool `json:"no_store" mapstructure:"no_store"` RequireCN bool `json:"require_cn" mapstructure:"require_cn"` @@ -593,6 +633,11 @@ func (r *roleEntry) ToResponseData() map[string]interface{} { "key_usage": r.KeyUsage, "ou": r.OU, "organization": r.Organization, + "country": r.Country, + "locality": r.Locality, + "province": r.Province, + "street_address": r.StreetAddress, + "postal_code": r.PostalCode, "no_store": r.NoStore, "allowed_other_sans": r.AllowedOtherSANs, } diff --git a/builtin/logical/pki/path_root.go b/builtin/logical/pki/path_root.go index 57ca3e172b0e..ce89fd2bfe8f 100644 --- a/builtin/logical/pki/path_root.go +++ b/builtin/logical/pki/path_root.go @@ -252,6 +252,13 @@ func (b *backend) pathCASignIntermediate(ctx context.Context, req *logical.Reque } role := &roleEntry{ + OU: data.Get("ou").([]string), + Organization: data.Get("organization").([]string), + Country: data.Get("country").([]string), + Locality: data.Get("locality").([]string), + Province: data.Get("province").([]string), + StreetAddress: data.Get("street_address").([]string), + PostalCode: data.Get("postal_code").([]string), TTL: (time.Duration(data.Get("ttl").(int)) * time.Second).String(), AllowLocalhost: true, AllowAnyName: true,