Skip to content

Commit baf34ec

Browse files
author
Ajay Kumar
committed
get CA cert in same rpc call
1 parent ec5aa95 commit baf34ec

File tree

11 files changed

+126
-49
lines changed

11 files changed

+126
-49
lines changed

hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ public static InetSocketAddress getScmAddressForBlockClients(
178178
* @return {@link SCMSecurityProtocol}
179179
* @throws IOException
180180
*/
181-
public static SCMSecurityProtocol getScmSecurityClient(
181+
public static SCMSecurityProtocolClientSideTranslatorPB getScmSecurityClient(
182182
OzoneConfiguration conf, InetSocketAddress address) throws IOException {
183183
RPC.setProtocolEngine(conf, SCMSecurityProtocolPB.class,
184184
ProtobufRpcEngine.class);

hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/protocolPB/SCMSecurityProtocolClientSideTranslatorPB.java

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DatanodeDetailsProto;
2424
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.OzoneManagerDetailsProto;
2525
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetCACertificateRequestProto;
26+
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetCertResponseProto;
2627
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetCertificateRequestProto;
2728
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetCertificateRequestProto.Builder;
2829
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetDataNodeCertRequestProto;
@@ -79,18 +80,8 @@ public void close() throws IOException {
7980
@Override
8081
public String getDataNodeCertificate(DatanodeDetailsProto dataNodeDetails,
8182
String certSignReq) throws IOException {
82-
SCMGetDataNodeCertRequestProto.Builder builder =
83-
SCMGetDataNodeCertRequestProto
84-
.newBuilder()
85-
.setCSR(certSignReq)
86-
.setDatanodeDetails(dataNodeDetails);
87-
try {
88-
return rpcProxy
89-
.getDataNodeCertificate(NULL_RPC_CONTROLLER, builder.build())
90-
.getX509Certificate();
91-
} catch (ServiceException e) {
92-
throw ProtobufHelper.getRemoteException(e);
93-
}
83+
return getDataNodeCertificateChain(dataNodeDetails, certSignReq)
84+
.getX509Certificate();
9485
}
9586

9687
/**
@@ -103,13 +94,25 @@ public String getDataNodeCertificate(DatanodeDetailsProto dataNodeDetails,
10394
@Override
10495
public String getOMCertificate(OzoneManagerDetailsProto omDetails,
10596
String certSignReq) throws IOException {
97+
return getOMCertChain(omDetails, certSignReq).getX509Certificate();
98+
}
99+
100+
/**
101+
* Get SCM signed certificate for OM.
102+
*
103+
* @param omDetails - OzoneManager Details.
104+
* @param certSignReq - Certificate signing request.
105+
* @return byte[] - SCM signed certificate.
106+
*/
107+
public SCMGetCertResponseProto getOMCertChain(
108+
OzoneManagerDetailsProto omDetails, String certSignReq)
109+
throws IOException {
106110
SCMGetOMCertRequestProto.Builder builder = SCMGetOMCertRequestProto
107111
.newBuilder()
108112
.setCSR(certSignReq)
109113
.setOmDetails(omDetails);
110114
try {
111-
return rpcProxy.getOMCertificate(NULL_RPC_CONTROLLER, builder.build())
112-
.getX509Certificate();
115+
return rpcProxy.getOMCertificate(NULL_RPC_CONTROLLER, builder.build());
113116
} catch (ServiceException e) {
114117
throw ProtobufHelper.getRemoteException(e);
115118
}
@@ -135,6 +138,28 @@ public String getCertificate(String certSerialId) throws IOException {
135138
}
136139
}
137140

141+
/**
142+
* Get SCM signed certificate for Datanode.
143+
*
144+
* @param dnDetails - Datanode Details.
145+
* @param certSignReq - Certificate signing request.
146+
* @return byte[] - SCM signed certificate.
147+
*/
148+
public SCMGetCertResponseProto getDataNodeCertificateChain(
149+
DatanodeDetailsProto dnDetails, String certSignReq)
150+
throws IOException {
151+
SCMGetDataNodeCertRequestProto.Builder builder =
152+
SCMGetDataNodeCertRequestProto.newBuilder()
153+
.setCSR(certSignReq)
154+
.setDatanodeDetails(dnDetails);
155+
try {
156+
return rpcProxy.getDataNodeCertificate(NULL_RPC_CONTROLLER,
157+
builder.build());
158+
} catch (ServiceException e) {
159+
throw ProtobufHelper.getRemoteException(e);
160+
}
161+
}
162+
138163
/**
139164
* Get CA certificate.
140165
*

hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/protocolPB/SCMSecurityProtocolServerSideTranslatorPB.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ public SCMGetCertResponseProto getDataNodeCertificate(
6161
SCMGetCertResponseProto
6262
.newBuilder()
6363
.setResponseCode(ResponseCode.success)
64-
.setX509Certificate(certificate);
64+
.setX509Certificate(certificate)
65+
.setX509CACertificate(impl.getCACertificate());
66+
6567
return builder.build();
6668
} catch (IOException e) {
6769
throw new ServiceException(e);
@@ -87,7 +89,8 @@ public SCMGetCertResponseProto getOMCertificate(
8789
SCMGetCertResponseProto
8890
.newBuilder()
8991
.setResponseCode(ResponseCode.success)
90-
.setX509Certificate(certificate);
92+
.setX509Certificate(certificate)
93+
.setX509CACertificate(impl.getCACertificate());
9194
return builder.build();
9295
} catch (IOException e) {
9396
throw new ServiceException(e);

hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/CertificateClient.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ boolean verifySignature(byte[] data, byte[] signature,
129129
*/
130130
X509Certificate queryCertificate(String query);
131131

132+
/**
133+
* Stores the Certificate for this client. Don't use this api to add
134+
* trusted certificates of others.
135+
*
136+
* @param pemEncodedCert - pem encoded X509 Certificate
137+
* @param force - override any existing file
138+
* @throws CertificateException - on Error.
139+
*
140+
*/
141+
void storeCertificate(String pemEncodedCert, boolean force)
142+
throws CertificateException;
143+
132144
/**
133145
* Stores the Certificate for this client. Don't use this api to add
134146
* trusted certificates of others.

hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ private X509Certificate getCertificateFromScm(String certId)
252252
(OzoneConfiguration) securityConfig.getConfiguration());
253253
String pemEncodedCert =
254254
scmSecurityProtocolClient.getCertificate(certId);
255-
this.storeCertificate(pemEncodedCert, true, false);
255+
this.storeCertificate(pemEncodedCert, true);
256256
return CertificateCodec.getX509Certificate(pemEncodedCert);
257257
} catch (Exception e) {
258258
getLogger().error("Error while getting Certificate with " +
@@ -449,6 +449,21 @@ public X509Certificate queryCertificate(String query) {
449449
throw new UnsupportedOperationException("Operation not supported");
450450
}
451451

452+
/**
453+
* Stores the Certificate for this client. Don't use this api to add trusted
454+
* certificates of others.
455+
*
456+
* @param pemEncodedCert - pem encoded X509 Certificate
457+
* @param force - override any existing file
458+
* @throws CertificateException - on Error.
459+
*
460+
*/
461+
@Override
462+
public void storeCertificate(String pemEncodedCert, boolean force)
463+
throws CertificateException {
464+
this.storeCertificate(pemEncodedCert, force, false);
465+
}
466+
452467
/**
453468
* Stores the Certificate for this client. Don't use this api to add trusted
454469
* certificates of others.

hadoop-hdds/common/src/main/proto/SCMSecurityProtocol.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ message SCMGetCertResponseProto {
7676
}
7777
required ResponseCode responseCode = 1;
7878
required string x509Certificate = 2; // Base64 encoded X509 certificate.
79+
optional string x509CACertificate = 3; // Base64 encoded CA X509 certificate.
7980
}
8081

8182

hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDefaultCertificateClient.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ public void testCertificateOps() throws Exception {
174174
X509Certificate cert = omCertClient.getCertificate();
175175
assertNull(cert);
176176
omCertClient.storeCertificate(getPEMEncodedString(x509Certificate),
177-
true, false);
177+
true);
178178

179179
cert = omCertClient.getCertificate(
180180
x509Certificate.getSerialNumber().toString());
@@ -327,9 +327,9 @@ public void testStoreCertificate() throws Exception {
327327
X509Certificate cert2 = generateX509Cert(keyPair);
328328
X509Certificate cert3 = generateX509Cert(keyPair);
329329

330-
dnCertClient.storeCertificate(getPEMEncodedString(cert1), true, false);
331-
dnCertClient.storeCertificate(getPEMEncodedString(cert2), true, false);
332-
dnCertClient.storeCertificate(getPEMEncodedString(cert3), true, false);
330+
dnCertClient.storeCertificate(getPEMEncodedString(cert1), true);
331+
dnCertClient.storeCertificate(getPEMEncodedString(cert2), true);
332+
dnCertClient.storeCertificate(getPEMEncodedString(cert3), true);
333333

334334
assertNotNull(dnCertClient.getCertificate(cert1.getSerialNumber()
335335
.toString()));

hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/HddsDatanodeService.java

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
import org.apache.hadoop.hdds.cli.HddsVersionProvider;
2727
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
2828
import org.apache.hadoop.hdds.protocol.DatanodeDetails;
29-
import org.apache.hadoop.hdds.protocol.SCMSecurityProtocol;
29+
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetCertResponseProto;
30+
import org.apache.hadoop.hdds.protocolPB.SCMSecurityProtocolClientSideTranslatorPB;
3031
import org.apache.hadoop.hdds.scm.HddsServerUtil;
3132
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
3233
import org.apache.hadoop.hdds.security.x509.SecurityConfig;
@@ -271,19 +272,25 @@ private void getSCMSignedCert(OzoneConfiguration config) {
271272
try {
272273
PKCS10CertificationRequest csr = getCSR(config);
273274
// TODO: For SCM CA we should fetch certificate from multiple SCMs.
274-
SCMSecurityProtocol secureScmClient =
275+
SCMSecurityProtocolClientSideTranslatorPB secureScmClient =
275276
HddsUtils.getScmSecurityClient(config,
276277
HddsUtils.getScmAddressForSecurityProtocol(config));
277-
278-
String pemEncodedCert = secureScmClient.getDataNodeCertificate(
279-
datanodeDetails.getProtoBufMessage(), getEncodedString(csr));
280-
dnCertClient.storeCertificate(pemEncodedCert, true, false);
281-
datanodeDetails.setCertSerialId(getX509Certificate(pemEncodedCert).
282-
getSerialNumber().toString());
283-
persistDatanodeDetails(datanodeDetails);
284-
// Get SCM CA certificate and store it in filesystem.
285-
String pemEncodedRootCert = secureScmClient.getCACertificate();
286-
dnCertClient.storeCertificate(pemEncodedRootCert, true, true);
278+
SCMGetCertResponseProto response = secureScmClient.
279+
getDataNodeCertificateChain(datanodeDetails.getProtoBufMessage(),
280+
getEncodedString(csr));
281+
// Persist certificates.
282+
if(response.hasX509CACertificate()) {
283+
String pemEncodedCert = response.getX509Certificate();
284+
dnCertClient.storeCertificate(pemEncodedCert, true);
285+
dnCertClient.storeCertificate(response.getX509CACertificate(), true,
286+
true);
287+
datanodeDetails.setCertSerialId(getX509Certificate(pemEncodedCert).
288+
getSerialNumber().toString());
289+
persistDatanodeDetails(datanodeDetails);
290+
} else {
291+
throw new RuntimeException("Unable to retrieve datanode certificate " +
292+
"chain");
293+
}
287294
} catch (IOException | CertificateException e) {
288295
LOG.error("Error while storing SCM signed certificate.", e);
289296
throw new RuntimeException(e);

hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -785,8 +785,8 @@ public void testSecureOmInitSuccess() throws Exception {
785785
String pemEncodedCACert =
786786
scm.getSecurityProtocolServer().getCACertificate();
787787
X509Certificate caCert = CertificateCodec.getX509Cert(pemEncodedCACert);
788-
X509Certificate caCertStored = om.getCertificateClient().getCertificate(caCert.getSerialNumber().
789-
toString());
788+
X509Certificate caCertStored = om.getCertificateClient()
789+
.getCertificate(caCert.getSerialNumber().toString());
790790
assertEquals(caCert, caCertStored);
791791
} finally {
792792
if (scm != null) {

hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/CertificateClientTestImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ public X509Certificate queryCertificate(String query) {
136136
return null;
137137
}
138138

139+
@Override
140+
public void storeCertificate(String cert, boolean force)
141+
throws CertificateException {
142+
}
143+
139144
@Override
140145
public void storeCertificate(String cert, boolean force, boolean caCert)
141146
throws CertificateException {

0 commit comments

Comments
 (0)