Skip to content

Commit

Permalink
Allow roles to specify whether CSR SANs should be used instead of (#2489
Browse files Browse the repository at this point in the history
)

request values. Fix up some documentation.

Fixes #2451
Fixes #2488
  • Loading branch information
jefferai authored Mar 15, 2017
1 parent 38d70b7 commit 688104e
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 27 deletions.
66 changes: 40 additions & 26 deletions builtin/logical/pki/cert_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,10 +563,8 @@ func generateCreationBundle(b *backend,
// Get the common name
var cn string
{
if csr != nil {
if role.UseCSRCommonName {
cn = csr.Subject.CommonName
}
if csr != nil && role.UseCSRCommonName {
cn = csr.Subject.CommonName
}
if cn == "" {
cn = data.Get("common_name").(string)
Expand Down Expand Up @@ -596,6 +594,11 @@ func generateCreationBundle(b *backend,
dnsNames := []string{}
emailAddresses := []string{}
{
if csr != nil && role.UseCSRSANs {
dnsNames = csr.DNSNames
emailAddresses = csr.EmailAddresses
}

if !data.Get("exclude_cn_from_sans").(bool) {
if strings.Contains(cn, "@") {
// Note: emails are not disallowed if the role's email protection
Expand All @@ -608,15 +611,18 @@ func generateCreationBundle(b *backend,
dnsNames = append(dnsNames, cn)
}
}
cnAltInt, ok := data.GetOk("alt_names")
if ok {
cnAlt := cnAltInt.(string)
if len(cnAlt) != 0 {
for _, v := range strings.Split(cnAlt, ",") {
if strings.Contains(v, "@") {
emailAddresses = append(emailAddresses, v)
} else {
dnsNames = append(dnsNames, v)

if csr == nil || !role.UseCSRSANs {
cnAltInt, ok := data.GetOk("alt_names")
if ok {
cnAlt := cnAltInt.(string)
if len(cnAlt) != 0 {
for _, v := range strings.Split(cnAlt, ",") {
if strings.Contains(v, "@") {
emailAddresses = append(emailAddresses, v)
} else {
dnsNames = append(dnsNames, v)
}
}
}
}
Expand Down Expand Up @@ -646,21 +652,29 @@ func generateCreationBundle(b *backend,
ipAddresses := []net.IP{}
var ipAltInt interface{}
{
ipAltInt, ok = data.GetOk("ip_sans")
if ok {
ipAlt := ipAltInt.(string)
if len(ipAlt) != 0 {
if !role.AllowIPSANs {
return nil, errutil.UserError{Err: fmt.Sprintf(
"IP Subject Alternative Names are not allowed in this role, but was provided %s", ipAlt)}
}
for _, v := range strings.Split(ipAlt, ",") {
parsedIP := net.ParseIP(v)
if parsedIP == nil {
if csr != nil && role.UseCSRSANs {
if !role.AllowIPSANs {
return nil, errutil.UserError{Err: fmt.Sprintf(
"IP Subject Alternative Names are not allowed in this role, but was provided some via CSR")}
}
ipAddresses = csr.IPAddresses
} else {
ipAltInt, ok = data.GetOk("ip_sans")
if ok {
ipAlt := ipAltInt.(string)
if len(ipAlt) != 0 {
if !role.AllowIPSANs {
return nil, errutil.UserError{Err: fmt.Sprintf(
"the value '%s' is not a valid IP address", v)}
"IP Subject Alternative Names are not allowed in this role, but was provided %s", ipAlt)}
}
for _, v := range strings.Split(ipAlt, ",") {
parsedIP := net.ParseIP(v)
if parsedIP == nil {
return nil, errutil.UserError{Err: fmt.Sprintf(
"the value '%s' is not a valid IP address", v)}
}
ipAddresses = append(ipAddresses, parsedIP)
}
ipAddresses = append(ipAddresses, parsedIP)
}
}
}
Expand Down
1 change: 1 addition & 0 deletions builtin/logical/pki/path_issue_sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ func (b *backend) pathSignVerbatim(
EnforceHostnames: false,
KeyType: "any",
UseCSRCommonName: true,
UseCSRSANs: true,
}

return b.pathIssueSignCert(req, data, role, true, true)
Expand Down
10 changes: 10 additions & 0 deletions builtin/logical/pki/path_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ does *not* include any requested Subject Alternative
Names. Defaults to true.`,
},

"use_csr_sans": &framework.FieldSchema{
Type: framework.TypeBool,
Default: true,
Description: `If set, when used with a signing profile,
the SANs in the CSR will be used. This does *not*
include the Common Name (cn). Defaults to true.`,
},

"ou": &framework.FieldSchema{
Type: framework.TypeString,
Default: "",
Expand Down Expand Up @@ -371,6 +379,7 @@ func (b *backend) pathRoleCreate(
KeyType: data.Get("key_type").(string),
KeyBits: data.Get("key_bits").(int),
UseCSRCommonName: data.Get("use_csr_common_name").(bool),
UseCSRSANs: data.Get("use_csr_sans").(bool),
KeyUsage: data.Get("key_usage").(string),
OU: data.Get("ou").(string),
Organization: data.Get("organization").(string),
Expand Down Expand Up @@ -487,6 +496,7 @@ type roleEntry struct {
CodeSigningFlag bool `json:"code_signing_flag" structs:"code_signing_flag" mapstructure:"code_signing_flag"`
EmailProtectionFlag bool `json:"email_protection_flag" structs:"email_protection_flag" mapstructure:"email_protection_flag"`
UseCSRCommonName bool `json:"use_csr_common_name" structs:"use_csr_common_name" mapstructure:"use_csr_common_name"`
UseCSRSANs bool `json:"use_csr_sans" structs:"use_csr_sans" mapstructure:"use_csr_sans"`
KeyType string `json:"key_type" structs:"key_type" mapstructure:"key_type"`
KeyBits int `json:"key_bits" structs:"key_bits" mapstructure:"key_bits"`
MaxPathLength *int `json:",omitempty" structs:"max_path_length,omitempty" mapstructure:"max_path_length"`
Expand Down
19 changes: 18 additions & 1 deletion website/source/docs/secrets/pki/index.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -1221,7 +1221,24 @@ subpath for interactive help output.
<span class="param-flags">optional</span>
If set, when used with the CSR signing endpoint, the common name in the
CSR will be used instead of taken from the JSON data. This does `not`
include any requested SANs in the CSR. Defaults to `false`.
include any requested SANs in the CSR; use `use_csr_sans` for that.
Defaults to `true`.
</li>
<li>
<span class="param">use_csr_sans</span>
<span class="param-flags">optional</span>
If set, when used with the CSR signing endpoint, the subject alternate
names in the CSR will be used instead of taken from the JSON data. This
does `not` include the common name in the CSR; use
`use_csr_common_name` for that. Defaults to `true`.
</li>
<li>
<span class="param">allow_token_displayname</span>
<span class="param-flags">optional</span>
If set, the display name of the token used when requesting a
certificate will be considered to be a valid host name by the role.
Normal verification behavior applies with respect to subdomains and
wildcards.
</li>
<li>
<span class="param">ou</span>
Expand Down

0 comments on commit 688104e

Please sign in to comment.