Skip to content

Commit 446573e

Browse files
committed
[FAB-2362] Customizable Hash at MSP
This change-set does the following: 1. It allows the hash function to be used to sign/verify and to compute the msp identity's identifier. In order to do so, FabricMSPConfig message has been enhanced to contain information about the crypto algorithms to be used. Currently, the configuration values are hardcoded. Change-Id: I50c78fb907f48ebdf66e3833b595ff5cbfde5e9e Signed-off-by: Angelo De Caro <[email protected]>
1 parent 88ac3ba commit 446573e

10 files changed

+203
-44
lines changed

bccsp/hashopts.go

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

1717
package bccsp
1818

19+
import "fmt"
20+
1921
// SHA256Opts contains options relating to SHA-256.
2022
type SHA256Opts struct {
2123
}
@@ -51,3 +53,18 @@ type SHA3_384Opts struct {
5153
func (opts *SHA3_384Opts) Algorithm() string {
5254
return SHA3_384
5355
}
56+
57+
// GetHashOpt returns the HashOpts corresponding to the passed hash function
58+
func GetHashOpt(hashFunction string) (HashOpts, error) {
59+
switch hashFunction {
60+
case SHA256:
61+
return &SHA256Opts{}, nil
62+
case SHA384:
63+
return &SHA384Opts{}, nil
64+
case SHA3_256:
65+
return &SHA3_256Opts{}, nil
66+
case SHA3_384:
67+
return &SHA3_384Opts{}, nil
68+
}
69+
return nil, fmt.Errorf("hash function not recognized [%s]", hashFunction)
70+
}

bccsp/opts.go

+5
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ const (
6666
// an error will be returned.
6767
SHA = "SHA"
6868

69+
// SHA2 is an identifier for SHA2 hash family
70+
SHA2 = "SHA2"
71+
// SHA3 is an identifier for SHA3 hash family
72+
SHA3 = "SHA3"
73+
6974
// SHA256
7075
SHA256 = "SHA256"
7176
// SHA384

msp/configbuilder.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"encoding/pem"
2626
"path/filepath"
2727

28+
"github.com/hyperledger/fabric/bccsp"
2829
"github.com/hyperledger/fabric/bccsp/factory"
2930
"github.com/hyperledger/fabric/protos/msp"
3031
)
@@ -161,12 +162,20 @@ func getMspConfig(dir string, bccspConfig *factory.FactoryOpts, ID string, sigid
161162
intermediatecert, _ := getPemMaterialFromDir(intermediatecertsDir)
162163
// intermediate certs are not mandatory
163164

165+
// Load FabricCryptoConfig
166+
cryptoConfig := &msp.FabricCryptoConfig{
167+
SignatureHashFamily: bccsp.SHA2,
168+
IdentityIdentifierHashFunction: bccsp.SHA256,
169+
}
170+
171+
// Compose FabricMSPConfig
164172
fmspconf := &msp.FabricMSPConfig{
165173
Admins: admincert,
166174
RootCerts: cacerts,
167175
IntermediateCerts: intermediatecert,
168176
SigningIdentity: sigid,
169-
Name: ID}
177+
Name: ID,
178+
CryptoConfig: cryptoConfig}
170179

171180
fmpsjs, _ := proto.Marshal(fmspconf)
172181

msp/identities.go

+22-2
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,12 @@ func (id *identity) Verify(msg []byte, sig []byte) error {
116116
// mspLogger.Infof("Verifying signature")
117117

118118
// Compute Hash
119-
digest, err := id.msp.bccsp.Hash(msg, &bccsp.SHA256Opts{})
119+
hashOpt, err := id.getHashOpt(id.msp.cryptoConfig.SignatureHashFamily)
120+
if err != nil {
121+
return fmt.Errorf("Failed getting hash function options [%s]", err)
122+
}
123+
124+
digest, err := id.msp.bccsp.Hash(msg, hashOpt)
120125
if err != nil {
121126
return fmt.Errorf("Failed computing digest [%s]", err)
122127
}
@@ -167,6 +172,16 @@ func (id *identity) Serialize() ([]byte, error) {
167172
return idBytes, nil
168173
}
169174

175+
func (id *identity) getHashOpt(hashFamily string) (bccsp.HashOpts, error) {
176+
switch hashFamily {
177+
case bccsp.SHA2:
178+
return bccsp.GetHashOpt(bccsp.SHA256)
179+
case bccsp.SHA3:
180+
return bccsp.GetHashOpt(bccsp.SHA3_256)
181+
}
182+
return nil, fmt.Errorf("hash famility not recognized [%s]", hashFamily)
183+
}
184+
170185
type signingidentity struct {
171186
// we embed everything from a base identity
172187
identity
@@ -185,7 +200,12 @@ func (id *signingidentity) Sign(msg []byte) ([]byte, error) {
185200
//mspLogger.Infof("Signing message")
186201

187202
// Compute Hash
188-
digest, err := id.msp.bccsp.Hash(msg, &bccsp.SHA256Opts{})
203+
hashOpt, err := id.getHashOpt(id.msp.cryptoConfig.SignatureHashFamily)
204+
if err != nil {
205+
return nil, fmt.Errorf("Failed getting hash function options [%s]", err)
206+
}
207+
208+
digest, err := id.msp.bccsp.Hash(msg, hashOpt)
189209
if err != nil {
190210
return nil, fmt.Errorf("Failed computing digest [%s]", err)
191211
}

msp/mspimpl.go

+41-4
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ type bccspmsp struct {
6464

6565
// list of OUs
6666
ouIdentifiers []*m.FabricOUIdentifier
67+
68+
// cryptoConfig contains
69+
cryptoConfig *m.FabricCryptoConfig
6770
}
6871

6972
// NewBccspMsp returns an MSP instance backed up by a BCCSP
@@ -82,7 +85,7 @@ func NewBccspMsp() (MSP, error) {
8285

8386
func (msp *bccspmsp) getIdentityFromConf(idBytes []byte) (Identity, bccsp.Key, error) {
8487
if idBytes == nil {
85-
return nil, nil, fmt.Errorf("getIdentityFromBytes error: nil idBytes")
88+
return nil, nil, fmt.Errorf("getIdentityFromConf error: nil idBytes")
8689
}
8790

8891
// Decode the pem bytes
@@ -105,7 +108,12 @@ func (msp *bccspmsp) getIdentityFromConf(idBytes []byte) (Identity, bccsp.Key, e
105108
}
106109

107110
// Use the hash of the identity's certificate as id in the IdentityIdentifier
108-
digest, err := factory.GetDefault().Hash(cert.Raw, &bccsp.SHA256Opts{})
111+
hashOpt, err := bccsp.GetHashOpt(msp.cryptoConfig.IdentityIdentifierHashFunction)
112+
if err != nil {
113+
return nil, nil, fmt.Errorf("getIdentityFromConf failed getting hash function options [%s]", err)
114+
}
115+
116+
digest, err := msp.bccsp.Hash(cert.Raw, hashOpt)
109117
if err != nil {
110118
return nil, nil, fmt.Errorf("getIdentityFromConf failed hashing raw certificate to compute the id of the IdentityIdentifier [%s]", err)
111119
}
@@ -152,7 +160,12 @@ func (msp *bccspmsp) getSigningIdentityFromConf(sidInfo *m.SigningIdentityInfo)
152160
}
153161

154162
// Use the hash of the identity's certificate as id in the IdentityIdentifier
155-
digest, err := factory.GetDefault().Hash(idPub.(*identity).cert.Raw, &bccsp.SHA256Opts{})
163+
hashOpt, err := bccsp.GetHashOpt(msp.cryptoConfig.IdentityIdentifierHashFunction)
164+
if err != nil {
165+
return nil, fmt.Errorf("getIdentityFromBytes failed getting hash function options [%s]", err)
166+
}
167+
168+
digest, err := msp.bccsp.Hash(idPub.(*identity).cert.Raw, hashOpt)
156169
if err != nil {
157170
return nil, fmt.Errorf("Failed hashing raw certificate to compute the id of the IdentityIdentifier [%s]", err)
158171
}
@@ -263,6 +276,25 @@ func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error {
263276
msp.name = conf.Name
264277
mspLogger.Debugf("Setting up MSP instance %s", msp.name)
265278

279+
// setup crypto config
280+
msp.cryptoConfig = conf.CryptoConfig
281+
if msp.cryptoConfig == nil {
282+
// Move to defaults
283+
msp.cryptoConfig = &m.FabricCryptoConfig{
284+
SignatureHashFamily: bccsp.SHA2,
285+
IdentityIdentifierHashFunction: bccsp.SHA256,
286+
}
287+
mspLogger.Debugf("CryptoConfig was nil. Move to defaults.")
288+
}
289+
if msp.cryptoConfig.SignatureHashFamily == "" {
290+
msp.cryptoConfig.SignatureHashFamily = bccsp.SHA2
291+
mspLogger.Debugf("CryptoConfig.SignatureHashFamily was nil. Move to defaults.")
292+
}
293+
if msp.cryptoConfig.IdentityIdentifierHashFunction == "" {
294+
msp.cryptoConfig.IdentityIdentifierHashFunction = bccsp.SHA256
295+
mspLogger.Debugf("CryptoConfig.IdentityIdentifierHashFunction was nil. Move to defaults.")
296+
}
297+
266298
// make and fill the set of admin certs (if present)
267299
msp.admins = make([]Identity, len(conf.Admins))
268300
for i, admCert := range conf.Admins {
@@ -526,7 +558,12 @@ func (msp *bccspmsp) deserializeIdentityInternal(serializedIdentity []byte) (Ide
526558
// (yet) to encode the MSP ID into the x.509 body of a cert
527559

528560
// Use the hash of the identity's certificate as id in the IdentityIdentifier
529-
digest, err := factory.GetDefault().Hash(cert.Raw, &bccsp.SHA256Opts{})
561+
hashOpt, err := bccsp.GetHashOpt(msp.cryptoConfig.IdentityIdentifierHashFunction)
562+
if err != nil {
563+
return nil, fmt.Errorf("Failed getting hash function options [%s]", err)
564+
}
565+
566+
digest, err := msp.bccsp.Hash(cert.Raw, hashOpt)
530567
if err != nil {
531568
return nil, fmt.Errorf("Failed hashing raw certificate to compute the id of the IdentityIdentifier [%s]", err)
532569
}

msp/mspwithintermediatecas_test.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"testing"
2121

2222
"github.com/golang/protobuf/proto"
23+
"github.com/hyperledger/fabric/bccsp"
2324
"github.com/hyperledger/fabric/protos/msp"
2425
"github.com/stretchr/testify/assert"
2526
)
@@ -90,11 +91,17 @@ func TestMSPWithIntermediateCAs(t *testing.T) {
9091

9192
sigid := &msp.SigningIdentityInfo{PublicSigner: []byte(signcert), PrivateSigner: keyinfo}
9293

94+
cryptoConfig := &msp.FabricCryptoConfig{
95+
SignatureHashFamily: bccsp.SHA2,
96+
IdentityIdentifierHashFunction: bccsp.SHA256,
97+
}
98+
9399
fmspconf := &msp.FabricMSPConfig{
94100
RootCerts: [][]byte{[]byte(cacert)},
95101
IntermediateCerts: [][]byte{[]byte(intermediatecert)},
96102
SigningIdentity: sigid,
97-
Name: "DEFAULT"}
103+
Name: "DEFAULT",
104+
CryptoConfig: cryptoConfig}
98105

99106
fmpsjs, _ := proto.Marshal(fmspconf)
100107

msp/revocation_test.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"testing"
2121

2222
"github.com/golang/protobuf/proto"
23+
"github.com/hyperledger/fabric/bccsp"
2324
"github.com/hyperledger/fabric/protos/msp"
2425
"github.com/stretchr/testify/assert"
2526
)
@@ -83,11 +84,17 @@ func TestRevocation(t *testing.T) {
8384

8485
sigid := &msp.SigningIdentityInfo{PublicSigner: []byte(signcertrev), PrivateSigner: keyinfo}
8586

87+
cryptoConfig := &msp.FabricCryptoConfig{
88+
SignatureHashFamily: bccsp.SHA2,
89+
IdentityIdentifierHashFunction: bccsp.SHA256,
90+
}
91+
8692
fmspconf := &msp.FabricMSPConfig{
8793
RootCerts: [][]byte{[]byte(cacertrev)},
8894
RevocationList: [][]byte{[]byte(crlrev)},
8995
SigningIdentity: sigid,
90-
Name: "DEFAULT"}
96+
Name: "DEFAULT",
97+
CryptoConfig: cryptoConfig}
9198

9299
fmpsjs, _ := proto.Marshal(fmspconf)
93100

protos/msp/identities.pb.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)