mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 03:27:54 +00:00
Add sign method (untested)
This commit is contained in:
@@ -43,6 +43,7 @@ func Backend() *framework.Backend {
|
||||
pathSetCA(&b),
|
||||
pathConfigCA(&b),
|
||||
pathConfigCRL(&b),
|
||||
pathSign(&b),
|
||||
pathIssue(&b),
|
||||
pathRotateCRL(&b),
|
||||
pathFetchCA(&b),
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"crypto/sha1"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
@@ -215,7 +216,6 @@ func generateCSR(b *backend,
|
||||
func signCert(b *backend,
|
||||
role *roleEntry,
|
||||
signingBundle *certutil.ParsedCertBundle,
|
||||
csr *x509.CertificateRequest,
|
||||
isCA bool,
|
||||
req *logical.Request,
|
||||
data *framework.FieldData) (*certutil.ParsedCertBundle, error) {
|
||||
@@ -225,6 +225,22 @@ func signCert(b *backend,
|
||||
return nil, certutil.UserError{Err: "The common_name field is required"}
|
||||
}
|
||||
|
||||
csrString := req.Data["csr"].(string)
|
||||
if csrString == "" {
|
||||
return nil, certutil.UserError{Err: fmt.Sprintf(
|
||||
"\"csr\" is empty")}
|
||||
}
|
||||
|
||||
pemBytes := []byte(csrString)
|
||||
pemBlock, pemBytes := pem.Decode(pemBytes)
|
||||
if pemBlock == nil {
|
||||
return nil, certutil.UserError{Err: "csr contains no data"}
|
||||
}
|
||||
csr, err := x509.ParseCertificateRequest(pemBlock.Bytes)
|
||||
if err != nil {
|
||||
return nil, certutil.UserError{Err: "certificate request could not be parsed"}
|
||||
}
|
||||
|
||||
creationBundle, err := generateCreationBundle(b, role, signingBundle, isCA, req, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package pki
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -413,22 +411,6 @@ func (b *backend) pathCASignWrite(
|
||||
pkiAddress = pkiAddress[:len(pkiAddress)-1]
|
||||
}
|
||||
|
||||
csrString := req.Data["csr"].(string)
|
||||
if csrString == "" {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"\"csr\" is empty")), nil
|
||||
}
|
||||
|
||||
pemBytes := []byte(csrString)
|
||||
pemBlock, pemBytes := pem.Decode(pemBytes)
|
||||
if pemBlock == nil {
|
||||
return nil, certutil.UserError{Err: "csr contains no data"}
|
||||
}
|
||||
csr, err := x509.ParseCertificateRequest(pemBlock.Bytes)
|
||||
if err != nil {
|
||||
return nil, certutil.UserError{Err: "certificate request could not be parsed"}
|
||||
}
|
||||
|
||||
req.Data["pki_address"] = pkiAddress
|
||||
|
||||
role := &roleEntry{
|
||||
@@ -464,7 +446,7 @@ func (b *backend) pathCASignWrite(
|
||||
"Error fetching CA certificate: %s", caErr)}
|
||||
}
|
||||
|
||||
parsedBundle, err := signCert(b, role, signingBundle, csr, true, req, data)
|
||||
parsedBundle, err := signCert(b, role, signingBundle, true, req, data)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case certutil.UserError:
|
||||
|
||||
@@ -44,10 +44,6 @@ the role default, backend default, or system
|
||||
default TTL is used, in that order. Cannot
|
||||
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 {
|
||||
@@ -65,7 +61,7 @@ func pathIssue(b *backend) *framework.Path {
|
||||
}
|
||||
|
||||
func pathSign(b *backend) *framework.Path {
|
||||
return &framework.Path{
|
||||
ret := &framework.Path{
|
||||
Pattern: "sign/" + framework.GenericNameRegex("role"),
|
||||
Fields: issueAndSignSchema,
|
||||
|
||||
@@ -76,6 +72,13 @@ func pathSign(b *backend) *framework.Path {
|
||||
HelpSynopsis: pathIssueCertHelpSyn,
|
||||
HelpDescription: pathIssueCertHelpDesc,
|
||||
}
|
||||
|
||||
ret.Fields["csr"] = &framework.FieldSchema{
|
||||
Type: framework.TypeString,
|
||||
Description: `PEM-format CSR to be signed.`,
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (b *backend) pathIssueCert(
|
||||
@@ -136,6 +139,64 @@ func (b *backend) pathIssueCert(
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (b *backend) pathSignCSR(
|
||||
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
roleName := data.Get("role").(string)
|
||||
|
||||
// Get the role
|
||||
role, err := b.getRole(req.Storage, roleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if role == nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf("Unknown role: %s", roleName)), nil
|
||||
}
|
||||
|
||||
var caErr error
|
||||
signingBundle, caErr := fetchCAInfo(req)
|
||||
switch caErr.(type) {
|
||||
case certutil.UserError:
|
||||
return nil, certutil.UserError{Err: fmt.Sprintf(
|
||||
"Could not fetch the CA certificate (was one set?): %s", caErr)}
|
||||
case certutil.InternalError:
|
||||
return nil, certutil.InternalError{Err: fmt.Sprintf(
|
||||
"Error fetching CA certificate: %s", caErr)}
|
||||
}
|
||||
|
||||
parsedBundle, err := signCert(b, role, signingBundle, false, req, data)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case certutil.UserError:
|
||||
return logical.ErrorResponse(err.Error()), nil
|
||||
case certutil.InternalError:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
cb, err := parsedBundle.ToCertBundle()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error converting raw cert bundle to cert bundle: %s", err)
|
||||
}
|
||||
|
||||
resp := b.Secret(SecretCertsType).Response(
|
||||
structs.New(cb).Map(),
|
||||
map[string]interface{}{
|
||||
"serial_number": cb.SerialNumber,
|
||||
})
|
||||
|
||||
resp.Secret.TTL = parsedBundle.Certificate.NotAfter.Sub(time.Now())
|
||||
|
||||
err = req.Storage.Put(&logical.StorageEntry{
|
||||
Key: "certs/" + cb.SerialNumber,
|
||||
Value: parsedBundle.CertificateBytes,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to store certificate locally")
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
const pathIssueCertHelpSyn = `
|
||||
Request certificates using a certain role with the provided common name.
|
||||
`
|
||||
Reference in New Issue
Block a user