Update flag to field with format info

This commit is contained in:
Andrew Stuart 2015-12-10 21:00:17 -07:00
parent 50b7be1c9a
commit ceb74f956c
No known key found for this signature in database
GPG Key ID: D409317C5B5ACD4D
2 changed files with 43 additions and 16 deletions

View File

@ -123,6 +123,7 @@ func ParsePEMBundle(pemBundle string) (*ParsedCertBundle, error) {
if parsedBundle.PrivateKeyType != UnknownPrivateKey { if parsedBundle.PrivateKeyType != UnknownPrivateKey {
return nil, UserError{"more than one private key given; provide only one private key in the bundle"} return nil, UserError{"more than one private key given; provide only one private key in the bundle"}
} }
parsedBundle.PrivateKeyFormat = EC
parsedBundle.PrivateKeyType = ECPrivateKey parsedBundle.PrivateKeyType = ECPrivateKey
parsedBundle.PrivateKeyBytes = pemBlock.Bytes parsedBundle.PrivateKeyBytes = pemBlock.Bytes
parsedBundle.PrivateKey = signer parsedBundle.PrivateKey = signer
@ -132,10 +133,11 @@ func ParsePEMBundle(pemBundle string) (*ParsedCertBundle, error) {
return nil, UserError{"more than one private key given; provide only one private key in the bundle"} return nil, UserError{"more than one private key given; provide only one private key in the bundle"}
} }
parsedBundle.PrivateKeyType = RSAPrivateKey parsedBundle.PrivateKeyType = RSAPrivateKey
parsedBundle.PrivateKeyFormat = PKCS1
parsedBundle.PrivateKeyBytes = pemBlock.Bytes parsedBundle.PrivateKeyBytes = pemBlock.Bytes
parsedBundle.PrivateKey = signer parsedBundle.PrivateKey = signer
} else if signer, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes); err == nil { } else if signer, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes); err == nil {
parsedBundle.PKCS8 = true parsedBundle.PrivateKeyFormat = PKCS8
if parsedBundle.PrivateKeyType != UnknownPrivateKey { if parsedBundle.PrivateKeyType != UnknownPrivateKey {
return nil, UserError{"More than one private key given; provide only one private key in the bundle"} return nil, UserError{"More than one private key given; provide only one private key in the bundle"}

View File

@ -47,6 +47,16 @@ const (
TLSClient TLSClient
) )
//KeyFormat indicates the serialization format of the key
type KeyFormat string
//Well-known formats
const (
PKCS1 KeyFormat = "pkcs1"
PKCS8 KeyFormat = "pkcs8"
EC KeyFormat = "ec"
)
// UserError represents an error generated due to invalid user input // UserError represents an error generated due to invalid user input
type UserError struct { type UserError struct {
Err string Err string
@ -66,7 +76,7 @@ func (e InternalError) Error() string {
return e.Err return e.Err
} }
// Used to allow common key setting for certs and CSRs //ParsedPrivateKeyContainer allows common key setting for certs and CSRs
type ParsedPrivateKeyContainer interface { type ParsedPrivateKeyContainer interface {
SetParsedPrivateKey(crypto.Signer, int, []byte) SetParsedPrivateKey(crypto.Signer, int, []byte)
} }
@ -76,6 +86,7 @@ type ParsedPrivateKeyContainer interface {
// returned from a successful Issue request // returned from a successful Issue request
type CertBundle struct { type CertBundle struct {
PrivateKeyType string `json:"private_key_type" structs:"private_key_type" mapstructure:"private_key_type"` PrivateKeyType string `json:"private_key_type" structs:"private_key_type" mapstructure:"private_key_type"`
PrivateKeyFormat KeyFormat `json:"private_key_format" structs:"private_key_format" mapstructure:"private_key_format"`
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"` PrivateKey string `json:"private_key" structs:"private_key" mapstructure:"private_key"`
@ -86,7 +97,7 @@ type CertBundle struct {
// and a DER-encoded certificate // and a DER-encoded certificate
type ParsedCertBundle struct { type ParsedCertBundle struct {
PrivateKeyType int PrivateKeyType int
PKCS8 bool PrivateKeyFormat KeyFormat
PrivateKeyBytes []byte PrivateKeyBytes []byte
PrivateKey crypto.Signer PrivateKey crypto.Signer
IssuingCABytes []byte IssuingCABytes []byte
@ -126,6 +137,7 @@ func (c *CertBundle) ToParsedCertBundle() (*ParsedCertBundle, error) {
return nil, UserError{"Error decoding private key from cert bundle"} return nil, UserError{"Error decoding private key from cert bundle"}
} }
result.PrivateKeyBytes = pemBlock.Bytes result.PrivateKeyBytes = pemBlock.Bytes
result.PrivateKeyFormat = c.PrivateKeyFormat
switch c.PrivateKeyType { switch c.PrivateKeyType {
case "ec": case "ec":
@ -135,13 +147,20 @@ func (c *CertBundle) ToParsedCertBundle() (*ParsedCertBundle, error) {
default: default:
// Try to figure it out and correct // Try to figure it out and correct
if _, err := x509.ParseECPrivateKey(pemBlock.Bytes); err == nil { if _, err := x509.ParseECPrivateKey(pemBlock.Bytes); err == nil {
result.PrivateKeyFormat = EC
c.PrivateKeyFormat = EC
result.PrivateKeyType = ECPrivateKey result.PrivateKeyType = ECPrivateKey
c.PrivateKeyType = "ec" c.PrivateKeyType = "ec"
} else if _, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes); err == nil { } else if _, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes); err == nil {
result.PrivateKeyFormat = PKCS1
c.PrivateKeyFormat = PKCS1
result.PrivateKeyType = RSAPrivateKey result.PrivateKeyType = RSAPrivateKey
c.PrivateKeyType = "rsa" c.PrivateKeyType = "rsa"
} else if k, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes); err == nil { } else if k, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes); err == nil {
result.PKCS8 = true result.PrivateKeyFormat = PKCS8
c.PrivateKeyFormat = PKCS8
switch k.(type) { switch k.(type) {
case *ecdsa.PrivateKey: case *ecdsa.PrivateKey:
@ -216,6 +235,7 @@ func (p *ParsedCertBundle) ToCertBundle() (*CertBundle, error) {
} }
if p.PrivateKeyBytes != nil && len(p.PrivateKeyBytes) > 0 { if p.PrivateKeyBytes != nil && len(p.PrivateKeyBytes) > 0 {
result.PrivateKeyFormat = p.PrivateKeyFormat
block.Bytes = p.PrivateKeyBytes block.Bytes = p.PrivateKeyBytes
switch p.PrivateKeyType { switch p.PrivateKeyType {
case RSAPrivateKey: case RSAPrivateKey:
@ -227,7 +247,7 @@ func (p *ParsedCertBundle) ToCertBundle() (*CertBundle, error) {
default: default:
return nil, InternalError{"Could not determine private key type when creating block"} return nil, InternalError{"Could not determine private key type when creating block"}
} }
if p.PKCS8 { if p.PrivateKeyFormat == PKCS8 {
block.Type = "PRIVATE KEY" block.Type = "PRIVATE KEY"
} }
result.PrivateKey = strings.TrimSpace(string(pem.EncodeToMemory(&block))) result.PrivateKey = strings.TrimSpace(string(pem.EncodeToMemory(&block)))
@ -248,14 +268,19 @@ func (p *ParsedCertBundle) getSigner() (crypto.Signer, error) {
return nil, UserError{"Given parsed cert bundle does not have private key information"} return nil, UserError{"Given parsed cert bundle does not have private key information"}
} }
if p.PrivateKeyFormat == PKCS8 {
if k, err := x509.ParsePKCS8PrivateKey(p.PrivateKeyBytes); err == nil { if k, err := x509.ParsePKCS8PrivateKey(p.PrivateKeyBytes); err == nil {
switch k := k.(type) { switch k := k.(type) {
case *rsa.PrivateKey: case *rsa.PrivateKey:
return k, nil return k, nil
case *ecdsa.PrivateKey: case *ecdsa.PrivateKey:
return k, nil return k, nil
default:
return nil, UserError{"Found unknown private key type in pkcs#8 wrapping"}
} }
} }
return nil, UserError{fmt.Sprintf("Failed to parse pkcs#8 key: %v", err)}
}
switch p.PrivateKeyType { switch p.PrivateKeyType {
case ECPrivateKey: case ECPrivateKey: