mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-11-04 04:28:08 +00:00 
			
		
		
		
	Don't show field names when not needed
This commit is contained in:
		@@ -37,8 +37,9 @@ func Backend() *framework.Backend {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		Paths: []*framework.Path{
 | 
							Paths: []*framework.Path{
 | 
				
			||||||
			pathRoles(&b),
 | 
								pathRoles(&b),
 | 
				
			||||||
			pathGenerateCA(&b),
 | 
								pathGenerateRootCA(&b),
 | 
				
			||||||
			pathSignCA(&b),
 | 
								pathGenerateIntermediateCA(&b),
 | 
				
			||||||
 | 
								pathSignIntermediateCA(&b),
 | 
				
			||||||
			pathSetCA(&b),
 | 
								pathSetCA(&b),
 | 
				
			||||||
			pathConfigCA(&b),
 | 
								pathConfigCA(&b),
 | 
				
			||||||
			pathConfigCRL(&b),
 | 
								pathConfigCRL(&b),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -170,10 +170,16 @@ func validateCommonNames(req *logical.Request, commonNames []string, role *roleE
 | 
				
			|||||||
func generateCert(b *backend,
 | 
					func generateCert(b *backend,
 | 
				
			||||||
	role *roleEntry,
 | 
						role *roleEntry,
 | 
				
			||||||
	signingBundle *certutil.ParsedCertBundle,
 | 
						signingBundle *certutil.ParsedCertBundle,
 | 
				
			||||||
 | 
						isCA bool,
 | 
				
			||||||
	req *logical.Request,
 | 
						req *logical.Request,
 | 
				
			||||||
	data *framework.FieldData) (*certutil.ParsedCertBundle, error) {
 | 
						data *framework.FieldData) (*certutil.ParsedCertBundle, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	creationBundle, err := generateCreationBundle(b, role, signingBundle, req, data)
 | 
						_, ok := data.GetOk("common_name")
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return nil, certutil.UserError{Err: "The common_name field is required"}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						creationBundle, err := generateCreationBundle(b, role, signingBundle, isCA, req, data)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -189,10 +195,11 @@ func generateCert(b *backend,
 | 
				
			|||||||
func generateCSR(b *backend,
 | 
					func generateCSR(b *backend,
 | 
				
			||||||
	role *roleEntry,
 | 
						role *roleEntry,
 | 
				
			||||||
	signingBundle *certutil.ParsedCertBundle,
 | 
						signingBundle *certutil.ParsedCertBundle,
 | 
				
			||||||
 | 
						isCA bool,
 | 
				
			||||||
	req *logical.Request,
 | 
						req *logical.Request,
 | 
				
			||||||
	data *framework.FieldData) (*certutil.ParsedCSRBundle, error) {
 | 
						data *framework.FieldData) (*certutil.ParsedCSRBundle, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	creationBundle, err := generateCreationBundle(b, role, signingBundle, req, data)
 | 
						creationBundle, err := generateCreationBundle(b, role, signingBundle, isCA, req, data)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -209,10 +216,16 @@ func signCert(b *backend,
 | 
				
			|||||||
	role *roleEntry,
 | 
						role *roleEntry,
 | 
				
			||||||
	signingBundle *certutil.ParsedCertBundle,
 | 
						signingBundle *certutil.ParsedCertBundle,
 | 
				
			||||||
	csr *x509.CertificateRequest,
 | 
						csr *x509.CertificateRequest,
 | 
				
			||||||
 | 
						isCA bool,
 | 
				
			||||||
	req *logical.Request,
 | 
						req *logical.Request,
 | 
				
			||||||
	data *framework.FieldData) (*certutil.ParsedCertBundle, error) {
 | 
						data *framework.FieldData) (*certutil.ParsedCertBundle, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	creationBundle, err := generateCreationBundle(b, role, signingBundle, req, data)
 | 
						_, ok := data.GetOk("common_name")
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return nil, certutil.UserError{Err: "The common_name field is required"}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						creationBundle, err := generateCreationBundle(b, role, signingBundle, isCA, req, data)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -228,29 +241,34 @@ func signCert(b *backend,
 | 
				
			|||||||
func generateCreationBundle(b *backend,
 | 
					func generateCreationBundle(b *backend,
 | 
				
			||||||
	role *roleEntry,
 | 
						role *roleEntry,
 | 
				
			||||||
	signingBundle *certutil.ParsedCertBundle,
 | 
						signingBundle *certutil.ParsedCertBundle,
 | 
				
			||||||
 | 
						isCA bool,
 | 
				
			||||||
	req *logical.Request,
 | 
						req *logical.Request,
 | 
				
			||||||
	data *framework.FieldData) (*certCreationBundle, error) {
 | 
						data *framework.FieldData) (*certCreationBundle, error) {
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get the common name(s)
 | 
						// Get the common name(s)
 | 
				
			||||||
	var commonNames []string
 | 
						var cn string
 | 
				
			||||||
	cn := data.Get("common_name").(string)
 | 
						cnInt, ok := data.GetOk("common_name")
 | 
				
			||||||
	if len(cn) == 0 {
 | 
						if ok {
 | 
				
			||||||
		return nil, certutil.UserError{Err: "The common_name field is required"}
 | 
							cn = cnInt.(string)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	commonNames = []string{cn}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cnAlt := data.Get("alt_names").(string)
 | 
						commonNames := []string{cn}
 | 
				
			||||||
 | 
						cnAltInt, ok := data.GetOk("alt_names")
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							cnAlt := cnAltInt.(string)
 | 
				
			||||||
		if len(cnAlt) != 0 {
 | 
							if len(cnAlt) != 0 {
 | 
				
			||||||
			for _, v := range strings.Split(cnAlt, ",") {
 | 
								for _, v := range strings.Split(cnAlt, ",") {
 | 
				
			||||||
				commonNames = append(commonNames, v)
 | 
									commonNames = append(commonNames, v)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get any IP SANs
 | 
						// Get any IP SANs
 | 
				
			||||||
	ipSANs := []net.IP{}
 | 
						ipSANs := []net.IP{}
 | 
				
			||||||
 | 
						ipAltInt, ok := data.GetOk("ip_sans")
 | 
				
			||||||
	ipAlt := data.Get("ip_sans").(string)
 | 
						if ok {
 | 
				
			||||||
 | 
							ipAlt := ipAltInt.(string)
 | 
				
			||||||
		if len(ipAlt) != 0 {
 | 
							if len(ipAlt) != 0 {
 | 
				
			||||||
			if !role.AllowIPSANs {
 | 
								if !role.AllowIPSANs {
 | 
				
			||||||
				return nil, certutil.UserError{Err: fmt.Sprintf(
 | 
									return nil, certutil.UserError{Err: fmt.Sprintf(
 | 
				
			||||||
@@ -265,10 +283,14 @@ func generateCreationBundle(b *backend,
 | 
				
			|||||||
				ipSANs = append(ipSANs, parsedIP)
 | 
									ipSANs = append(ipSANs, parsedIP)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ttlField := data.Get("ttl").(string)
 | 
						var ttlField string
 | 
				
			||||||
	if len(ttlField) == 0 {
 | 
						ttlFieldInt, ok := data.GetOk("ttl")
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
		ttlField = role.TTL
 | 
							ttlField = role.TTL
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ttlField = ttlFieldInt.(string)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var ttl time.Duration
 | 
						var ttl time.Duration
 | 
				
			||||||
@@ -340,12 +362,14 @@ func generateCreationBundle(b *backend,
 | 
				
			|||||||
		Usage:         usage,
 | 
							Usage:         usage,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if isCA {
 | 
				
			||||||
		if _, ok := req.Data["ca_type"]; ok {
 | 
							if _, ok := req.Data["ca_type"]; ok {
 | 
				
			||||||
			creationBundle.CAType = req.Data["ca_type"].(string)
 | 
								creationBundle.CAType = req.Data["ca_type"].(string)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if _, ok := req.Data["pki_address"]; ok {
 | 
							if _, ok := req.Data["pki_address"]; ok {
 | 
				
			||||||
			creationBundle.PKIAddress = req.Data["pki_address"].(string)
 | 
								creationBundle.PKIAddress = req.Data["pki_address"].(string)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return creationBundle, nil
 | 
						return creationBundle, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,43 +14,7 @@ import (
 | 
				
			|||||||
	"github.com/hashicorp/vault/logical/framework"
 | 
						"github.com/hashicorp/vault/logical/framework"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var generateAndSignSchema = map[string]*framework.FieldSchema{
 | 
					var rootAndSignSchema = map[string]*framework.FieldSchema{
 | 
				
			||||||
	"type": &framework.FieldSchema{
 | 
					 | 
				
			||||||
		Type: framework.TypeString,
 | 
					 | 
				
			||||||
		Description: `Must be "self-signed" or "intermediate".
 | 
					 | 
				
			||||||
If set to "self-signed", a self-signed root CA
 | 
					 | 
				
			||||||
will be generated. If set to "intermediate", a
 | 
					 | 
				
			||||||
CSR will be returned for signing by the root.`,
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"exported": &framework.FieldSchema{
 | 
					 | 
				
			||||||
		Type: framework.TypeString,
 | 
					 | 
				
			||||||
		Description: `Must be "internal" or "exported".
 | 
					 | 
				
			||||||
If set to "exported", the generated private
 | 
					 | 
				
			||||||
key will be returned. This is your *only*
 | 
					 | 
				
			||||||
chance to retrieve the private key!`,
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"pki_address": &framework.FieldSchema{
 | 
					 | 
				
			||||||
		Type: framework.TypeString,
 | 
					 | 
				
			||||||
		Description: `The base URL of the PKI mount. For
 | 
					 | 
				
			||||||
"self-signed"; this is needed when
 | 
					 | 
				
			||||||
calling '/generate/' and should be
 | 
					 | 
				
			||||||
the base URL of the mount where you
 | 
					 | 
				
			||||||
are running this command, e.g.
 | 
					 | 
				
			||||||
"https://vault.example.com/v1/root_pki".
 | 
					 | 
				
			||||||
For "intermediate", this is needed
 | 
					 | 
				
			||||||
when calling '/sign/' and should be
 | 
					 | 
				
			||||||
the base URL of the destination
 | 
					 | 
				
			||||||
mount of the certificate, e.g.
 | 
					 | 
				
			||||||
"https://vault.example.com/v1/intermediate_pki".
 | 
					 | 
				
			||||||
For HA setups, the given host name
 | 
					 | 
				
			||||||
should be the address that can always
 | 
					 | 
				
			||||||
be used to contact the leader. This is
 | 
					 | 
				
			||||||
is used for generating the CA/CRL URLs in
 | 
					 | 
				
			||||||
the certificate. Required as specified.`,
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"common_name": &framework.FieldSchema{
 | 
						"common_name": &framework.FieldSchema{
 | 
				
			||||||
		Type: framework.TypeString,
 | 
							Type: framework.TypeString,
 | 
				
			||||||
		Description: `The requested common name; if you want more than
 | 
							Description: `The requested common name; if you want more than
 | 
				
			||||||
@@ -70,26 +34,16 @@ in a comma-delimited list`,
 | 
				
			|||||||
common-delimited list`,
 | 
					common-delimited list`,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"key_bits": &framework.FieldSchema{
 | 
					 | 
				
			||||||
		Type:    framework.TypeInt,
 | 
					 | 
				
			||||||
		Default: 2048,
 | 
					 | 
				
			||||||
		Description: `The number of bits to use. You will almost
 | 
					 | 
				
			||||||
certainly want to change this if you adjust
 | 
					 | 
				
			||||||
the key_type.`,
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"ttl": &framework.FieldSchema{
 | 
						"ttl": &framework.FieldSchema{
 | 
				
			||||||
		Type: framework.TypeString,
 | 
							Type: framework.TypeString,
 | 
				
			||||||
		Description: `The requested Time To Live for the certificate;
 | 
							Description: `The requested Time To Live for the certificate;
 | 
				
			||||||
sets the expiration date. If not specified
 | 
					sets the expiration date. If not specified
 | 
				
			||||||
the role default, backend default, or system
 | 
					the role default, backend default, or system
 | 
				
			||||||
default TTL is used, in that order. Cannot
 | 
					default TTL is used, in that order. Cannot
 | 
				
			||||||
be larger than the mount max TTL.`,
 | 
					be larger than the mount max TTL. Note:
 | 
				
			||||||
	},
 | 
					this only has an effect when generating
 | 
				
			||||||
 | 
					a CA cert or signing a CA cert, not when
 | 
				
			||||||
	"csr": &framework.FieldSchema{
 | 
					creating a CSR for an intermediate CA.`,
 | 
				
			||||||
		Type:        framework.TypeString,
 | 
					 | 
				
			||||||
		Description: `PEM-format CSR to be signed.`,
 | 
					 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -134,26 +88,88 @@ endpoint, just the signed certificate.`,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func pathGenerateCA(b *backend) *framework.Path {
 | 
					func pathGenerateRootCA(b *backend) *framework.Path {
 | 
				
			||||||
	return &framework.Path{
 | 
						ret := &framework.Path{
 | 
				
			||||||
		Pattern: "config/ca/generate/" + framework.GenericNameRegex("type") + "/" + framework.GenericNameRegex("exported"),
 | 
							Pattern: "config/ca/generate/root/" + framework.GenericNameRegex("exported"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Fields: generateAndSignSchema,
 | 
							Fields: rootAndSignSchema,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Callbacks: map[logical.Operation]framework.OperationFunc{
 | 
							Callbacks: map[logical.Operation]framework.OperationFunc{
 | 
				
			||||||
			logical.WriteOperation: b.pathCAGenerateWrite,
 | 
								logical.WriteOperation: b.pathCAGenerateRoot,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		HelpSynopsis:    pathConfigCAGenerateHelpSyn,
 | 
							HelpSynopsis:    pathConfigCAGenerateHelpSyn,
 | 
				
			||||||
		HelpDescription: pathConfigCAGenerateHelpDesc,
 | 
							HelpDescription: pathConfigCAGenerateHelpDesc,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret.Fields["pki_address"] = &framework.FieldSchema{
 | 
				
			||||||
 | 
							Type: framework.TypeString,
 | 
				
			||||||
 | 
							Description: `The base URL of the PKI mount, e.g.
 | 
				
			||||||
 | 
					"https://vault.example.com/v1/root_pki".
 | 
				
			||||||
 | 
					For HA setups, the given host name
 | 
				
			||||||
 | 
					should be the address that can always
 | 
				
			||||||
 | 
					be used to contact the leader, as this is
 | 
				
			||||||
 | 
					is used for generating the CA/CRL URLs in
 | 
				
			||||||
 | 
					the certificate.`,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret.Fields["exported"] = &framework.FieldSchema{
 | 
				
			||||||
 | 
							Type: framework.TypeString,
 | 
				
			||||||
 | 
							Description: `Must be "internal" or "exported".
 | 
				
			||||||
 | 
					If set to "exported", the generated private
 | 
				
			||||||
 | 
					key will be returned. This is your *only*
 | 
				
			||||||
 | 
					chance to retrieve the private key!`,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret.Fields["key_bits"] = &framework.FieldSchema{
 | 
				
			||||||
 | 
							Type:    framework.TypeInt,
 | 
				
			||||||
 | 
							Default: 2048,
 | 
				
			||||||
 | 
							Description: `The number of bits to use. You will almost
 | 
				
			||||||
 | 
					certainly want to change this if you adjust
 | 
				
			||||||
 | 
					the key_type.`,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func pathSignCA(b *backend) *framework.Path {
 | 
					func pathGenerateIntermediateCA(b *backend) *framework.Path {
 | 
				
			||||||
	return &framework.Path{
 | 
						ret := &framework.Path{
 | 
				
			||||||
 | 
							Pattern: "config/ca/generate/intermediate/" + framework.GenericNameRegex("exported"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Fields: map[string]*framework.FieldSchema{},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Callbacks: map[logical.Operation]framework.OperationFunc{
 | 
				
			||||||
 | 
								logical.WriteOperation: b.pathCAGenerateIntermediate,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							HelpSynopsis:    pathConfigCAGenerateHelpSyn,
 | 
				
			||||||
 | 
							HelpDescription: pathConfigCAGenerateHelpDesc,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret.Fields["exported"] = &framework.FieldSchema{
 | 
				
			||||||
 | 
							Type: framework.TypeString,
 | 
				
			||||||
 | 
							Description: `Must be "internal" or "exported".
 | 
				
			||||||
 | 
					If set to "exported", the generated private
 | 
				
			||||||
 | 
					key will be returned. This is your *only*
 | 
				
			||||||
 | 
					chance to retrieve the private key!`,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret.Fields["key_bits"] = &framework.FieldSchema{
 | 
				
			||||||
 | 
							Type:    framework.TypeInt,
 | 
				
			||||||
 | 
							Default: 2048,
 | 
				
			||||||
 | 
							Description: `The number of bits to use. You will almost
 | 
				
			||||||
 | 
					certainly want to change this if you adjust
 | 
				
			||||||
 | 
					the key_type.`,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func pathSignIntermediateCA(b *backend) *framework.Path {
 | 
				
			||||||
 | 
						ret := &framework.Path{
 | 
				
			||||||
		Pattern: "config/ca/sign",
 | 
							Pattern: "config/ca/sign",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Fields: generateAndSignSchema,
 | 
							Fields: rootAndSignSchema,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Callbacks: map[logical.Operation]framework.OperationFunc{
 | 
							Callbacks: map[logical.Operation]framework.OperationFunc{
 | 
				
			||||||
			logical.WriteOperation: b.pathCASignWrite,
 | 
								logical.WriteOperation: b.pathCASignWrite,
 | 
				
			||||||
@@ -162,9 +178,28 @@ func pathSignCA(b *backend) *framework.Path {
 | 
				
			|||||||
		HelpSynopsis:    pathConfigCASignHelpSyn,
 | 
							HelpSynopsis:    pathConfigCASignHelpSyn,
 | 
				
			||||||
		HelpDescription: pathConfigCASignHelpDesc,
 | 
							HelpDescription: pathConfigCASignHelpDesc,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret.Fields["pki_address"] = &framework.FieldSchema{
 | 
				
			||||||
 | 
							Type: framework.TypeString,
 | 
				
			||||||
 | 
							Description: `The base URL of the *destination*
 | 
				
			||||||
 | 
					PKI mount, e.g.
 | 
				
			||||||
 | 
					"https://vault.example.com/v1/intermediate_pki".
 | 
				
			||||||
 | 
					For HA setups, the given host name
 | 
				
			||||||
 | 
					should be the address that can always
 | 
				
			||||||
 | 
					be used to contact the leader, as this is
 | 
				
			||||||
 | 
					is used for generating the CA/CRL URLs in
 | 
				
			||||||
 | 
					the certificate.`,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret.Fields["csr"] = &framework.FieldSchema{
 | 
				
			||||||
 | 
							Type:        framework.TypeString,
 | 
				
			||||||
 | 
							Description: `PEM-format CSR to be signed.`,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *backend) pathCAGenerateWrite(
 | 
					func (b *backend) pathCAGenerateRoot(
 | 
				
			||||||
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
 | 
						req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	exported := data.Get("exported").(string)
 | 
						exported := data.Get("exported").(string)
 | 
				
			||||||
@@ -176,18 +211,8 @@ func (b *backend) pathCAGenerateWrite(
 | 
				
			|||||||
			"The \"exported\" path parameter must be \"internal\" or \"exported\"")), nil
 | 
								"The \"exported\" path parameter must be \"internal\" or \"exported\"")), nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	genType := data.Get("type").(string)
 | 
						req.Data["ca_type"] = "root"
 | 
				
			||||||
	switch genType {
 | 
					 | 
				
			||||||
	case "self-signed":
 | 
					 | 
				
			||||||
	case "intermediate":
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return logical.ErrorResponse(fmt.Sprintf(
 | 
					 | 
				
			||||||
			"The \"type\" path parameter must be \"self-signed\" or \"intermediate\"")), nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req.Data["ca_type"] = genType
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if genType == "self-signed" {
 | 
					 | 
				
			||||||
	pkiAddress := strings.ToLower(data.Get("pki_address").(string))
 | 
						pkiAddress := strings.ToLower(data.Get("pki_address").(string))
 | 
				
			||||||
	switch {
 | 
						switch {
 | 
				
			||||||
	case len(pkiAddress) == 0:
 | 
						case len(pkiAddress) == 0:
 | 
				
			||||||
@@ -208,7 +233,6 @@ func (b *backend) pathCAGenerateWrite(
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req.Data["pki_address"] = pkiAddress
 | 
						req.Data["pki_address"] = pkiAddress
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	role := &roleEntry{
 | 
						role := &roleEntry{
 | 
				
			||||||
		TTL:              data.Get("ttl").(string),
 | 
							TTL:              data.Get("ttl").(string),
 | 
				
			||||||
@@ -219,21 +243,6 @@ func (b *backend) pathCAGenerateWrite(
 | 
				
			|||||||
		EnforceHostnames: false,
 | 
							EnforceHostnames: false,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	maxSystemTTL := b.System().MaxLeaseTTL()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ttl := b.System().DefaultLeaseTTL()
 | 
					 | 
				
			||||||
	if len(role.TTL) != 0 {
 | 
					 | 
				
			||||||
		ttl, err = time.ParseDuration(role.TTL)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return logical.ErrorResponse(fmt.Sprintf(
 | 
					 | 
				
			||||||
				"Invalid ttl: %s", err)), nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ttl > maxSystemTTL {
 | 
					 | 
				
			||||||
		return logical.ErrorResponse(fmt.Sprintf(
 | 
					 | 
				
			||||||
			"\"ttl\" value must be less than mount max of %d seconds", maxSystemTTL/time.Second)), nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch role.KeyBits {
 | 
						switch role.KeyBits {
 | 
				
			||||||
	case 0:
 | 
						case 0:
 | 
				
			||||||
		role.KeyBits = 2048
 | 
							role.KeyBits = 2048
 | 
				
			||||||
@@ -246,9 +255,7 @@ func (b *backend) pathCAGenerateWrite(
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var resp *logical.Response
 | 
						var resp *logical.Response
 | 
				
			||||||
	switch genType {
 | 
						parsedBundle, err := generateCert(b, role, nil, true, req, data)
 | 
				
			||||||
	case "self-signed":
 | 
					 | 
				
			||||||
		parsedBundle, err := generateCert(b, role, nil, req, data)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		switch err.(type) {
 | 
							switch err.(type) {
 | 
				
			||||||
		case certutil.UserError:
 | 
							case certutil.UserError:
 | 
				
			||||||
@@ -302,8 +309,44 @@ func (b *backend) pathCAGenerateWrite(
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "intermediate":
 | 
						return resp, nil
 | 
				
			||||||
		parsedBundle, err := generateCSR(b, role, nil, req, data)
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b *backend) pathCAGenerateIntermediate(
 | 
				
			||||||
 | 
						req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						exported := data.Get("exported").(string)
 | 
				
			||||||
 | 
						switch exported {
 | 
				
			||||||
 | 
						case "exported":
 | 
				
			||||||
 | 
						case "internal":
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return logical.ErrorResponse(fmt.Sprintf(
 | 
				
			||||||
 | 
								"The \"exported\" path parameter must be \"internal\" or \"exported\"")), nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req.Data["ca_type"] = "intermediate"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						role := &roleEntry{
 | 
				
			||||||
 | 
							KeyType:          "rsa",
 | 
				
			||||||
 | 
							KeyBits:          data.Get("key_bits").(int),
 | 
				
			||||||
 | 
							AllowLocalhost:   true,
 | 
				
			||||||
 | 
							AllowAnyName:     true,
 | 
				
			||||||
 | 
							EnforceHostnames: false,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch role.KeyBits {
 | 
				
			||||||
 | 
						case 0:
 | 
				
			||||||
 | 
							role.KeyBits = 2048
 | 
				
			||||||
 | 
						case 1024:
 | 
				
			||||||
 | 
						case 2048:
 | 
				
			||||||
 | 
						case 4096:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return logical.ErrorResponse(fmt.Sprintf(
 | 
				
			||||||
 | 
								"\"key_bits\" must be 1024, 2048, or 4096")), nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var resp *logical.Response
 | 
				
			||||||
 | 
						parsedBundle, err := generateCSR(b, role, nil, true, req, data)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		switch err.(type) {
 | 
							switch err.(type) {
 | 
				
			||||||
		case certutil.UserError:
 | 
							case certutil.UserError:
 | 
				
			||||||
@@ -343,10 +386,6 @@ func (b *backend) pathCAGenerateWrite(
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return logical.ErrorResponse("Unknown generation type"), nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return resp, nil
 | 
						return resp, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -425,7 +464,7 @@ func (b *backend) pathCASignWrite(
 | 
				
			|||||||
			"Error fetching CA certificate: %s", caErr)}
 | 
								"Error fetching CA certificate: %s", caErr)}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	parsedBundle, err := signCert(b, role, signingBundle, csr, req, data)
 | 
						parsedBundle, err := signCert(b, role, signingBundle, csr, true, req, data)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		switch err.(type) {
 | 
							switch err.(type) {
 | 
				
			||||||
		case certutil.UserError:
 | 
							case certutil.UserError:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,10 +10,7 @@ import (
 | 
				
			|||||||
	"github.com/hashicorp/vault/logical/framework"
 | 
						"github.com/hashicorp/vault/logical/framework"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func pathIssue(b *backend) *framework.Path {
 | 
					var issueAndSignSchema = map[string]*framework.FieldSchema{
 | 
				
			||||||
	return &framework.Path{
 | 
					 | 
				
			||||||
		Pattern: "issue/" + framework.GenericNameRegex("role"),
 | 
					 | 
				
			||||||
		Fields: map[string]*framework.FieldSchema{
 | 
					 | 
				
			||||||
	"role": &framework.FieldSchema{
 | 
						"role": &framework.FieldSchema{
 | 
				
			||||||
		Type: framework.TypeString,
 | 
							Type: framework.TypeString,
 | 
				
			||||||
		Description: `The desired role with configuration for this
 | 
							Description: `The desired role with configuration for this
 | 
				
			||||||
@@ -47,7 +44,30 @@ the role default, backend default, or system
 | 
				
			|||||||
default TTL is used, in that order. Cannot
 | 
					default TTL is used, in that order. Cannot
 | 
				
			||||||
be later than the role max TTL.`,
 | 
					be later than the role max TTL.`,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						"csr": &framework.FieldSchema{
 | 
				
			||||||
 | 
							Type:        framework.TypeString,
 | 
				
			||||||
 | 
							Description: `PEM-format CSR to be signed.`,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func pathIssue(b *backend) *framework.Path {
 | 
				
			||||||
 | 
						return &framework.Path{
 | 
				
			||||||
 | 
							Pattern: "issue/" + framework.GenericNameRegex("role"),
 | 
				
			||||||
 | 
							Fields:  issueAndSignSchema,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Callbacks: map[logical.Operation]framework.OperationFunc{
 | 
				
			||||||
 | 
								logical.WriteOperation: b.pathIssueCert,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							HelpSynopsis:    pathIssueCertHelpSyn,
 | 
				
			||||||
 | 
							HelpDescription: pathIssueCertHelpDesc,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func pathSign(b *backend) *framework.Path {
 | 
				
			||||||
 | 
						return &framework.Path{
 | 
				
			||||||
 | 
							Pattern: "sign/" + framework.GenericNameRegex("role"),
 | 
				
			||||||
 | 
							Fields:  issueAndSignSchema,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Callbacks: map[logical.Operation]framework.OperationFunc{
 | 
							Callbacks: map[logical.Operation]framework.OperationFunc{
 | 
				
			||||||
			logical.WriteOperation: b.pathIssueCert,
 | 
								logical.WriteOperation: b.pathIssueCert,
 | 
				
			||||||
@@ -82,13 +102,7 @@ func (b *backend) pathIssueCert(
 | 
				
			|||||||
			"Error fetching CA certificate: %s", caErr)}
 | 
								"Error fetching CA certificate: %s", caErr)}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Don't allow these on the standard path. Ideally we should determine
 | 
						parsedBundle, err := generateCert(b, role, signingBundle, false, req, data)
 | 
				
			||||||
	// this internally once we get SudoPrivilege from System() working
 | 
					 | 
				
			||||||
	// for non-TokenStore
 | 
					 | 
				
			||||||
	delete(req.Data, "ca_type")
 | 
					 | 
				
			||||||
	delete(req.Data, "pki_address")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	parsedBundle, err := generateCert(b, role, signingBundle, req, data)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		switch err.(type) {
 | 
							switch err.(type) {
 | 
				
			||||||
		case certutil.UserError:
 | 
							case certutil.UserError:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user