@@ -382,49 +382,15 @@ func (msp *bccspmsp) Validate(id Identity) error {
382
382
// this is how I can validate it given the
383
383
// root of trust this MSP has
384
384
case * identity :
385
- // we expect to have a valid VerifyOptions instance
386
- if msp .opts == nil {
387
- return errors .New ("Invalid msp instance" )
388
- }
389
-
390
- // CAs cannot be directly used as identities..
391
- if id .cert .IsCA {
392
- return errors .New ("A CA certificate cannot be used directly by this MSP" )
393
- }
394
-
395
- // at this point we might want to perform some
396
- // more elaborate validation. We do not do this
397
- // yet because we do not want to impose any
398
- // constraints without knowing the exact requirements,
399
- // but we at least list the kind of extra validation that we might perform:
400
- // 1) we might only allow a single verification chain (e.g. we expect the
401
- // cert to be signed exactly only by the CA or only by the intermediate)
402
- // 2) we might want to let golang find any path, and then have a blacklist
403
- // of paths (e.g. it can be signed by CA -> iCA1 -> iCA2 and it can be
404
- // signed by CA but not by CA -> iCA1)
405
-
406
- // ask golang to validate the cert for us based on the options that we've built at setup time
407
- validationChain , err := id .cert .Verify (* (msp .opts ))
385
+ validationChain , err := msp .getCertificationChainForBCCSPIdentity (id )
408
386
if err != nil {
409
- return fmt .Errorf ("The supplied identity is not valid, Verify() returned %s" , err )
410
- }
411
-
412
- // we only support a single validation chain;
413
- // if there's more than one then there might
414
- // be unclarity about who owns the identity
415
- if len (validationChain ) != 1 {
416
- return fmt .Errorf ("This MSP only supports a single validation chain, got %d" , len (validationChain ))
417
- }
418
-
419
- // we expect a chain of length at least 2
420
- if len (validationChain [0 ]) < 2 {
421
- return fmt .Errorf ("Expected a chain of length at least 2, got %d" , len (validationChain ))
387
+ return fmt .Errorf ("Could not obtain certification chain, err %s" , err )
422
388
}
423
389
424
390
// here we know that the identity is valid; now we have to check whether it has been revoked
425
391
426
392
// identify the SKI of the CA that signed this cert
427
- SKI , err := getSubjectKeyIdentifierFromCert (validationChain [0 ][ 1 ])
393
+ SKI , err := getSubjectKeyIdentifierFromCert (validationChain [1 ])
428
394
if err != nil {
429
395
return fmt .Errorf ("Could not obtain Subject Key Identifier for signer cert, err %s" , err )
430
396
}
@@ -447,7 +413,7 @@ func (msp *bccspmsp) Validate(id Identity) error {
447
413
// certificate that is under validation. As a
448
414
// precaution, we verify that said CA is also the
449
415
// signer of this CRL.
450
- err = validationChain [0 ][ 1 ].CheckCRLSignature (crl )
416
+ err = validationChain [1 ].CheckCRLSignature (crl )
451
417
if err != nil {
452
418
// the CA cert that signed the certificate
453
419
// that is under validation did not sign the
@@ -609,7 +575,8 @@ func (msp *bccspmsp) SatisfiesPrincipal(id Identity, principal *m.MSPPrincipal)
609
575
610
576
// now we check whether any of this identity's OUs match the requested one
611
577
for _ , ou := range id .GetOrganizationalUnits () {
612
- if ou == OU .OrganizationalUnitIdentifier {
578
+ if ou .OrganizationalUnitIdentifier == OU .OrganizationalUnitIdentifier &&
579
+ bytes .Equal (ou .CertifiersIdentifier , OU .CertifiersIdentifier ) {
613
580
return nil
614
581
}
615
582
}
@@ -620,3 +587,86 @@ func (msp *bccspmsp) SatisfiesPrincipal(id Identity, principal *m.MSPPrincipal)
620
587
return fmt .Errorf ("Invalid principal type %d" , int32 (principal .PrincipalClassification ))
621
588
}
622
589
}
590
+
591
+ // getCertificationChain returns the certification chain of the passed identity within this msp
592
+ func (msp * bccspmsp ) getCertificationChain (id Identity ) ([]* x509.Certificate , error ) {
593
+ mspLogger .Debugf ("MSP %s getting certification chain" , msp .name )
594
+
595
+ switch id := id .(type ) {
596
+ // If this identity is of this specific type,
597
+ // this is how I can validate it given the
598
+ // root of trust this MSP has
599
+ case * identity :
600
+ return msp .getCertificationChainForBCCSPIdentity (id )
601
+ default :
602
+ return nil , fmt .Errorf ("Identity type not recognized" )
603
+ }
604
+ }
605
+
606
+ // getCertificationChainForBCCSPIdentity returns the certification chain of the passed bccsp identity within this msp
607
+ func (msp * bccspmsp ) getCertificationChainForBCCSPIdentity (id * identity ) ([]* x509.Certificate , error ) {
608
+ if id == nil {
609
+ return nil , errors .New ("Invalid bccsp identity. Must be different from nil." )
610
+ }
611
+
612
+ // we expect to have a valid VerifyOptions instance
613
+ if msp .opts == nil {
614
+ return nil , errors .New ("Invalid msp instance" )
615
+ }
616
+
617
+ // CAs cannot be directly used as identities..
618
+ if id .cert .IsCA {
619
+ return nil , errors .New ("A CA certificate cannot be used directly by this MSP" )
620
+ }
621
+
622
+ // at this point we might want to perform some
623
+ // more elaborate validation. We do not do this
624
+ // yet because we do not want to impose any
625
+ // constraints without knowing the exact requirements,
626
+ // but we at least list the kind of extra validation that we might perform:
627
+ // 1) we might only allow a single verification chain (e.g. we expect the
628
+ // cert to be signed exactly only by the CA or only by the intermediate)
629
+ // 2) we might want to let golang find any path, and then have a blacklist
630
+ // of paths (e.g. it can be signed by CA -> iCA1 -> iCA2 and it can be
631
+ // signed by CA but not by CA -> iCA1)
632
+
633
+ // ask golang to validate the cert for us based on the options that we've built at setup time
634
+ validationChain , err := id .cert .Verify (* (msp .opts ))
635
+ if err != nil {
636
+ return nil , fmt .Errorf ("The supplied identity is not valid, Verify() returned %s" , err )
637
+ }
638
+
639
+ // we only support a single validation chain;
640
+ // if there's more than one then there might
641
+ // be unclarity about who owns the identity
642
+ if len (validationChain ) != 1 {
643
+ return nil , fmt .Errorf ("This MSP only supports a single validation chain, got %d" , len (validationChain ))
644
+ }
645
+
646
+ // we expect a chain of length at least 2
647
+ if len (validationChain [0 ]) < 2 {
648
+ return nil , fmt .Errorf ("Expected a chain of length at least 2, got %d" , len (validationChain ))
649
+ }
650
+
651
+ return validationChain [0 ], nil
652
+ }
653
+
654
+ // getCertificationChainIdentifier returns the certification chain identifier of the passed identity within this msp.
655
+ // The identifier is computes as the SHA256 of the concatenation of the certificates in the chain.
656
+ func (msp * bccspmsp ) getCertificationChainIdentifier (id Identity ) ([]byte , error ) {
657
+ chain , err := msp .getCertificationChain (id )
658
+ if err != nil {
659
+ return nil , fmt .Errorf ("Failed getting certification chain for [%v]: [%s]" , id , err )
660
+ }
661
+
662
+ // Hash the chain
663
+ hf , err := msp .bccsp .GetHash (& bccsp.SHA256Opts {})
664
+ if err != nil {
665
+ return nil , fmt .Errorf ("Failed getting hash function when computing certification chain identifier for [%v]: [%s]" , id , err )
666
+ }
667
+
668
+ for i := 0 ; i < len (chain ); i ++ {
669
+ hf .Write (chain [i ].Raw )
670
+ }
671
+ return hf .Sum (nil ), nil
672
+ }
0 commit comments