@@ -19,26 +19,29 @@ package msp
19
19
import (
20
20
"crypto/x509"
21
21
"fmt"
22
- "time"
23
22
24
23
"encoding/pem"
25
24
26
25
"bytes"
27
26
27
+ "errors"
28
+
28
29
"github.com/golang/protobuf/proto"
29
30
"github.com/hyperledger/fabric/bccsp"
30
31
"github.com/hyperledger/fabric/bccsp/signer"
31
32
"github.com/hyperledger/fabric/bccsp/sw"
32
33
"github.com/hyperledger/fabric/protos/common"
33
34
m "github.com/hyperledger/fabric/protos/msp"
34
- "github.com/syndtr/goleveldb/leveldb/errors"
35
35
)
36
36
37
37
// This is an instantiation of an MSP that
38
38
// uses BCCSP for its cryptographic primitives.
39
39
type bccspmsp struct {
40
- // list of certs we trust
41
- trustedCerts []Identity
40
+ // list of CA certs we trust
41
+ rootCerts []Identity
42
+
43
+ // list of intermediate certs we trust
44
+ intermediateCerts []Identity
42
45
43
46
// list of signing identities
44
47
signer SigningIdentity
@@ -51,6 +54,9 @@ type bccspmsp struct {
51
54
52
55
// the provider identifier for this MSP
53
56
name string
57
+
58
+ // verification options for MSP members
59
+ opts * x509.VerifyOptions
54
60
}
55
61
56
62
// NewBccspMsp returns an MSP instance backed up by a BCCSP
@@ -153,26 +159,46 @@ func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error {
153
159
msp .name = conf .Name
154
160
mspLogger .Debugf ("Setting up MSP instance %s" , msp .name )
155
161
156
- // make and fill the set of admin certs
157
- msp .admins = make ([]Identity , len (conf .Admins ))
158
- for i , admCert := range conf .Admins {
159
- id , err := msp .getIdentityFromConf (admCert )
160
- if err != nil {
161
- return err
162
- }
162
+ // make and fill the set of admin certs (if present)
163
+ if conf .Admins != nil {
164
+ msp .admins = make ([]Identity , len (conf .Admins ))
165
+ for i , admCert := range conf .Admins {
166
+ id , err := msp .getIdentityFromConf (admCert )
167
+ if err != nil {
168
+ return err
169
+ }
163
170
164
- msp .admins [i ] = id
171
+ msp .admins [i ] = id
172
+ }
165
173
}
166
174
167
- // make and fill the set of CA certs
168
- msp .trustedCerts = make ([]Identity , len (conf .RootCerts ))
175
+ // make and fill the set of CA certs - we expect them to be there
176
+ if len (conf .RootCerts ) == 0 {
177
+ return errors .New ("Expected at least one CA certificate" )
178
+ }
179
+ msp .rootCerts = make ([]Identity , len (conf .RootCerts ))
169
180
for i , trustedCert := range conf .RootCerts {
170
181
id , err := msp .getIdentityFromConf (trustedCert )
171
182
if err != nil {
172
183
return err
173
184
}
174
185
175
- msp .trustedCerts [i ] = id
186
+ msp .rootCerts [i ] = id
187
+ }
188
+
189
+ // make and fill the set of intermediate certs (if present)
190
+ if conf .IntermediateCerts != nil {
191
+ msp .intermediateCerts = make ([]Identity , len (conf .IntermediateCerts ))
192
+ for i , trustedCert := range conf .IntermediateCerts {
193
+ id , err := msp .getIdentityFromConf (trustedCert )
194
+ if err != nil {
195
+ return err
196
+ }
197
+
198
+ msp .intermediateCerts [i ] = id
199
+ }
200
+ } else {
201
+ msp .intermediateCerts = make ([]Identity , 0 )
176
202
}
177
203
178
204
// setup the signer (if present)
@@ -185,6 +211,18 @@ func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error {
185
211
msp .signer = sid
186
212
}
187
213
214
+ // pre-create the verify options with roots and intermediates
215
+ msp .opts = & x509.VerifyOptions {
216
+ Roots : x509 .NewCertPool (),
217
+ Intermediates : x509 .NewCertPool (),
218
+ }
219
+ for _ , v := range msp .rootCerts {
220
+ msp .opts .Roots .AddCert (v .(* identity ).cert )
221
+ }
222
+ for _ , v := range msp .intermediateCerts {
223
+ msp .opts .Intermediates .AddCert (v .(* identity ).cert )
224
+ }
225
+
188
226
return nil
189
227
}
190
228
@@ -230,16 +268,29 @@ func (msp *bccspmsp) Validate(id Identity) error {
230
268
// this is how I can validate it given the
231
269
// root of trust this MSP has
232
270
case * identity :
233
- opts := x509. VerifyOptions {
234
- Roots : x509 . NewCertPool (),
235
- CurrentTime : time . Now (),
271
+ // we expect to have a valid VerifyOptions instance
272
+ if msp . opts == nil {
273
+ return errors . New ( "Invalid msp instance" )
236
274
}
237
275
238
- for _ , v := range msp .trustedCerts {
239
- opts .Roots .AddCert (v .(* identity ).cert )
276
+ // CAs cannot be directly used as identities..
277
+ if id .(* identity ).cert .IsCA {
278
+ return errors .New ("A CA certificate cannot be used directly by this MSP" )
240
279
}
241
280
242
- _ , err := id .(* identity ).cert .Verify (opts )
281
+ // at this point we might want to perform some
282
+ // more elaborate validation. We do not do this
283
+ // yet because we do not want to impose any
284
+ // constraints without knowing the exact requirements,
285
+ // but we at least list the kind of extra validation that we might perform:
286
+ // 1) we might only allow a single verification chain (e.g. we expect the
287
+ // cert to be signed exactly only by the CA or only by the intermediate)
288
+ // 2) we might want to let golang find any path, and then have a blacklist
289
+ // of paths (e.g. it can be signed by CA -> iCA1 -> iCA2 and it can be
290
+ // signed by CA but not by CA -> iCA1)
291
+
292
+ // ask golang to validate the cert for us based on the options that we've built at setup time
293
+ _ , err := id .(* identity ).cert .Verify (* (msp .opts ))
243
294
if err != nil {
244
295
return fmt .Errorf ("The supplied identity is not valid, Verify() returned %s" , err )
245
296
} else {
0 commit comments