Skip to content

Commit cd43506

Browse files
committed
Default Fabric Crypto Service Provider
This change-set introduces a default implementation of the BCCSP whose interfaces were introduced in https://gerrit.hyperledger.org/r/#/c/2027/ The implementation is based on the crypto/primitives package and provides the following capabilities: 1. ecdsa key generation, sign, verify and public key marshalling, 2. HMAC, 3. Hashing, 4. AES key generation, encryption/decryption in CBC mode with PKCS7 padding. This change-set comes in the context of: https://jira.hyperledger.org/browse/FAB-354 Change-Id: Ica504c36756209ea540d010b4f48a801290a7be2 Signed-off-by: Angelo De Caro <[email protected]>
1 parent b4473da commit cd43506

File tree

7 files changed

+1381
-4
lines changed

7 files changed

+1381
-4
lines changed

core/crypto/bccsp/bccsp.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,12 @@ type Key interface {
3232
// false is this key is asymmetric
3333
Symmetric() bool
3434

35-
// Private returns true if this key is an asymmetric private key,
35+
// Private returns true if this key is a private key,
3636
// false otherwise.
3737
Private() bool
3838

39-
// PublicKey returns the corresponding public key if this key
40-
// is an asymmetric private key. If this key is already public,
41-
// PublicKey returns this key itself.
39+
// PublicKey returns the corresponding public key part of an asymmetric public/private key pair.
40+
// This method returns an error in symmetric key schemes.
4241
PublicKey() (Key, error)
4342
}
4443

core/crypto/bccsp/sw/aeskey.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package sw
2+
3+
import (
4+
"errors"
5+
6+
"github.com/hyperledger/fabric/core/crypto/bccsp"
7+
"github.com/hyperledger/fabric/core/crypto/primitives"
8+
)
9+
10+
type aesPrivateKey struct {
11+
k []byte
12+
exportable bool
13+
}
14+
15+
// Bytes converts this key to its byte representation,
16+
// if this operation is allowed.
17+
func (k *aesPrivateKey) Bytes() (raw []byte, err error) {
18+
if k.exportable {
19+
return k.k, nil
20+
}
21+
22+
return nil, errors.New("Not supported.")
23+
}
24+
25+
// SKI returns the subject key identifier of this key.
26+
func (k *aesPrivateKey) SKI() (ski []byte) {
27+
return primitives.Hash(k.k)
28+
}
29+
30+
// Symmetric returns true if this key is a symmetric key,
31+
// false if this key is asymmetric
32+
func (k *aesPrivateKey) Symmetric() bool {
33+
return true
34+
}
35+
36+
// Private returns true if this key is a private key,
37+
// false otherwise.
38+
func (k *aesPrivateKey) Private() bool {
39+
return true
40+
}
41+
42+
// PublicKey returns the corresponding public key part of an asymmetric public/private key pair.
43+
// This method returns an error in symmetric key schemes.
44+
func (k *aesPrivateKey) PublicKey() (bccsp.Key, error) {
45+
return nil, errors.New("Cannot call this method on a symmetric key.")
46+
}

core/crypto/bccsp/sw/conf.go

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package sw
2+
3+
import (
4+
"errors"
5+
"path/filepath"
6+
7+
"os"
8+
9+
"github.com/spf13/viper"
10+
)
11+
12+
type config struct {
13+
keystorePath string
14+
15+
configurationPathProperty string
16+
}
17+
18+
func (conf *config) init() error {
19+
conf.configurationPathProperty = "security.bccsp.default.keyStorePath"
20+
21+
// Check mandatory fields
22+
var rootPath string
23+
if err := conf.checkProperty(conf.configurationPathProperty); err != nil {
24+
logger.Warning("'security.bccsp.default.keyStorePath' not set. Using the default directory [%s] for temporary files", os.TempDir())
25+
rootPath = os.TempDir()
26+
} else {
27+
rootPath = viper.GetString(conf.configurationPathProperty)
28+
}
29+
logger.Infof("Root Path [%s]", rootPath)
30+
// Set configuration path
31+
rootPath = filepath.Join(rootPath, "crypto")
32+
33+
// Set ks path
34+
conf.keystorePath = filepath.Join(rootPath, "ks")
35+
36+
return nil
37+
}
38+
39+
func (conf *config) checkProperty(property string) error {
40+
res := viper.GetString(property)
41+
if res == "" {
42+
return errors.New("Property not specified in configuration file. Please check that property is set: " + property)
43+
}
44+
return nil
45+
}
46+
47+
func (conf *config) getKeyStorePath() string {
48+
return conf.keystorePath
49+
}
50+
51+
func (conf *config) getPathForAlias(alias, suffix string) string {
52+
return filepath.Join(conf.getKeyStorePath(), alias+"_"+suffix)
53+
}

core/crypto/bccsp/sw/ecdsakey.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package sw
2+
3+
import (
4+
"crypto/ecdsa"
5+
"crypto/x509"
6+
"fmt"
7+
8+
"github.com/hyperledger/fabric/core/crypto/bccsp"
9+
"github.com/hyperledger/fabric/core/crypto/primitives"
10+
)
11+
12+
type ecdsaPrivateKey struct {
13+
k *ecdsa.PrivateKey
14+
}
15+
16+
// ToByte converts this key to its byte representation,
17+
// if this operation is allowed.
18+
func (k *ecdsaPrivateKey) Bytes() (raw []byte, err error) {
19+
return
20+
}
21+
22+
// SKI returns the subject key identifier of this key.
23+
func (k *ecdsaPrivateKey) SKI() (ski []byte) {
24+
raw, _ := primitives.PrivateKeyToDER(k.k)
25+
// TODO: Error should not be thrown. Anyway, move the marshalling at initialization.
26+
27+
return primitives.Hash(raw)
28+
}
29+
30+
// Symmetric returns true if this key is a symmetric key,
31+
// false if this key is asymmetric
32+
func (k *ecdsaPrivateKey) Symmetric() bool {
33+
return false
34+
}
35+
36+
// Private returns true if this key is a private key,
37+
// false otherwise.
38+
func (k *ecdsaPrivateKey) Private() bool {
39+
return true
40+
}
41+
42+
// PublicKey returns the corresponding public key part of an asymmetric public/private key pair.
43+
// This method returns an error in symmetric key schemes.
44+
func (k *ecdsaPrivateKey) PublicKey() (bccsp.Key, error) {
45+
return &ecdsaPublicKey{&k.k.PublicKey}, nil
46+
}
47+
48+
type ecdsaPublicKey struct {
49+
k *ecdsa.PublicKey
50+
}
51+
52+
// ToByte converts this key to its byte representation,
53+
// if this operation is allowed.
54+
func (k *ecdsaPublicKey) Bytes() (raw []byte, err error) {
55+
raw, err = x509.MarshalPKIXPublicKey(k.k)
56+
if err != nil {
57+
return nil, fmt.Errorf("Failed marshalling key [%s]", err)
58+
}
59+
return
60+
}
61+
62+
// SKI returns the subject key identifier of this key.
63+
func (k *ecdsaPublicKey) SKI() (ski []byte) {
64+
raw, _ := primitives.PublicKeyToPEM(k.k, nil)
65+
// TODO: Error should not be thrown. Anyway, move the marshalling at initialization.
66+
67+
return primitives.Hash(raw)
68+
}
69+
70+
// Symmetric returns true if this key is a symmetric key,
71+
// false if this key is asymmetric
72+
func (k *ecdsaPublicKey) Symmetric() bool {
73+
return false
74+
}
75+
76+
// Private returns true if this key is a private key,
77+
// false otherwise.
78+
func (k *ecdsaPublicKey) Private() bool {
79+
return false
80+
}
81+
82+
// PublicKey returns the corresponding public key part of an asymmetric public/private key pair.
83+
// This method returns an error in symmetric key schemes.
84+
func (k *ecdsaPublicKey) PublicKey() (bccsp.Key, error) {
85+
return k, nil
86+
}

0 commit comments

Comments
 (0)