Allow the format to be specified as pem_bundle, which creates a

concatenated PEM file.

Fixes #992
This commit is contained in:
Jeff Mitchell 2016-02-01 13:19:41 -05:00
parent 0f5db5da6c
commit fc6d23a54e
7 changed files with 85 additions and 29 deletions

View File

@ -22,7 +22,7 @@ func (b *backend) getGenerationParams(
format = getFormat(data)
if format == "" {
errorResp = logical.ErrorResponse(
`The "format" path parameter must be "pem" or "der"`)
`The "format" path parameter must be "pem", "der", or "pem_bundle"`)
return
}

View File

@ -74,6 +74,7 @@ func getFormat(data *framework.FieldData) string {
switch format {
case "pem":
case "der":
case "pem_bundle":
default:
format = ""
}

View File

@ -8,8 +8,10 @@ func addIssueAndSignCommonFields(fields map[string]*framework.FieldSchema) map[s
fields["format"] = &framework.FieldSchema{
Type: framework.TypeString,
Default: "pem",
Description: `Format for returned data. Can be "pem" or "der";
defaults to "pem".`,
Description: `Format for returned data. Can be "pem", "der",
or "pem_bundle". If "pem_bundle" any private
private key and issuing cert will be appended
to the certificate pem. Defaults to "pem".`,
}
fields["ip_sans"] = &framework.FieldSchema{

View File

@ -88,6 +88,15 @@ func (b *backend) pathGenerateIntermediate(
resp.Data["private_key"] = csrb.PrivateKey
resp.Data["private_key_type"] = csrb.PrivateKeyType
}
case "pem_bundle":
resp.Data["csr"] = csrb.CSR
if exported {
resp.Data["csr"] = fmt.Sprintf("%s\n%s", csrb.PrivateKey, csrb.CSR)
resp.Data["private_key"] = csrb.PrivateKey
resp.Data["private_key_type"] = csrb.PrivateKeyType
}
case "der":
resp.Data["csr"] = base64.StdEncoding.EncodeToString(parsedBundle.CSRBytes)
if exported {

View File

@ -133,7 +133,7 @@ func (b *backend) pathIssueSignCert(
format := getFormat(data)
if format == "" {
return logical.ErrorResponse(
`The "format" path parameter must be "pem" or "der"`), nil
`The "format" path parameter must be "pem", "der", or "pem_bundle"`), nil
}
var caErr error
@ -170,20 +170,33 @@ func (b *backend) pathIssueSignCert(
resp := b.Secret(SecretCertsType).Response(
map[string]interface{}{
"certificate": cb.Certificate,
"issuing_ca": cb.IssuingCA,
"serial_number": cb.SerialNumber,
"certificate": cb.Certificate,
"issuing_ca": cb.IssuingCA,
},
map[string]interface{}{
"serial_number": cb.SerialNumber,
})
if !useCSR {
resp.Data["private_key"] = cb.PrivateKey
resp.Data["private_key_type"] = cb.PrivateKeyType
}
switch format {
case "pem":
resp.Data["issuing_ca"] = cb.IssuingCA
resp.Data["certificate"] = cb.Certificate
if format == "der" {
if !useCSR {
resp.Data["private_key"] = cb.PrivateKey
resp.Data["private_key_type"] = cb.PrivateKeyType
}
case "pem_bundle":
resp.Data["issuing_ca"] = cb.IssuingCA
resp.Data["certificate"] = fmt.Sprintf("%s\n%s", cb.Certificate, cb.IssuingCA)
if !useCSR {
resp.Data["private_key"] = cb.PrivateKey
resp.Data["private_key_type"] = cb.PrivateKeyType
resp.Data["certificate"] = fmt.Sprintf("%s\n%s\n%s", cb.PrivateKey, cb.Certificate, cb.IssuingCA)
}
case "der":
resp.Data["certificate"] = base64.StdEncoding.EncodeToString(parsedBundle.CertificateBytes)
resp.Data["issuing_ca"] = base64.StdEncoding.EncodeToString(parsedBundle.IssuingCABytes)
if !useCSR {

View File

@ -101,8 +101,6 @@ func (b *backend) pathCAGenerateRoot(
map[string]interface{}{
"expiration": int64(parsedBundle.Certificate.NotAfter.Unix()),
"serial_number": cb.SerialNumber,
"certificate": cb.Certificate,
"issuing_ca": cb.IssuingCA,
},
map[string]interface{}{
"serial_number": cb.SerialNumber,
@ -110,10 +108,24 @@ func (b *backend) pathCAGenerateRoot(
switch format {
case "pem":
resp.Data["certificate"] = cb.Certificate
resp.Data["issuing_ca"] = cb.IssuingCA
if exported {
resp.Data["private_key"] = cb.PrivateKey
resp.Data["private_key_type"] = cb.PrivateKeyType
}
case "pem_bundle":
resp.Data["issuing_ca"] = cb.IssuingCA
if exported {
resp.Data["private_key"] = cb.PrivateKey
resp.Data["private_key_type"] = cb.PrivateKeyType
resp.Data["certificate"] = fmt.Sprintf("%s\n%s\n%s", cb.PrivateKey, cb.Certificate, cb.IssuingCA)
} else {
resp.Data["certificate"] = fmt.Sprintf("%s\n%s", cb.Certificate, cb.IssuingCA)
}
case "der":
resp.Data["certificate"] = base64.StdEncoding.EncodeToString(parsedBundle.CertificateBytes)
resp.Data["issuing_ca"] = base64.StdEncoding.EncodeToString(parsedBundle.IssuingCABytes)
@ -228,14 +240,21 @@ func (b *backend) pathCASignIntermediate(
map[string]interface{}{
"expiration": int64(parsedBundle.Certificate.NotAfter.Unix()),
"serial_number": cb.SerialNumber,
"certificate": cb.Certificate,
"issuing_ca": cb.IssuingCA,
},
map[string]interface{}{
"serial_number": cb.SerialNumber,
})
if format == "der" {
switch format {
case "pem":
resp.Data["certificate"] = cb.Certificate
resp.Data["issuing_ca"] = cb.IssuingCA
case "pem_bundle":
resp.Data["certificate"] = fmt.Sprintf("%s\n%s", cb.Certificate, cb.IssuingCA)
resp.Data["issuing_ca"] = cb.IssuingCA
case "der":
resp.Data["certificate"] = base64.StdEncoding.EncodeToString(parsedBundle.CertificateBytes)
resp.Data["issuing_ca"] = base64.StdEncoding.EncodeToString(parsedBundle.IssuingCABytes)
}

View File

@ -741,8 +741,10 @@ subpath for interactive help output.
<li>
<span class="param">format</span>
<span class="param-flags">optional</span>
Format for returned data. Can be `pem` or `der`; defaults to `pem`. If
`der`, the output is base64 encoded.
Format for returned data. Can be `pem`, `der`, or `pem_bundle`;
defaults to `pem`. If `der`, the output is base64 encoded. If
`pem_bundle`, the `csr` field will contain the private key (if
exported) and CSR, concatenated.
</li>
<li>
<span class="param">key_type</span>
@ -860,8 +862,10 @@ subpath for interactive help output.
<li>
<span class="param">format</span>
<span class="param-flags">optional</span>
Format for returned data. Can be `pem` or `der`; defaults to `pem`. If
`der`, the output is base64 encoded.
Format for returned data. Can be `pem`, `der`, or `pem_bundle`;
defaults to `pem`. If `der`, the output is base64 encoded. If
`pem_bundle`, the `certificate` field will contain the private key,
certificate, and issuing CA, concatenated.
</li>
</ul>
</dd>
@ -1233,8 +1237,10 @@ subpath for interactive help output.
<li>
<span class="param">format</span>
<span class="param-flags">optional</span>
Format for returned data. Can be `pem` or `der`; defaults to `pem`. If
`der`, the output is base64 encoded.
Format for returned data. Can be `pem`, `der`, or `pem_bundle`;
defaults to `pem`. If `der`, the output is base64 encoded. If
`pem_bundle`, the `certificate` field will contain the private key (if exported),
certificate, and issuing CA, concatenated.
</li>
<li>
<span class="param">key_type</span>
@ -1333,8 +1339,10 @@ subpath for interactive help output.
<li>
<span class="param">format</span>
<span class="param-flags">optional</span>
Format for returned data. Can be `pem` or `der`; defaults to `pem`. If
`der`, the output is base64 encoded.
Format for returned data. Can be `pem`, `der`, or `pem_bundle`;
defaults to `pem`. If `der`, the output is base64 encoded. If
`pem_bundle`, the `certificate` field will contain the certificate and
issuing CA, concatenated.
</li>
<li>
<span class="param">max_path_length</span>
@ -1435,8 +1443,10 @@ subpath for interactive help output.
<li>
<span class="param">format</span>
<span class="param-flags">optional</span>
Format for returned data. Can be `pem` or `der`; defaults to `pem`. If
`der`, the output is base64 encoded.
Format for returned data. Can be `pem`, `der`, or `pem_bundle`;
defaults to `pem`. If `der`, the output is base64 encoded. If
`pem_bundle`, the `certificate` field will contain the certificate and
issuing CA, concatenated.
</li>
</ul>
</dd>
@ -1499,8 +1509,10 @@ subpath for interactive help output.
<li>
<span class="param">format</span>
<span class="param-flags">optional</span>
Format for returned data. Can be `pem` or `der`; defaults to `pem`. If
`der`, the output is base64 encoded.
Format for returned data. Can be `pem`, `der`, or `pem_bundle`;
defaults to `pem`. If `der`, the output is base64 encoded. If
`pem_bundle`, the `certificate` field will contain the certificate and
issuing CA, concatenated.
</li>
</ul>
</dd>