Support old or imported RSA keys

This commit is contained in:
Darren Shepherd 2019-11-15 23:43:02 +00:00
parent ccf76b35ea
commit 3c2990b7c5
3 changed files with 25 additions and 40 deletions

View File

@ -1,13 +1,16 @@
package factory
import (
"crypto/ecdsa"
"crypto"
"crypto/x509"
"fmt"
"io/ioutil"
"os"
"github.com/rancher/dynamiclistener/cert"
)
func GenCA() (*x509.Certificate, *ecdsa.PrivateKey, error) {
func GenCA() (*x509.Certificate, crypto.Signer, error) {
caKey, err := NewPrivateKey()
if err != nil {
return nil, nil, err
@ -21,7 +24,7 @@ func GenCA() (*x509.Certificate, *ecdsa.PrivateKey, error) {
return caCert, caKey, nil
}
func LoadOrGenCA() (*x509.Certificate, *ecdsa.PrivateKey, error) {
func LoadOrGenCA() (*x509.Certificate, crypto.Signer, error) {
cert, key, err := loadCA()
if err == nil {
return cert, key, nil
@ -52,11 +55,11 @@ func LoadOrGenCA() (*x509.Certificate, *ecdsa.PrivateKey, error) {
return cert, key, nil
}
func loadCA() (*x509.Certificate, *ecdsa.PrivateKey, error) {
func loadCA() (*x509.Certificate, crypto.Signer, error) {
return LoadCerts("./certs/ca.pem", "./certs/ca.key")
}
func LoadCerts(certFile, keyFile string) (*x509.Certificate, *ecdsa.PrivateKey, error) {
func LoadCerts(certFile, keyFile string) (*x509.Certificate, crypto.Signer, error) {
caPem, err := ioutil.ReadFile(certFile)
if err != nil {
return nil, nil, err
@ -66,15 +69,19 @@ func LoadCerts(certFile, keyFile string) (*x509.Certificate, *ecdsa.PrivateKey,
return nil, nil, err
}
key, err := ParseECPrivateKeyPEM(caKey)
key, err := cert.ParsePrivateKeyPEM(caKey)
if err != nil {
return nil, nil, err
}
signer, ok := key.(crypto.Signer)
if !ok {
return nil, nil, fmt.Errorf("key is not a crypto.Signer")
}
cert, err := ParseCertPEM(caPem)
if err != nil {
return nil, nil, err
}
return cert, key, nil
return cert, signer, nil
}

View File

@ -2,7 +2,6 @@ package factory
import (
"crypto"
"crypto/ecdsa"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
@ -15,8 +14,7 @@ import (
)
const (
ECPrivateKeyBlockType = "EC PRIVATE KEY"
CertificateBlockType = "CERTIFICATE"
CertificateBlockType = "CERTIFICATE"
)
func NewSelfSignedCACert(key crypto.Signer, cn string, org ...string) (*x509.Certificate, error) {
@ -72,22 +70,6 @@ func NewSignedCert(signer crypto.Signer, caCert *x509.Certificate, caKey crypto.
return x509.ParseCertificate(cert)
}
func ParseECPrivateKeyPEM(keyData []byte) (*ecdsa.PrivateKey, error) {
var privateKeyPemBlock *pem.Block
for {
privateKeyPemBlock, keyData = pem.Decode(keyData)
if privateKeyPemBlock == nil {
break
}
if privateKeyPemBlock.Type == ECPrivateKeyBlockType {
return x509.ParseECPrivateKey(privateKeyPemBlock.Bytes)
}
}
return nil, fmt.Errorf("pem does not include a valid EC private key")
}
func ParseCertPEM(pemCerts []byte) (*x509.Certificate, error) {
var pemBlock *pem.Block
for {

View File

@ -13,6 +13,7 @@ import (
"sort"
"strings"
"github.com/rancher/dynamiclistener/cert"
v1 "k8s.io/api/core/v1"
)
@ -105,7 +106,7 @@ func (t *TLS) AddCN(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) {
return secret, true, nil
}
func (t *TLS) newCert(domains []string, ips []net.IP, privateKey *ecdsa.PrivateKey) (*x509.Certificate, error) {
func (t *TLS) newCert(domains []string, ips []net.IP, privateKey crypto.Signer) (*x509.Certificate, error) {
return NewSignedCert(privateKey, t.CACert, t.CAKey, t.CN, t.Organization, domains, ips)
}
@ -134,39 +135,34 @@ func NeedsUpdate(secret *v1.Secret, cn ...string) bool {
return false
}
func getPrivateKey(secret *v1.Secret) (*ecdsa.PrivateKey, error) {
func getPrivateKey(secret *v1.Secret) (crypto.Signer, error) {
keyBytes := secret.Data[v1.TLSPrivateKeyKey]
if len(keyBytes) == 0 {
return NewPrivateKey()
}
privateKey, err := ParseECPrivateKeyPEM(keyBytes)
if err == nil {
return privateKey, nil
privateKey, err := cert.ParsePrivateKeyPEM(keyBytes)
if signer, ok := privateKey.(crypto.Signer); ok && err == nil {
return signer, nil
}
return NewPrivateKey()
}
func Marshal(x509Cert *x509.Certificate, privateKey *ecdsa.PrivateKey) ([]byte, []byte, error) {
func Marshal(x509Cert *x509.Certificate, privateKey crypto.Signer) ([]byte, []byte, error) {
certBlock := pem.Block{
Type: CertificateBlockType,
Bytes: x509Cert.Raw,
}
keyBytes, err := x509.MarshalECPrivateKey(privateKey)
keyBytes, err := cert.MarshalPrivateKeyToPEM(privateKey)
if err != nil {
return nil, nil, err
}
keyBlock := pem.Block{
Type: ECPrivateKeyBlockType,
Bytes: keyBytes,
}
return pem.EncodeToMemory(&certBlock), pem.EncodeToMemory(&keyBlock), nil
return pem.EncodeToMemory(&certBlock), keyBytes, nil
}
func NewPrivateKey() (*ecdsa.PrivateKey, error) {
func NewPrivateKey() (crypto.Signer, error) {
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
}