mirror of
https://github.com/rancher/dynamiclistener.git
synced 2025-07-17 16:11:23 +00:00
Merge pull request #11 from ibuildthecloud/master
Support old or imported RSA keys
This commit is contained in:
commit
b6b942bff0
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -80,9 +80,19 @@ func (s *storage) init(secrets v1controller.SecretController) {
|
||||
})
|
||||
s.secrets = secrets
|
||||
|
||||
secret, err := s.storage.Get()
|
||||
if err == nil && secret != nil {
|
||||
s.saveInK8s(secret)
|
||||
if secret, err := s.storage.Get(); err == nil && secret != nil && len(secret.Data) > 0 {
|
||||
// just ensure there is a secret in k3s
|
||||
if _, err := s.secrets.Get(s.namespace, s.name, metav1.GetOptions{}); errors.IsNotFound(err) {
|
||||
_, _ = s.secrets.Create(&v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: s.name,
|
||||
Namespace: s.namespace,
|
||||
Annotations: secret.Annotations,
|
||||
},
|
||||
Type: v1.SecretTypeTLS,
|
||||
Data: secret.Data,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,10 +142,10 @@ func (s *storage) saveInK8s(secret *v1.Secret) (*v1.Secret, error) {
|
||||
targetSecret.Data = secret.Data
|
||||
|
||||
if targetSecret.UID == "" {
|
||||
logrus.Infof("Creating new TLS secret for %v (count: %d)", targetSecret.Name, len(targetSecret.Data)-1)
|
||||
logrus.Infof("Creating new TLS secret for %v (count: %d): %v", targetSecret.Name, len(targetSecret.Annotations)-1, targetSecret.Annotations)
|
||||
return s.secrets.Create(targetSecret)
|
||||
} else {
|
||||
logrus.Infof("Updating TLS secret for %v (count: %d)", targetSecret.Name, len(targetSecret.Data)-1)
|
||||
logrus.Infof("Updating TLS secret for %v (count: %d): %v", targetSecret.Name, len(targetSecret.Annotations)-1, targetSecret.Annotations)
|
||||
return s.secrets.Update(targetSecret)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package memory
|
||||
|
||||
import (
|
||||
"github.com/rancher/dynamiclistener"
|
||||
"github.com/sirupsen/logrus"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
@ -15,7 +16,7 @@ func NewBacked(storage dynamiclistener.TLSStorage) dynamiclistener.TLSStorage {
|
||||
|
||||
type memory struct {
|
||||
storage dynamiclistener.TLSStorage
|
||||
secret *v1.Secret
|
||||
secret *v1.Secret
|
||||
}
|
||||
|
||||
func (m *memory) Get() (*v1.Secret, error) {
|
||||
@ -37,6 +38,7 @@ func (m *memory) Update(secret *v1.Secret) error {
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Infof("Active TLS secret %s (ver=%s) (count %d): %v", secret.Name, secret.ResourceVersion, len(secret.Annotations)-1, secret.Annotations)
|
||||
m.secret = secret
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user