rootCAs) {
+ if (rootCaCertificates.containsAll(rootCAs)) {
+ return CompletableFuture.completedFuture(null);
+ }
+ CertificateRenewerService renewerService = new CertificateRenewerService(
+ this, true);
+ return CompletableFuture.runAsync(renewerService, executorService);
+ }
+
public synchronized void startCertificateMonitor() {
Preconditions.checkNotNull(getCertificate(),
"Component certificate should not be empty");
@@ -1238,7 +1311,7 @@ public synchronized void startCertificateMonitor() {
.setDaemon(true).build());
}
this.executorService.scheduleAtFixedRate(
- new CertificateLifetimeMonitor(this),
+ new CertificateRenewerService(this, false),
timeBeforeGracePeriod, interval, TimeUnit.MILLISECONDS);
getLogger().info("CertificateLifetimeMonitor for {} is started with " +
"first delay {} ms and interval {} ms.", component,
@@ -1246,13 +1319,16 @@ public synchronized void startCertificateMonitor() {
}
/**
- * Task to monitor certificate lifetime and renew the certificate if needed.
+ * Task to monitor certificate lifetime and renew the certificate if needed.
*/
- public class CertificateLifetimeMonitor implements Runnable {
+ public class CertificateRenewerService implements Runnable {
private CertificateClient certClient;
+ private boolean forceRenewal;
- public CertificateLifetimeMonitor(CertificateClient client) {
+ public CertificateRenewerService(CertificateClient client,
+ boolean forceRenewal) {
this.certClient = client;
+ this.forceRenewal = forceRenewal;
}
@Override
@@ -1267,40 +1343,41 @@ public void run() {
synchronized (DefaultCertificateClient.class) {
X509Certificate currentCert = getCertificate();
Duration timeLeft = timeBeforeExpiryGracePeriod(currentCert);
- if (timeLeft.isZero()) {
- String newCertId;
- try {
- getLogger().info("Current certificate has entered the expiry" +
- " grace period {}. Starting renew key and certs.",
- timeLeft, securityConfig.getRenewalGracePeriod());
- newCertId = renewAndStoreKeyAndCertificate(false);
- } catch (CertificateException e) {
- if (e.errorCode() ==
- CertificateException.ErrorCode.ROLLBACK_ERROR) {
- if (shutdownCallback != null) {
- getLogger().error("Failed to rollback key and cert after an " +
- " unsuccessful renew try.", e);
- shutdownCallback.run();
- }
+ if (!forceRenewal && !timeLeft.isZero()) {
+ return;
+ }
+ String newCertId;
+ try {
+ getLogger().info("Current certificate has entered the expiry" +
+ " grace period {}. Starting renew key and certs.",
+ timeLeft, securityConfig.getRenewalGracePeriod());
+ newCertId = renewAndStoreKeyAndCertificate(forceRenewal);
+ } catch (CertificateException e) {
+ if (e.errorCode() ==
+ CertificateException.ErrorCode.ROLLBACK_ERROR) {
+ if (shutdownCallback != null) {
+ getLogger().error("Failed to rollback key and cert after an " +
+ " unsuccessful renew try.", e);
+ shutdownCallback.run();
}
- getLogger().error("Failed to renew and store key and cert." +
- " Keep using existing certificates.", e);
- return;
- }
-
- // Persist new cert serial id in component VERSION file
- if (certIdSaveCallback != null) {
- certIdSaveCallback.accept(newCertId);
}
+ getLogger().error("Failed to renew and store key and cert." +
+ " Keep using existing certificates.", e);
+ return;
+ }
- // reset and reload all certs
- reloadKeyAndCertificate(newCertId);
- // cleanup backup directory
- cleanBackupDir();
- // notify notification receivers
- notificationReceivers.forEach(r -> r.notifyCertificateRenewed(
- certClient, currentCert.getSerialNumber().toString(), newCertId));
+ // Persist new cert serial id in component VERSION file
+ if (certIdSaveCallback != null) {
+ certIdSaveCallback.accept(newCertId);
}
+
+ // reset and reload all certs
+ reloadKeyAndCertificate(newCertId);
+ // cleanup backup directory
+ cleanBackupDir();
+ // notify notification receivers
+ notificationReceivers.forEach(r -> r.notifyCertificateRenewed(
+ certClient, currentCert.getSerialNumber().toString(), newCertId));
}
}
}
diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/RootCaRotationPoller.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/RootCaRotationPoller.java
new file mode 100644
index 000000000000..a49cfb0da7d2
--- /dev/null
+++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/RootCaRotationPoller.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hdds.security.x509.certificate.client;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.hdds.protocolPB.SCMSecurityProtocolClientSideTranslatorPB;
+import org.apache.hadoop.hdds.security.SecurityConfig;
+import org.apache.hadoop.ozone.OzoneSecurityUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * Poller mechanism for Root Ca Rotation for clients.
+ */
+public class RootCaRotationPoller implements Runnable, Closeable {
+
+ private static final Logger LOG =
+ LoggerFactory.getLogger(RootCaRotationPoller.class);
+ private final List, CompletableFuture>>
+ rootCARotationProcessors;
+ private final ScheduledExecutorService poller;
+ private final Duration pollingRate;
+ private Set knownRootCerts;
+ private final SCMSecurityProtocolClientSideTranslatorPB scmSecureClient;
+
+ public RootCaRotationPoller(SecurityConfig securityConfig,
+ Set initiallyKnownRootCaCerts,
+ SCMSecurityProtocolClientSideTranslatorPB scmSecureClient) {
+ this.scmSecureClient = scmSecureClient;
+ this.knownRootCerts = initiallyKnownRootCaCerts;
+ poller = Executors.newScheduledThreadPool(1,
+ new ThreadFactoryBuilder().setNameFormat(
+ "RootCaRotationPoller")
+ .setDaemon(true).build());
+ pollingRate = securityConfig.getRootCaClientPollingFrequency();
+ rootCARotationProcessors = new ArrayList<>();
+ }
+
+ private void pollRootCas() {
+ try {
+ List pemEncodedRootCaList =
+ scmSecureClient.getAllRootCaCertificates();
+ List rootCAsFromSCM =
+ OzoneSecurityUtil.convertToX509(pemEncodedRootCaList);
+ List scmCertsWithoutKnownCerts
+ = new ArrayList<>(rootCAsFromSCM);
+ scmCertsWithoutKnownCerts.removeAll(knownRootCerts);
+ if (scmCertsWithoutKnownCerts.isEmpty()) {
+ return;
+ }
+ LOG.info("Some root CAs are not known to the client out of the root " +
+ "CAs known to the SCMs. Root CA Cert ids known to the client: " +
+ getPrintableCertIds(knownRootCerts) + ". Root CA Cert ids from " +
+ "SCM not known by the client: " +
+ getPrintableCertIds(scmCertsWithoutKnownCerts));
+
+ CompletableFuture allRootCAProcessorFutures =
+ CompletableFuture.allOf(rootCARotationProcessors.stream()
+ .map(c -> c.apply(rootCAsFromSCM))
+ .toArray(CompletableFuture[]::new));
+
+ allRootCAProcessorFutures.whenComplete((unused, throwable) -> {
+ if (throwable == null) {
+ knownRootCerts = new HashSet<>(rootCAsFromSCM);
+ }
+ });
+ } catch (IOException e) {
+ LOG.error("Error while trying to rotate root ca certificate", e);
+ }
+ }
+
+ public void addRootCARotationProcessor(
+ Function, CompletableFuture> processor) {
+ rootCARotationProcessors.add(processor);
+ }
+
+ @Override
+ public void run() {
+ poller.scheduleAtFixedRate(this::pollRootCas, 0,
+ pollingRate.getSeconds(), TimeUnit.SECONDS);
+ }
+
+ @Override
+ public void close() {
+ executorServiceShutdownGraceful(poller);
+ }
+
+ private void executorServiceShutdownGraceful(ExecutorService executor) {
+ executor.shutdown();
+ try {
+ if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
+ executor.shutdownNow();
+ }
+ if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
+ LOG.error("Unable to shutdown root ca certificate rotation poller.");
+ }
+ } catch (InterruptedException e) {
+ LOG.error("Error attempting to shutdown.", e);
+ executor.shutdownNow();
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ private String getPrintableCertIds(Collection certs) {
+ return StringUtils.join(certs.stream()
+ .map(X509Certificate::getSerialNumber)
+ .map(BigInteger::toString)
+ .collect(Collectors.toList()), ", ");
+ }
+}
diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/SCMCertificateClient.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/SCMCertificateClient.java
index 51eb2959a6e9..26676a82b005 100644
--- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/SCMCertificateClient.java
+++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/SCMCertificateClient.java
@@ -18,6 +18,7 @@
package org.apache.hadoop.hdds.security.x509.certificate.client;
+import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetCertResponseProto;
import org.apache.hadoop.hdds.protocolPB.SCMSecurityProtocolClientSideTranslatorPB;
import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateSignRequest;
@@ -27,7 +28,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyPair;
@@ -150,9 +150,20 @@ public Logger getLogger() {
}
@Override
- public String signAndStoreCertificate(PKCS10CertificationRequest request,
- Path certPath) throws CertificateException {
+ protected SCMGetCertResponseProto getCertificateSignResponse(
+ PKCS10CertificationRequest request) {
+ throw new UnsupportedOperationException("getCertSignResponse of " +
+ " SCMCertificateClient is not supported currently");
+ }
+
+ @Override
+ public String signAndStoreCertificate(PKCS10CertificationRequest request) {
throw new UnsupportedOperationException("signAndStoreCertificate of " +
" SCMCertificateClient is not supported currently");
}
+
+ @Override
+ protected void startRootCaRotationPoller() {
+ //SCM root CA rotation is handled separately from polling
+ }
}
diff --git a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDefaultCertificateClient.java b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDefaultCertificateClient.java
index 2fe0bf84ea24..395ae46ae67b 100644
--- a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDefaultCertificateClient.java
+++ b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDefaultCertificateClient.java
@@ -20,7 +20,7 @@
import org.apache.hadoop.hdds.HddsConfigKeys;
import org.apache.hadoop.hdds.protocol.MockDatanodeDetails;
-import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos;
+import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetCertResponseProto;
import org.apache.hadoop.hdds.protocolPB.SCMSecurityProtocolClientSideTranslatorPB;
import org.apache.hadoop.hdds.security.x509.certificate.authority.CAType;
import org.apache.hadoop.hdds.security.x509.certificate.client.CertificateClient.InitResponse;
@@ -483,9 +483,15 @@ public X509Certificate getCertificate() {
return mockCert;
}
+ @Override
+ protected SCMGetCertResponseProto getCertificateSignResponse(
+ PKCS10CertificationRequest request) {
+ return null;
+ }
+
@Override
public String signAndStoreCertificate(
- PKCS10CertificationRequest request, Path certificatePath) {
+ PKCS10CertificationRequest request) {
return null;
}
}) {
@@ -529,10 +535,10 @@ public void testRenewAndStoreKeyAndCertificate() throws Exception {
X509Certificate newCert = generateX509Cert(null);
String pemCert = CertificateCodec.getPEMEncodedString(newCert);
- SCMSecurityProtocolProtos.SCMGetCertResponseProto responseProto =
- SCMSecurityProtocolProtos.SCMGetCertResponseProto
- .newBuilder().setResponseCode(SCMSecurityProtocolProtos
- .SCMGetCertResponseProto.ResponseCode.success)
+ SCMGetCertResponseProto responseProto =
+ SCMGetCertResponseProto
+ .newBuilder()
+ .setResponseCode(SCMGetCertResponseProto.ResponseCode.success)
.setX509Certificate(pemCert)
.setX509CACertificate(pemCert)
.build();
@@ -619,8 +625,14 @@ public void testCloseCertificateClient(@TempDir File metaDir)
) {
@Override
- protected String signAndStoreCertificate(
- PKCS10CertificationRequest request, Path certificatePath) {
+ protected SCMGetCertResponseProto getCertificateSignResponse(
+ PKCS10CertificationRequest request) {
+ return null;
+ }
+
+ @Override
+ public String signAndStoreCertificate(
+ PKCS10CertificationRequest request) {
return "";
}
};
diff --git a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/TestRootCaRotationPoller.java b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/TestRootCaRotationPoller.java
new file mode 100644
index 000000000000..e102310b3f00
--- /dev/null
+++ b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/TestRootCaRotationPoller.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.hadoop.hdds.security.x509.certificate.utils;
+
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.protocolPB.SCMSecurityProtocolClientSideTranslatorPB;
+import org.apache.hadoop.hdds.security.SecurityConfig;
+import org.apache.hadoop.hdds.security.x509.certificate.client.RootCaRotationPoller;
+import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
+import org.apache.ozone.test.GenericTestUtils;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.security.KeyPair;
+import java.security.cert.X509Certificate;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_X509_ROOTCA_CLIENT_POLLING_FREQUENCY;
+
+/**
+ * Test for Root Ca Rotation polling mechanism on client side.
+ */
+public class TestRootCaRotationPoller {
+
+ private SecurityConfig secConf;
+
+ @Mock
+ private SCMSecurityProtocolClientSideTranslatorPB scmSecurityClient;
+
+ @BeforeEach
+ public void setup() {
+ MockitoAnnotations.openMocks(this);
+ OzoneConfiguration conf = new OzoneConfiguration();
+ conf.set(HDDS_X509_ROOTCA_CLIENT_POLLING_FREQUENCY, "PT1s");
+ secConf = new SecurityConfig(conf);
+ }
+
+ @Test
+ public void testPollerDoesNotInvokeRootCaProcessor() throws Exception {
+ X509Certificate knownCert = generateX509Cert(
+ LocalDateTime.now(), Duration.ofSeconds(50));
+ HashSet knownCerts = new HashSet<>();
+ knownCerts.add(knownCert);
+ List certsFromScm = new ArrayList<>();
+ certsFromScm.add(CertificateCodec.getPEMEncodedString(knownCert));
+ RootCaRotationPoller poller = new RootCaRotationPoller(secConf,
+ knownCerts, scmSecurityClient);
+
+ Mockito.when(scmSecurityClient.getAllRootCaCertificates())
+ .thenReturn(certsFromScm);
+ AtomicBoolean atomicBoolean = new AtomicBoolean();
+ atomicBoolean.set(false);
+ poller.addRootCARotationProcessor(
+ certificates -> CompletableFuture.supplyAsync(() -> {
+ atomicBoolean.set(true);
+ Assertions.assertEquals(certificates.size(), 2);
+ return null;
+ }));
+ poller.run();
+ Assertions.assertThrows(TimeoutException.class, () ->
+ GenericTestUtils.waitFor(atomicBoolean::get, 50, 5000));
+ }
+
+ @Test
+ public void testPollerInvokesRootCaProcessors() throws Exception {
+ X509Certificate knownCert = generateX509Cert(
+ LocalDateTime.now(), Duration.ofSeconds(50));
+ X509Certificate newRootCa = generateX509Cert(
+ LocalDateTime.now(), Duration.ofSeconds(50));
+ HashSet knownCerts = new HashSet<>();
+ knownCerts.add(knownCert);
+ List certsFromScm = new ArrayList<>();
+ certsFromScm.add(CertificateCodec.getPEMEncodedString(knownCert));
+ certsFromScm.add(CertificateCodec.getPEMEncodedString(newRootCa));
+ RootCaRotationPoller poller = new RootCaRotationPoller(secConf,
+ knownCerts, scmSecurityClient);
+ poller.run();
+ Mockito.when(scmSecurityClient.getAllRootCaCertificates())
+ .thenReturn(certsFromScm);
+ AtomicBoolean atomicBoolean = new AtomicBoolean();
+ atomicBoolean.set(false);
+ poller.addRootCARotationProcessor(
+ certificates -> CompletableFuture.supplyAsync(() -> {
+ atomicBoolean.set(true);
+ Assertions.assertEquals(certificates.size(), 2);
+ return null;
+ }));
+ GenericTestUtils.waitFor(atomicBoolean::get, 50, 5000);
+ }
+
+ private X509Certificate generateX509Cert(
+ LocalDateTime startDate, Duration certLifetime) throws Exception {
+ KeyPair keyPair = KeyStoreTestUtil.generateKeyPair("RSA");
+ LocalDateTime start = startDate == null ? LocalDateTime.now() : startDate;
+ LocalDateTime end = start.plus(certLifetime);
+ return new JcaX509CertificateConverter().getCertificate(
+ SelfSignedCertificate.newBuilder().setBeginDate(start)
+ .setEndDate(end).setClusterID("cluster").setKey(keyPair)
+ .setSubject("localhost").setConfiguration(secConf).setScmID("test")
+ .build());
+ }
+}
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OMCertificateClient.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OMCertificateClient.java
index 88312cacf403..997b7939cca5 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OMCertificateClient.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OMCertificateClient.java
@@ -24,9 +24,7 @@
import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetCertResponseProto;
import org.apache.hadoop.hdds.protocolPB.SCMSecurityProtocolClientSideTranslatorPB;
import org.apache.hadoop.hdds.security.SecurityConfig;
-import org.apache.hadoop.hdds.security.x509.certificate.authority.CAType;
import org.apache.hadoop.hdds.security.x509.certificate.client.CommonCertificateClient;
-import org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
import org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateSignRequest;
import org.apache.hadoop.hdds.security.x509.exception.CertificateException;
import org.apache.hadoop.ozone.om.OMStorage;
@@ -36,7 +34,6 @@
import org.slf4j.LoggerFactory;
import java.io.IOException;
-import java.nio.file.Path;
import java.security.KeyPair;
import java.util.function.Consumer;
@@ -121,44 +118,14 @@ public CertificateSignRequest.Builder getCSRBuilder()
}
@Override
- public String signAndStoreCertificate(PKCS10CertificationRequest request,
- Path certificatePath) throws CertificateException {
- try {
- SCMGetCertResponseProto response = getScmSecureClient()
- .getOMCertChain(omInfo, getEncodedString(request));
-
- String pemEncodedCert = response.getX509Certificate();
- CertificateCodec certCodec = new CertificateCodec(
- getSecurityConfig(), certificatePath);
-
- // Store SCM CA certificate.
- if (response.hasX509CACertificate()) {
- String pemEncodedRootCert = response.getX509CACertificate();
- storeCertificate(pemEncodedRootCert,
- CAType.SUBORDINATE, certCodec, false);
- storeCertificate(pemEncodedCert, CAType.NONE, certCodec,
- false);
-
- // Store Root CA certificate if available.
- if (response.hasX509RootCACertificate()) {
- storeCertificate(response.getX509RootCACertificate(),
- CAType.ROOT, certCodec, false);
- }
- return CertificateCodec.getX509Certificate(pemEncodedCert)
- .getSerialNumber().toString();
- } else {
- throw new CertificateException("Unable to retrieve OM certificate " +
- "chain.");
- }
- } catch (IOException | java.security.cert.CertificateException e) {
- LOG.error("Error while signing and storing SCM signed certificate.", e);
- throw new CertificateException(
- "Error while signing and storing SCM signed certificate.", e);
- }
+ public Logger getLogger() {
+ return LOG;
}
@Override
- public Logger getLogger() {
- return LOG;
+ protected SCMGetCertResponseProto getCertificateSignResponse(
+ PKCS10CertificationRequest request) throws IOException {
+ return getScmSecureClient().getOMCertChain(
+ omInfo, getEncodedString(request));
}
}
diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/security/ReconCertificateClient.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/security/ReconCertificateClient.java
index 2a78ddae23b3..6dd9afc8944a 100644
--- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/security/ReconCertificateClient.java
+++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/security/ReconCertificateClient.java
@@ -18,12 +18,10 @@
package org.apache.hadoop.ozone.recon.security;
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
-import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos;
+import org.apache.hadoop.hdds.protocol.proto.SCMSecurityProtocolProtos.SCMGetCertResponseProto;
import org.apache.hadoop.hdds.protocolPB.SCMSecurityProtocolClientSideTranslatorPB;
import org.apache.hadoop.hdds.security.SecurityConfig;
-import org.apache.hadoop.hdds.security.x509.certificate.authority.CAType;
import org.apache.hadoop.hdds.security.x509.certificate.client.CommonCertificateClient;
-import org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
import org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateSignRequest;
import org.apache.hadoop.hdds.security.x509.exception.CertificateException;
import org.apache.hadoop.ozone.recon.scm.ReconStorageConfig;
@@ -34,11 +32,9 @@
import java.io.IOException;
import java.net.InetAddress;
-import java.nio.file.Path;
import java.security.KeyPair;
import java.util.function.Consumer;
-import static org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec.getX509Certificate;
import static org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateSignRequest.getEncodedString;
import static org.apache.hadoop.hdds.security.x509.exception.CertificateException.ErrorCode.CSR_ERROR;
@@ -89,51 +85,23 @@ public CertificateSignRequest.Builder getCSRBuilder()
}
@Override
- public String signAndStoreCertificate(PKCS10CertificationRequest csr,
- Path certificatePath) throws CertificateException {
- try {
- SCMSecurityProtocolProtos.SCMGetCertResponseProto response;
- HddsProtos.NodeDetailsProto.Builder reconDetailsProtoBuilder =
- HddsProtos.NodeDetailsProto.newBuilder()
- .setHostName(InetAddress.getLocalHost().getHostName())
- .setClusterId(clusterID)
- .setUuid(reconID)
- .setNodeType(HddsProtos.NodeType.RECON);
- // TODO: For SCM CA we should fetch certificate from multiple SCMs.
- response = getScmSecureClient().getCertificateChain(
- reconDetailsProtoBuilder.build(), getEncodedString(csr));
-
- // Persist certificates.
- if (response.hasX509CACertificate()) {
- String pemEncodedCert = response.getX509Certificate();
- CertificateCodec certCodec = new CertificateCodec(
- getSecurityConfig(), certificatePath);
- storeCertificate(pemEncodedCert, CAType.NONE,
- certCodec,
- false);
- storeCertificate(response.getX509CACertificate(),
- CAType.SUBORDINATE,
- certCodec, false);
-
- // Store Root CA certificate.
- if (response.hasX509RootCACertificate()) {
- storeCertificate(response.getX509RootCACertificate(),
- CAType.ROOT, certCodec, false);
- }
- return getX509Certificate(pemEncodedCert).getSerialNumber().toString();
- } else {
- throw new CertificateException("Unable to retrieve recon certificate " +
- "chain");
- }
- } catch (IOException | java.security.cert.CertificateException e) {
- LOG.error("Error while signing and storing SCM signed certificate.", e);
- throw new CertificateException(
- "Error while signing and storing SCM signed certificate.", e);
- }
+ public Logger getLogger() {
+ return LOG;
}
@Override
- public Logger getLogger() {
- return LOG;
+ protected SCMGetCertResponseProto getCertificateSignResponse(
+ PKCS10CertificationRequest request) throws IOException {
+ SCMGetCertResponseProto response;
+ HddsProtos.NodeDetailsProto.Builder reconDetailsProtoBuilder =
+ HddsProtos.NodeDetailsProto.newBuilder()
+ .setHostName(InetAddress.getLocalHost().getHostName())
+ .setClusterId(clusterID)
+ .setUuid(reconID)
+ .setNodeType(HddsProtos.NodeType.RECON);
+ // TODO: For SCM CA we should fetch certificate from multiple SCMs.
+ response = getScmSecureClient().getCertificateChain(
+ reconDetailsProtoBuilder.build(), getEncodedString(request));
+ return response;
}
}