Update tests and finish implementation of PKCS8 handling

This commit is contained in:
Andrew Stuart 2015-12-09 13:41:32 -07:00
parent 39a3a92e79
commit e38596fc1c
No known key found for this signature in database
GPG Key ID: D409317C5B5ACD4D
2 changed files with 103 additions and 5 deletions

View File

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"log"
"strings"
"testing"
@ -18,18 +19,23 @@ import (
func TestCertBundleConversion(t *testing.T) {
cbuts := []*CertBundle{
refreshRSACertBundle(),
refreshRSA8CertBundle(),
refreshECCertBundle(),
refreshEC8CertBundle(),
}
for _, cbut := range cbuts {
for i, cbut := range cbuts {
pcbut, err := cbut.ToParsedCertBundle()
if err != nil {
t.Fatalf("Error converting to parsed cert bundle: %s", err)
t.Logf("Error occurred with bundle %d in test array (index %d).\n", i+1, i)
t.Errorf("Error converting to parsed cert bundle: %s", err)
continue
}
err = compareCertBundleToParsedCertBundle(cbut, pcbut)
if err != nil {
t.Fatalf(err.Error())
t.Logf("Error occurred with bundle %d in test array (index %d).\n", i+1, i)
t.Errorf(err.Error())
}
cbut, err := pcbut.ToCertBundle()
@ -108,10 +114,18 @@ func compareCertBundleToParsedCertBundle(cbut *CertBundle, pcbut *ParsedCertBund
if pcbut.PrivateKeyType != RSAPrivateKey {
return fmt.Errorf("Parsed bundle has wrong private key type")
}
case privRSA8KeyPem:
if pcbut.PrivateKeyType != RSAPrivateKey {
return fmt.Errorf("Parsed bundle has wrong private key type")
}
case privECKeyPem:
if pcbut.PrivateKeyType != ECPrivateKey {
return fmt.Errorf("Parsed bundle has wrong private key type")
}
case privEC8KeyPem:
if pcbut.PrivateKeyType != ECPrivateKey {
return fmt.Errorf("Parsed bundle has wrong private key type")
}
default:
return fmt.Errorf("Parsed bundle has unknown private key type")
}
@ -143,14 +157,15 @@ func compareCertBundleToParsedCertBundle(cbut *CertBundle, pcbut *ParsedCertBund
if pcbut.PrivateKeyType != RSAPrivateKey {
return fmt.Errorf("Bundle has wrong private key type")
}
if cb.PrivateKey != privRSAKeyPem {
if cb.PrivateKey != privRSAKeyPem && cb.PrivateKey != privRSA8KeyPem {
log.Println(cb.PrivateKey, privRSAKeyPem, privRSA8KeyPem)
return fmt.Errorf("Bundle private key does not match")
}
case "ec":
if pcbut.PrivateKeyType != ECPrivateKey {
return fmt.Errorf("Bundle has wrong private key type")
}
if cb.PrivateKey != privECKeyPem {
if cb.PrivateKey != privECKeyPem && cb.PrivateKey != privEC8KeyPem {
return fmt.Errorf("Bundle private key does not match")
}
default:
@ -326,6 +341,14 @@ func TestTLSConfig(t *testing.T) {
}
}
func refreshRSA8CertBundle() *CertBundle {
return &CertBundle{
Certificate: certRSAPem,
PrivateKey: privRSA8KeyPem,
IssuingCA: issuingCaPem,
}
}
func refreshRSACertBundle() *CertBundle {
ret := &CertBundle{
Certificate: certRSAPem,
@ -360,7 +383,44 @@ func refreshECCSRBundle() *CSRBundle {
return ret
}
func refreshEC8CertBundle() *CertBundle {
return &CertBundle{
Certificate: certECPem,
PrivateKey: privEC8KeyPem,
IssuingCA: issuingCaPem,
}
}
const (
privRSA8KeyPem = `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC3dklRrO0JGJWD
zs/TLxPtAw0VCLrUEJIgp6nFddZzvOLkklIx9ACy1ckSoFiJKGxKlibqyiJPqFfT
vi3vBAAcZLf67uo2iBamZMBRNSc0gz5ALEfY1z+TNjFpZqO6lXOAa8t6KpTd3i0h
ST9mR+29YmvKvaFlzzMQ3cLikZL/YX5FD7M6/4GkAjUF1tAaEXub3a+fopL+Jayq
bAcb2gKGC9Z4EeNZQjyoZq4Fz6K3hLlHF83wkkgFdQhm1tqoVnOCO/yRQPKqhAa+
Rj/gJ7UrRsUmwzvCYw+/7lCxwgEXgpaA3SRNIw89d+ef9AgB+FphCRP0yPAavr4H
dI4M0YJNAgMBAAECggEAe1LCGmsZs2GZL88XmKguxsWkR51kqSSydcz+rEN38rjn
9Cn/oqCYz54x2Zl7qkdH9CNW6cESq2VIFIfkrKSNxohVvBJZ0mpMf3F+bZhDUGNg
txaM/VBD5hspv+ZE7SmFSLAtSWPSSgoNYDCys3hqcUH1n4U1NxC/DPllBZRBsfSd
5C1Y7WcO8uxJyC7WRyGgTMkQloU5DX4d8Z5bEPvrp9nKplCLn5wuuE6oc4ZKU74g
VV7SGC6IQcWv0sQ9NdeRm05HjBN/uPVSzyzUpD+O/TWzH1LscRtkm6vMiNLbc7LA
RR0l3USwgTaUlXZBTBKICw9hk5JBmWA4bM9VEpWQaQKBgQDW76lU/av7FLFjLwpx
1xEJ0YYGHTRUvHXIlEdZnliMXnqGnRHRwb7EYtqvkoJ0GmviMmdAYivHyXDdIMK3
gReXGAnGK1eUG2IoHIzv+ZhFF9RGv1YxGvjzwZCVYNujZdqWe5pzSqWQWpUiDQFp
b5nXkD8TUvr1pTFpHSjOUD0mXwKBgQDag0DkXai2rOj141i5w0COKFWEBN3XUMQJ
C9shCn/RsQl7RmefOr9AgYg5VqkLRUoYHAE/kO4svU/+dM+OMT9mGMW6Ew0zk/ML
qhsCMGH6AKlz5z7bVB6u/tEpROLawZPNEe6WlxxEN+4XxuHMPqUCjnQWlKY8T+i9
nNv34ixe0wKBgFWdR0z0cqHjvzjrzvRDn6TSkdkzntm17BDGh5k6Crl3FMU0IZn0
28EsQ0G2UUJgF+MVAq3RrPC627spRoaD5FqqF5KZRxxWwAWMQdOBD1dOQ58erf2H
aezmiGoIF9UBSE2y1HXiIQrcGhVjKtHNw3DrI0TWQ+K/N2xQUiXELmdvAoGANRSN
PuxBf56hOJnxg66aj+3cWCWWfidwd4IZyPzz78xBsWB464Up0FGm9cbHaaV7SkAD
TZ23Pcb/F6DoinIMJJD/9yOJoW3fLIY16WI3arOedjlGW6Ejkv7zcEL7mIhNjxM8
EfjDNQ8hF0WItETDcMuKB7I0b5I5x1XDWYPno2ECgYEAsWHewaSG8+Ij8b+L/m0Z
lUD91L/gNVc6gdbjf5kMdYTCqI3q9N/9VWJyb7yRx8tjUTl9J//h7uYhCrujmpWf
1jcdaxqNLUUV7OcmM+PglprUe96A1zJwDOxc5DvHLbf/zBS6mA14PWYV1IUJdDdR
52wm5UEewSU9zlbvirgXj4U=
-----END PRIVATE KEY-----`
privRSAKeyPem = `-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAt3ZJUaztCRiVg87P0y8T7QMNFQi61BCSIKepxXXWc7zi5JJS
MfQAstXJEqBYiShsSpYm6soiT6hX074t7wQAHGS3+u7qNogWpmTAUTUnNIM+QCxH
@ -445,6 +505,12 @@ wvvgOeCBovN3tSuGKzTiUKAAMAoGCCqGSM49BAMCAz8AMDwCHFap/5XDuqtXCG1g
ljbYH5OWGBqGYCfL2k2+/6cCHAuk1bmOkGx7JAq/fSPd09i0DQIqUu7WHQHms48=
-----END CERTIFICATE REQUEST-----`
privEC8KeyPem = `-----BEGIN PRIVATE KEY-----
MHgCAQAwEAYHKoZIzj0CAQYFK4EEACEEYTBfAgEBBBzN57mC5a72sATfYRlXLvZq
WghK+yzHuOGu6EDsoTwDOgAEwWd1V8ARPaHkkRKTOW9uT1ulori2+BF1qSmco4+e
dkGCmHu0AbhnvcL74DnggaLzd7Urhis04lA=
-----END PRIVATE KEY-----`
certECPem = `-----BEGIN CERTIFICATE-----
MIIDJDCCAg6gAwIBAgIUM3J02tw0ZvpHUVHv6t8kcoft2/MwCwYJKoZIhvcNAQEL
MBsxGTAXBgNVBAMMEFZhdWx0IFRlc3RpbmcgQ0EwHhcNMTUwNjE5MTcyODQyWhcN

View File

@ -10,6 +10,8 @@ package certutil
import (
"crypto"
"crypto/ecdsa"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"encoding/pem"
@ -84,6 +86,7 @@ type CertBundle struct {
// and a DER-encoded certificate
type ParsedCertBundle struct {
PrivateKeyType int
PKCS8 bool
PrivateKeyBytes []byte
PrivateKey crypto.Signer
IssuingCABytes []byte
@ -137,6 +140,17 @@ func (c *CertBundle) ToParsedCertBundle() (*ParsedCertBundle, error) {
} else if _, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes); err == nil {
result.PrivateKeyType = RSAPrivateKey
c.PrivateKeyType = "rsa"
} else if k, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes); err == nil {
result.PKCS8 = true
switch k.(type) {
case *ecdsa.PrivateKey:
result.PrivateKeyType = ECPrivateKey
c.PrivateKeyType = "ec"
case *rsa.PrivateKey:
result.PrivateKeyType = RSAPrivateKey
c.PrivateKeyType = "rsa"
}
} else {
return nil, UserError{fmt.Sprintf("Unknown private key type in bundle: %s", c.PrivateKeyType)}
}
@ -213,6 +227,9 @@ func (p *ParsedCertBundle) ToCertBundle() (*CertBundle, error) {
default:
return nil, InternalError{"Could not determine private key type when creating block"}
}
if p.PKCS8 {
block.Type = "PRIVATE KEY"
}
result.PrivateKey = strings.TrimSpace(string(pem.EncodeToMemory(&block)))
}
@ -231,6 +248,21 @@ func (p *ParsedCertBundle) getSigner() (crypto.Signer, error) {
return nil, UserError{"Given parsed cert bundle does not have private key information"}
}
if p.PKCS8 {
if k, err := x509.ParsePKCS8PrivateKey(p.PrivateKeyBytes); err == nil {
switch k := k.(type) {
case *rsa.PrivateKey:
return k, nil
case *ecdsa.PrivateKey:
return k, nil
default:
return nil, UserError{fmt.Sprintf("Unable to determine pkcs8 key type")}
}
} else {
return nil, UserError{fmt.Sprintf("Error decoding pkcs8: %v", err)}
}
}
switch p.PrivateKeyType {
case ECPrivateKey:
signer, err = x509.ParseECPrivateKey(p.PrivateKeyBytes)