@@ -44,6 +44,12 @@ type bccspmsp struct {
44
44
// list of intermediate certs we trust
45
45
intermediateCerts []Identity
46
46
47
+ // certificationTreeInternalNodesMap whose keys correspond to the raw material
48
+ // (DER representation) of a certificate casted to a string, and whose values
49
+ // are boolean. True means that the certificate is an internal node of the certification tree.
50
+ // False means that the certificate corresponds to a leaf of the certification tree.
51
+ certificationTreeInternalNodesMap map [string ]bool
52
+
47
53
// list of signing identities
48
54
signer SigningIdentity
49
55
@@ -311,26 +317,24 @@ func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error {
311
317
return errors .New ("Expected at least one CA certificate" )
312
318
}
313
319
314
- // pre-create the verify options with roots and intermediates
315
- // this is needed to make certificate sanitation working.
316
- msp . opts = & x509. VerifyOptions {
317
- Roots : x509 . NewCertPool (),
318
- Intermediates : x509 . NewCertPool (),
319
- }
320
+ // pre-create the verify options with roots and intermediates.
321
+ // This is needed to make certificate sanitation working.
322
+ // Recall that sanitization is applied also to root CA and intermediate
323
+ // CA certificates. After their sanitization is done, the opts
324
+ // will be recreated using the sanitized certs.
325
+ msp . opts = & x509. VerifyOptions { Roots : x509 . NewCertPool (), Intermediates : x509 . NewCertPool () }
320
326
for _ , v := range conf .RootCerts {
321
327
cert , err := msp .getCertFromPem (v )
322
328
if err != nil {
323
329
return err
324
330
}
325
-
326
331
msp .opts .Roots .AddCert (cert )
327
332
}
328
333
for _ , v := range conf .IntermediateCerts {
329
334
cert , err := msp .getCertFromPem (v )
330
335
if err != nil {
331
336
return err
332
337
}
333
-
334
338
msp .opts .Intermediates .AddCert (cert )
335
339
}
336
340
@@ -357,6 +361,15 @@ func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error {
357
361
msp .intermediateCerts [i ] = id
358
362
}
359
363
364
+ // root CA and intermediate CA certificates are sanitized, they can be reimported
365
+ msp .opts = & x509.VerifyOptions {Roots : x509 .NewCertPool (), Intermediates : x509 .NewCertPool ()}
366
+ for _ , id := range msp .rootCerts {
367
+ msp .opts .Roots .AddCert (id .(* identity ).cert )
368
+ }
369
+ for _ , id := range msp .intermediateCerts {
370
+ msp .opts .Intermediates .AddCert (id .(* identity ).cert )
371
+ }
372
+
360
373
// make and fill the set of admin certs (if present)
361
374
msp .admins = make ([]Identity , len (conf .Admins ))
362
375
for i , admCert := range conf .Admins {
@@ -395,6 +408,21 @@ func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error {
395
408
}
396
409
}
397
410
411
+ // populate certificationTreeInternalNodesMap to mark the internal nodes of the
412
+ // certification tree
413
+ msp .certificationTreeInternalNodesMap = make (map [string ]bool )
414
+ for _ , cert := range append ([]Identity {}, msp .intermediateCerts ... ) {
415
+ chain , err := msp .getUniqueValidationChain (cert .(* identity ).cert )
416
+ if err != nil {
417
+ return fmt .Errorf ("Failed getting validation chain, (SN: %s)" , cert .(* identity ).cert .SerialNumber )
418
+ }
419
+
420
+ // Recall chain[0] is cert.(*identity).cert so it does not count as a parent
421
+ for i := 1 ; i < len (chain ); i ++ {
422
+ msp .certificationTreeInternalNodesMap [string (chain [i ].Raw )] = true
423
+ }
424
+ }
425
+
398
426
// setup the signer (if present)
399
427
if conf .SigningIdentity != nil {
400
428
sid , err := msp .getSigningIdentityFromConf (conf .SigningIdentity )
@@ -683,6 +711,11 @@ func (msp *bccspmsp) getValidationChain(cert *x509.Certificate) ([]*x509.Certifi
683
711
return nil , fmt .Errorf ("Expected a chain of length at least 2, got %d" , len (validationChain ))
684
712
}
685
713
714
+ // check that the parent is a leaf of the certification tree
715
+ if msp .certificationTreeInternalNodesMap [string (validationChain [1 ].Raw )] {
716
+ return nil , fmt .Errorf ("Invalid validation chain. Parent certificate should be a leaf of the certification tree [%v]." , cert .Raw )
717
+ }
718
+
686
719
return validationChain , nil
687
720
}
688
721
0 commit comments