Skip to content

Commit 55fd4c4

Browse files
committed
BCCSP Generalized Key Import
This change-set generalizes the BCCSP key import function. It now takes in input an interface{} and allows direct import of golang objects like keys and certificates. This change-set comes in the context of: https://jira.hyperledger.org/browse/FAB-354 Change-Id: I48a52b7d6aa1426922efa23661167c602da769f6 Signed-off-by: Angelo De Caro <[email protected]>
1 parent 9d3abd1 commit 55fd4c4

File tree

4 files changed

+54
-61
lines changed

4 files changed

+54
-61
lines changed

core/crypto/bccsp/bccsp.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ type BCCSP interface {
110110

111111
// KeyImport imports a key from its raw representation using opts.
112112
// The opts argument should be appropriate for the primitive used.
113-
KeyImport(raw []byte, opts KeyImportOpts) (k Key, err error)
113+
KeyImport(raw interface{}, opts KeyImportOpts) (k Key, err error)
114114

115115
// GetKey returns the key this CSP associates to
116116
// the Subject Key Identifier ski.

core/crypto/bccsp/bccsp_opts.go

-24
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@ limitations under the License.
1616

1717
package bccsp
1818

19-
import (
20-
"crypto/ecdsa"
21-
"crypto/rsa"
22-
"crypto/x509"
23-
)
24-
2519
const (
2620
// ECDSA Elliptic Curve Digital Signature Algorithm (key gen, import, sign, verify),
2721
// at default security level (see primitives package).
@@ -105,7 +99,6 @@ func (opts *ECDSAPrivateKeyImportOpts) Ephemeral() bool {
10599
// ECDSAGoPublicKeyImportOpts contains options for ECDSA key importation from ecdsa.PublicKey
106100
type ECDSAGoPublicKeyImportOpts struct {
107101
Temporary bool
108-
PK *ecdsa.PublicKey
109102
}
110103

111104
// Algorithm returns an identifier for the algorithm to be used
@@ -120,11 +113,6 @@ func (opts *ECDSAGoPublicKeyImportOpts) Ephemeral() bool {
120113
return opts.Temporary
121114
}
122115

123-
// PublicKey returns the ecdsa.PublicKey to be imported.
124-
func (opts *ECDSAGoPublicKeyImportOpts) PublicKey() *ecdsa.PublicKey {
125-
return opts.PK
126-
}
127-
128116
// ECDSAReRandKeyOpts contains options for ECDSA key re-randomization.
129117
type ECDSAReRandKeyOpts struct {
130118
Temporary bool
@@ -280,7 +268,6 @@ func (opts *RSAKeyGenOpts) Ephemeral() bool {
280268
// ECDSAGoPublicKeyImportOpts contains options for RSA key importation from rsa.PublicKey
281269
type RSAGoPublicKeyImportOpts struct {
282270
Temporary bool
283-
PK *rsa.PublicKey
284271
}
285272

286273
// Algorithm returns an identifier for the algorithm to be used
@@ -295,15 +282,9 @@ func (opts *RSAGoPublicKeyImportOpts) Ephemeral() bool {
295282
return opts.Temporary
296283
}
297284

298-
// PublicKey returns the ecdsa.PublicKey to be imported.
299-
func (opts *RSAGoPublicKeyImportOpts) PublicKey() *rsa.PublicKey {
300-
return opts.PK
301-
}
302-
303285
// X509PublicKeyImportOpts contains options for importing public keys from an x509 certificate
304286
type X509PublicKeyImportOpts struct {
305287
Temporary bool
306-
Cert *x509.Certificate
307288
}
308289

309290
// Algorithm returns an identifier for the algorithm to be used
@@ -317,8 +298,3 @@ func (opts *X509PublicKeyImportOpts) Algorithm() string {
317298
func (opts *X509PublicKeyImportOpts) Ephemeral() bool {
318299
return opts.Temporary
319300
}
320-
321-
// PublicKey returns the ecdsa.PublicKey to be imported.
322-
func (opts *X509PublicKeyImportOpts) Certificate() *x509.Certificate {
323-
return opts.Cert
324-
}

core/crypto/bccsp/sw/impl.go

+43-24
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import (
2828

2929
"hash"
3030

31+
"crypto/x509"
32+
3133
"github.com/hyperledger/fabric/core/crypto/bccsp"
3234
"github.com/hyperledger/fabric/core/crypto/primitives"
3335
"github.com/hyperledger/fabric/core/crypto/utils"
@@ -256,21 +258,29 @@ func (csp *impl) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, e
256258

257259
// KeyImport imports a key from its raw representation using opts.
258260
// The opts argument should be appropriate for the primitive used.
259-
func (csp *impl) KeyImport(raw []byte, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) {
261+
func (csp *impl) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) {
260262
// Validate arguments
263+
if raw == nil {
264+
return nil, errors.New("Invalid raw. Cannot be nil")
265+
}
266+
261267
if opts == nil {
262268
return nil, errors.New("Invalid Opts parameter. It must not be nil.")
263269
}
264270

265271
switch opts.(type) {
266272

267273
case *bccsp.AES256ImportKeyOpts:
274+
aesRaw, ok := raw.([]byte)
275+
if !ok {
276+
return nil, errors.New("[AES256ImportKeyOpts] Invalid raw material. Expected byte array.")
277+
}
268278

269-
if len(raw) != 32 {
270-
return nil, fmt.Errorf("[AES256ImportKeyOpts] Invalid Key Length [%d]. Must be 32 bytes", len(raw))
279+
if len(aesRaw) != 32 {
280+
return nil, fmt.Errorf("[AES256ImportKeyOpts] Invalid Key Length [%d]. Must be 32 bytes", len(aesRaw))
271281
}
272282

273-
aesK := &aesPrivateKey{utils.Clone(raw), false}
283+
aesK := &aesPrivateKey{utils.Clone(aesRaw), false}
274284

275285
// If the key is not Ephemeral, store it.
276286
if !opts.Ephemeral() {
@@ -284,12 +294,16 @@ func (csp *impl) KeyImport(raw []byte, opts bccsp.KeyImportOpts) (k bccsp.Key, e
284294
return aesK, nil
285295

286296
case *bccsp.HMACImportKeyOpts:
297+
aesRaw, ok := raw.([]byte)
298+
if !ok {
299+
return nil, errors.New("[HMACImportKeyOpts] Invalid raw material. Expected byte array.")
300+
}
287301

288-
if len(raw) == 0 {
302+
if len(aesRaw) == 0 {
289303
return nil, errors.New("[HMACImportKeyOpts] Invalid raw. It must not be nil.")
290304
}
291305

292-
aesK := &aesPrivateKey{utils.Clone(raw), false}
306+
aesK := &aesPrivateKey{utils.Clone(aesRaw), false}
293307

294308
// If the key is not Ephemeral, store it.
295309
if !opts.Ephemeral() {
@@ -303,12 +317,16 @@ func (csp *impl) KeyImport(raw []byte, opts bccsp.KeyImportOpts) (k bccsp.Key, e
303317
return aesK, nil
304318

305319
case *bccsp.ECDSAPKIXPublicKeyImportOpts:
320+
der, ok := raw.([]byte)
321+
if !ok {
322+
return nil, errors.New("[ECDSAPKIXPublicKeyImportOpts] Invalid raw material. Expected byte array.")
323+
}
306324

307-
if len(raw) == 0 {
325+
if len(der) == 0 {
308326
return nil, errors.New("[ECDSAPKIXPublicKeyImportOpts] Invalid raw. It must not be nil.")
309327
}
310328

311-
lowLevelKey, err := primitives.DERToPublicKey(raw)
329+
lowLevelKey, err := primitives.DERToPublicKey(der)
312330
if err != nil {
313331
return nil, fmt.Errorf("Failed converting PKIX to ECDSA public key [%s]", err)
314332
}
@@ -332,12 +350,16 @@ func (csp *impl) KeyImport(raw []byte, opts bccsp.KeyImportOpts) (k bccsp.Key, e
332350
return k, nil
333351

334352
case *bccsp.ECDSAPrivateKeyImportOpts:
353+
der, ok := raw.([]byte)
354+
if !ok {
355+
return nil, errors.New("[ECDSADERPrivateKeyImportOpts] Invalid raw material. Expected byte array.")
356+
}
335357

336-
if len(raw) == 0 {
358+
if len(der) == 0 {
337359
return nil, errors.New("[ECDSADERPrivateKeyImportOpts] Invalid raw. It must not be nil.")
338360
}
339361

340-
lowLevelKey, err := primitives.DERToPrivateKey(raw)
362+
lowLevelKey, err := primitives.DERToPrivateKey(der)
341363
if err != nil {
342364
return nil, fmt.Errorf("Failed converting PKIX to ECDSA public key [%s]", err)
343365
}
@@ -361,10 +383,9 @@ func (csp *impl) KeyImport(raw []byte, opts bccsp.KeyImportOpts) (k bccsp.Key, e
361383
return k, nil
362384

363385
case *bccsp.ECDSAGoPublicKeyImportOpts:
364-
365-
lowLevelKey := opts.(*bccsp.ECDSAGoPublicKeyImportOpts).PublicKey()
366-
if lowLevelKey == nil {
367-
return nil, errors.New("Invalid Opts. ECDSA Public key cannot be nil")
386+
lowLevelKey, ok := raw.(*ecdsa.PublicKey)
387+
if !ok {
388+
return nil, errors.New("[ECDSAGoPublicKeyImportOpts] Invalid raw material. Expected *ecdsa.PublicKey.")
368389
}
369390

370391
k = &ecdsaPublicKey{lowLevelKey}
@@ -381,10 +402,9 @@ func (csp *impl) KeyImport(raw []byte, opts bccsp.KeyImportOpts) (k bccsp.Key, e
381402
return k, nil
382403

383404
case *bccsp.RSAGoPublicKeyImportOpts:
384-
385-
lowLevelKey := opts.(*bccsp.RSAGoPublicKeyImportOpts).PublicKey()
386-
if lowLevelKey == nil {
387-
return nil, errors.New("Invalid Opts. ECDSA Public key cannot be nil")
405+
lowLevelKey, ok := raw.(*rsa.PublicKey)
406+
if !ok {
407+
return nil, errors.New("[RSAGoPublicKeyImportOpts] Invalid raw material. Expected *rsa.PublicKey.")
388408
}
389409

390410
k = &rsaPublicKey{lowLevelKey}
@@ -401,19 +421,18 @@ func (csp *impl) KeyImport(raw []byte, opts bccsp.KeyImportOpts) (k bccsp.Key, e
401421
return k, nil
402422

403423
case *bccsp.X509PublicKeyImportOpts:
404-
405-
x509Cert := opts.(*bccsp.X509PublicKeyImportOpts).Certificate()
406-
if x509Cert == nil {
407-
return nil, errors.New("Invalid Opts. X509 certificate cannot be nil")
424+
x509Cert, ok := raw.(*x509.Certificate)
425+
if !ok {
426+
return nil, errors.New("[X509PublicKeyImportOpts] Invalid raw material. Expected *x509.Certificate.")
408427
}
409428

410429
pk := x509Cert.PublicKey
411430

412431
switch pk.(type) {
413432
case *ecdsa.PublicKey:
414-
return csp.KeyImport(nil, &bccsp.ECDSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral(), PK: pk.(*ecdsa.PublicKey)})
433+
return csp.KeyImport(pk, &bccsp.ECDSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral()})
415434
case *rsa.PublicKey:
416-
return csp.KeyImport(nil, &bccsp.RSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral(), PK: pk.(*rsa.PublicKey)})
435+
return csp.KeyImport(pk, &bccsp.RSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral()})
417436
default:
418437
return nil, errors.New("Certificate public key type not recognized. Supported keys: [ECDSA, RSA]")
419438
}

core/crypto/bccsp/sw/impl_test.go

+10-12
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ import (
2323
"crypto"
2424
"crypto/rsa"
2525

26-
"crypto/ecdsa"
27-
2826
"crypto/rand"
2927
"crypto/x509"
3028
"crypto/x509/pkix"
@@ -387,7 +385,7 @@ func TestECDSAKeyImportFromECDSAPublicKey(t *testing.T) {
387385
}
388386

389387
// Import the ecdsa.PublicKey
390-
pk2, err := csp.KeyImport(pkRaw, &bccsp.ECDSAGoPublicKeyImportOpts{Temporary: true, PK: pub.(*ecdsa.PublicKey)})
388+
pk2, err := csp.KeyImport(pub, &bccsp.ECDSAGoPublicKeyImportOpts{Temporary: true})
391389
if err != nil {
392390
t.Fatalf("Failed importing ECDSA public key [%s]", err)
393391
}
@@ -543,8 +541,8 @@ func TestKeyImportFromX509ECDSAPublicKey(t *testing.T) {
543541
},
544542
}
545543

546-
signer := &signer.CryptoSigner{}
547-
err = signer.Init(csp, k)
544+
cryptoSigner := &signer.CryptoSigner{}
545+
err = cryptoSigner.Init(csp, k)
548546
if err != nil {
549547
t.Fatalf("Failed initializing CyrptoSigner [%s]", err)
550548
}
@@ -565,7 +563,7 @@ func TestKeyImportFromX509ECDSAPublicKey(t *testing.T) {
565563
t.Fatalf("Failed converting raw to ECDSA.PublicKey [%s]", err)
566564
}
567565

568-
certRaw, err := x509.CreateCertificate(rand.Reader, &template, &template, pub, signer)
566+
certRaw, err := x509.CreateCertificate(rand.Reader, &template, &template, pub, cryptoSigner)
569567
if err != nil {
570568
t.Fatalf("Failed generating self-signed certificate [%s]", err)
571569
}
@@ -576,7 +574,7 @@ func TestKeyImportFromX509ECDSAPublicKey(t *testing.T) {
576574
}
577575

578576
// Import the certificate's public key
579-
pk2, err := csp.KeyImport(nil, &bccsp.X509PublicKeyImportOpts{Temporary: true, Cert: cert})
577+
pk2, err := csp.KeyImport(cert, &bccsp.X509PublicKeyImportOpts{Temporary: true})
580578

581579
if err != nil {
582580
t.Fatalf("Failed importing ECDSA public key [%s]", err)
@@ -1086,7 +1084,7 @@ func TestRSAKeyImportFromRSAPublicKey(t *testing.T) {
10861084
}
10871085

10881086
// Import the RSA.PublicKey
1089-
pk2, err := csp.KeyImport(pkRaw, &bccsp.RSAGoPublicKeyImportOpts{Temporary: true, PK: pub.(*rsa.PublicKey)})
1087+
pk2, err := csp.KeyImport(pub, &bccsp.RSAGoPublicKeyImportOpts{Temporary: true})
10901088
if err != nil {
10911089
t.Fatalf("Failed importing RSA public key [%s]", err)
10921090
}
@@ -1182,8 +1180,8 @@ func TestKeyImportFromX509RSAPublicKey(t *testing.T) {
11821180
},
11831181
}
11841182

1185-
signer := &signer.CryptoSigner{}
1186-
err = signer.Init(csp, k)
1183+
cryptoSigner := &signer.CryptoSigner{}
1184+
err = cryptoSigner.Init(csp, k)
11871185
if err != nil {
11881186
t.Fatalf("Failed initializing CyrptoSigner [%s]", err)
11891187
}
@@ -1204,7 +1202,7 @@ func TestKeyImportFromX509RSAPublicKey(t *testing.T) {
12041202
t.Fatalf("Failed converting raw to RSA.PublicKey [%s]", err)
12051203
}
12061204

1207-
certRaw, err := x509.CreateCertificate(rand.Reader, &template, &template, pub, signer)
1205+
certRaw, err := x509.CreateCertificate(rand.Reader, &template, &template, pub, cryptoSigner)
12081206
if err != nil {
12091207
t.Fatalf("Failed generating self-signed certificate [%s]", err)
12101208
}
@@ -1215,7 +1213,7 @@ func TestKeyImportFromX509RSAPublicKey(t *testing.T) {
12151213
}
12161214

12171215
// Import the certificate's public key
1218-
pk2, err := csp.KeyImport(nil, &bccsp.X509PublicKeyImportOpts{Temporary: true, Cert: cert})
1216+
pk2, err := csp.KeyImport(cert, &bccsp.X509PublicKeyImportOpts{Temporary: true})
12191217

12201218
if err != nil {
12211219
t.Fatalf("Failed importing RSA public key [%s]", err)

0 commit comments

Comments
 (0)