package pki import ( "crypto" "crypto/ecdsa" "crypto/ed25519" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" acmapi "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/apis/anthoscertmanager/v1" ) // EncodePrivateKey will encode a given crypto.PrivateKey by first inspecting // the type of key encoding and then inspecting the type of key provided. // It only supports encoding RSA or ECDSA keys. func EncodePrivateKey(pk crypto.PrivateKey, keyEncoding acmapi.PrivateKeyEncoding) ([]byte, error) { switch keyEncoding { case acmapi.PrivateKeyEncoding(""), acmapi.PKCS1: switch k := pk.(type) { case *rsa.PrivateKey: return EncodePKCS1PrivateKey(k), nil case *ecdsa.PrivateKey: return EncodeECPrivateKey(k) case ed25519.PrivateKey: return EncodePKCS8PrivateKey(k) default: return nil, fmt.Errorf("error encoding private key: unknown key type: %T", pk) } case acmapi.PKCS8: return EncodePKCS8PrivateKey(pk) default: return nil, fmt.Errorf("error encoding private key: unknown key encoding: %s", keyEncoding) } } // EncodePKCS1PrivateKey will marshal a RSA private key into x509 PEM format. func EncodePKCS1PrivateKey(pk *rsa.PrivateKey) []byte { block := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(pk)} return pem.EncodeToMemory(block) } // EncodePKCS8PrivateKey will marshal a private key into x509 PEM format. func EncodePKCS8PrivateKey(pk interface{}) ([]byte, error) { keyBytes, err := x509.MarshalPKCS8PrivateKey(pk) if err != nil { return nil, err } block := &pem.Block{Type: "PRIVATE KEY", Bytes: keyBytes} return pem.EncodeToMemory(block), nil } // EncodeECPrivateKey will marshal an ECDSA private key into x509 PEM format. func EncodeECPrivateKey(pk *ecdsa.PrivateKey) ([]byte, error) { asnBytes, err := x509.MarshalECPrivateKey(pk) if err != nil { return nil, fmt.Errorf("error encoding private key: %s", err.Error()) } block := &pem.Block{Type: "EC PRIVATE KEY", Bytes: asnBytes} return pem.EncodeToMemory(block), nil }