mirror of
https://github.com/hashicorp/vault.git
synced 2026-06-08 16:24:51 -04:00
Allow roles to specify whether CSR SANs should be used instead of (#2489)
request values. Fix up some documentation. Fixes #2451 Fixes #2488
This commit is contained in:
parent
38d70b7eb7
commit
688104e69a
4 changed files with 69 additions and 27 deletions
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ func (b *backend) pathSignVerbatim(
|
|||
EnforceHostnames: false,
|
||||
KeyType: "any",
|
||||
UseCSRCommonName: true,
|
||||
UseCSRSANs: true,
|
||||
}
|
||||
|
||||
return b.pathIssueSignCert(req, data, role, true, true)
|
||||
|
|
|
|||
|
|
@ -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: "",
|
||||
|
|
@ -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),
|
||||
|
|
@ -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"`
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue