HDDS-5071. Fix duration of sub-ca certs. (#2127)
diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsConfigKeys.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsConfigKeys.java
index d5cdcc7..5552fdc 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsConfigKeys.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsConfigKeys.java
@@ -140,7 +140,8 @@
"hdds.block.token.expiry.time";
public static final String HDDS_BLOCK_TOKEN_EXPIRY_TIME_DEFAULT = "1d";
/**
- * Maximum duration of certificates issued by SCM including Self-Signed Roots.
+ * Maximum duration of certificates issued by SCM including Self-Signed
+ * Roots and sub-ca certificates issued by root CA.
* The formats accepted are based on the ISO-8601 duration format PnDTnHnMn.nS
* Default value is 5 years and written as P1865D.
*/
diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/SecurityConfig.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/SecurityConfig.java
index 394a0c3..61c58da 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/SecurityConfig.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/SecurityConfig.java
@@ -90,7 +90,7 @@
private final String keyDir;
private final String privateKeyFileName;
private final String publicKeyFileName;
- private final Duration certDuration;
+ private final Duration maxCertDuration;
private final String x509SignatureAlgo;
private final boolean blockTokenEnabled;
private final String certificateDir;
@@ -130,7 +130,7 @@
String durationString = this.configuration.get(HDDS_X509_MAX_DURATION,
HDDS_X509_MAX_DURATION_DEFAULT);
- this.certDuration = Duration.parse(durationString);
+ this.maxCertDuration = Duration.parse(durationString);
this.x509SignatureAlgo = this.configuration.get(HDDS_X509_SIGNATURE_ALGO,
HDDS_X509_SIGNATURE_ALGO_DEFAULT);
this.certificateDir = this.configuration.get(HDDS_X509_DIR_NAME,
@@ -159,6 +159,13 @@
HDDS_X509_DEFAULT_DURATION_DEFAULT);
defaultCertDuration = Duration.parse(certDurationString);
+ if (maxCertDuration.compareTo(defaultCertDuration) < 0) {
+ LOG.error("Certificate duration {} should not be greater than Maximum " +
+ "Certificate duration {}", maxCertDuration, defaultCertDuration);
+ throw new IllegalArgumentException("Certificate duration should not be " +
+ "greater than maximum Certificate duration");
+ }
+
this.crlName = this.configuration.get(HDDS_X509_CRL_NAME,
HDDS_X509_CRL_NAME_DEFAULT);
@@ -320,7 +327,7 @@
* @return Duration.
*/
public Duration getMaxCertificateDuration() {
- return this.certDuration;
+ return this.maxCertDuration;
}
public boolean isBlockTokenEnabled() {
diff --git a/hadoop-hdds/common/src/main/resources/ozone-default.xml b/hadoop-hdds/common/src/main/resources/ozone-default.xml
index 52e6241..ee18441 100644
--- a/hadoop-hdds/common/src/main/resources/ozone-default.xml
+++ b/hadoop-hdds/common/src/main/resources/ozone-default.xml
@@ -1858,8 +1858,9 @@
<value>P1865D</value>
<tag>OZONE, HDDS, SECURITY</tag>
<description>Max time for which certificate issued by SCM CA are valid.
- . The formats accepted are based on the ISO-8601 duration format
- PnDTnHnMn.nS</description>
+ This duration is used for self-signed root cert and scm sub-ca certs
+ issued by root ca. The formats accepted are based on the ISO-8601
+ duration format PnDTnHnMn.nS</description>
</property>
<property>
<name>hdds.x509.signature.algorithm</name>
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 7622dda..7a83509 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
@@ -214,8 +214,15 @@
CertificateApprover.ApprovalType approverType, NodeType role) {
LocalDate beginDate = LocalDate.now().atStartOfDay().toLocalDate();
LocalDateTime temp = LocalDateTime.of(beginDate, LocalTime.MIDNIGHT);
- LocalDate endDate =
- temp.plus(config.getDefaultCertDuration()).toLocalDate();
+
+ LocalDate endDate;
+ // When issuing certificates for sub-ca use the max certificate duration
+ // similar to self signed root certificate.
+ if (role == NodeType.SCM) {
+ endDate = temp.plus(config.getMaxCertificateDuration()).toLocalDate();
+ } else {
+ endDate = temp.plus(config.getDefaultCertDuration()).toLocalDate();
+ }
CompletableFuture<X509CertificateHolder> xcertHolder =
approver.inspectCSR(csr);
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 f5a2d8c..7e68aeb 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
@@ -20,6 +20,7 @@
package org.apache.hadoop.hdds.security.x509.certificate.authority;
import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.hadoop.hdds.HddsConfigKeys;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.security.exception.SCMSecurityException;
import org.apache.hadoop.hdds.security.x509.SecurityConfig;
@@ -49,6 +50,8 @@
import java.security.NoSuchProviderException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.time.LocalDate;
+import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
@@ -345,6 +348,8 @@
@Test
public void testIntermediaryCA() throws Exception {
+ conf.set(HddsConfigKeys.HDDS_X509_MAX_DURATION, "P3650D");
+
String clusterId = RandomStringUtils.randomAlphanumeric(4);
String scmId = RandomStringUtils.randomAlphanumeric(4);
@@ -378,7 +383,12 @@
Assert.assertTrue(holder.isDone());
X509CertificateHolder certificateHolder = holder.get();
+
+
Assert.assertNotNull(certificateHolder);
+ Assert.assertEquals(10, certificateHolder.getNotAfter().toInstant()
+ .atZone(ZoneId.systemDefault())
+ .toLocalDate().compareTo(LocalDate.now()));
X509CertificateHolder rootCertHolder = rootCA.getCACertificate();