Mostly revert changes to certutil as the embedded struct stuff was being
problematic.
This commit is contained in:
parent
af3d6ced8e
commit
0dbe15cb87
|
@ -585,10 +585,9 @@ func createCertificate(creationInfo *creationBundle) (*certutil.ParsedCertBundle
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resultIface := interface{}(result)
|
|
||||||
if err := certutil.GeneratePrivateKey(creationInfo.KeyType,
|
if err := certutil.GeneratePrivateKey(creationInfo.KeyType,
|
||||||
creationInfo.KeyBits,
|
creationInfo.KeyBits,
|
||||||
resultIface.(certutil.EmbeddedParsedPrivateKeyContainer)); err != nil {
|
result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,10 +692,9 @@ func createCSR(creationInfo *creationBundle) (*certutil.ParsedCSRBundle, error)
|
||||||
var err error
|
var err error
|
||||||
result := &certutil.ParsedCSRBundle{}
|
result := &certutil.ParsedCSRBundle{}
|
||||||
|
|
||||||
resultIface := interface{}(result)
|
|
||||||
if err := certutil.GeneratePrivateKey(creationInfo.KeyType,
|
if err := certutil.GeneratePrivateKey(creationInfo.KeyType,
|
||||||
creationInfo.KeyBits,
|
creationInfo.KeyBits,
|
||||||
resultIface.(certutil.EmbeddedParsedPrivateKeyContainer)); err != nil {
|
result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -184,20 +184,22 @@ func ParsePEMBundle(pemBundle string) (*ParsedCertBundle, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GeneratePrivateKey generates a private key with the specified type and key bits
|
// GeneratePrivateKey generates a private key with the specified type and key bits
|
||||||
func GeneratePrivateKey(keyType string, keyBits int, emb EmbeddedParsedPrivateKeyContainer) error {
|
func GeneratePrivateKey(keyType string, keyBits int, container ParsedPrivateKeyContainer) error {
|
||||||
var err error
|
var err error
|
||||||
result := &EmbeddedParsedPrivateKey{}
|
var privateKeyType int
|
||||||
|
var privateKeyBytes []byte
|
||||||
|
var privateKey crypto.Signer
|
||||||
|
|
||||||
switch keyType {
|
switch keyType {
|
||||||
case "rsa":
|
case "rsa":
|
||||||
result.PrivateKeyType = RSAPrivateKey
|
privateKeyType = RSAPrivateKey
|
||||||
result.PrivateKey, err = rsa.GenerateKey(rand.Reader, keyBits)
|
privateKey, err = rsa.GenerateKey(rand.Reader, keyBits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError{Err: fmt.Sprintf("error generating RSA private key: %v", err)}
|
return InternalError{Err: fmt.Sprintf("error generating RSA private key: %v", err)}
|
||||||
}
|
}
|
||||||
result.PrivateKeyBytes = x509.MarshalPKCS1PrivateKey(result.PrivateKey.(*rsa.PrivateKey))
|
privateKeyBytes = x509.MarshalPKCS1PrivateKey(privateKey.(*rsa.PrivateKey))
|
||||||
case "ec":
|
case "ec":
|
||||||
result.PrivateKeyType = ECPrivateKey
|
privateKeyType = ECPrivateKey
|
||||||
var curve elliptic.Curve
|
var curve elliptic.Curve
|
||||||
switch keyBits {
|
switch keyBits {
|
||||||
case 224:
|
case 224:
|
||||||
|
@ -211,11 +213,11 @@ func GeneratePrivateKey(keyType string, keyBits int, emb EmbeddedParsedPrivateKe
|
||||||
default:
|
default:
|
||||||
return UserError{Err: fmt.Sprintf("unsupported bit length for EC key: %d", keyBits)}
|
return UserError{Err: fmt.Sprintf("unsupported bit length for EC key: %d", keyBits)}
|
||||||
}
|
}
|
||||||
result.PrivateKey, err = ecdsa.GenerateKey(curve, rand.Reader)
|
privateKey, err = ecdsa.GenerateKey(curve, rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError{Err: fmt.Sprintf("error generating EC private key: %v", err)}
|
return InternalError{Err: fmt.Sprintf("error generating EC private key: %v", err)}
|
||||||
}
|
}
|
||||||
result.PrivateKeyBytes, err = x509.MarshalECPrivateKey(result.PrivateKey.(*ecdsa.PrivateKey))
|
privateKeyBytes, err = x509.MarshalECPrivateKey(privateKey.(*ecdsa.PrivateKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return InternalError{Err: fmt.Sprintf("error marshalling EC private key: %v", err)}
|
return InternalError{Err: fmt.Sprintf("error marshalling EC private key: %v", err)}
|
||||||
}
|
}
|
||||||
|
@ -223,7 +225,7 @@ func GeneratePrivateKey(keyType string, keyBits int, emb EmbeddedParsedPrivateKe
|
||||||
return UserError{Err: fmt.Sprintf("unknown key type: %s", keyType)}
|
return UserError{Err: fmt.Sprintf("unknown key type: %s", keyType)}
|
||||||
}
|
}
|
||||||
|
|
||||||
emb.SetParsedPrivateKey(result)
|
container.SetParsedPrivateKey(privateKey, privateKeyType, privateKeyBytes)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,47 +64,28 @@ func (e InternalError) Error() string {
|
||||||
return e.Err
|
return e.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmbeddedPrivateKey contains private key information
|
// Used to allow common key setting for certs and CSRs
|
||||||
type EmbeddedPrivateKey struct {
|
type ParsedPrivateKeyContainer interface {
|
||||||
PrivateKeyType string `json:"private_key_type" structs:"private_key_type" mapstructure:"private_key_type"`
|
SetParsedPrivateKey(crypto.Signer, int, []byte)
|
||||||
PrivateKey string `json:"private_key" structs:"private_key" mapstructure:"private_key"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// EmbeddedParsedPrivateKey contains parsed private key information
|
|
||||||
type EmbeddedParsedPrivateKey struct {
|
|
||||||
PrivateKeyType int
|
|
||||||
PrivateKeyBytes []byte
|
|
||||||
PrivateKey crypto.Signer
|
|
||||||
}
|
|
||||||
|
|
||||||
// EmbeddedPrivateKeyContainer abstracts the private key from
|
|
||||||
// certificates and CSRs to allow common functions
|
|
||||||
type EmbeddedPrivateKeyContainer interface {
|
|
||||||
GetPrivateKey() *EmbeddedPrivateKey
|
|
||||||
SetPrivateKey(*EmbeddedPrivateKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EmbeddedParsedPrivateKeyContainer abstracts the private key from
|
|
||||||
// parsed certificates and parsed CSRs to allow common functions
|
|
||||||
type EmbeddedParsedPrivateKeyContainer interface {
|
|
||||||
GetParsedPrivateKey() *EmbeddedParsedPrivateKey
|
|
||||||
SetParsedPrivateKey(*EmbeddedParsedPrivateKey)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CertBundle contains a key type, a PEM-encoded private key,
|
// CertBundle contains a key type, a PEM-encoded private key,
|
||||||
// a PEM-encoded certificate, and a string-encoded serial number,
|
// a PEM-encoded certificate, and a string-encoded serial number,
|
||||||
// returned from a successful Issue request
|
// returned from a successful Issue request
|
||||||
type CertBundle struct {
|
type CertBundle struct {
|
||||||
EmbeddedPrivateKey
|
PrivateKeyType string `json:"private_key_type" structs:"private_key_type" mapstructure:"private_key_type"`
|
||||||
Certificate string `json:"certificate" structs:"certificate" mapstructure:"certificate"`
|
Certificate string `json:"certificate" structs:"certificate" mapstructure:"certificate"`
|
||||||
IssuingCA string `json:"issuing_ca" structs:"issuing_ca" mapstructure:"issuing_ca"`
|
IssuingCA string `json:"issuing_ca" structs:"issuing_ca" mapstructure:"issuing_ca"`
|
||||||
|
PrivateKey string `json:"private_key" structs:"private_key" mapstructure:"private_key"`
|
||||||
SerialNumber string `json:"serial_number" structs:"serial_number" mapstructure:"serial_number"`
|
SerialNumber string `json:"serial_number" structs:"serial_number" mapstructure:"serial_number"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParsedCertBundle contains a key type, a DER-encoded private key,
|
// ParsedCertBundle contains a key type, a DER-encoded private key,
|
||||||
// and a DER-encoded certificate
|
// and a DER-encoded certificate
|
||||||
type ParsedCertBundle struct {
|
type ParsedCertBundle struct {
|
||||||
EmbeddedParsedPrivateKey
|
PrivateKeyType int
|
||||||
|
PrivateKeyBytes []byte
|
||||||
|
PrivateKey crypto.Signer
|
||||||
IssuingCABytes []byte
|
IssuingCABytes []byte
|
||||||
IssuingCA *x509.Certificate
|
IssuingCA *x509.Certificate
|
||||||
CertificateBytes []byte
|
CertificateBytes []byte
|
||||||
|
@ -114,31 +95,21 @@ type ParsedCertBundle struct {
|
||||||
// CSRBundle contains a key type, a PEM-encoded private key,
|
// CSRBundle contains a key type, a PEM-encoded private key,
|
||||||
// and a PEM-encoded CSR
|
// and a PEM-encoded CSR
|
||||||
type CSRBundle struct {
|
type CSRBundle struct {
|
||||||
EmbeddedPrivateKey
|
PrivateKeyType string `json:"private_key_type" structs:"private_key_type" mapstructure:"private_key_type"`
|
||||||
CSR string `json:"csr" structs:"csr" mapstructure:"csr"`
|
CSR string `json:"csr" structs:"csr" mapstructure:"csr"`
|
||||||
|
PrivateKey string `json:"private_key" structs:"private_key" mapstructure:"private_key"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParsedCSRBundle contains a key type, a DER-encoded private key,
|
// ParsedCSRBundle contains a key type, a DER-encoded private key,
|
||||||
// and a DER-encoded certificate request
|
// and a DER-encoded certificate request
|
||||||
type ParsedCSRBundle struct {
|
type ParsedCSRBundle struct {
|
||||||
EmbeddedParsedPrivateKey
|
PrivateKeyType int
|
||||||
|
PrivateKeyBytes []byte
|
||||||
|
PrivateKey crypto.Signer
|
||||||
CSRBytes []byte
|
CSRBytes []byte
|
||||||
CSR *x509.CertificateRequest
|
CSR *x509.CertificateRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrivateKey returns the embedded private key values
|
|
||||||
func (c *CertBundle) GetPrivateKey() *EmbeddedPrivateKey {
|
|
||||||
return &EmbeddedPrivateKey{
|
|
||||||
PrivateKeyType: c.PrivateKeyType,
|
|
||||||
PrivateKey: c.PrivateKey,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPrivateKey sets the embedded private key values
|
|
||||||
func (c *CertBundle) SetPrivateKey(emb *EmbeddedPrivateKey) {
|
|
||||||
c.EmbeddedPrivateKey = *emb
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToParsedCertBundle converts a string-based certificate bundle
|
// ToParsedCertBundle converts a string-based certificate bundle
|
||||||
// to a byte-based raw certificate bundle
|
// to a byte-based raw certificate bundle
|
||||||
func (c *CertBundle) ToParsedCertBundle() (*ParsedCertBundle, error) {
|
func (c *CertBundle) ToParsedCertBundle() (*ParsedCertBundle, error) {
|
||||||
|
@ -248,18 +219,164 @@ func (p *ParsedCertBundle) ToCertBundle() (*CertBundle, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetParsedPrivateKey returns the embedded private key values
|
// GetSigner returns a crypto.Signer corresponding to the private key
|
||||||
func (p *ParsedCertBundle) GetParsedPrivateKey() *EmbeddedParsedPrivateKey {
|
// contained in this ParsedCertBundle. The Signer contains a Public() function
|
||||||
return &EmbeddedParsedPrivateKey{
|
// for getting the corresponding public. The Signer can also be
|
||||||
PrivateKeyType: p.PrivateKeyType,
|
// type-converted to private keys
|
||||||
PrivateKey: p.PrivateKey,
|
func (p *ParsedCertBundle) getSigner() (crypto.Signer, error) {
|
||||||
PrivateKeyBytes: p.PrivateKeyBytes,
|
var signer crypto.Signer
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if p.PrivateKeyBytes == nil || len(p.PrivateKeyBytes) == 0 {
|
||||||
|
return nil, UserError{"Given parsed cert bundle does not have private key information"}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch p.PrivateKeyType {
|
||||||
|
case ECPrivateKey:
|
||||||
|
signer, err = x509.ParseECPrivateKey(p.PrivateKeyBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, UserError{fmt.Sprintf("Unable to parse CA's private EC key: %s", err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
case RSAPrivateKey:
|
||||||
|
signer, err = x509.ParsePKCS1PrivateKey(p.PrivateKeyBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, UserError{fmt.Sprintf("Unable to parse CA's private RSA key: %s", err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, UserError{"Unable to determine type of private key; only RSA and EC are supported"}
|
||||||
|
}
|
||||||
|
return signer, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetParsedPrivateKey sets the private key parameters on the bundle
|
||||||
|
func (p *ParsedCertBundle) SetParsedPrivateKey(privateKey crypto.Signer, privateKeyType int, privateKeyBytes []byte) {
|
||||||
|
p.PrivateKey = privateKey
|
||||||
|
p.PrivateKeyType = privateKeyType
|
||||||
|
p.PrivateKeyBytes = privateKeyBytes
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToParsedCSRBundle converts a string-based CSR bundle
|
||||||
|
// to a byte-based raw CSR bundle
|
||||||
|
func (c *CSRBundle) ToParsedCSRBundle() (*ParsedCSRBundle, error) {
|
||||||
|
result := &ParsedCSRBundle{}
|
||||||
|
var err error
|
||||||
|
var pemBlock *pem.Block
|
||||||
|
|
||||||
|
if len(c.PrivateKey) > 0 {
|
||||||
|
pemBlock, _ = pem.Decode([]byte(c.PrivateKey))
|
||||||
|
if pemBlock == nil {
|
||||||
|
return nil, UserError{"Error decoding private key from cert bundle"}
|
||||||
|
}
|
||||||
|
result.PrivateKeyBytes = pemBlock.Bytes
|
||||||
|
|
||||||
|
switch c.PrivateKeyType {
|
||||||
|
case "ec":
|
||||||
|
result.PrivateKeyType = ECPrivateKey
|
||||||
|
case "rsa":
|
||||||
|
result.PrivateKeyType = RSAPrivateKey
|
||||||
|
default:
|
||||||
|
// Try to figure it out and correct
|
||||||
|
if _, err := x509.ParseECPrivateKey(pemBlock.Bytes); err == nil {
|
||||||
|
result.PrivateKeyType = ECPrivateKey
|
||||||
|
c.PrivateKeyType = "ec"
|
||||||
|
} else if _, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes); err == nil {
|
||||||
|
result.PrivateKeyType = RSAPrivateKey
|
||||||
|
c.PrivateKeyType = "rsa"
|
||||||
|
} else {
|
||||||
|
return nil, UserError{fmt.Sprintf("Unknown private key type in bundle: %s", c.PrivateKeyType)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetParsedPrivateKey sets the embedded private key values
|
result.PrivateKey, err = result.getSigner()
|
||||||
func (p *ParsedCertBundle) SetParsedPrivateKey(emb *EmbeddedParsedPrivateKey) {
|
if err != nil {
|
||||||
p.EmbeddedParsedPrivateKey = *emb
|
return nil, UserError{fmt.Sprintf("Error getting signer: %s", err)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c.CSR) > 0 {
|
||||||
|
pemBlock, _ = pem.Decode([]byte(c.CSR))
|
||||||
|
if pemBlock == nil {
|
||||||
|
return nil, UserError{"Error decoding certificate from cert bundle"}
|
||||||
|
}
|
||||||
|
result.CSRBytes = pemBlock.Bytes
|
||||||
|
result.CSR, err = x509.ParseCertificateRequest(result.CSRBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, UserError{"Error encountered parsing certificate bytes from raw bundle"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToCSRBundle converts a byte-based raw DER certificate bundle
|
||||||
|
// to a PEM-based string certificate bundle
|
||||||
|
func (p *ParsedCSRBundle) ToCSRBundle() (*CSRBundle, error) {
|
||||||
|
result := &CSRBundle{}
|
||||||
|
block := pem.Block{
|
||||||
|
Type: "CERTIFICATE REQUEST",
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.CSRBytes != nil && len(p.CSRBytes) > 0 {
|
||||||
|
block.Bytes = p.CSRBytes
|
||||||
|
result.CSR = strings.TrimSpace(string(pem.EncodeToMemory(&block)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.PrivateKeyBytes != nil && len(p.PrivateKeyBytes) > 0 {
|
||||||
|
block.Bytes = p.PrivateKeyBytes
|
||||||
|
switch p.PrivateKeyType {
|
||||||
|
case RSAPrivateKey:
|
||||||
|
result.PrivateKeyType = "rsa"
|
||||||
|
block.Type = "RSA PRIVATE KEY"
|
||||||
|
case ECPrivateKey:
|
||||||
|
result.PrivateKeyType = "ec"
|
||||||
|
block.Type = "EC PRIVATE KEY"
|
||||||
|
default:
|
||||||
|
return nil, InternalError{"Could not determine private key type when creating block"}
|
||||||
|
}
|
||||||
|
result.PrivateKey = strings.TrimSpace(string(pem.EncodeToMemory(&block)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSigner returns a crypto.Signer corresponding to the private key
|
||||||
|
// contained in this ParsedCSRBundle. The Signer contains a Public() function
|
||||||
|
// for getting the corresponding public. The Signer can also be
|
||||||
|
// type-converted to private keys
|
||||||
|
func (p *ParsedCSRBundle) getSigner() (crypto.Signer, error) {
|
||||||
|
var signer crypto.Signer
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if p.PrivateKeyBytes == nil || len(p.PrivateKeyBytes) == 0 {
|
||||||
|
return nil, UserError{"Given parsed cert bundle does not have private key information"}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch p.PrivateKeyType {
|
||||||
|
case ECPrivateKey:
|
||||||
|
signer, err = x509.ParseECPrivateKey(p.PrivateKeyBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, UserError{fmt.Sprintf("Unable to parse CA's private EC key: %s", err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
case RSAPrivateKey:
|
||||||
|
signer, err = x509.ParsePKCS1PrivateKey(p.PrivateKeyBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, UserError{fmt.Sprintf("Unable to parse CA's private RSA key: %s", err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, UserError{"Unable to determine type of private key; only RSA and EC are supported"}
|
||||||
|
}
|
||||||
|
return signer, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetParsedPrivateKey sets the private key parameters on the bundle
|
||||||
|
func (p *ParsedCSRBundle) SetParsedPrivateKey(privateKey crypto.Signer, privateKeyType int, privateKeyBytes []byte) {
|
||||||
|
p.PrivateKey = privateKey
|
||||||
|
p.PrivateKeyType = privateKeyType
|
||||||
|
p.PrivateKeyBytes = privateKeyBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTLSConfig returns a TLS config generally suitable for client
|
// GetTLSConfig returns a TLS config generally suitable for client
|
||||||
|
@ -320,148 +437,6 @@ func (p *ParsedCertBundle) GetTLSConfig(usage TLSUsage) (*tls.Config, error) {
|
||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrivateKey returns the embedded private key values
|
|
||||||
func (c *CSRBundle) GetPrivateKey() *EmbeddedPrivateKey {
|
|
||||||
return &EmbeddedPrivateKey{
|
|
||||||
PrivateKeyType: c.PrivateKeyType,
|
|
||||||
PrivateKey: c.PrivateKey,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPrivateKey sets the embedded private key values
|
|
||||||
func (c *CSRBundle) SetPrivateKey(emb *EmbeddedPrivateKey) {
|
|
||||||
c.EmbeddedPrivateKey = *emb
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToParsedCSRBundle converts a string-based CSR bundle
|
|
||||||
// to a byte-based raw CSR bundle
|
|
||||||
func (c *CSRBundle) ToParsedCSRBundle() (*ParsedCSRBundle, error) {
|
|
||||||
result := &ParsedCSRBundle{}
|
|
||||||
var err error
|
|
||||||
var pemBlock *pem.Block
|
|
||||||
|
|
||||||
if len(c.PrivateKey) > 0 {
|
|
||||||
pemBlock, _ = pem.Decode([]byte(c.PrivateKey))
|
|
||||||
if pemBlock == nil {
|
|
||||||
return nil, UserError{"Error decoding private key from cert bundle"}
|
|
||||||
}
|
|
||||||
result.PrivateKeyBytes = pemBlock.Bytes
|
|
||||||
|
|
||||||
switch c.PrivateKeyType {
|
|
||||||
case "ec":
|
|
||||||
result.PrivateKeyType = ECPrivateKey
|
|
||||||
case "rsa":
|
|
||||||
result.PrivateKeyType = RSAPrivateKey
|
|
||||||
default:
|
|
||||||
// Try to figure it out and correct
|
|
||||||
if _, err := x509.ParseECPrivateKey(pemBlock.Bytes); err == nil {
|
|
||||||
result.PrivateKeyType = ECPrivateKey
|
|
||||||
c.PrivateKeyType = "ec"
|
|
||||||
} else if _, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes); err == nil {
|
|
||||||
result.PrivateKeyType = RSAPrivateKey
|
|
||||||
c.PrivateKeyType = "rsa"
|
|
||||||
} else {
|
|
||||||
return nil, UserError{fmt.Sprintf("Unknown private key type in bundle: %s", c.PrivateKeyType)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.PrivateKey, err = result.getSigner()
|
|
||||||
if err != nil {
|
|
||||||
return nil, UserError{fmt.Sprintf("Error getting signer: %s", err)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(c.CSR) > 0 {
|
|
||||||
pemBlock, _ = pem.Decode([]byte(c.CSR))
|
|
||||||
if pemBlock == nil {
|
|
||||||
return nil, UserError{"Error decoding certificate from cert bundle"}
|
|
||||||
}
|
|
||||||
result.CSRBytes = pemBlock.Bytes
|
|
||||||
result.CSR, err = x509.ParseCertificateRequest(result.CSRBytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, UserError{"Error encountered parsing certificate bytes from raw bundle"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetParsedPrivateKey returns the embedded private key values
|
|
||||||
func (p *ParsedCSRBundle) GetParsedPrivateKey() *EmbeddedParsedPrivateKey {
|
|
||||||
return &EmbeddedParsedPrivateKey{
|
|
||||||
PrivateKeyType: p.PrivateKeyType,
|
|
||||||
PrivateKey: p.PrivateKey,
|
|
||||||
PrivateKeyBytes: p.PrivateKeyBytes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetParsedPrivateKey sets the embedded private key values
|
|
||||||
func (p *ParsedCSRBundle) SetParsedPrivateKey(emb *EmbeddedParsedPrivateKey) {
|
|
||||||
p.EmbeddedParsedPrivateKey = *emb
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToCSRBundle converts a byte-based raw DER certificate bundle
|
|
||||||
// to a PEM-based string certificate bundle
|
|
||||||
func (p *ParsedCSRBundle) ToCSRBundle() (*CSRBundle, error) {
|
|
||||||
result := &CSRBundle{}
|
|
||||||
block := pem.Block{
|
|
||||||
Type: "CERTIFICATE REQUEST",
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.CSRBytes != nil && len(p.CSRBytes) > 0 {
|
|
||||||
block.Bytes = p.CSRBytes
|
|
||||||
result.CSR = strings.TrimSpace(string(pem.EncodeToMemory(&block)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.PrivateKeyBytes != nil && len(p.PrivateKeyBytes) > 0 {
|
|
||||||
block.Bytes = p.PrivateKeyBytes
|
|
||||||
switch p.PrivateKeyType {
|
|
||||||
case RSAPrivateKey:
|
|
||||||
result.PrivateKeyType = "rsa"
|
|
||||||
block.Type = "RSA PRIVATE KEY"
|
|
||||||
case ECPrivateKey:
|
|
||||||
result.PrivateKeyType = "ec"
|
|
||||||
block.Type = "EC PRIVATE KEY"
|
|
||||||
default:
|
|
||||||
return nil, InternalError{"Could not determine private key type when creating block"}
|
|
||||||
}
|
|
||||||
result.PrivateKey = strings.TrimSpace(string(pem.EncodeToMemory(&block)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSigner returns a crypto.Signer corresponding to the private key
|
|
||||||
// contained in this ParsedCSRBundle. The Signer contains a Public() function
|
|
||||||
// for getting the corresponding public. The Signer can also be
|
|
||||||
// type-converted to private keys
|
|
||||||
func (e *EmbeddedParsedPrivateKey) getSigner() (crypto.Signer, error) {
|
|
||||||
var signer crypto.Signer
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if e.PrivateKeyBytes == nil || len(e.PrivateKeyBytes) == 0 {
|
|
||||||
return nil, UserError{"given parsed bundle does not have private key information"}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch e.PrivateKeyType {
|
|
||||||
case ECPrivateKey:
|
|
||||||
signer, err = x509.ParseECPrivateKey(e.PrivateKeyBytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, UserError{fmt.Sprintf("unable to parse EC key: %s", err)}
|
|
||||||
}
|
|
||||||
|
|
||||||
case RSAPrivateKey:
|
|
||||||
signer, err = x509.ParsePKCS1PrivateKey(e.PrivateKeyBytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, UserError{fmt.Sprintf("Unable to parse RSA key: %s", err)}
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil, UserError{"unable to determine type of private key; only RSA and EC are supported"}
|
|
||||||
}
|
|
||||||
return signer, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IssueData is a structure that is suitable for marshaling into a request;
|
// IssueData is a structure that is suitable for marshaling into a request;
|
||||||
// either via JSON, or into a map[string]interface{} via the structs package
|
// either via JSON, or into a map[string]interface{} via the structs package
|
||||||
type IssueData struct {
|
type IssueData struct {
|
||||||
|
|
Loading…
Reference in a new issue