Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit 7fac5e4

Browse files
irririkibestbeforetoday
authored andcommitted
Allow client TLS certificate and key to be specified in connection profile (#261)
Signed-off-by: Sheng Guo <[email protected]> (cherry picked from commit 678746b)
1 parent 51ddbbf commit 7fac5e4

File tree

9 files changed

+289
-51
lines changed

9 files changed

+289
-51
lines changed

src/main/java/org/hyperledger/fabric/sdk/Channel.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,25 +1627,25 @@ public Orderer addOrderer(SDOrdererAdditionInfo sdOrdererAdditionInfo) throws In
16271627

16281628
String protocol = (String) findClientProp(config, "protocol", mspid, endpoint, sdOrdererAdditionInfo.isTLS() ? "grpcs:" : "grpc:");
16291629

1630-
String clientCertFile = (String) findClientProp(config, "clientCertFile", mspid, endpoint, null);
1630+
String clientCertFile = (String) findClientProp(config, NetworkConfig.CLIENT_CERT_FILE, mspid, endpoint, null);
16311631

16321632
if (null != clientCertFile) {
1633-
properties.put("clientCertFile", clientCertFile);
1633+
properties.put(NetworkConfig.CLIENT_CERT_FILE, clientCertFile);
16341634
}
16351635

1636-
String clientKeyFile = (String) findClientProp(config, "clientKeyFile", mspid, endpoint, null);
1636+
String clientKeyFile = (String) findClientProp(config, NetworkConfig.CLIENT_KEY_FILE, mspid, endpoint, null);
16371637
if (null != clientKeyFile) {
1638-
properties.put("clientKeyFile", clientKeyFile);
1638+
properties.put(NetworkConfig.CLIENT_KEY_FILE, clientKeyFile);
16391639
}
16401640

1641-
byte[] clientCertBytes = (byte[]) findClientProp(config, "clientCertBytes", mspid, endpoint, null);
1641+
byte[] clientCertBytes = (byte[]) findClientProp(config, NetworkConfig.CLIENT_CERT_BYTES, mspid, endpoint, null);
16421642
if (null != clientCertBytes) {
1643-
properties.put("clientCertBytes", clientCertBytes);
1643+
properties.put(NetworkConfig.CLIENT_CERT_BYTES, clientCertBytes);
16441644
}
16451645

1646-
byte[] clientKeyBytes = (byte[]) findClientProp(config, "clientKeyBytes", mspid, endpoint, null);
1646+
byte[] clientKeyBytes = (byte[]) findClientProp(config, NetworkConfig.CLIENT_KEY_BYTES, mspid, endpoint, null);
16471647
if (null != clientKeyBytes) {
1648-
properties.put("clientKeyBytes", clientKeyBytes);
1648+
properties.put(NetworkConfig.CLIENT_KEY_BYTES, clientKeyBytes);
16491649
}
16501650

16511651
String hostnameOverride = (String) findClientProp(config, "hostnameOverride", mspid, endpoint, null);
@@ -1693,23 +1693,23 @@ public Peer addPeer(SDPeerAdditionInfo sdPeerAddition) throws InvalidArgumentExc
16931693

16941694
}
16951695

1696-
String clientCertFile = (String) findClientProp(config, "clientCertFile", mspid, endpoint, null);
1696+
String clientCertFile = (String) findClientProp(config, NetworkConfig.CLIENT_CERT_FILE, mspid, endpoint, null);
16971697

1698-
byte[] clientCertBytes = (byte[]) findClientProp(config, "clientCertBytes", mspid, endpoint, null);
1698+
byte[] clientCertBytes = (byte[]) findClientProp(config, NetworkConfig.CLIENT_CERT_BYTES, mspid, endpoint, null);
16991699
if (null != clientCertBytes) {
1700-
properties.put("clientCertBytes", clientCertBytes);
1700+
properties.put(NetworkConfig.CLIENT_CERT_BYTES, clientCertBytes);
17011701
} else if (null != clientCertFile) {
1702-
properties.put("clientCertFile", clientCertFile);
1702+
properties.put(NetworkConfig.CLIENT_CERT_FILE, clientCertFile);
17031703
}
17041704

17051705
properties.put(Peer.PEER_ORGANIZATION_MSPID_PROPERTY, sdPeerAddition.getMspId());
17061706

1707-
byte[] clientKeyBytes = (byte[]) findClientProp(config, "clientKeyBytes", mspid, endpoint, null);
1708-
String clientKeyFile = (String) findClientProp(config, "clientKeyFile", mspid, endpoint, null);
1707+
byte[] clientKeyBytes = (byte[]) findClientProp(config, NetworkConfig.CLIENT_KEY_BYTES, mspid, endpoint, null);
1708+
String clientKeyFile = (String) findClientProp(config, NetworkConfig.CLIENT_KEY_FILE, mspid, endpoint, null);
17091709
if (null != clientKeyBytes) {
1710-
properties.put("clientKeyBytes", clientKeyBytes);
1710+
properties.put(NetworkConfig.CLIENT_KEY_BYTES, clientKeyBytes);
17111711
} else if (null != clientKeyFile) {
1712-
properties.put("clientKeyFile", clientKeyFile);
1712+
properties.put(NetworkConfig.CLIENT_KEY_FILE, clientKeyFile);
17131713
}
17141714

17151715
String hostnameOverride = (String) findClientProp(config, "hostnameOverride", mspid, endpoint, null);

src/main/java/org/hyperledger/fabric/sdk/Endpoint.java

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import static org.hyperledger.fabric.sdk.helper.Utils.parseGrpcUrl;
6767

6868
class Endpoint {
69+
6970
private static final Log logger = LogFactory.getLog(Endpoint.class);
7071

7172
private static final String SSLPROVIDER = Config.getConfig().getDefaultSSLProvider();
@@ -172,28 +173,28 @@ class Endpoint {
172173
}
173174
// check for mutual TLS - both clientKey and clientCert must be present
174175
byte[] ckb = null, ccb = null;
175-
if (properties.containsKey("clientKeyFile") && properties.containsKey("clientKeyBytes")) {
176+
if (properties.containsKey(NetworkConfig.CLIENT_KEY_FILE) && properties.containsKey(NetworkConfig.CLIENT_KEY_BYTES)) {
176177
throw new RuntimeException("Properties \"clientKeyFile\" and \"clientKeyBytes\" must cannot both be set");
177-
} else if (properties.containsKey("clientCertFile") && properties.containsKey("clientCertBytes")) {
178+
} else if (properties.containsKey(NetworkConfig.CLIENT_CERT_FILE) && properties.containsKey(NetworkConfig.CLIENT_CERT_BYTES)) {
178179
throw new RuntimeException("Properties \"clientCertFile\" and \"clientCertBytes\" must cannot both be set");
179-
} else if (properties.containsKey("clientKeyFile") || properties.containsKey("clientCertFile")) {
180-
if ((properties.getProperty("clientKeyFile") != null) && (properties.getProperty("clientCertFile") != null)) {
180+
} else if (properties.containsKey(NetworkConfig.CLIENT_KEY_FILE) || properties.containsKey(NetworkConfig.CLIENT_CERT_FILE)) {
181+
if ((properties.getProperty(NetworkConfig.CLIENT_KEY_FILE) != null) && (properties.getProperty(NetworkConfig.CLIENT_CERT_FILE) != null)) {
181182
try {
182-
logger.trace(format("Endpoint %s reading clientKeyFile: %s", url, properties.getProperty("clientKeyFile")));
183-
ckb = Files.readAllBytes(Paths.get(properties.getProperty("clientKeyFile")));
184-
logger.trace(format("Endpoint %s reading clientCertFile: %s", url, properties.getProperty("clientCertFile")));
185-
ccb = Files.readAllBytes(Paths.get(properties.getProperty("clientCertFile")));
183+
logger.trace(format("Endpoint %s reading clientKeyFile: %s", url, properties.getProperty(NetworkConfig.CLIENT_KEY_FILE)));
184+
ckb = Files.readAllBytes(Paths.get(properties.getProperty(NetworkConfig.CLIENT_KEY_FILE)));
185+
logger.trace(format("Endpoint %s reading clientCertFile: %s", url, properties.getProperty(NetworkConfig.CLIENT_CERT_FILE)));
186+
ccb = Files.readAllBytes(Paths.get(properties.getProperty(NetworkConfig.CLIENT_CERT_FILE)));
186187
} catch (IOException e) {
187188
throw new RuntimeException("Failed to parse TLS client key and/or cert", e);
188189
}
189190
} else {
190-
throw new RuntimeException("Properties \"clientKeyFile\" and \"clientCertFile\" must both be set or both be null");
191+
throw new RuntimeException(String.format("Properties \"%s\" and \"%s\" must both be set or both be null", NetworkConfig.CLIENT_KEY_FILE, NetworkConfig.CLIENT_CERT_FILE));
191192
}
192-
} else if (properties.containsKey("clientKeyBytes") || properties.containsKey("clientCertBytes")) {
193-
ckb = (byte[]) properties.get("clientKeyBytes");
194-
ccb = (byte[]) properties.get("clientCertBytes");
193+
} else if (properties.containsKey(NetworkConfig.CLIENT_KEY_BYTES) || properties.containsKey(NetworkConfig.CLIENT_CERT_BYTES)) {
194+
ckb = (byte[]) properties.get(NetworkConfig.CLIENT_KEY_BYTES);
195+
ccb = (byte[]) properties.get(NetworkConfig.CLIENT_CERT_BYTES);
195196
if ((ckb == null) || (ccb == null)) {
196-
throw new RuntimeException("Properties \"clientKeyBytes\" and \"clientCertBytes\" must both be set or both be null");
197+
throw new RuntimeException(String.format("Properties \"%s\" and \"%s\" must both be set or both be null", NetworkConfig.CLIENT_KEY_BYTES, NetworkConfig.CLIENT_CERT_BYTES));
197198
}
198199
}
199200

@@ -400,28 +401,28 @@ AbstractMap.SimpleImmutableEntry<PrivateKey, X509Certificate[]> getClientTLSProp
400401

401402
// check for mutual TLS - both clientKey and clientCert must be present
402403
byte[] ckb = null, ccb = null;
403-
if (properties.containsKey("clientKeyFile") && properties.containsKey("clientKeyBytes")) {
404+
if (properties.containsKey(NetworkConfig.CLIENT_KEY_FILE) && properties.containsKey(NetworkConfig.CLIENT_KEY_BYTES)) {
404405
throw new RuntimeException("Properties \"clientKeyFile\" and \"clientKeyBytes\" must cannot both be set");
405-
} else if (properties.containsKey("clientCertFile") && properties.containsKey("clientCertBytes")) {
406+
} else if (properties.containsKey(NetworkConfig.CLIENT_CERT_FILE) && properties.containsKey(NetworkConfig.CLIENT_CERT_BYTES)) {
406407
throw new RuntimeException("Properties \"clientCertFile\" and \"clientCertBytes\" must cannot both be set");
407-
} else if (properties.containsKey("clientKeyFile") || properties.containsKey("clientCertFile")) {
408-
if ((properties.getProperty("clientKeyFile") != null) && (properties.getProperty("clientCertFile") != null)) {
408+
} else if (properties.containsKey(NetworkConfig.CLIENT_KEY_FILE) || properties.containsKey(NetworkConfig.CLIENT_CERT_FILE)) {
409+
if ((properties.getProperty(NetworkConfig.CLIENT_KEY_FILE) != null) && (properties.getProperty(NetworkConfig.CLIENT_CERT_FILE) != null)) {
409410
try {
410-
logger.trace(format("Endpoint %s reading clientKeyFile: %s", url, new File(properties.getProperty("clientKeyFile")).getAbsolutePath()));
411-
ckb = Files.readAllBytes(Paths.get(properties.getProperty("clientKeyFile")));
412-
logger.trace(format("Endpoint %s reading clientCertFile: %s", url, new File(properties.getProperty("clientCertFile")).getAbsolutePath()));
413-
ccb = Files.readAllBytes(Paths.get(properties.getProperty("clientCertFile")));
411+
logger.trace(format("Endpoint %s reading clientKeyFile: %s", url, new File(properties.getProperty(NetworkConfig.CLIENT_KEY_FILE)).getAbsolutePath()));
412+
ckb = Files.readAllBytes(Paths.get(properties.getProperty(NetworkConfig.CLIENT_KEY_FILE)));
413+
logger.trace(format("Endpoint %s reading clientCertFile: %s", url, new File(properties.getProperty(NetworkConfig.CLIENT_CERT_FILE)).getAbsolutePath()));
414+
ccb = Files.readAllBytes(Paths.get(properties.getProperty(NetworkConfig.CLIENT_CERT_FILE)));
414415
} catch (IOException e) {
415416
throw new RuntimeException("Failed to parse TLS client key and/or cert", e);
416417
}
417418
} else {
418-
throw new RuntimeException("Properties \"clientKeyFile\" and \"clientCertFile\" must both be set or both be null");
419+
throw new RuntimeException(String.format("Properties \"%s\" and \"%s\" must both be set or both be null", NetworkConfig.CLIENT_KEY_FILE, NetworkConfig.CLIENT_CERT_FILE));
419420
}
420-
} else if (properties.containsKey("clientKeyBytes") || properties.containsKey("clientCertBytes")) {
421-
ckb = (byte[]) properties.get("clientKeyBytes");
422-
ccb = (byte[]) properties.get("clientCertBytes");
421+
} else if (properties.containsKey(NetworkConfig.CLIENT_KEY_BYTES) || properties.containsKey(NetworkConfig.CLIENT_CERT_BYTES)) {
422+
ckb = (byte[]) properties.get(NetworkConfig.CLIENT_KEY_BYTES);
423+
ccb = (byte[]) properties.get(NetworkConfig.CLIENT_CERT_BYTES);
423424
if ((ckb == null) || (ccb == null)) {
424-
throw new RuntimeException("Properties \"clientKeyBytes\" and \"clientCertBytes\" must both be set or both be null");
425+
throw new RuntimeException(String.format("Properties \"%s\" and \"%s\" must both be set or both be null", NetworkConfig.CLIENT_KEY_BYTES, NetworkConfig.CLIENT_CERT_BYTES));
425426
}
426427
}
427428

src/main/java/org/hyperledger/fabric/sdk/NetworkConfig.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@
7272
*/
7373

7474
public class NetworkConfig {
75+
public static final String CLIENT_CERT_BYTES = "clientCertBytes";
76+
77+
public static final String CLIENT_KEY_BYTES = "clientKeyBytes";
78+
79+
public static final String CLIENT_CERT_FILE = "clientCertFile";
80+
81+
public static final String CLIENT_KEY_FILE = "clientKeyFile";
82+
7583
private static final String URL_PROP_NAME = "url";
7684

7785
private final JsonObject jsonConfig;
@@ -843,22 +851,22 @@ private void getTLSCerts(JsonObject jsonOrderer, Properties props) {
843851
String certfile = getJsonValueAsString(jsonTlsClientCerts.get("certfile"));
844852

845853
if (keyfile != null) {
846-
props.put("tlsClientKeyFile", keyfile);
854+
props.put(CLIENT_KEY_FILE, keyfile);
847855
}
848856

849857
if (certfile != null) {
850-
props.put("tlsClientCertFile", certfile);
858+
props.put(CLIENT_CERT_FILE, certfile);
851859
}
852860

853861
String keyBytes = getJsonValueAsString(jsonTlsClientCerts.get("keyPem"));
854862
String certBytes = getJsonValueAsString(jsonTlsClientCerts.get("certPem"));
855863

856864
if (keyBytes != null) {
857-
props.put("tlsClientKeyBytes", keyBytes.getBytes());
865+
props.put(CLIENT_KEY_BYTES, keyBytes.getBytes());
858866
}
859867

860868
if (certBytes != null) {
861-
props.put("tlsClientCertBytes", certBytes.getBytes());
869+
props.put(CLIENT_CERT_BYTES, certBytes.getBytes());
862870
}
863871
}
864872
}

src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,17 +1617,17 @@ private void setUpSSL() throws InvalidArgumentException {
16171617
}
16181618
}
16191619

1620-
String tlsClientKeyFile = properties.getProperty("tlsClientKeyFile");
1621-
String tlsClientCertFile = properties.getProperty("tlsClientCertFile");
1620+
String tlsClientKeyFile = properties.getProperty(NetworkConfig.CLIENT_KEY_FILE);
1621+
String tlsClientCertFile = properties.getProperty(NetworkConfig.CLIENT_CERT_FILE);
16221622

1623-
byte[] tlsClientKeyAsBytes = (byte[]) properties.get("tlsClientKeyBytes");
1623+
byte[] tlsClientKeyAsBytes = (byte[]) properties.get(NetworkConfig.CLIENT_KEY_BYTES);
16241624
if (tlsClientKeyFile != null && tlsClientKeyAsBytes != null) {
16251625
logger.warn("SSL CA client key is specified as bytes and as a file path. Using client key specified as bytes.");
16261626
}
16271627
if (tlsClientKeyFile != null && tlsClientKeyAsBytes == null) {
16281628
tlsClientKeyAsBytes = Files.readAllBytes(Paths.get(tlsClientKeyFile));
16291629
}
1630-
byte[] tlsClientCertAsBytes = (byte[]) properties.get("tlsClientCertBytes");
1630+
byte[] tlsClientCertAsBytes = (byte[]) properties.get(NetworkConfig.CLIENT_CERT_BYTES);
16311631
if (tlsClientCertFile != null && tlsClientCertAsBytes != null) {
16321632
logger.warn("SSL CA client cert is specified as bytes and as a file path. Using client cert specified as bytes.");
16331633
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
{
2+
"name": "global-trade-network",
3+
"x-type": "hlfv1",
4+
"description": "The network to be in if you want to stay in the global trade business",
5+
"version": "1.0.0",
6+
"client": {
7+
"organization": "Org1",
8+
"credentialStore": {
9+
"path": "/tmp/hfc-kvs",
10+
"cryptoStore": {
11+
"path": "/tmp/hfc-cvs"
12+
},
13+
"wallet": "wallet-name"
14+
}
15+
},
16+
"channels": {
17+
"mychannel": {
18+
"orderers": [
19+
"orderer.example.com"
20+
],
21+
"peers": {
22+
"peer0.org1.example.com": {
23+
"endorsingPeer": true,
24+
"chaincodeQuery": true,
25+
"ledgerQuery": true,
26+
"eventSource": true
27+
28+
},
29+
"peer1.org1.example.com": {
30+
"endorsingPeer": true,
31+
"chaincodeQuery": true,
32+
"ledgerQuery": true,
33+
"eventSource": true
34+
}
35+
},
36+
"chaincodes": [
37+
"example02:v1",
38+
"marbles:1.0"
39+
]
40+
}
41+
},
42+
"organizations": {
43+
"Org1": {
44+
"mspid": "Org1MSP",
45+
"peers": [
46+
"peer0.org1.example.com",
47+
"peer1.org1.example.com"
48+
],
49+
"certificateAuthorities": [
50+
"ca-org1"
51+
],
52+
"adminPrivateKey": {
53+
"pem": "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQghnA7rdgbZi/wndusiXjyf0KgE6OKZjQ+5INjwelRAC6hRANCAASb3u+hY+U/FZvhYDN6d08HJ1v56UJUyz/n2NHyJgTg6kC05AaJMeGIinEF0JeJtRDNVQGzoQJQYjnzUTS9FvGh\n-----END PRIVATE KEY-----"
54+
},
55+
"signedCert": {
56+
"path": "src/test/fixture/sdkintegration/e2e-2Orgs/v1.3/crypto-config/peerOrganizations/org1.example.com/users/[email protected]/msp/signcerts/[email protected]"
57+
}
58+
}
59+
},
60+
"orderers": {
61+
"orderer.example.com": {
62+
"url": "grpcs://localhost:7050",
63+
"grpcOptions": {
64+
"ssl-target-name-override": "orderer.example.com",
65+
"grpc-max-send-message-length": 15
66+
},
67+
"tlsCACerts": {
68+
"pem": "-----BEGIN CERTIFICATE----- <etc>"
69+
}
70+
}
71+
},
72+
"peers": {
73+
"peer0.org1.example.com": {
74+
"url": "grpcs://localhost:7051",
75+
"grpcOptions": {
76+
"ssl-target-name-override": "peer0.org1.example.com",
77+
"grpc.http2.keepalive_time": 15
78+
},
79+
"tlsCACerts": {
80+
"path": "src/test/fixture/sdkintegration/e2e-2Orgs/v1.3/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt",
81+
"client": {
82+
"certfile": "./tls/sign.pem",
83+
"keyfile": "./tls/key.pem"
84+
}
85+
}
86+
},
87+
"peer1.org1.example.com": {
88+
"url": "grpcs://localhost:7051",
89+
"grpcOptions": {
90+
"ssl-target-name-override": "peer1.org1.example.com",
91+
"grpc.http2.keepalive_time": 15
92+
},
93+
"tlsCACerts": {
94+
"path": "src/test/fixture/sdkintegration/e2e-2Orgs/v1.3/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/server.crt",
95+
"client": {
96+
"certPem": "-----BEGIN CERTIFICATE----- <etc>",
97+
"keyPem": "-----BEGIN PRIVATE KEY----- <etc>"
98+
}
99+
}
100+
}
101+
},"certificateAuthorities": {
102+
"ca-org1": {
103+
"url": "https://localhost:7054",
104+
"httpOptions": {
105+
"verify": true
106+
},
107+
"tlsCACerts": {
108+
"path": "peerOrganizations/org1.example.com/ca/org1.example.com-cert.pem",
109+
"pem": "-----BEGIN CERTIFICATE----- <etc>"
110+
},
111+
"registrar": [
112+
{
113+
"enrollId": "admin",
114+
"enrollSecret": "adminpw"
115+
}
116+
],
117+
"caName": "caNameHere"
118+
}
119+
}
120+
}

src/test/fixture/testPems/client.key

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-----BEGIN EC PRIVATE KEY-----
2+
MHcCAQEEILaiKBtmV7pPCel9NBp74A6jJWHc/Vobug5AyMkncB3ToAoGCCqGSM49
3+
AwEHoUQDQgAEJT+fZ/nl8t38QY6VmddSvjB9HMITio6JUFZhDJ3qoAqCVAfKi6EI
4+
sH+zLZuZA/324j3iHRYkNFUqkNA9wU91qw==
5+
-----END EC PRIVATE KEY-----

0 commit comments

Comments
 (0)