Skip to content

Commit

Permalink
Adding TLS changes to SDK
Browse files Browse the repository at this point in the history
Merging in TLS related changes from previous work which
were mistakenly left out of this branch. These changes
were originally made and tested on the Fabric05 branch.

Fixes FAB-374

Change-Id: If5b482d00297d840924dab78f35824a4245e1f02
Signed-off-by: Anna D Derbakova <adderbak@us.ibm.com>
Signed-off-by: Allen Bailey <eabailey@us.ibm.com>
  • Loading branch information
Mr. Angry committed Sep 14, 2016
1 parent cc111e2 commit 4d97069
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 24 deletions.
115 changes: 92 additions & 23 deletions sdk/node/src/hfc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,16 @@
* the server side transaction processing path.
*/

// Instruct boringssl to use ECC for tls.
process.env['GRPC_SSL_CIPHER_SUITES'] = 'HIGH+ECDSA';
process.env.GRPC_SSL_CIPHER_SUITES = process.env.GRPC_SSL_CIPHER_SUITES
? process.env.GRPC_SSL_CIPHER_SUITES
: 'ECDHE-RSA-AES128-GCM-SHA256:' +
'ECDHE-RSA-AES128-SHA256:' +
'ECDHE-RSA-AES256-SHA384:' +
'ECDHE-RSA-AES256-GCM-SHA384:' +
'ECDHE-ECDSA-AES128-GCM-SHA256:' +
'ECDHE-ECDSA-AES128-SHA256:' +
'ECDHE-ECDSA-AES256-SHA384:' +
'ECDHE-ECDSA-AES256-GCM-SHA384' ;

var debugModule = require('debug');
var fs = require('fs');
Expand Down Expand Up @@ -209,6 +217,12 @@ export interface Enrollment {
chainKey:string;
}

// GRPCOptions
export interface GRPCOptions {
pem: string;
hostnameOverride: string;
}

// A request to get a batch of TCerts
export class GetTCertBatchRequest {
constructor( public name: string,
Expand Down Expand Up @@ -346,6 +360,8 @@ export interface DeployRequest extends TransactionRequest {
chaincodePath:string;
// The name identifier for the chaincode to deploy in development mode.
chaincodeName:string;
// The directory on the server side, where the certificate.pem will be copied
certificatePath:string;
}

/**
Expand Down Expand Up @@ -461,10 +477,11 @@ export class Chain {

/**
* Add a peer given an endpoint specification.
* @param endpoint The endpoint of the form: { url: "grpcs://host:port", tls: { .... } }
* @param url The URL of the peer.
* @param opts Optional GRPC options.
* @returns {Peer} Returns a new peer.
*/
addPeer(url:string, pem?:string):Peer {
addPeer(url:string, opts?:GRPCOptions):Peer {

//check to see if the peer is already part of the chain
this.peers.forEach(function(peer){
Expand All @@ -477,7 +494,7 @@ export class Chain {
}
})

let peer = new Peer(url, this, pem);
let peer = new Peer(url, this, opts);
this.peers.push(peer);
return peer;
};
Expand Down Expand Up @@ -508,9 +525,10 @@ export class Chain {
/**
* Set the member services URL
* @param {string} url Member services URL of the form: "grpc://host:port" or "grpcs://host:port"
* @param {GRPCOptions} opts optional GRPC options
*/
setMemberServicesUrl(url:string, pem?:string):void {
this.setMemberServices(newMemberServices(url,pem));
setMemberServicesUrl(url:string, opts?:GRPCOptions):void {
this.setMemberServices(newMemberServices(url,opts));
}

/**
Expand Down Expand Up @@ -552,6 +570,20 @@ export class Chain {
this.preFetchMode = preFetchMode;
}

/**
* Enable or disable ECDSA mode for GRPC.
*/
setECDSAModeForGRPC(enabled:boolean):void {
// TODO: Handle multiple chains in different modes appropriately; this will not currently work
// since it is based env variables.
if (enabled) {
// Instruct boringssl to use ECC for tls.
process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA';
} else {
delete process.env.GRPC_SSL_CIPHER_SUITES;
}
}

/**
* Determine if dev mode is enabled.
*/
Expand Down Expand Up @@ -1677,6 +1709,16 @@ export class TransactionContext extends events.EventEmitter {
// Substitute the hashStrHash for the image name
dockerFileContents = util.format(dockerFileContents, hash);

// Add the certificate path on the server, if it is being passed in
debug("type of request.certificatePath: " + typeof(request.certificatePath));
debug("request.certificatePath: " + request.certificatePath);
if (request.certificatePath !== "" && request.certificatePath !== undefined) {
debug("Adding COPY certificate.pem command");

dockerFileContents = dockerFileContents + "\n" + "COPY certificate.pem %s";
dockerFileContents = util.format(dockerFileContents, request.certificatePath);
}

// Create a Docker file with dockerFileContents
let dockerFilePath = projDir + "/Dockerfile";
fs.writeFile(dockerFilePath, dockerFileContents, function(err) {
Expand Down Expand Up @@ -2077,16 +2119,19 @@ export class Peer {
* and returns the new Peer.
* @param {string} url The URL with format of "grpcs://host:port".
* @param {Chain} chain The chain of which this peer is a member.
* @param {string} pem The certificate file, in PEM format,
* to use with the gRPC protocol (that is, with TransportCredentials).
* Required when using the grpcs protocol.
* @param {GRPCOptions} optional GRPC options to use with the gRPC,
* protocol (that is, with TransportCredentials) including a root
* certificate file, in PEM format, and hostnameOverride. A certificate
* is required when using the grpcs (TLS) protocol.
* @returns {Peer} The new peer.
*/
constructor(url:string, chain:Chain, pem:string) {
constructor(url:string, chain:Chain, opts:GRPCOptions) {
this.url = url;
this.chain = chain;
let pem = getPemFromOpts(opts);
opts = getOptsFromOpts(opts);
this.ep = new Endpoint(url,pem);
this.peerClient = new _fabricProto.Peer(this.ep.addr, this.ep.creds);
this.peerClient = new _fabricProto.Peer(this.ep.addr, this.ep.creds, opts);
}

/**
Expand Down Expand Up @@ -2272,16 +2317,14 @@ class MemberServicesImpl implements MemberServices {
* @param config The config information required by this member services implementation.
* @returns {MemberServices} A MemberServices object.
*/
constructor(url:string,pem:string) {
constructor(url:string,opts:GRPCOptions) {
var pem = getPemFromOpts(opts);
opts = getOptsFromOpts(opts);
let ep = new Endpoint(url,pem);
var options = {
'grpc.ssl_target_name_override' : 'tlsca',
'grpc.default_authority': 'tlsca'
};
this.ecaaClient = new _caProto.ECAA(ep.addr, ep.creds, options);
this.ecapClient = new _caProto.ECAP(ep.addr, ep.creds, options);
this.tcapClient = new _caProto.TCAP(ep.addr, ep.creds, options);
this.tlscapClient = new _caProto.TLSCAP(ep.addr, ep.creds, options);
this.ecaaClient = new _caProto.ECAA(ep.addr, ep.creds, opts);
this.ecapClient = new _caProto.ECAP(ep.addr, ep.creds, opts);
this.tcapClient = new _caProto.TCAP(ep.addr, ep.creds, opts);
this.tlscapClient = new _caProto.TLSCAP(ep.addr, ep.creds, opts);
this.cryptoPrimitives = new crypto.Crypto(DEFAULT_HASH_ALGORITHM, DEFAULT_SECURITY_LEVEL);
}

Expand Down Expand Up @@ -2317,6 +2360,9 @@ class MemberServicesImpl implements MemberServices {
this.cryptoPrimitives.setHashAlgorithm(hashAlgorithm);
}

/**
* Get the crypto object.
*/
getCrypto():crypto.Crypto {
return this.cryptoPrimitives;
}
Expand Down Expand Up @@ -2599,8 +2645,8 @@ class MemberServicesImpl implements MemberServices {

} // end MemberServicesImpl

function newMemberServices(url,pem) {
return new MemberServicesImpl(url,pem);
function newMemberServices(url:string,opts:GRPCOptions) {
return new MemberServicesImpl(url,opts);
}

/**
Expand Down Expand Up @@ -2709,6 +2755,29 @@ function rolesToMask(roles?:string[]):number {
return mask;
}

// Get the PEM from the options
function getPemFromOpts(opts:any):string {
if (isObject(opts)) return opts.pem;
return opts;
}

// Normalize opts
function getOptsFromOpts(opts:any):GRPCOptions {
if (isObject(opts)) {
delete opts.pem;
if (opts.hostnameOverride) {
opts['grpc.ssl_target_name_override'] = opts.hostnameOverride;
opts['grpc.default_authority'] = opts.hostnameOverride;
delete opts.hostnameOverride;
}
return <GRPCOptions>opts;
}
if (isString(opts)) {
// backwards compatible to handle pem as opts
return <GRPCOptions>{ pem: opts };
}
}

function endsWith(str:string, suffix:string) {
return str.length >= suffix.length && str.substr(str.length - suffix.length) === suffix;
};
Expand Down
3 changes: 2 additions & 1 deletion sdk/node/src/sdk_util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ export function GenerateTarGz(src, dest, cb) {
".yaml",
".json",
".c",
".h"
".h",
".pem"
];

// Create the pack stream specifying the ignore/filtering function
Expand Down

0 comments on commit 4d97069

Please sign in to comment.