43
43
* the server side transaction processing path.
44
44
*/
45
45
46
- // Instruct boringssl to use ECC for tls.
47
- process . env [ 'GRPC_SSL_CIPHER_SUITES' ] = 'HIGH+ECDSA' ;
46
+ process . env . GRPC_SSL_CIPHER_SUITES = process . env . GRPC_SSL_CIPHER_SUITES
47
+ ? process . env . GRPC_SSL_CIPHER_SUITES
48
+ : 'ECDHE-RSA-AES128-GCM-SHA256:' +
49
+ 'ECDHE-RSA-AES128-SHA256:' +
50
+ 'ECDHE-RSA-AES256-SHA384:' +
51
+ 'ECDHE-RSA-AES256-GCM-SHA384:' +
52
+ 'ECDHE-ECDSA-AES128-GCM-SHA256:' +
53
+ 'ECDHE-ECDSA-AES128-SHA256:' +
54
+ 'ECDHE-ECDSA-AES256-SHA384:' +
55
+ 'ECDHE-ECDSA-AES256-GCM-SHA384' ;
48
56
49
57
var debugModule = require ( 'debug' ) ;
50
58
var fs = require ( 'fs' ) ;
@@ -209,6 +217,12 @@ export interface Enrollment {
209
217
chainKey :string ;
210
218
}
211
219
220
+ // GRPCOptions
221
+ export interface GRPCOptions {
222
+ pem : string ;
223
+ hostnameOverride : string ;
224
+ }
225
+
212
226
// A request to get a batch of TCerts
213
227
export class GetTCertBatchRequest {
214
228
constructor ( public name : string ,
@@ -346,6 +360,8 @@ export interface DeployRequest extends TransactionRequest {
346
360
chaincodePath :string ;
347
361
// The name identifier for the chaincode to deploy in development mode.
348
362
chaincodeName :string ;
363
+ // The directory on the server side, where the certificate.pem will be copied
364
+ certificatePath :string ;
349
365
}
350
366
351
367
/**
@@ -461,10 +477,11 @@ export class Chain {
461
477
462
478
/**
463
479
* Add a peer given an endpoint specification.
464
- * @param endpoint The endpoint of the form: { url: "grpcs://host:port", tls: { .... } }
480
+ * @param url The URL of the peer.
481
+ * @param opts Optional GRPC options.
465
482
* @returns {Peer } Returns a new peer.
466
483
*/
467
- addPeer ( url :string , pem ?: string ) :Peer {
484
+ addPeer ( url :string , opts ?: GRPCOptions ) :Peer {
468
485
469
486
//check to see if the peer is already part of the chain
470
487
this . peers . forEach ( function ( peer ) {
@@ -477,7 +494,7 @@ export class Chain {
477
494
}
478
495
} )
479
496
480
- let peer = new Peer ( url , this , pem ) ;
497
+ let peer = new Peer ( url , this , opts ) ;
481
498
this . peers . push ( peer ) ;
482
499
return peer ;
483
500
} ;
@@ -508,9 +525,10 @@ export class Chain {
508
525
/**
509
526
* Set the member services URL
510
527
* @param {string } url Member services URL of the form: "grpc://host:port" or "grpcs://host:port"
528
+ * @param {GRPCOptions } opts optional GRPC options
511
529
*/
512
- setMemberServicesUrl ( url :string , pem ?: string ) :void {
513
- this . setMemberServices ( newMemberServices ( url , pem ) ) ;
530
+ setMemberServicesUrl ( url :string , opts ?: GRPCOptions ) :void {
531
+ this . setMemberServices ( newMemberServices ( url , opts ) ) ;
514
532
}
515
533
516
534
/**
@@ -552,6 +570,20 @@ export class Chain {
552
570
this . preFetchMode = preFetchMode ;
553
571
}
554
572
573
+ /**
574
+ * Enable or disable ECDSA mode for GRPC.
575
+ */
576
+ setECDSAModeForGRPC ( enabled :boolean ) :void {
577
+ // TODO: Handle multiple chains in different modes appropriately; this will not currently work
578
+ // since it is based env variables.
579
+ if ( enabled ) {
580
+ // Instruct boringssl to use ECC for tls.
581
+ process . env . GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA' ;
582
+ } else {
583
+ delete process . env . GRPC_SSL_CIPHER_SUITES ;
584
+ }
585
+ }
586
+
555
587
/**
556
588
* Determine if dev mode is enabled.
557
589
*/
@@ -1677,6 +1709,16 @@ export class TransactionContext extends events.EventEmitter {
1677
1709
// Substitute the hashStrHash for the image name
1678
1710
dockerFileContents = util . format ( dockerFileContents , hash ) ;
1679
1711
1712
+ // Add the certificate path on the server, if it is being passed in
1713
+ debug ( "type of request.certificatePath: " + typeof ( request . certificatePath ) ) ;
1714
+ debug ( "request.certificatePath: " + request . certificatePath ) ;
1715
+ if ( request . certificatePath !== "" && request . certificatePath !== undefined ) {
1716
+ debug ( "Adding COPY certificate.pem command" ) ;
1717
+
1718
+ dockerFileContents = dockerFileContents + "\n" + "COPY certificate.pem %s" ;
1719
+ dockerFileContents = util . format ( dockerFileContents , request . certificatePath ) ;
1720
+ }
1721
+
1680
1722
// Create a Docker file with dockerFileContents
1681
1723
let dockerFilePath = projDir + "/Dockerfile" ;
1682
1724
fs . writeFile ( dockerFilePath , dockerFileContents , function ( err ) {
@@ -2077,16 +2119,19 @@ export class Peer {
2077
2119
* and returns the new Peer.
2078
2120
* @param {string } url The URL with format of "grpcs://host:port".
2079
2121
* @param {Chain } chain The chain of which this peer is a member.
2080
- * @param {string } pem The certificate file, in PEM format,
2081
- * to use with the gRPC protocol (that is, with TransportCredentials).
2082
- * Required when using the grpcs protocol.
2122
+ * @param {GRPCOptions } optional GRPC options to use with the gRPC,
2123
+ * protocol (that is, with TransportCredentials) including a root
2124
+ * certificate file, in PEM format, and hostnameOverride. A certificate
2125
+ * is required when using the grpcs (TLS) protocol.
2083
2126
* @returns {Peer } The new peer.
2084
2127
*/
2085
- constructor ( url :string , chain :Chain , pem : string ) {
2128
+ constructor ( url :string , chain :Chain , opts : GRPCOptions ) {
2086
2129
this . url = url ;
2087
2130
this . chain = chain ;
2131
+ let pem = getPemFromOpts ( opts ) ;
2132
+ opts = getOptsFromOpts ( opts ) ;
2088
2133
this . ep = new Endpoint ( url , pem ) ;
2089
- this . peerClient = new _fabricProto . Peer ( this . ep . addr , this . ep . creds ) ;
2134
+ this . peerClient = new _fabricProto . Peer ( this . ep . addr , this . ep . creds , opts ) ;
2090
2135
}
2091
2136
2092
2137
/**
@@ -2272,16 +2317,14 @@ class MemberServicesImpl implements MemberServices {
2272
2317
* @param config The config information required by this member services implementation.
2273
2318
* @returns {MemberServices } A MemberServices object.
2274
2319
*/
2275
- constructor ( url :string , pem :string ) {
2320
+ constructor ( url :string , opts :GRPCOptions ) {
2321
+ var pem = getPemFromOpts ( opts ) ;
2322
+ opts = getOptsFromOpts ( opts ) ;
2276
2323
let ep = new Endpoint ( url , pem ) ;
2277
- var options = {
2278
- 'grpc.ssl_target_name_override' : 'tlsca' ,
2279
- 'grpc.default_authority' : 'tlsca'
2280
- } ;
2281
- this . ecaaClient = new _caProto . ECAA ( ep . addr , ep . creds , options ) ;
2282
- this . ecapClient = new _caProto . ECAP ( ep . addr , ep . creds , options ) ;
2283
- this . tcapClient = new _caProto . TCAP ( ep . addr , ep . creds , options ) ;
2284
- this . tlscapClient = new _caProto . TLSCAP ( ep . addr , ep . creds , options ) ;
2324
+ this . ecaaClient = new _caProto . ECAA ( ep . addr , ep . creds , opts ) ;
2325
+ this . ecapClient = new _caProto . ECAP ( ep . addr , ep . creds , opts ) ;
2326
+ this . tcapClient = new _caProto . TCAP ( ep . addr , ep . creds , opts ) ;
2327
+ this . tlscapClient = new _caProto . TLSCAP ( ep . addr , ep . creds , opts ) ;
2285
2328
this . cryptoPrimitives = new crypto . Crypto ( DEFAULT_HASH_ALGORITHM , DEFAULT_SECURITY_LEVEL ) ;
2286
2329
}
2287
2330
@@ -2317,6 +2360,9 @@ class MemberServicesImpl implements MemberServices {
2317
2360
this . cryptoPrimitives . setHashAlgorithm ( hashAlgorithm ) ;
2318
2361
}
2319
2362
2363
+ /**
2364
+ * Get the crypto object.
2365
+ */
2320
2366
getCrypto ( ) :crypto . Crypto {
2321
2367
return this . cryptoPrimitives ;
2322
2368
}
@@ -2599,8 +2645,8 @@ class MemberServicesImpl implements MemberServices {
2599
2645
2600
2646
} // end MemberServicesImpl
2601
2647
2602
- function newMemberServices ( url , pem ) {
2603
- return new MemberServicesImpl ( url , pem ) ;
2648
+ function newMemberServices ( url : string , opts : GRPCOptions ) {
2649
+ return new MemberServicesImpl ( url , opts ) ;
2604
2650
}
2605
2651
2606
2652
/**
@@ -2709,6 +2755,29 @@ function rolesToMask(roles?:string[]):number {
2709
2755
return mask ;
2710
2756
}
2711
2757
2758
+ // Get the PEM from the options
2759
+ function getPemFromOpts ( opts :any ) :string {
2760
+ if ( isObject ( opts ) ) return opts . pem ;
2761
+ return opts ;
2762
+ }
2763
+
2764
+ // Normalize opts
2765
+ function getOptsFromOpts ( opts :any ) :GRPCOptions {
2766
+ if ( isObject ( opts ) ) {
2767
+ delete opts . pem ;
2768
+ if ( opts . hostnameOverride ) {
2769
+ opts [ 'grpc.ssl_target_name_override' ] = opts . hostnameOverride ;
2770
+ opts [ 'grpc.default_authority' ] = opts . hostnameOverride ;
2771
+ delete opts . hostnameOverride ;
2772
+ }
2773
+ return < GRPCOptions > opts ;
2774
+ }
2775
+ if ( isString ( opts ) ) {
2776
+ // backwards compatible to handle pem as opts
2777
+ return < GRPCOptions > { pem : opts } ;
2778
+ }
2779
+ }
2780
+
2712
2781
function endsWith ( str :string , suffix :string ) {
2713
2782
return str . length >= suffix . length && str . substr ( str . length - suffix . length ) === suffix ;
2714
2783
} ;
0 commit comments