From 7bf6a1321eac21e43089d15112fd74db41b4ccdd Mon Sep 17 00:00:00 2001 From: Chris Elder Date: Mon, 22 Jan 2024 18:22:40 -0500 Subject: [PATCH] Re-add the RSA definitions to BCCSP - RSA implementation additional changes BCCSP supported RSA in version 1.4. The Fabric CA is currently using the Fabric 1.4 dependency. It is necessary to move Fabric CA off of Fabric 1.4 dependencies since they are no longer maintained. Fabric 2.X does not support RSA, however the CA still needs to support RSA for any older but not expired certificates that may be in use by older netwo Github: https://github.com/hyperledger/fabric/issues/4625 Signed-off-by: Chris Elder --- bccsp/sw/fileks.go | 21 +++++++++++++++++++++ bccsp/sw/keyimport.go | 35 +++++++++++++++++++++++++++++++++++ bccsp/sw/keys.go | 34 ++++++++++++++++++++++++++++++++-- bccsp/sw/new.go | 4 ++++ 4 files changed, 92 insertions(+), 2 deletions(-) diff --git a/bccsp/sw/fileks.go b/bccsp/sw/fileks.go index 8dfb52af513..d0e002bc25d 100644 --- a/bccsp/sw/fileks.go +++ b/bccsp/sw/fileks.go @@ -9,6 +9,7 @@ package sw import ( "bytes" "crypto/ecdsa" + "crypto/rsa" "encoding/hex" "errors" "fmt" @@ -141,6 +142,8 @@ func (ks *fileBasedKeyStore) GetKey(ski []byte) (bccsp.Key, error) { switch k := key.(type) { case *ecdsa.PrivateKey: return &ecdsaPrivateKey{k}, nil + case *rsa.PrivateKey: + return &rsaPrivateKey{k}, nil default: return nil, errors.New("secret key type not recognized") } @@ -154,6 +157,8 @@ func (ks *fileBasedKeyStore) GetKey(ski []byte) (bccsp.Key, error) { switch k := key.(type) { case *ecdsa.PublicKey: return &ecdsaPublicKey{k}, nil + case *rsa.PublicKey: + return &rsaPublicKey{k}, nil default: return nil, errors.New("public key type not recognized") } @@ -185,6 +190,20 @@ func (ks *fileBasedKeyStore) StoreKey(k bccsp.Key) (err error) { return fmt.Errorf("failed storing ECDSA public key [%s]", err) } + case *rsaPrivateKey: + + err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.privKey) + if err != nil { + return fmt.Errorf("failed storing RSA private key [%s]", err) + } + + case *rsaPublicKey: + + err = ks.storePublicKey(hex.EncodeToString(k.SKI()), kk.pubKey) + if err != nil { + return fmt.Errorf("failed storing RSA public key [%s]", err) + } + case *aesPrivateKey: err = ks.storeKey(hex.EncodeToString(k.SKI()), kk.privKey) if err != nil { @@ -227,6 +246,8 @@ func (ks *fileBasedKeyStore) searchKeystoreForSKI(ski []byte) (k bccsp.Key, err switch kk := key.(type) { case *ecdsa.PrivateKey: k = &ecdsaPrivateKey{kk} + case *rsa.PrivateKey: + k = &rsaPrivateKey{kk} default: continue } diff --git a/bccsp/sw/keyimport.go b/bccsp/sw/keyimport.go index fb57bc26b9e..e37104e8bc7 100644 --- a/bccsp/sw/keyimport.go +++ b/bccsp/sw/keyimport.go @@ -112,6 +112,17 @@ func (*ecdsaGoPublicKeyImportOptsKeyImporter) KeyImport(raw interface{}, opts bc return &ecdsaPublicKey{lowLevelKey}, nil } +type rsaGoPublicKeyImportOptsKeyImporter struct{} + +func (*rsaGoPublicKeyImportOptsKeyImporter) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (bccsp.Key, error) { + lowLevelKey, ok := raw.(*rsa.PublicKey) + if !ok { + return nil, errors.New("Invalid raw material. Expected *rsa.PublicKey") + } + + return &rsaPublicKey{lowLevelKey}, nil +} + type x509PublicKeyImportOptsKeyImporter struct { bccsp *CSP } @@ -137,3 +148,27 @@ func (ki *x509PublicKeyImportOptsKeyImporter) KeyImport(raw interface{}, opts bc return nil, errors.New("Certificate's public key type not recognized. Supported keys: [ECDSA, RSA]") } } + +/* +func (ki *x509PublicKeyImportOptsKeyImporter) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (bccsp.Key, error) { + x509Cert, ok := raw.(*x509.Certificate) + if !ok { + return nil, errors.New("Invalid raw material. Expected *x509.Certificate.") + } + + pk := x509Cert.PublicKey + + switch pk := pk.(type) { + case *ecdsa.PublicKey: + return ki.bccsp.KeyImporters[reflect.TypeOf(&bccsp.ECDSAGoPublicKeyImportOpts{})].KeyImport( + pk, + &bccsp.ECDSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral()}) + case *rsa.PublicKey: + return ki.bccsp.KeyImporters[reflect.TypeOf(&bccsp.RSAGoPublicKeyImportOpts{})].KeyImport( + pk, + &bccsp.RSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral()}) + default: + return nil, errors.New("Certificate's public key type not recognized. Supported keys: [ECDSA, RSA]") + } +} +*/ diff --git a/bccsp/sw/keys.go b/bccsp/sw/keys.go index 579e6844247..6a7f3880ab2 100644 --- a/bccsp/sw/keys.go +++ b/bccsp/sw/keys.go @@ -10,6 +10,7 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" + "crypto/rsa" "crypto/x509" "encoding/asn1" "encoding/pem" @@ -114,8 +115,21 @@ func privateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) { }, ), nil + case *rsa.PrivateKey: + if k == nil { + return nil, errors.New("invalid rsa private key. It must be different from nil") + } + raw := x509.MarshalPKCS1PrivateKey(k) + + return pem.EncodeToMemory( + &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: raw, + }, + ), nil + default: - return nil, errors.New("invalid key type. It must be *ecdsa.PrivateKey") + return nil, errors.New("invalid key type. It must be *ecdsa.PrivateKey or *rsa.PrivateKey") } } @@ -279,8 +293,24 @@ func publicKeyToPEM(publicKey interface{}, pwd []byte) ([]byte, error) { }, ), nil + case *rsa.PublicKey: + if k == nil { + return nil, errors.New("invalid rsa public key. It must be different from nil") + } + PubASN1, err := x509.MarshalPKIXPublicKey(k) + if err != nil { + return nil, err + } + + return pem.EncodeToMemory( + &pem.Block{ + Type: "RSA PUBLIC KEY", + Bytes: PubASN1, + }, + ), nil + default: - return nil, errors.New("invalid key type. It must be *ecdsa.PublicKey") + return nil, errors.New("invalid key type. It must be *ecdsa.PublicKey or *rsa.PublicKey") } } diff --git a/bccsp/sw/new.go b/bccsp/sw/new.go index b8b10c77b00..52780913aad 100644 --- a/bccsp/sw/new.go +++ b/bccsp/sw/new.go @@ -60,10 +60,13 @@ func NewWithParams(securityLevel int, hashFamily string, keyStore bccsp.KeyStore // Set the Signers swbccsp.AddWrapper(reflect.TypeOf(&ecdsaPrivateKey{}), &ecdsaSigner{}) + swbccsp.AddWrapper(reflect.TypeOf(&rsaPrivateKey{}), &rsaSigner{}) // Set the Verifiers swbccsp.AddWrapper(reflect.TypeOf(&ecdsaPrivateKey{}), &ecdsaPrivateKeyVerifier{}) swbccsp.AddWrapper(reflect.TypeOf(&ecdsaPublicKey{}), &ecdsaPublicKeyKeyVerifier{}) + swbccsp.AddWrapper(reflect.TypeOf(&rsaPrivateKey{}), &rsaPrivateKeyVerifier{}) + swbccsp.AddWrapper(reflect.TypeOf(&rsaPublicKey{}), &rsaPublicKeyKeyVerifier{}) // Set the Hashers swbccsp.AddWrapper(reflect.TypeOf(&bccsp.SHAOpts{}), &hasher{hash: conf.hashFunction}) @@ -97,6 +100,7 @@ func NewWithParams(securityLevel int, hashFamily string, keyStore bccsp.KeyStore swbccsp.AddWrapper(reflect.TypeOf(&bccsp.ECDSAPKIXPublicKeyImportOpts{}), &ecdsaPKIXPublicKeyImportOptsKeyImporter{}) swbccsp.AddWrapper(reflect.TypeOf(&bccsp.ECDSAPrivateKeyImportOpts{}), &ecdsaPrivateKeyImportOptsKeyImporter{}) swbccsp.AddWrapper(reflect.TypeOf(&bccsp.ECDSAGoPublicKeyImportOpts{}), &ecdsaGoPublicKeyImportOptsKeyImporter{}) + swbccsp.AddWrapper(reflect.TypeOf(&bccsp.RSAGoPublicKeyImportOpts{}), &rsaGoPublicKeyImportOptsKeyImporter{}) swbccsp.AddWrapper(reflect.TypeOf(&bccsp.X509PublicKeyImportOpts{}), &x509PublicKeyImportOptsKeyImporter{bccsp: swbccsp}) return swbccsp, nil