Skip to content

Commit d39194c

Browse files
committed
Added support for TLS in java shim
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 <[email protected]>
1 parent aeb88b4 commit d39194c

File tree

6 files changed

+70
-34
lines changed

6 files changed

+70
-34
lines changed

core/chaincode/chaincode_support.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,14 @@ func (chaincodeSupport *ChaincodeSupport) getArgsAndEnv(cccid *CCContext, cLang
380380
chaincodeSupport.peerAddress, cccid.Name),
381381
" ")
382382
if chaincodeSupport.peerTLS {
383-
args = append(args, " -s")
383+
args = append(args, "-s")
384+
if chaincodeSupport.peerTLSSvrHostOrd != "" {
385+
args = append(args, "-o")
386+
args = append(args, chaincodeSupport.peerTLSSvrHostOrd)
387+
}
384388
}
385389
chaincodeLogger.Debugf("Executable is %s", args[0])
390+
chaincodeLogger.Debugf("Args %v", args)
386391
default:
387392
return nil, nil, fmt.Errorf("Unknown chaincodeType: %s", cLang)
388393
}

core/chaincode/platforms/java/package.go

+12-8
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,18 @@ func writeChaincodePackage(spec *pb.ChaincodeSpec, tw *tar.Writer) error {
9191
var dockerFileContents string
9292
var buf []string
9393

94-
if viper.GetBool("security.enabled") {
95-
//todo
96-
} else {
97-
buf = append(buf, cutil.GetDockerfileFromConfig("chaincode.java.Dockerfile"))
98-
buf = append(buf, "COPY src /root/chaincode")
99-
buf = append(buf, "RUN cd /root/chaincode && "+buildCmd)
100-
buf = append(buf, "RUN cp /root/chaincode/build/chaincode.jar /root")
101-
buf = append(buf, "RUN cp /root/chaincode/build/libs/* /root/libs")
94+
buf = append(buf, cutil.GetDockerfileFromConfig("chaincode.java.Dockerfile"))
95+
buf = append(buf, "COPY src /root/chaincode")
96+
buf = append(buf, "RUN cd /root/chaincode && "+buildCmd)
97+
buf = append(buf, "RUN cp /root/chaincode/build/chaincode.jar /root")
98+
buf = append(buf, "RUN cp /root/chaincode/build/libs/* /root/libs")
99+
100+
// Add COPY command to Dockerfile when it is a self-signed cert and rootcert.pem
101+
// is specified in the peer.tls.rootcert.file configuration. It is made available
102+
// in the docker context tar file in writer.go
103+
104+
if viper.GetBool("peer.tls.enabled") && viper.GetString("peer.tls.rootcert.file") != "" {
105+
buf = append(buf, "COPY src/certs/rootcert.pem /root/certs/rootcert.pem")
102106
}
103107

104108
dockerFileContents = strings.Join(buf, "\n")

core/chaincode/shim/java/build.gradle

+9-4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ buildscript {
2121
jcenter()
2222
}
2323
dependencies {
24-
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.7.6'
24+
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'
2525
}
2626
}
2727

2828
plugins {
2929
id "java"
30-
id "com.google.protobuf" version "0.7.6"
30+
id "com.google.protobuf" version "0.8.0"
3131
id "eclipse"
3232
id "maven-publish"
3333

@@ -52,10 +52,14 @@ repositories {
5252
mavenCentral()
5353
}
5454

55+
apply plugin: "com.google.osdetector"
56+
57+
def tcnative_classifier = osdetector.classifier;
58+
5559
protobuf {
5660
generatedFilesBaseDir = "$projectDir/src"
5761
protoc {
58-
artifact = 'com.google.protobuf:protoc:3.0.0-beta-2'
62+
artifact = 'com.google.protobuf:protoc:3.0.0'
5963
}
6064
plugins {
6165
grpc {
@@ -105,9 +109,10 @@ build.finalizedBy(copyToLib)
105109
build.finalizedBy(publishToMavenLocal)
106110

107111
dependencies {
108-
compile 'com.google.protobuf:protobuf-java:3.0.0-beta-2'
112+
compile 'com.google.protobuf:protobuf-java:3.0.0'
109113
compile 'io.grpc:grpc-all:0.13.2'
110114
compile 'commons-cli:commons-cli:1.3.1'
115+
compile 'io.netty:netty-tcnative-boringssl-static:1.1.33.Fork21:' + tcnative_classifier
111116
}
112117

113118
publishing {

core/chaincode/shim/java/src/main/java/org/hyperledger/java/shim/ChaincodeBase.java

+30-21
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,27 @@
1616

1717
package org.hyperledger.java.shim;
1818

19-
import java.io.File;
20-
21-
import javax.net.ssl.SSLException;
22-
23-
import org.apache.commons.cli.CommandLine;
24-
import org.apache.commons.cli.DefaultParser;
25-
import org.apache.commons.cli.Options;
26-
2719
import com.google.protobuf.ByteString;
28-
29-
import org.apache.commons.logging.Log;
30-
import org.apache.commons.logging.LogFactory;
31-
3220
import io.grpc.ManagedChannel;
3321
import io.grpc.netty.GrpcSslContexts;
3422
import io.grpc.netty.NegotiationType;
3523
import io.grpc.netty.NettyChannelBuilder;
3624
import io.grpc.stub.StreamObserver;
3725
import io.netty.handler.ssl.SslContext;
26+
import org.apache.commons.cli.CommandLine;
27+
import org.apache.commons.cli.DefaultParser;
28+
import org.apache.commons.cli.Options;
29+
import org.apache.commons.logging.Log;
30+
import org.apache.commons.logging.LogFactory;
3831
import org.hyperledger.protos.Chaincode.ChaincodeID;
3932
import org.hyperledger.protos.Chaincode.ChaincodeMessage;
4033
import org.hyperledger.protos.Chaincode.ChaincodeMessage.Type;
4134
import org.hyperledger.protos.ChaincodeSupportGrpc;
4235
import org.hyperledger.protos.ChaincodeSupportGrpc.ChaincodeSupportStub;
4336

37+
import javax.net.ssl.SSLException;
38+
import java.io.File;
39+
4440
public abstract class ChaincodeBase {
4541

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

5551
private String host = DEFAULT_HOST;
5652
private int port = DEFAULT_PORT;
53+
private String hostOverrideAuthority = "";
54+
private static final String ROOTCERT_PEM = "/root/certs/rootcert.pem";
55+
private boolean tlsEnabled=false;
5756

5857
private Handler handler;
5958
private String id = getChaincodeID();
@@ -64,7 +63,7 @@ public void start(String[] args) {
6463
options.addOption("a", "peerAddress", true, "Address of peer to connect to");
6564
options.addOption("s", "securityEnabled", false, "Present if security is enabled");
6665
options.addOption("i", "id", true, "Identity of chaincode");
67-
66+
options.addOption("o", "hostNameOverride", true, "Hostname override for server certificate");
6867
try {
6968
CommandLine cl = new DefaultParser().parse(options, args);
7069
if (cl.hasOption('a')) {
@@ -73,8 +72,12 @@ public void start(String[] args) {
7372
host = host.split(":")[0];
7473
}
7574
if (cl.hasOption('s')) {
76-
//TODO
77-
logger.warn("securityEnabled option not implemented yet");
75+
tlsEnabled = true;
76+
logger.debug("TLS enabled");
77+
if (cl.hasOption('o')){
78+
hostOverrideAuthority = cl.getOptionValue('o');
79+
logger.debug("server host override given " + hostOverrideAuthority);
80+
}
7881
}
7982
if (cl.hasOption('i')) {
8083
id = cl.getOptionValue('i');
@@ -96,21 +99,27 @@ public void start(String[] args) {
9699

97100
public ManagedChannel newPeerClientConnection() {
98101
NettyChannelBuilder builder = NettyChannelBuilder.forAddress(host, port);
99-
//TODO security
100-
if (false) {//"true".equals(params.get("peer.tls.enabled"))) {
102+
logger.info("Inside newPeerCLientConnection");
103+
104+
if (tlsEnabled) {
105+
logger.info("tls enable");
101106
try {
102-
SslContext sslContext = GrpcSslContexts.forClient().trustManager(
103-
new File("pathToServerCertPemFile")).keyManager(new File("pathToOwnCertPemFile"),
104-
new File("pathToOwnPrivateKeyPemFile")).build();
107+
SslContext sslContext = GrpcSslContexts.forClient()
108+
.trustManager(new File(ROOTCERT_PEM))
109+
.build();
105110
builder.negotiationType(NegotiationType.TLS);
111+
if (!hostOverrideAuthority.equals("")){
112+
logger.info("host override " + hostOverrideAuthority);
113+
builder.overrideAuthority(hostOverrideAuthority);
114+
}
106115
builder.sslContext(sslContext);
116+
logger.info("context built" + sslContext);
107117
} catch (SSLException e) {
108118
logger.error("failed connect to peer with SSLException",e);
109119
}
110120
} else {
111121
builder.usePlaintext(true);
112122
}
113-
114123
return builder.build();
115124
}
116125

core/container/util/writer.go

+7
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,13 @@ func WriteJavaProjectToPackage(tw *tar.Writer, srcPath string) error {
149149
vmLogger.Errorf("Error writing folder to tar package %s", err)
150150
return err
151151
}
152+
// Add the ca for self signed cert to tar
153+
if viper.GetBool("peer.tls.enabled") && viper.GetString("peer.tls.rootcert.file") != "" {
154+
err := WriteFileToPackage(viper.GetString("peer.tls.rootcert.file"), "src/certs/rootcert.pem", tw)
155+
if err != nil {
156+
return fmt.Errorf("Error writing cert file to package: %s", err)
157+
}
158+
}
152159
// Write the tar file out
153160
if err := tw.Close(); err != nil {
154161
return err

peer/core.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,12 @@ peer:
183183
file: testdata/server1.pem
184184
key:
185185
file: testdata/server1.key
186+
# Root cert file for selfsigned certificates
187+
# This represents a self-signed x509 cert that was used to sign the cert.file,
188+
# this is sent to client to validate the recived certificate from server when
189+
# establishing TLS connection
190+
rootcert:
191+
file:
186192
# The server name use to verify the hostname returned by TLS handshake
187193
serverhostoverride:
188194

0 commit comments

Comments
 (0)