You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by vi...@apache.org on 2021/05/14 19:31:07 UTC

[ozone] branch master updated: HDDS-5155. Add revokeCertificate to SCMSecurityProtocolServer. (#2191)

This is an automated email from the ASF dual-hosted git repository.

vivekratnavel pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 9cab560  HDDS-5155. Add revokeCertificate to SCMSecurityProtocolServer. (#2191)
9cab560 is described below

commit 9cab560eccddc387cbfb619f272b2bbc95b08085
Author: Xiaoyu Yao <xy...@apache.org>
AuthorDate: Fri May 14 12:30:39 2021 -0700

    HDDS-5155. Add revokeCertificate to SCMSecurityProtocolServer. (#2191)
---
 .../hadoop/hdds/scm/exceptions/SCMException.java   |  3 +-
 .../hadoop/hdds/protocol/SCMSecurityProtocol.java  | 11 ++++++++
 .../SCMSecurityProtocolClientSideTranslatorPB.java | 14 +++++++++
 .../certificate/authority/CertificateServer.java   |  4 +--
 .../certificate/authority/DefaultCAServer.java     |  3 +-
 .../certificate/authority/TestDefaultCAServer.java |  6 ++--
 .../src/main/proto/ScmServerProtocol.proto         |  1 +
 .../src/main/proto/ScmServerSecurityProtocol.proto | 28 ++++++++++++++++++
 .../SCMSecurityProtocolServerSideTranslatorPB.java | 16 +++++++++++
 .../hdds/scm/server/SCMSecurityProtocolServer.java | 33 +++++++++++++++++++++-
 10 files changed, 108 insertions(+), 11 deletions(-)

diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/exceptions/SCMException.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/exceptions/SCMException.java
index 82e3034..8c1be36 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/exceptions/SCMException.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/exceptions/SCMException.java
@@ -125,6 +125,7 @@ public class SCMException extends IOException {
     INTERNAL_ERROR,
     FAILED_TO_INIT_PIPELINE_CHOOSE_POLICY,
     FAILED_TO_INIT_LEADER_CHOOSE_POLICY,
-    SCM_NOT_LEADER
+    SCM_NOT_LEADER,
+    FAILED_TO_REVOKE_CERTIFICATES,
   }
 }
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 d11dd8b..606b459 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
@@ -147,4 +147,15 @@ public interface SCMSecurityProtocol {
    */
   long getLatestCrlId() throws IOException;
 
+
+  /**
+   * Revoke a list of certificates at specified time.
+   * @param certIds - cert ids
+   * @param reason - reason code: refer @org.bouncycastle.asn1.x509.CRLReason.
+   * @param revocationTime - revocation time.
+   * @return
+   * @throws IOException
+   */
+  long revokeCertificates(List<String> certIds, int reason, long revocationTime)
+      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 e034f7b..d89ecc6 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
@@ -41,6 +41,8 @@ import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetDat
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMListCACertificateRequestProto;
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetLatestCrlIdRequestProto;
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMListCertificateRequestProto;
+import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMRevokeCertificatesRequestProto;
+import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMRevokeCertificatesRequestProto.Reason;
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMSecurityRequest;
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMSecurityRequest.Builder;
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMSecurityResponse;
@@ -356,6 +358,18 @@ public class SCMSecurityProtocolClientSideTranslatorPB implements
         .getGetLatestCrlIdResponseProto().getCrlId();
   }
 
+  @Override
+  public long revokeCertificates(List<String> certIds, int reason,
+      long revocationTime) throws IOException {
+    SCMRevokeCertificatesRequestProto req = SCMRevokeCertificatesRequestProto
+        .newBuilder().addAllCertIds(certIds)
+        .setReason(Reason.valueOf(reason))
+        .setRevokeTime(revocationTime).build();
+    return submitRequest(Type.RevokeCertificates,
+        builder->builder.setRevokeCertificatesRequest(req))
+        .getRevokeCertificatesResponseProto().getCrlId();
+  }
+
   /**
    * Return the proxy object underlying this protocol translator.
    *
diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateServer.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateServer.java
index 3912d71..0af22da 100644
--- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateServer.java
+++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateServer.java
@@ -111,15 +111,13 @@ public interface CertificateServer {
    *
    * @param serialIDs       - List of serial IDs of Certificates to be revoked.
    * @param reason          - Reason for revocation.
-   * @param securityConfig  - Security Configuration.
    * @param revocationTime  - Revocation time for the certificates.
    * @return Future that gives a list of certificates that were revoked.
    */
   Future<Optional<Long>> revokeCertificates(
       List<BigInteger> serialIDs,
       CRLReason reason,
-      Date revocationTime,
-      SecurityConfig securityConfig);
+      Date revocationTime);
 
   /**
    * List certificates.
diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultCAServer.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultCAServer.java
index ae2ca01..fc2a77b 100644
--- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultCAServer.java
+++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultCAServer.java
@@ -301,8 +301,7 @@ public class DefaultCAServer implements CertificateServer {
   public Future<Optional<Long>> revokeCertificates(
       List<BigInteger> certificates,
       CRLReason reason,
-      Date revocationTime,
-      SecurityConfig securityConfig) {
+      Date revocationTime) {
     CompletableFuture<Optional<Long>> revoked = new CompletableFuture<>();
     if (CollectionUtils.isEmpty(certificates)) {
       revoked.completeExceptionally(new SCMSecurityException(
diff --git a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultCAServer.java b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultCAServer.java
index 7e68aeb..7f2a3b4 100644
--- a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultCAServer.java
+++ b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultCAServer.java
@@ -276,8 +276,7 @@ public class TestDefaultCAServer {
     List<BigInteger> serialIDs = new ArrayList<>();
     serialIDs.add(certificate.getSerialNumber());
     Future<Optional<Long>> revoked = testCA.revokeCertificates(serialIDs,
-        CRLReason.lookup(CRLReason.keyCompromise), now,
-        new SecurityConfig(conf));
+        CRLReason.lookup(CRLReason.keyCompromise), now);
 
     // Revoking a valid certificate complete successfully without errors.
     assertTrue(revoked.isDone());
@@ -288,8 +287,7 @@ public class TestDefaultCAServer {
         () -> {
           Future<Optional<Long>> result =
               testCA.revokeCertificates(Collections.emptyList(),
-              CRLReason.lookup(CRLReason.keyCompromise), now,
-                  new SecurityConfig(conf));
+              CRLReason.lookup(CRLReason.keyCompromise), now);
           result.isDone();
           result.get();
         });
diff --git a/hadoop-hdds/interface-server/src/main/proto/ScmServerProtocol.proto b/hadoop-hdds/interface-server/src/main/proto/ScmServerProtocol.proto
index 1b73d6a..23b667d 100644
--- a/hadoop-hdds/interface-server/src/main/proto/ScmServerProtocol.proto
+++ b/hadoop-hdds/interface-server/src/main/proto/ScmServerProtocol.proto
@@ -123,6 +123,7 @@ enum Status {
   FAILED_TO_INIT_PIPELINE_CHOOSE_POLICY = 30;
   FAILED_TO_INIT_LEADER_CHOOSE_POLICY = 31;
   SCM_NOT_LEADER = 32;
+  FAILED_TO_REVOKE_CERTIFICATES = 33;
 }
 
 /**
diff --git a/hadoop-hdds/interface-server/src/main/proto/ScmServerSecurityProtocol.proto b/hadoop-hdds/interface-server/src/main/proto/ScmServerSecurityProtocol.proto
index 557d7f2..d91a986 100644
--- a/hadoop-hdds/interface-server/src/main/proto/ScmServerSecurityProtocol.proto
+++ b/hadoop-hdds/interface-server/src/main/proto/ScmServerSecurityProtocol.proto
@@ -53,6 +53,7 @@ message SCMSecurityRequest {
     optional SCMListCACertificateRequestProto listCACertificateRequestProto = 9;
     optional SCMGetCrlsRequestProto getCrlsRequest = 10;
     optional SCMGetLatestCrlIdRequestProto getLatestCrlIdRequest = 11;
+    optional SCMRevokeCertificatesRequestProto revokeCertificatesRequest = 12;
 
 }
 
@@ -77,6 +78,8 @@ message SCMSecurityResponse {
 
     optional SCMGetLatestCrlIdResponseProto getLatestCrlIdResponseProto = 9;
 
+    optional SCMRevokeCertificatesResponseProto revokeCertificatesResponseProto = 10;
+
 }
 
 enum Type {
@@ -90,6 +93,7 @@ enum Type {
     ListCACertificate = 8;
     GetCrls = 9;
     GetLatestCrlId = 10;
+    RevokeCertificates = 11;
 }
 
 enum Status {
@@ -109,6 +113,7 @@ enum Status {
     BLOCK_TOKEN_VERIFICATION_FAILED = 14;
     GET_ROOT_CA_CERTIFICATE_FAILED = 15;
     NOT_A_PRIMARY_SCM = 16;
+    REVOKE_CERTIFICATE_FAILED = 17;
 }
 /**
 * This message is send by data node to prove its identity and get an SCM
@@ -211,6 +216,29 @@ message SCMGetLatestCrlIdResponseProto {
     optional int64 crlId = 1;
 }
 
+message SCMRevokeCertificatesRequestProto {
+    // Match with org.bouncycastle.asn1.x509.CRLReason
+    enum Reason {
+        unspecified = 0;
+        keyCompromise = 1;
+        cACompromise = 2;
+        affiliationChanged = 3;
+        superseded = 4;
+        cessationOfOperation = 5;
+        certificateHold = 6;
+        removeFromCRL = 8;
+        privilegeWithdrawn = 9;
+        aACompromise = 10;
+    };
+    repeated string certIds = 1;
+    optional Reason reason = 2 [default = unspecified];
+    optional uint64 revokeTime = 3;
+}
+
+message SCMRevokeCertificatesResponseProto {
+    optional int64 crlId = 1;
+}
+
 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 088f74d..4b97444 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
@@ -33,6 +33,8 @@ import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetOMC
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetSCMCertRequestProto;
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMListCertificateRequestProto;
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMListCertificateResponseProto;
+import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMRevokeCertificatesRequestProto;
+import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMRevokeCertificatesResponseProto;
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMSecurityRequest;
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMSecurityResponse;
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.Status;
@@ -141,6 +143,12 @@ public class SCMSecurityProtocolServerSideTranslatorPB
             .setGetLatestCrlIdResponseProto(getLatestCrlId(
                 request.getGetLatestCrlIdRequest()))
             .build();
+      case RevokeCertificates:
+        return SCMSecurityResponse.newBuilder()
+            .setCmdType(request.getCmdType())
+            .setRevokeCertificatesResponseProto(revokeCertificates(
+                request.getRevokeCertificatesRequest()))
+            .build();
       default:
         throw new IllegalArgumentException(
             "Unknown request type: " + request.getCmdType());
@@ -322,6 +330,14 @@ public class SCMSecurityProtocolServerSideTranslatorPB
     return builder.build();
   }
 
+  public SCMRevokeCertificatesResponseProto revokeCertificates(
+      SCMRevokeCertificatesRequestProto request) throws IOException {
+    SCMRevokeCertificatesResponseProto.Builder builder =
+        SCMRevokeCertificatesResponseProto.newBuilder().setCrlId(
+            impl.revokeCertificates(request.getCertIdsList(),
+                request.getReason().getNumber(), request.getRevokeTime()));
+    return builder.build();
+  }
 
   public SCMGetCertResponseProto getRootCACertificate() throws IOException {
     if (scm.getScmStorageConfig().checkPrimarySCMIdInitialized()) {
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 4e04cb1..77bf5a7 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
@@ -16,17 +16,22 @@
  */
 package org.apache.hadoop.hdds.scm.server;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.protobuf.BlockingService;
 
 import java.io.IOException;
+import java.math.BigInteger;
 import java.net.InetSocketAddress;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
+import java.util.stream.Collectors;
 
 import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
 import org.apache.hadoop.hdds.annotation.InterfaceAudience;
@@ -37,6 +42,7 @@ import org.apache.hadoop.hdds.protocol.proto.HddsProtos.OzoneManagerDetailsProto
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ScmNodeDetailsProto;
 import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos;
 import org.apache.hadoop.hdds.protocolPB.SCMSecurityProtocolPB;
+import org.apache.hadoop.hdds.scm.exceptions.SCMException;
 import org.apache.hadoop.hdds.scm.protocol.SCMSecurityProtocolServerSideTranslatorPB;
 import org.apache.hadoop.hdds.security.exception.SCMSecurityException;
 import org.apache.hadoop.hdds.security.x509.crl.CRLInfo;
@@ -46,11 +52,14 @@ import org.apache.hadoop.hdds.scm.ScmConfigKeys;
 import org.apache.hadoop.hdds.protocol.SCMSecurityProtocol;
 import org.apache.hadoop.hdds.security.x509.certificate.authority.CertificateServer;
 import org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
+import org.apache.hadoop.hdds.utils.ProtocolMessageMetrics;
 import org.apache.hadoop.ipc.ProtobufRpcEngine;
 import org.apache.hadoop.ipc.RPC;
-import org.apache.hadoop.hdds.utils.ProtocolMessageMetrics;
+import org.apache.hadoop.ipc.Server;
 import org.apache.hadoop.security.KerberosInfo;
 
+import org.apache.hadoop.security.UserGroupInformation;
+import org.bouncycastle.asn1.x509.CRLReason;
 import org.bouncycastle.cert.X509CertificateHolder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -333,6 +342,28 @@ public class SCMSecurityProtocolServer implements SCMSecurityProtocol {
     return scmCertificateServer.getLatestCrlId();
   }
 
+  @Override
+  public long revokeCertificates(List<String> certIds, int reason,
+      long revocationTime) throws IOException {
+    storageContainerManager.checkAdminAccess(getRpcRemoteUser());
+
+    Future<Optional<Long>> revoked = scmCertificateServer.revokeCertificates(
+        certIds.stream().map(id -> new BigInteger(id))
+            .collect(Collectors.toList()), CRLReason.lookup(reason),
+        new Date(revocationTime));
+    try {
+      return revoked.get().get().longValue();
+    } catch (InterruptedException | ExecutionException e) {
+      throw new SCMException("Fail to revoke certs",
+          SCMException.ResultCodes.FAILED_TO_REVOKE_CERTIFICATES);
+    }
+  }
+
+  @VisibleForTesting
+  public UserGroupInformation getRpcRemoteUser() {
+    return Server.getRemoteUser();
+  }
+
   public RPC.Server getRpcServer() {
     return rpcServer;
   }

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@ozone.apache.org
For additional commands, e-mail: commits-help@ozone.apache.org