Skip to content

Commit

Permalink
Added support for TLS in java shim
Browse files Browse the repository at this point in the history
FIX FAB-159

This patch adds support for TLS in java shim layer, also adds a
parameter (peer.tls.rootcert.file) in core.yaml to support
self-signed certificates used for TLS communication. This file if
present is packaged to Java chaincode docker image.

Change-Id: I34f1beb3b7048699a3a99ed4a890ccaf0bf96744
Signed-off-by: Satheesh Kathamuthu <satheesh.ceg@gmail.com>
  • Loading branch information
xspeedcruiser committed Dec 19, 2016
1 parent aeb88b4 commit d39194c
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 34 deletions.
7 changes: 6 additions & 1 deletion core/chaincode/chaincode_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,14 @@ func (chaincodeSupport *ChaincodeSupport) getArgsAndEnv(cccid *CCContext, cLang
chaincodeSupport.peerAddress, cccid.Name),
" ")
if chaincodeSupport.peerTLS {
args = append(args, " -s")
args = append(args, "-s")
if chaincodeSupport.peerTLSSvrHostOrd != "" {
args = append(args, "-o")
args = append(args, chaincodeSupport.peerTLSSvrHostOrd)
}
}
chaincodeLogger.Debugf("Executable is %s", args[0])
chaincodeLogger.Debugf("Args %v", args)
default:
return nil, nil, fmt.Errorf("Unknown chaincodeType: %s", cLang)
}
Expand Down
20 changes: 12 additions & 8 deletions core/chaincode/platforms/java/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,18 @@ func writeChaincodePackage(spec *pb.ChaincodeSpec, tw *tar.Writer) error {
var dockerFileContents string
var buf []string

if viper.GetBool("security.enabled") {
//todo
} else {
buf = append(buf, cutil.GetDockerfileFromConfig("chaincode.java.Dockerfile"))
buf = append(buf, "COPY src /root/chaincode")
buf = append(buf, "RUN cd /root/chaincode && "+buildCmd)
buf = append(buf, "RUN cp /root/chaincode/build/chaincode.jar /root")
buf = append(buf, "RUN cp /root/chaincode/build/libs/* /root/libs")
buf = append(buf, cutil.GetDockerfileFromConfig("chaincode.java.Dockerfile"))
buf = append(buf, "COPY src /root/chaincode")
buf = append(buf, "RUN cd /root/chaincode && "+buildCmd)
buf = append(buf, "RUN cp /root/chaincode/build/chaincode.jar /root")
buf = append(buf, "RUN cp /root/chaincode/build/libs/* /root/libs")

// Add COPY command to Dockerfile when it is a self-signed cert and rootcert.pem
// is specified in the peer.tls.rootcert.file configuration. It is made available
// in the docker context tar file in writer.go

if viper.GetBool("peer.tls.enabled") && viper.GetString("peer.tls.rootcert.file") != "" {
buf = append(buf, "COPY src/certs/rootcert.pem /root/certs/rootcert.pem")
}

dockerFileContents = strings.Join(buf, "\n")
Expand Down
13 changes: 9 additions & 4 deletions core/chaincode/shim/java/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.7.6'
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'
}
}

plugins {
id "java"
id "com.google.protobuf" version "0.7.6"
id "com.google.protobuf" version "0.8.0"
id "eclipse"
id "maven-publish"

Expand All @@ -52,10 +52,14 @@ repositories {
mavenCentral()
}

apply plugin: "com.google.osdetector"

def tcnative_classifier = osdetector.classifier;

protobuf {
generatedFilesBaseDir = "$projectDir/src"
protoc {
artifact = 'com.google.protobuf:protoc:3.0.0-beta-2'
artifact = 'com.google.protobuf:protoc:3.0.0'
}
plugins {
grpc {
Expand Down Expand Up @@ -105,9 +109,10 @@ build.finalizedBy(copyToLib)
build.finalizedBy(publishToMavenLocal)

dependencies {
compile 'com.google.protobuf:protobuf-java:3.0.0-beta-2'
compile 'com.google.protobuf:protobuf-java:3.0.0'
compile 'io.grpc:grpc-all:0.13.2'
compile 'commons-cli:commons-cli:1.3.1'
compile 'io.netty:netty-tcnative-boringssl-static:1.1.33.Fork21:' + tcnative_classifier
}

publishing {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,27 @@

package org.hyperledger.java.shim;

import java.io.File;

import javax.net.ssl.SSLException;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;

import com.google.protobuf.ByteString;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import io.grpc.ManagedChannel;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NegotiationType;
import io.grpc.netty.NettyChannelBuilder;
import io.grpc.stub.StreamObserver;
import io.netty.handler.ssl.SslContext;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hyperledger.protos.Chaincode.ChaincodeID;
import org.hyperledger.protos.Chaincode.ChaincodeMessage;
import org.hyperledger.protos.Chaincode.ChaincodeMessage.Type;
import org.hyperledger.protos.ChaincodeSupportGrpc;
import org.hyperledger.protos.ChaincodeSupportGrpc.ChaincodeSupportStub;

import javax.net.ssl.SSLException;
import java.io.File;

public abstract class ChaincodeBase {

private static Log logger = LogFactory.getLog(ChaincodeBase.class);
Expand All @@ -54,6 +50,9 @@ public abstract class ChaincodeBase {

private String host = DEFAULT_HOST;
private int port = DEFAULT_PORT;
private String hostOverrideAuthority = "";
private static final String ROOTCERT_PEM = "/root/certs/rootcert.pem";
private boolean tlsEnabled=false;

private Handler handler;
private String id = getChaincodeID();
Expand All @@ -64,7 +63,7 @@ public void start(String[] args) {
options.addOption("a", "peerAddress", true, "Address of peer to connect to");
options.addOption("s", "securityEnabled", false, "Present if security is enabled");
options.addOption("i", "id", true, "Identity of chaincode");

options.addOption("o", "hostNameOverride", true, "Hostname override for server certificate");
try {
CommandLine cl = new DefaultParser().parse(options, args);
if (cl.hasOption('a')) {
Expand All @@ -73,8 +72,12 @@ public void start(String[] args) {
host = host.split(":")[0];
}
if (cl.hasOption('s')) {
//TODO
logger.warn("securityEnabled option not implemented yet");
tlsEnabled = true;
logger.debug("TLS enabled");
if (cl.hasOption('o')){
hostOverrideAuthority = cl.getOptionValue('o');
logger.debug("server host override given " + hostOverrideAuthority);
}
}
if (cl.hasOption('i')) {
id = cl.getOptionValue('i');
Expand All @@ -96,21 +99,27 @@ public void start(String[] args) {

public ManagedChannel newPeerClientConnection() {
NettyChannelBuilder builder = NettyChannelBuilder.forAddress(host, port);
//TODO security
if (false) {//"true".equals(params.get("peer.tls.enabled"))) {
logger.info("Inside newPeerCLientConnection");

if (tlsEnabled) {
logger.info("tls enable");
try {
SslContext sslContext = GrpcSslContexts.forClient().trustManager(
new File("pathToServerCertPemFile")).keyManager(new File("pathToOwnCertPemFile"),
new File("pathToOwnPrivateKeyPemFile")).build();
SslContext sslContext = GrpcSslContexts.forClient()
.trustManager(new File(ROOTCERT_PEM))
.build();
builder.negotiationType(NegotiationType.TLS);
if (!hostOverrideAuthority.equals("")){
logger.info("host override " + hostOverrideAuthority);
builder.overrideAuthority(hostOverrideAuthority);
}
builder.sslContext(sslContext);
logger.info("context built" + sslContext);
} catch (SSLException e) {
logger.error("failed connect to peer with SSLException",e);
}
} else {
builder.usePlaintext(true);
}

return builder.build();
}

Expand Down
7 changes: 7 additions & 0 deletions core/container/util/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ func WriteJavaProjectToPackage(tw *tar.Writer, srcPath string) error {
vmLogger.Errorf("Error writing folder to tar package %s", err)
return err
}
// Add the ca for self signed cert to tar
if viper.GetBool("peer.tls.enabled") && viper.GetString("peer.tls.rootcert.file") != "" {
err := WriteFileToPackage(viper.GetString("peer.tls.rootcert.file"), "src/certs/rootcert.pem", tw)
if err != nil {
return fmt.Errorf("Error writing cert file to package: %s", err)
}
}
// Write the tar file out
if err := tw.Close(); err != nil {
return err
Expand Down
6 changes: 6 additions & 0 deletions peer/core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ peer:
file: testdata/server1.pem
key:
file: testdata/server1.key
# Root cert file for selfsigned certificates
# This represents a self-signed x509 cert that was used to sign the cert.file,
# this is sent to client to validate the recived certificate from server when
# establishing TLS connection
rootcert:
file:
# The server name use to verify the hostname returned by TLS handshake
serverhostoverride:

Expand Down

0 comments on commit d39194c

Please sign in to comment.