Skip to content

Commit

Permalink
Add Locality, Province, and other fields to roles (will be set as-is)
Browse files Browse the repository at this point in the history
and CA generation/signing endpoints.
  • Loading branch information
jefferai committed Feb 16, 2018
1 parent ec8e9e0 commit ce463a5
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 31 deletions.
7 changes: 7 additions & 0 deletions builtin/logical/pki/ca_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
43 changes: 14 additions & 29 deletions builtin/logical/pki/cert_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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[:],
Expand Down
42 changes: 42 additions & 0 deletions builtin/logical/pki/fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
49 changes: 47 additions & 2 deletions builtin/logical/pki/path_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.`,
},

Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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"`
Expand Down Expand Up @@ -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,
}
Expand Down
7 changes: 7 additions & 0 deletions builtin/logical/pki/path_root.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit ce463a5

Please sign in to comment.