HDDS-4952. Implement listCAs and getRootCA API. (#2042)
diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/exception/SCMSecurityException.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/exception/SCMSecurityException.java
index 534cf7a..d75acc4 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/exception/SCMSecurityException.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/exception/SCMSecurityException.java
@@ -107,6 +107,7 @@
INTERNAL_ERROR,
DEFAULT,
MISSING_BLOCK_TOKEN,
- BLOCK_TOKEN_VERIFICATION_FAILED
+ BLOCK_TOKEN_VERIFICATION_FAILED,
+ GET_ROOT_CA_CERT_FAILED
}
}
diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/protocol/SCMSecurityProtocol.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/protocol/SCMSecurityProtocol.java
index 4a59570..778a6d4 100644
--- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/protocol/SCMSecurityProtocol.java
+++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/protocol/SCMSecurityProtocol.java
@@ -105,4 +105,31 @@
List<String> listCertificate(HddsProtos.NodeType type, long startSerialId,
int count, boolean isRevoked) throws IOException;
+ /**
+ * Get Root CA certificate.
+ * @return
+ * @throws IOException
+ */
+ String getRootCACertificate() throws IOException;
+
+ /**
+ * Returns all the individual SCM CA's along with Root CA.
+ *
+ * For example 3 nodes SCM HA cluster, the output will be
+ *
+ * SCM1 CA
+ * SCM2 CA
+ * SCM3 CA
+ * Root CA
+ * @return list of CA's
+ *
+ * For example on non-HA cluster the output will be SCM CA and Root CA.
+ *
+ * SCM CA
+ * Root CA
+ *
+ * @throws IOException
+ */
+ List<String> listCACertificate() throws IOException;
+
}
diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/protocolPB/SCMSecurityProtocolClientSideTranslatorPB.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/protocolPB/SCMSecurityProtocolClientSideTranslatorPB.java
index f54d228..0ab5d7e 100644
--- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/protocolPB/SCMSecurityProtocolClientSideTranslatorPB.java
+++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/protocolPB/SCMSecurityProtocolClientSideTranslatorPB.java
@@ -33,6 +33,7 @@
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetCertResponseProto;
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetCertificateRequestProto;
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetDataNodeCertRequestProto;
+import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMListCACertificateRequestProto;
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMListCertificateRequestProto;
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMSecurityRequest;
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMSecurityRequest.Builder;
@@ -296,6 +297,24 @@
.getListCertificateResponseProto().getCertificatesList();
}
+ @Override
+ public String getRootCACertificate() throws IOException {
+ SCMGetCACertificateRequestProto protoIns = SCMGetCACertificateRequestProto
+ .getDefaultInstance();
+ return submitRequest(Type.GetCACertificate,
+ builder -> builder.setGetCACertificateRequest(protoIns))
+ .getGetCertResponseProto().getX509RootCACertificate();
+ }
+
+ @Override
+ public List<String> listCACertificate() throws IOException {
+ SCMListCACertificateRequestProto proto =
+ SCMListCACertificateRequestProto.getDefaultInstance();
+ return submitRequest(Type.ListCACertificate,
+ builder -> builder.setListCACertificateRequestProto(proto))
+ .getListCertificateResponseProto().getCertificatesList();
+ }
+
/**
* Return the proxy object underlying this protocol translator.
*
diff --git a/hadoop-hdds/interface-server/src/main/proto/ScmServerSecurityProtocol.proto b/hadoop-hdds/interface-server/src/main/proto/ScmServerSecurityProtocol.proto
index 48c6cf9..31aac90 100644
--- a/hadoop-hdds/interface-server/src/main/proto/ScmServerSecurityProtocol.proto
+++ b/hadoop-hdds/interface-server/src/main/proto/ScmServerSecurityProtocol.proto
@@ -50,6 +50,7 @@
optional SCMGetCACertificateRequestProto getCACertificateRequest = 6;
optional SCMListCertificateRequestProto listCertificateRequest = 7;
optional SCMGetSCMCertRequestProto getSCMCertificateRequest = 8;
+ optional SCMListCACertificateRequestProto listCACertificateRequestProto = 9;
}
@@ -79,6 +80,8 @@
GetCACertificate = 4;
ListCertificate = 5;
GetSCMCertificate = 6;
+ GetRootCACertificate = 7;
+ ListCACertificate = 8;
}
enum Status {
@@ -96,6 +99,7 @@
DEFAULT = 12;
MISSING_BLOCK_TOKEN = 13;
BLOCK_TOKEN_VERIFICATION_FAILED = 14;
+ GET_ROOT_CA_CERTIFICATE_FAILED = 15;
}
/**
* This message is send by data node to prove its identity and get an SCM
@@ -155,6 +159,8 @@
required ResponseCode responseCode = 1;
required string x509Certificate = 2; // Base64 encoded X509 certificate.
optional string x509CACertificate = 3; // Base64 encoded CA X509 certificate.
+ // Base64 encoded Root CA X509 certificate.
+ optional string x509RootCACertificate = 4;
}
/**
@@ -169,6 +175,11 @@
repeated string certificates = 2;
}
+message SCMGetRootCACertificateRequestProto {
+}
+
+message SCMListCACertificateRequestProto {
+}
service SCMSecurityProtocolService {
rpc submitRequest (SCMSecurityRequest) returns (SCMSecurityResponse);
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/SCMSecurityProtocolServerSideTranslatorPB.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/SCMSecurityProtocolServerSideTranslatorPB.java
index 06da6e4..cc0c776 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/SCMSecurityProtocolServerSideTranslatorPB.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/SCMSecurityProtocolServerSideTranslatorPB.java
@@ -111,6 +111,12 @@
case GetSCMCertificate:
return scmSecurityResponse.setGetCertResponseProto(getSCMCertificate(
request.getGetSCMCertificateRequest())).build();
+ case GetRootCACertificate:
+ return scmSecurityResponse.setGetCertResponseProto(
+ getRootCACertificate()).build();
+ case ListCACertificate:
+ return scmSecurityResponse.setListCertificateResponseProto(
+ listCACertificate()).build();
default:
throw new IllegalArgumentException(
"Unknown request type: " + request.getCmdType());
@@ -257,4 +263,32 @@
}
+
+
+ public SCMGetCertResponseProto getRootCACertificate() throws IOException {
+ String rootCACertificate = impl.getRootCACertificate();
+ SCMGetCertResponseProto.Builder builder =
+ SCMGetCertResponseProto
+ .newBuilder()
+ .setResponseCode(ResponseCode.success)
+ .setX509RootCACertificate(rootCACertificate);
+ return builder.build();
+ }
+
+ public SCMListCertificateResponseProto listCACertificate()
+ throws IOException {
+
+ List<String> certs = impl.listCACertificate();
+
+ SCMListCertificateResponseProto.Builder builder =
+ SCMListCertificateResponseProto
+ .newBuilder()
+ .setResponseCode(SCMListCertificateResponseProto
+ .ResponseCode.success)
+ .addAllCertificates(certs);
+ return builder.build();
+
+ }
+
+
}
\ No newline at end of file
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMSecurityProtocolServer.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMSecurityProtocolServer.java
index 5df3aa7..5a1ecf3 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMSecurityProtocolServer.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMSecurityProtocolServer.java
@@ -57,6 +57,7 @@
import static org.apache.hadoop.hdds.security.exception.SCMSecurityException.ErrorCode.CERTIFICATE_NOT_FOUND;
import static org.apache.hadoop.hdds.security.exception.SCMSecurityException.ErrorCode.GET_CA_CERT_FAILED;
import static org.apache.hadoop.hdds.security.exception.SCMSecurityException.ErrorCode.GET_CERTIFICATE_FAILED;
+import static org.apache.hadoop.hdds.security.exception.SCMSecurityException.ErrorCode.GET_ROOT_CA_CERT_FAILED;
import static org.apache.hadoop.hdds.security.x509.certificate.authority.CertificateApprover.ApprovalType.KERBEROS_TRUSTED;
/**
@@ -283,6 +284,28 @@
return results;
}
+ @Override
+ public List<String> listCACertificate() throws IOException {
+ List<String> caCerts =
+ listCertificate(NodeType.SCM, 0, 10, false);
+ caCerts.add(getRootCACertificate());
+ return caCerts;
+ }
+
+ @Override
+ public String getRootCACertificate() throws IOException {
+ LOGGER.debug("Getting Root CA certificate.");
+ //TODO: This code will be modified after HDDS-4897 is merged and
+ // integrated. For now getting RootCA cert from certificateServer.
+ try {
+ return CertificateCodec.getPEMEncodedString(
+ certificateServer.getCACertificate());
+ } catch (CertificateException e) {
+ throw new SCMSecurityException("getRootCertificate operation failed. ",
+ e, GET_ROOT_CA_CERT_FAILED);
+ }
+ }
+
public RPC.Server getRpcServer() {
return rpcServer;
}