@@ -23,6 +23,7 @@ import (
23
23
"net"
24
24
"sync"
25
25
26
+ "github.com/golang/protobuf/proto"
26
27
"github.com/hyperledger/fabric/common/config"
27
28
"github.com/hyperledger/fabric/common/configtx"
28
29
configtxapi "github.com/hyperledger/fabric/common/configtx/api"
@@ -35,6 +36,7 @@ import (
35
36
"github.com/hyperledger/fabric/core/ledger"
36
37
"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
37
38
"github.com/hyperledger/fabric/gossip/service"
39
+ "github.com/hyperledger/fabric/msp"
38
40
mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
39
41
"github.com/hyperledger/fabric/protos/common"
40
42
pb "github.com/hyperledger/fabric/protos/peer"
@@ -48,6 +50,15 @@ var peerLogger = logging.MustGetLogger("peer")
48
50
49
51
var peerServer comm.GRPCServer
50
52
53
+ var rootCASupport = struct {
54
+ sync.RWMutex
55
+ appRootCAsByChain map [string ][][]byte
56
+ ordererRootCAsByChain map [string ][][]byte
57
+ }{
58
+ appRootCAsByChain : make (map [string ][][]byte ),
59
+ ordererRootCAsByChain : make (map [string ][][]byte ),
60
+ }
61
+
51
62
type chainSupport struct {
52
63
configtxapi.Manager
53
64
config.Application
@@ -183,10 +194,14 @@ func createChain(cid string, ledger ledger.PeerLedger, cb *common.Block) error {
183
194
})
184
195
}
185
196
197
+ trustedRootsCallbackWrapper := func (cm configtxapi.Manager ) {
198
+ updateTrustedRoots (cm )
199
+ }
200
+
186
201
configtxManager , err := configtx .NewManagerImpl (
187
202
envelopeConfig ,
188
203
configtxInitializer ,
189
- []func (cm configtxapi.Manager ){gossipCallbackWrapper },
204
+ []func (cm configtxapi.Manager ){gossipCallbackWrapper , trustedRootsCallbackWrapper },
190
205
)
191
206
if err != nil {
192
207
return err
@@ -299,6 +314,122 @@ func GetCurrConfigBlock(cid string) *common.Block {
299
314
return nil
300
315
}
301
316
317
+ // updates the trusted roots for the peer based on updates to channels
318
+ func updateTrustedRoots (cm configtxapi.Manager ) {
319
+ // this is triggered on per channel basis so first update the roots for the channel
320
+
321
+ var secureConfig comm.SecureServerConfig
322
+ var err error
323
+ // only run is TLS is enabled
324
+ secureConfig , err = GetSecureConfig ()
325
+ if err == nil && secureConfig .UseTLS {
326
+ buildTrustedRootsForChain (cm )
327
+
328
+ // now iterate over all roots for all app and orderer chains
329
+ trustedRoots := [][]byte {}
330
+ rootCASupport .RLock ()
331
+ defer rootCASupport .RUnlock ()
332
+ for _ , roots := range rootCASupport .appRootCAsByChain {
333
+ trustedRoots = append (trustedRoots , roots ... )
334
+ }
335
+ // also need to append statically configured root certs
336
+ if len (secureConfig .ClientRootCAs ) > 0 {
337
+ trustedRoots = append (trustedRoots , secureConfig .ClientRootCAs ... )
338
+ }
339
+ if len (secureConfig .ServerRootCAs ) > 0 {
340
+ trustedRoots = append (trustedRoots , secureConfig .ServerRootCAs ... )
341
+ }
342
+
343
+ server := GetPeerServer ()
344
+ // now update the client roots for the peerServer
345
+ if server != nil {
346
+ err := server .SetClientRootCAs (trustedRoots )
347
+ if err != nil {
348
+ msg := "Failed to update trusted roots for peer from latest config " +
349
+ "block. This peer may not be able to communicate " +
350
+ "with members of channel %s (%s)"
351
+ peerLogger .Warningf (msg , cm .ChainID (), err )
352
+ }
353
+ }
354
+ }
355
+ }
356
+
357
+ // populates the appRootCAs and orderRootCAs maps by getting the
358
+ // root and intermediate certs for all msps assocaited with the MSPManager
359
+ func buildTrustedRootsForChain (cm configtxapi.Manager ) {
360
+ rootCASupport .Lock ()
361
+ defer rootCASupport .Unlock ()
362
+
363
+ appRootCAs := [][]byte {}
364
+ ordererRootCAs := [][]byte {}
365
+ cid := cm .ChainID ()
366
+ msps , err := cm .MSPManager ().GetMSPs ()
367
+ if err != nil {
368
+ peerLogger .Errorf ("Error getting getting root CA for channel %s (%s)" , cid , err )
369
+ }
370
+ if err == nil {
371
+ for _ , v := range msps {
372
+ // check to see if this is a FABRIC MSP
373
+ if v .GetType () == msp .FABRIC {
374
+ for _ , root := range v .GetRootCerts () {
375
+ sid , err := root .Serialize ()
376
+ if err == nil {
377
+ id := & msp.SerializedIdentity {}
378
+ err = proto .Unmarshal (sid , id )
379
+ if err == nil {
380
+ appRootCAs = append (appRootCAs , id .IdBytes )
381
+ }
382
+ }
383
+ }
384
+ for _ , intermediate := range v .GetIntermediateCerts () {
385
+ sid , err := intermediate .Serialize ()
386
+ if err == nil {
387
+ id := & msp.SerializedIdentity {}
388
+ err = proto .Unmarshal (sid , id )
389
+ if err == nil {
390
+ appRootCAs = append (appRootCAs , id .IdBytes )
391
+ }
392
+ }
393
+ }
394
+ }
395
+ }
396
+ // TODO: separate app and orderer CAs
397
+ ordererRootCAs = appRootCAs
398
+ rootCASupport .appRootCAsByChain [cid ] = appRootCAs
399
+ rootCASupport .ordererRootCAsByChain [cid ] = ordererRootCAs
400
+ }
401
+ }
402
+
403
+ // GetRootCAs returns the PEM-encoded root certificates for all of the
404
+ // application and orderer organizations defined for all chains
405
+ func GetRootCAs () (appRootCAs , ordererRootCAs [][]byte ) {
406
+ rootCASupport .RLock ()
407
+ defer rootCASupport .RUnlock ()
408
+
409
+ appRootCAs = [][]byte {}
410
+ ordererRootCAs = [][]byte {}
411
+
412
+ for _ , appRootCA := range rootCASupport .appRootCAsByChain {
413
+ appRootCAs = append (appRootCAs , appRootCA ... )
414
+ }
415
+ // also need to append statically configured root certs
416
+ secureConfig , err := GetSecureConfig ()
417
+ if err == nil {
418
+ if len (secureConfig .ClientRootCAs ) > 0 {
419
+ appRootCAs = append (appRootCAs , secureConfig .ClientRootCAs ... )
420
+ }
421
+ if len (secureConfig .ServerRootCAs ) > 0 {
422
+ appRootCAs = append (appRootCAs , secureConfig .ServerRootCAs ... )
423
+ }
424
+ }
425
+
426
+ for _ , ordererRootCA := range rootCASupport .appRootCAsByChain {
427
+ ordererRootCAs = append (ordererRootCAs , ordererRootCA ... )
428
+ }
429
+
430
+ return appRootCAs , ordererRootCAs
431
+ }
432
+
302
433
// GetMSPIDs returns the ID of each application MSP defined on this chain
303
434
func GetMSPIDs (cid string ) []string {
304
435
chains .RLock ()
0 commit comments