Custom extended key usage for PKI. (#4667)

Custom extended key usage for PKI
This commit is contained in:
Alex Ionescu 2018-06-01 08:13:54 -05:00 committed by Jeff Mitchell
parent 1d4d302bfa
commit 33ec066278
3 changed files with 38 additions and 1 deletions

View File

@ -62,6 +62,7 @@ type creationParameters struct {
NotAfter time.Time
KeyUsage x509.KeyUsage
ExtKeyUsage certExtKeyUsage
ExtKeyUsageOIDs []string
PolicyIdentifiers []string
BasicConstraintsValidForNonCA bool
@ -918,6 +919,7 @@ func generateCreationBundle(b *backend, data *dataBundle) error {
NotAfter: notAfter,
KeyUsage: x509.KeyUsage(parseKeyUsages(data.role.KeyUsage)),
ExtKeyUsage: extUsage,
ExtKeyUsageOIDs: data.role.ExtKeyUsageOIDs,
PolicyIdentifiers: data.role.PolicyIdentifiers,
BasicConstraintsValidForNonCA: data.role.BasicConstraintsValidForNonCA,
}
@ -989,6 +991,16 @@ func addPolicyIdentifiers(data *dataBundle, certTemplate *x509.Certificate) {
}
}
// addExtKeyUsageOids adds custom extended key usage OIDs to certificate
func addExtKeyUsageOids(data *dataBundle, certTemplate *x509.Certificate) {
for _, oidstr := range data.params.ExtKeyUsageOIDs {
oid, err := stringToOid(oidstr)
if err == nil {
certTemplate.UnknownExtKeyUsage = append(certTemplate.UnknownExtKeyUsage, oid)
}
}
}
// Performs the heavy lifting of creating a certificate. Returns
// a fully-filled-in ParsedCertBundle.
func createCertificate(data *dataBundle) (*certutil.ParsedCertBundle, error) {
@ -1045,6 +1057,8 @@ func createCertificate(data *dataBundle) (*certutil.ParsedCertBundle, error) {
addKeyUsages(data, certTemplate)
addExtKeyUsageOids(data, certTemplate)
certTemplate.IssuingCertificateURL = data.params.URLs.IssuingCertificates
certTemplate.CRLDistributionPoints = data.params.URLs.CRLDistributionPoints
certTemplate.OCSPServer = data.params.URLs.OCSPServers
@ -1254,6 +1268,8 @@ func signCertificate(data *dataBundle) (*certutil.ParsedCertBundle, error) {
addKeyUsages(data, certTemplate)
addExtKeyUsageOids(data, certTemplate)
var certBytes []byte
certTemplate.IssuingCertificateURL = data.params.URLs.IssuingCertificates

View File

@ -166,6 +166,11 @@ To remove all key usages from being set, set
this value to an empty list.`,
},
"ext_key_usage_oids": &framework.FieldSchema{
Type: framework.TypeCommaStringSlice,
Description: `A comma-separated string or list of extended key usage oids.`,
},
"use_csr_common_name": &framework.FieldSchema{
Type: framework.TypeBool,
Default: true,
@ -451,6 +456,7 @@ func (b *backend) pathRoleCreate(ctx context.Context, req *logical.Request, data
UseCSRCommonName: data.Get("use_csr_common_name").(bool),
UseCSRSANs: data.Get("use_csr_sans").(bool),
KeyUsage: data.Get("key_usage").([]string),
ExtKeyUsageOIDs: data.Get("ext_key_usage_oids").([]string),
OU: data.Get("ou").([]string),
Organization: data.Get("organization").([]string),
Country: data.Get("country").([]string),
@ -495,6 +501,15 @@ func (b *backend) pathRoleCreate(ctx context.Context, req *logical.Request, data
return errResp, nil
}
if len(entry.ExtKeyUsageOIDs) > 0 {
for _, oidstr := range entry.ExtKeyUsageOIDs {
_, err := stringToOid(oidstr)
if err != nil {
return logical.ErrorResponse(fmt.Sprintf("%q could not be parsed as a valid oid for an extended key usage", oidstr)), nil
}
}
}
if len(entry.PolicyIdentifiers) > 0 {
for _, oidstr := range entry.PolicyIdentifiers {
_, err := stringToOid(oidstr)
@ -588,6 +603,7 @@ type roleEntry struct {
RequireCN bool `json:"require_cn" mapstructure:"require_cn"`
AllowedOtherSANs []string `json:"allowed_other_sans" mapstructure:"allowed_other_sans"`
PolicyIdentifiers []string `json:"policy_identifiers" mapstructure:"policy_identifiers"`
ExtKeyUsageOIDs []string `json:"ext_key_usage_oids" mapstructure:"ext_key_usage_oids"`
BasicConstraintsValidForNonCA bool `json:"basic_constraints_valid_for_non_ca" mapstructure:"basic_constraints_valid_for_non_ca"`
// Used internally for signing intermediates
@ -616,6 +632,7 @@ func (r *roleEntry) ToResponseData() map[string]interface{} {
"key_type": r.KeyType,
"key_bits": r.KeyBits,
"key_usage": r.KeyUsage,
"ext_key_usage_oids": r.ExtKeyUsageOIDs,
"ou": r.OU,
"organization": r.Organization,
"country": r.Country,

View File

@ -55,6 +55,10 @@ export default DS.Model.extend({
defaultValue: 'DigitalSignature,KeyAgreement,KeyEncipherment',
editType: 'stringArray',
}),
extKeyUsageOids: attr({
label: 'Custom extended key usage OIDs',
editType: 'stringArray',
}),
requireCn: attr('boolean', {
label: 'Require common name',
defaultValue: true,
@ -223,7 +227,7 @@ export default DS.Model.extend({
'allowedDomains',
],
},
{ 'Extended Key Usage': ['serverFlag', 'clientFlag', 'codeSigningFlag', 'emailProtectionFlag'] },
{ 'Extended Key Usage': ['serverFlag', 'clientFlag', 'codeSigningFlag', 'emailProtectionFlag', 'extKeyUsageOids'] },
{
Advanced: ['generateLease', 'noStore', 'basicConstraintsValidForNonCA', 'policyIdentifiers'],
},