This is an automated email from the ASF dual-hosted git repository.
pifta 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 19d623c3ee HDDS-10888. Restrict X509CertificateHolder usage to the
bare minimum required. (#6802)
19d623c3ee is described below
commit 19d623c3eed6c3faeacbe3ace542d326aee9227d
Author: Istvan Fajth <[email protected]>
AuthorDate: Thu Jun 20 19:54:45 2024 +0200
HDDS-10888. Restrict X509CertificateHolder usage to the bare minimum
required. (#6802)
---
.../hadoop/hdds/security/SecurityConfig.java | 36 ++---
.../x509/certificate/utils/CertificateCodec.java | 107 +++----------
.../certificate/utils/SelfSignedCertificate.java | 24 +--
.../org/apache/hadoop/ozone/OzoneSecurityUtil.java | 5 +-
.../hdds/security/x509/CertificateTestUtils.java | 1 +
.../hadoop/ozone/TestHddsSecureDatanodeInit.java | 59 ++++---
.../x509/certificate/authority/BaseApprover.java | 18 +--
.../certificate/authority/CertificateApprover.java | 24 +--
.../certificate/authority/CertificateServer.java | 6 +-
.../certificate/authority/DefaultApprover.java | 26 ++-
.../certificate/authority/DefaultCAServer.java | 107 +++++--------
.../client/DefaultCertificateClient.java | 2 +-
.../certificate/client/SCMCertificateClient.java | 19 +--
.../apache/hadoop/hdds/utils/HddsServerUtil.java | 4 +
.../x509/certificate/authority/MockApprover.java | 58 -------
.../certificate/authority/TestDefaultCAServer.java | 80 ++++------
.../certificate/authority/TestDefaultProfile.java | 33 ++--
.../client/CertificateClientTestImpl.java | 64 +++-----
.../client/TestDefaultCertificateClient.java | 12 +-
.../client/TestDnCertificateClientInit.java | 7 +-
.../client/TestRootCaRotationPoller.java | 15 +-
.../certificate/utils/TestCertificateCodec.java | 174 ++++++---------------
.../certificate/utils/TestRootCertificate.java | 69 ++++----
.../hdds/scm/security/RootCARotationManager.java | 35 ++---
.../hdds/scm/ha/io/TestX509CertificateCodec.java | 8 +
.../scm/metadata/TestX509CertificateCodec.java | 8 +
.../scm/security/TestRootCARotationManager.java | 7 +-
.../hadoop/ozone/TestSecureOzoneCluster.java | 155 +++++++++---------
.../hadoop/ozone/om/TestSecureOzoneManager.java | 4 +-
.../security/TestOmCertificateClientInit.java | 4 +-
.../TestOzoneDelegationTokenSecretManager.java | 8 +-
31 files changed, 429 insertions(+), 750 deletions(-)
diff --git
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/SecurityConfig.java
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/SecurityConfig.java
index a3c3b7061f..b0bd68d031 100644
---
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/SecurityConfig.java
+++
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/SecurityConfig.java
@@ -148,8 +148,8 @@ public class SecurityConfig {
this.size = configuration.getInt(HDDS_KEY_LEN, HDDS_DEFAULT_KEY_LEN);
this.keyAlgo = configuration.get(HDDS_KEY_ALGORITHM,
HDDS_DEFAULT_KEY_ALGORITHM);
- this.providerString = configuration.get(HDDS_SECURITY_PROVIDER,
- HDDS_DEFAULT_SECURITY_PROVIDER);
+ initSecurityProvider(configuration);
+ this.providerString = configuration.get(HDDS_SECURITY_PROVIDER,
HDDS_DEFAULT_SECURITY_PROVIDER);
// Please Note: To make it easy for our customers we will attempt to read
// HDDS metadata dir and if that is not set, we will use Ozone directory.
@@ -263,15 +263,23 @@ public class SecurityConfig {
this.grpcSSLProvider = SslProvider.valueOf(
configuration.get(HDDS_GRPC_TLS_PROVIDER,
HDDS_GRPC_TLS_PROVIDER_DEFAULT));
+ }
+ public static synchronized void initSecurityProvider(ConfigurationSource
configuration) {
// First Startup -- if the provider is null, check for the provider.
if (SecurityConfig.provider == null) {
- synchronized (SecurityConfig.class) {
- provider = Security.getProvider(this.providerString);
+ String providerString = configuration.get(HDDS_SECURITY_PROVIDER,
HDDS_DEFAULT_SECURITY_PROVIDER);
+ provider = Security.getProvider(providerString);
+ if (SecurityConfig.provider == null) {
+ // Provider not found, let us try to Dynamically initialize the
+ // provider.
+ if ("BC".equals(providerString)) {
+ Security.addProvider(new BouncyCastleProvider());
+ provider = Security.getProvider(providerString);
+ }
if (SecurityConfig.provider == null) {
- // Provider not found, let us try to Dynamically initialize the
- // provider.
- provider = initSecurityProvider(this.providerString);
+ LOG.error("Security Provider:{} is unknown", provider);
+ throw new SecurityException("Unknown security provider:" + provider);
}
}
}
@@ -588,20 +596,6 @@ public class SecurityConfig {
return grpcTlsUseTestCert;
}
- /**
- * Adds a security provider dynamically if it is not loaded already.
- *
- * @param providerName - name of the provider.
- */
- private Provider initSecurityProvider(String providerName) {
- if ("BC".equals(providerName)) {
- Security.addProvider(new BouncyCastleProvider());
- return Security.getProvider(providerName);
- }
- LOG.error("Security Provider:{} is unknown", provider);
- throw new SecurityException("Unknown security provider:" + provider);
- }
-
public boolean isTokenEnabled() {
return blockTokenEnabled || containerTokenEnabled;
}
diff --git
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/utils/CertificateCodec.java
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/utils/CertificateCodec.java
index c6d15ab221..360dfbbf83 100644
---
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/utils/CertificateCodec.java
+++
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/utils/CertificateCodec.java
@@ -22,9 +22,6 @@ package
org.apache.hadoop.hdds.security.x509.certificate.utils;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.security.exception.SCMSecurityException;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,10 +42,11 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
+import java.security.NoSuchProviderException;
import java.security.cert.CertPath;
import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
@@ -72,8 +70,6 @@ public class CertificateCodec {
private static final Logger LOG =
LoggerFactory.getLogger(CertificateCodec.class);
- private static final JcaX509CertificateConverter CERTIFICATE_CONVERTER
- = new JcaX509CertificateConverter();
private final SecurityConfig securityConfig;
private final Path location;
private final Set<PosixFilePermission> permissionSet =
@@ -95,18 +91,6 @@ public class CertificateCodec {
this.location = certPath;
}
- /**
- * Returns a X509 Certificate from the Certificate Holder.
- *
- * @param holder - Holder
- * @return X509Certificate.
- * @throws CertificateException - on Error.
- */
- public static X509Certificate getX509Certificate(X509CertificateHolder
holder)
- throws CertificateException {
- return CERTIFICATE_CONVERTER.getCertificate(holder);
- }
-
/**
* Get a valid pem encoded string for the certification path.
*/
@@ -120,22 +104,6 @@ public class CertificateCodec {
return StringUtils.join(pemEncodedList, "\n");
}
- /**
- * Returns the Certificate as a PEM encoded String.
- *
- * @param x509CertHolder - X.509 Certificate Holder.
- * @return PEM Encoded Certificate String.
- * @throws SCMSecurityException - On failure to create a PEM String.
- */
- public static String getPEMEncodedString(X509CertificateHolder
x509CertHolder)
- throws SCMSecurityException {
- try {
- return getPEMEncodedString(getX509Certificate(x509CertHolder));
- } catch (CertificateException exp) {
- throw new SCMSecurityException(exp);
- }
- }
-
/**
* Encode the given certificate in PEM
* and then write it out to the given {@link OutputStream}.
@@ -207,9 +175,8 @@ public class CertificateCodec {
private static <E extends Exception> X509Certificate readX509Certificate(
InputStream input, Function<CertificateException, E> convertor)
throws E {
- final CertificateFactory fact = getCertFactory();
try {
- return (X509Certificate) fact.engineGenerateCertificate(input);
+ return (X509Certificate) getCertFactory().generateCertificate(input);
} catch (CertificateException e) {
throw convertor.apply(e);
}
@@ -228,8 +195,12 @@ public class CertificateCodec {
return (X509Certificate) certificatePath.getCertificates().get(0);
}
- public static CertificateFactory getCertFactory() {
- return new CertificateFactory();
+ public static CertificateFactory getCertFactory() throws
CertificateException {
+ try {
+ return CertificateFactory.getInstance("X.509", "BC");
+ } catch (NoSuchProviderException e) {
+ throw new RuntimeException("BouncyCastle JCE provider not loaded.", e);
+ }
}
/**
@@ -241,30 +212,13 @@ public class CertificateCodec {
return location;
}
- /**
- * Write the Certificate pointed to the location by the configs.
- *
- * @param xCertificate - Certificate to write.
- * @throws SCMSecurityException - on Error.
- * @throws IOException - on Error.
- */
- public void writeCertificate(X509CertificateHolder xCertificate)
- throws SCMSecurityException, IOException {
+ public void writeCertificate(X509Certificate xCertificate) throws
IOException {
String pem = getPEMEncodedString(xCertificate);
writeCertificate(location.toAbsolutePath(),
this.securityConfig.getCertificateFileName(), pem);
}
- /**
- * Write the Certificate to the specific file.
- *
- * @param xCertificate - Certificate to write.
- * @param fileName - file name to write to.
- * @throws SCMSecurityException - On Error.
- * @throws IOException - On Error.
- */
- public void writeCertificate(X509CertificateHolder xCertificate,
- String fileName) throws IOException {
+ public void writeCertificate(X509Certificate xCertificate, String fileName)
throws IOException {
String pem = getPEMEncodedString(xCertificate);
writeCertificate(location.toAbsolutePath(), fileName, pem);
}
@@ -340,62 +294,41 @@ public class CertificateCodec {
return getCertPath(this.securityConfig.getCertificateFileName());
}
- /**
- * Returns the Certificate holder from X509Certificate class.
- *
- * @param x509cert - Certificate class.
- * @return X509CertificateHolder
- * @throws CertificateEncodingException - on Error.
- * @throws IOException - on Error.
- */
- public static X509CertificateHolder getCertificateHolder(
- X509Certificate x509cert)
- throws CertificateEncodingException, IOException {
- return new X509CertificateHolder(x509cert.getEncoded());
- }
-
/**
* Helper method that takes in a certificate path and a certificate and
* generates a new certificate path starting with the new certificate
* followed by all certificates in the specified path.
*/
- public CertPath prependCertToCertPath(X509CertificateHolder certHolder,
- CertPath path) throws CertificateException {
+ public CertPath prependCertToCertPath(X509Certificate certificate, CertPath
path) throws CertificateException {
List<? extends Certificate> certificates = path.getCertificates();
ArrayList<X509Certificate> updatedList = new ArrayList<>();
- updatedList.add(getX509Certificate(certHolder));
+ updatedList.add(certificate);
for (Certificate cert : certificates) {
updatedList.add((X509Certificate) cert);
}
- CertificateFactory factory = getCertFactory();
- return factory.engineGenerateCertPath(updatedList);
+ return getCertFactory().generateCertPath(updatedList);
}
/**
* Helper method that gets one certificate from the specified location.
* The remaining certificates are ignored.
*/
- public X509CertificateHolder getTargetCertHolder(Path path,
- String fileName) throws CertificateException, IOException {
+ public X509Certificate getTargetCert(Path path, String fileName) throws
CertificateException, IOException {
CertPath certPath = getCertPath(path, fileName);
- X509Certificate certificate = firstCertificateFrom(certPath);
- return getCertificateHolder(certificate);
+ return firstCertificateFrom(certPath);
}
/**
* Helper method that gets one certificate from the default location.
* The remaining certificates are ignored.
*/
- public X509CertificateHolder getTargetCertHolder()
- throws CertificateException, IOException {
- return getTargetCertHolder(
+ public X509Certificate getTargetCert() throws CertificateException,
IOException {
+ return getTargetCert(
location, securityConfig.getCertificateFileName());
}
- private static CertPath generateCertPathFromInputStream(
- InputStream inputStream) throws CertificateException {
- CertificateFactory fact = getCertFactory();
- return fact.engineGenerateCertPath(inputStream, "PEM");
+ private static CertPath generateCertPathFromInputStream(InputStream
inputStream) throws CertificateException {
+ return getCertFactory().generateCertPath(inputStream, "PEM");
}
private void checkBasePathDirectory(Path basePath) throws IOException {
diff --git
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/utils/SelfSignedCertificate.java
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/utils/SelfSignedCertificate.java
index 87834cdb45..1e2e65c283 100644
---
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/utils/SelfSignedCertificate.java
+++
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/utils/SelfSignedCertificate.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.math.BigInteger;
import java.net.InetAddress;
import java.security.KeyPair;
+import java.security.cert.X509Certificate;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
@@ -54,14 +55,15 @@ import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.CertIOException;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static
org.apache.hadoop.hdds.security.x509.exception.CertificateException.ErrorCode.CERTIFICATE_ERROR;
import static
org.apache.hadoop.hdds.security.x509.exception.CertificateException.ErrorCode.CSR_ERROR;
/**
@@ -107,8 +109,7 @@ public final class SelfSignedCertificate {
return new Builder();
}
- private X509CertificateHolder generateCertificate(BigInteger caCertSerialId)
- throws OperatorCreationException, IOException {
+ private X509Certificate generateCertificate(BigInteger caCertSerialId)
throws OperatorCreationException, IOException {
byte[] encoded = key.getPublic().getEncoded();
SubjectPublicKeyInfo publicKeyInfo =
SubjectPublicKeyInfo.getInstance(encoded);
@@ -153,12 +154,15 @@ public final class SelfSignedCertificate {
new GeneralName[altNames.size()])).getEncoded()));
}
}
- X509CertificateHolder certHolder = builder.build(contentSigner);
- LOG.info("Certificate {} is issued by {} to {}, valid from {} to {}",
- certHolder.getSerialNumber(), certHolder.getIssuer(),
- certHolder.getSubject(), certHolder.getNotBefore(),
- certHolder.getNotAfter());
- return certHolder;
+ try {
+ //TODO: as part of HDDS-10743 ensure that converter is instantiated only
once
+ X509Certificate cert = new
JcaX509CertificateConverter().getCertificate(builder.build(contentSigner));
+ LOG.info("Certificate {} is issued by {} to {}, valid from {} to {}",
+ cert.getSerialNumber(), cert.getIssuerDN(), cert.getSubjectDN(),
cert.getNotBefore(), cert.getNotAfter());
+ return cert;
+ } catch (java.security.cert.CertificateException e) {
+ throw new CertificateException("Could not create self-signed
X509Certificate.", e, CERTIFICATE_ERROR);
+ }
}
/**
@@ -294,7 +298,7 @@ public final class SelfSignedCertificate {
false, 0, new DERSequence(otherName));
}
- public X509CertificateHolder build()
+ public X509Certificate build()
throws SCMSecurityException, IOException {
Preconditions.checkNotNull(key, "Key cannot be null");
Preconditions.checkArgument(StringUtils.isNotBlank(subject),
diff --git
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneSecurityUtil.java
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneSecurityUtil.java
index 407a967682..c47a79481c 100644
---
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneSecurityUtil.java
+++
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneSecurityUtil.java
@@ -42,6 +42,7 @@ import static
org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_HTTP_SECURITY_ENABLE
import static
org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_SECURITY_ENABLED_DEFAULT;
import static
org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_SECURITY_ENABLED_KEY;
+import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -63,8 +64,8 @@ public final class OzoneSecurityUtil {
}
public static boolean isSecurityEnabled(ConfigurationSource conf) {
- return conf.getBoolean(OZONE_SECURITY_ENABLED_KEY,
- OZONE_SECURITY_ENABLED_DEFAULT);
+ SecurityConfig.initSecurityProvider(conf);
+ return conf.getBoolean(OZONE_SECURITY_ENABLED_KEY,
OZONE_SECURITY_ENABLED_DEFAULT);
}
public static boolean isHttpSecurityEnabled(ConfigurationSource conf) {
diff --git
a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/CertificateTestUtils.java
b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/CertificateTestUtils.java
index c6e0750a87..9265e881b5 100644
---
a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/CertificateTestUtils.java
+++
b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/CertificateTestUtils.java
@@ -152,6 +152,7 @@ public final class CertificateTestUtils {
.addExtension(Extension.authorityKeyIdentifier, false, authorityKeyId)
.addExtension(Extension.basicConstraints, true, constraints);
+ //TODO: as part of HDDS-10743 ensure that converter is instantiated only
once
return new JcaX509CertificateConverter()
.setProvider(new BouncyCastleProvider())
.getCertificate(certificateBuilder.build(contentSigner));
diff --git
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/TestHddsSecureDatanodeInit.java
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/TestHddsSecureDatanodeInit.java
index 10d2bc91a7..253551115d 100644
---
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/TestHddsSecureDatanodeInit.java
+++
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/TestHddsSecureDatanodeInit.java
@@ -23,6 +23,7 @@ import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateExpiredException;
+import java.security.cert.X509Certificate;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
@@ -64,7 +65,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.apache.ozone.test.tag.Flaky;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.BeforeAll;
@@ -86,7 +86,7 @@ public class TestHddsSecureDatanodeInit {
private static SecurityConfig securityConfig;
private static KeyCodec keyCodec;
private static CertificateCodec certCodec;
- private static X509CertificateHolder certHolder;
+ private static X509Certificate cert;
private static final String DN_COMPONENT =
DNCertificateClient.COMPONENT_NAME;
private static final int CERT_LIFETIME = 15; // seconds
@@ -135,7 +135,7 @@ public class TestHddsSecureDatanodeInit {
privateKey = service.getCertificateClient().getPrivateKey();
publicKey = service.getCertificateClient().getPublicKey();
- certHolder = generateX509CertHolder(new KeyPair(publicKey, privateKey),
+ cert = generateX509Cert(new KeyPair(publicKey, privateKey),
null, Duration.ofSeconds(CERT_LIFETIME));
datanodeDetails = MockDatanodeDetails.randomDatanodeDetails();
@@ -156,7 +156,7 @@ public class TestHddsSecureDatanodeInit {
securityConfig.getCertificateFileName()).toFile());
dnLogs.clearOutput();
client = new DNCertificateClient(securityConfig, scmClient,
datanodeDetails,
- certHolder.getSerialNumber().toString(), id -> { }, null);
+ cert.getSerialNumber().toString(), id -> { }, null);
}
@AfterEach
@@ -181,7 +181,7 @@ public class TestHddsSecureDatanodeInit {
@Test
public void testSecureDnStartupCase1() throws Exception {
// Case 1: When only certificate is present.
- certCodec.writeCertificate(certHolder);
+ certCodec.writeCertificate(cert);
RuntimeException rteException = assertThrows(
RuntimeException.class,
() -> service.initializeCertificateClient(client));
@@ -214,7 +214,7 @@ public class TestHddsSecureDatanodeInit {
public void testSecureDnStartupCase3() throws Exception {
// Case 3: When only public key and certificate is present.
keyCodec.writePublicKey(publicKey);
- certCodec.writeCertificate(certHolder);
+ certCodec.writeCertificate(cert);
RuntimeException rteException = assertThrows(
RuntimeException.class,
() -> service.initializeCertificateClient(client));
@@ -232,9 +232,8 @@ public class TestHddsSecureDatanodeInit {
// Case 4: When public key as well as certificate is missing.
keyCodec.writePrivateKey(privateKey);
// provide a new valid SCMGetCertResponseProto
- X509CertificateHolder newCertHolder = generateX509CertHolder(null, null,
- Duration.ofSeconds(CERT_LIFETIME));
- String pemCert = CertificateCodec.getPEMEncodedString(newCertHolder);
+ X509Certificate newCert = generateX509Cert(null, null,
Duration.ofSeconds(CERT_LIFETIME));
+ String pemCert = CertificateCodec.getPEMEncodedString(newCert);
// provide an invalid SCMGetCertResponseProto. Without
// setX509CACertificate(pemCert), signAndStoreCert will throw exception.
SCMSecurityProtocolProtos.SCMGetCertResponseProto responseProto =
@@ -261,7 +260,7 @@ public class TestHddsSecureDatanodeInit {
@Test
public void testSecureDnStartupCase5() throws Exception {
// Case 5: If private key and certificate is present.
- certCodec.writeCertificate(certHolder);
+ certCodec.writeCertificate(cert);
keyCodec.writePrivateKey(privateKey);
service.initializeCertificateClient(client);
assertNotNull(client.getPrivateKey());
@@ -290,7 +289,7 @@ public class TestHddsSecureDatanodeInit {
// Case 7 When keypair and certificate is present.
keyCodec.writePublicKey(publicKey);
keyCodec.writePrivateKey(privateKey);
- certCodec.writeCertificate(certHolder);
+ certCodec.writeCertificate(cert);
service.initializeCertificateClient(client);
assertNotNull(client.getPrivateKey());
@@ -317,13 +316,12 @@ public class TestHddsSecureDatanodeInit {
@Test
public void testCertificateRotation() throws Exception {
// save the certificate on dn
- certCodec.writeCertificate(certHolder);
+ certCodec.writeCertificate(cert);
Duration gracePeriod = securityConfig.getRenewalGracePeriod();
- X509CertificateHolder newCertHolder = generateX509CertHolder(null,
- LocalDateTime.now().plus(gracePeriod),
- Duration.ofSeconds(CERT_LIFETIME));
- String pemCert = CertificateCodec.getPEMEncodedString(newCertHolder);
+ X509Certificate newCert =
+ generateX509Cert(null, LocalDateTime.now().plus(gracePeriod),
Duration.ofSeconds(CERT_LIFETIME));
+ String pemCert = CertificateCodec.getPEMEncodedString(newCert);
SCMSecurityProtocolProtos.SCMGetCertResponseProto responseProto =
SCMSecurityProtocolProtos.SCMGetCertResponseProto
.newBuilder().setResponseCode(SCMSecurityProtocolProtos
@@ -339,7 +337,7 @@ public class TestHddsSecureDatanodeInit {
rootCaList.add(pemCert);
when(scmClient.getAllRootCaCertificates()).thenReturn(rootCaList);
// check that new cert ID should not equal to current cert ID
- String certId = newCertHolder.getSerialNumber().toString();
+ String certId = newCert.getSerialNumber().toString();
assertNotEquals(certId,
client.getCertificate().getSerialNumber().toString());
// start monitor task to renew key and cert
@@ -357,10 +355,9 @@ public class TestHddsSecureDatanodeInit {
client.getRootCACertificate().getSerialNumber().toString();
// test the second time certificate rotation, generate a new cert
- newCertHolder = generateX509CertHolder(null, null,
- Duration.ofSeconds(CERT_LIFETIME));
+ newCert = generateX509Cert(null, null, Duration.ofSeconds(CERT_LIFETIME));
rootCaList.remove(pemCert);
- pemCert = CertificateCodec.getPEMEncodedString(newCertHolder);
+ pemCert = CertificateCodec.getPEMEncodedString(newCert);
responseProto = SCMSecurityProtocolProtos.SCMGetCertResponseProto
.newBuilder().setResponseCode(SCMSecurityProtocolProtos
.SCMGetCertResponseProto.ResponseCode.success)
@@ -372,7 +369,7 @@ public class TestHddsSecureDatanodeInit {
.thenReturn(responseProto);
rootCaList.add(pemCert);
when(scmClient.getAllRootCaCertificates()).thenReturn(rootCaList);
- String certId2 = newCertHolder.getSerialNumber().toString();
+ String certId2 = newCert.getSerialNumber().toString();
// check after renew, client will have the new cert ID
GenericTestUtils.waitFor(() -> {
@@ -392,13 +389,12 @@ public class TestHddsSecureDatanodeInit {
@Flaky("HDDS-8873")
public void testCertificateRotationRecoverableFailure() throws Exception {
// save the certificate on dn
- certCodec.writeCertificate(certHolder);
+ certCodec.writeCertificate(cert);
Duration gracePeriod = securityConfig.getRenewalGracePeriod();
- X509CertificateHolder newCertHolder = generateX509CertHolder(null,
- LocalDateTime.now().plus(gracePeriod),
- Duration.ofSeconds(CERT_LIFETIME));
- String pemCert = CertificateCodec.getPEMEncodedString(newCertHolder);
+ X509Certificate newCert =
+ generateX509Cert(null, LocalDateTime.now().plus(gracePeriod),
Duration.ofSeconds(CERT_LIFETIME));
+ String pemCert = CertificateCodec.getPEMEncodedString(newCert);
// provide an invalid SCMGetCertResponseProto. Without
// setX509CACertificate(pemCert), signAndStoreCert will throw exception.
SCMSecurityProtocolProtos.SCMGetCertResponseProto responseProto =
@@ -411,7 +407,7 @@ public class TestHddsSecureDatanodeInit {
.thenReturn(responseProto);
// check that new cert ID should not equal to current cert ID
- String certId = newCertHolder.getSerialNumber().toString();
+ String certId = newCert.getSerialNumber().toString();
assertNotEquals(certId,
client.getCertificate().getSerialNumber().toString());
// start monitor task to renew key and cert
@@ -427,9 +423,8 @@ public class TestHddsSecureDatanodeInit {
}
// provide a new valid SCMGetCertResponseProto
- newCertHolder = generateX509CertHolder(null, null,
- Duration.ofSeconds(CERT_LIFETIME));
- pemCert = CertificateCodec.getPEMEncodedString(newCertHolder);
+ newCert = generateX509Cert(null, null, Duration.ofSeconds(CERT_LIFETIME));
+ pemCert = CertificateCodec.getPEMEncodedString(newCert);
responseProto = SCMSecurityProtocolProtos.SCMGetCertResponseProto
.newBuilder().setResponseCode(SCMSecurityProtocolProtos
.SCMGetCertResponseProto.ResponseCode.success)
@@ -438,7 +433,7 @@ public class TestHddsSecureDatanodeInit {
.build();
when(scmClient.getDataNodeCertificateChain(any(), anyString()))
.thenReturn(responseProto);
- String certId2 = newCertHolder.getSerialNumber().toString();
+ String certId2 = newCert.getSerialNumber().toString();
// check after renew, client will have the new cert ID
GenericTestUtils.waitFor(() -> {
@@ -447,7 +442,7 @@ public class TestHddsSecureDatanodeInit {
}, 1000, CERT_LIFETIME * 1000);
}
- private static X509CertificateHolder generateX509CertHolder(KeyPair keyPair,
+ private static X509Certificate generateX509Cert(KeyPair keyPair,
LocalDateTime startDate, Duration certLifetime) throws Exception {
if (keyPair == null) {
keyPair = KeyStoreTestUtil.generateKeyPair("RSA");
diff --git
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/BaseApprover.java
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/BaseApprover.java
index 3e6194f920..0ea2c60f02 100644
---
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/BaseApprover.java
+++
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/BaseApprover.java
@@ -22,7 +22,6 @@ package
org.apache.hadoop.hdds.security.x509.certificate.authority;
import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.security.exception.SCMSecurityException;
import
org.apache.hadoop.hdds.security.x509.certificate.authority.profile.PKIProfile;
-import
org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateSignRequest;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.pkcs.Attribute;
@@ -30,7 +29,6 @@ import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.operator.ContentVerifierProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
@@ -39,7 +37,6 @@ import org.bouncycastle.pkcs.PKCSException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -182,17 +179,7 @@ public abstract class BaseApprover implements
CertificateApprover {
* {@inheritDoc}
*/
@Override
- public CompletableFuture<X509CertificateHolder> inspectCSR(String csr)
- throws IOException {
- return inspectCSR(CertificateSignRequest.getCertificationRequest(csr));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public CompletableFuture<X509CertificateHolder>
- inspectCSR(PKCS10CertificationRequest csr) {
+ public CompletableFuture<Void> inspectCSR(PKCS10CertificationRequest csr) {
/**
* The base approver executes the following algorithm to verify that a
* CSR meets the PKI Profile criteria.
@@ -214,8 +201,7 @@ public abstract class BaseApprover implements
CertificateApprover {
* the Certificate when finished.
*/
- CompletableFuture<X509CertificateHolder> response =
- new CompletableFuture<>();
+ CompletableFuture<Void> response = new CompletableFuture<>();
try {
// Step 0: Verify this is not a CA Certificate.
// Will be done by the Ozone PKI profile for time being.
diff --git
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateApprover.java
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateApprover.java
index 2d07630208..63c69bc06e 100644
---
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateApprover.java
+++
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateApprover.java
@@ -20,12 +20,13 @@
package org.apache.hadoop.hdds.security.x509.certificate.authority;
import org.apache.hadoop.hdds.security.SecurityConfig;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import java.io.IOException;
import java.security.PrivateKey;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.concurrent.CompletableFuture;
@@ -37,20 +38,9 @@ public interface CertificateApprover {
* Approves a Certificate Request based on the policies of this approver.
*
* @param csr - Certificate Signing Request.
- * @return - Future that will be contain the certificate or exception.
+ * @return - Future that will contain Void if the certificate is considered
valid otherwise an exception.
*/
- CompletableFuture<X509CertificateHolder>
- inspectCSR(PKCS10CertificationRequest csr);
-
- /**
- * Approves a Certificate Request based on the policies of this approver.
- *
- * @param csr - Certificate Signing Request.
- * @return - Future that will be contain the certificate or exception.
- * @throws IOException - On Error.
- */
- CompletableFuture<X509CertificateHolder>
- inspectCSR(String csr) throws IOException;
+ CompletableFuture<Void> inspectCSR(PKCS10CertificationRequest csr);
/**
* Sign function signs a Certificate.
@@ -68,17 +58,17 @@ public interface CertificateApprover {
* @throws OperatorCreationException - on Error.
*/
@SuppressWarnings("ParameterNumber")
- X509CertificateHolder sign(
+ X509Certificate sign(
SecurityConfig config,
PrivateKey caPrivate,
- X509CertificateHolder caCertificate,
+ X509Certificate caCertificate,
Date validFrom,
Date validTill,
PKCS10CertificationRequest certificationRequest,
String scmId,
String clusterId,
String certSerialId)
- throws IOException, OperatorCreationException;
+ throws IOException, OperatorCreationException, CertificateException;
/**
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 70bd5ad04e..360657889d 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
@@ -23,7 +23,6 @@ import
org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeType;
import org.apache.hadoop.hdds.scm.metadata.SCMMetadataStore;
import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.security.exception.SCMSecurityException;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import java.io.IOException;
@@ -52,13 +51,12 @@ public interface CertificateServer {
/**
* Returns the CA Certificate for this CA.
*
- * @return X509CertificateHolder - Certificate for this CA.
+ * @return X509Certificate - Certificate for this CA.
* @throws CertificateException - usually thrown if this CA is not
* initialized.
* @throws IOException - on Error.
*/
- X509CertificateHolder getCACertificate()
- throws CertificateException, IOException;
+ X509Certificate getCACertificate() throws CertificateException, IOException;
/**
* Gets the certificate bundle for the CA certificate of this server.
diff --git
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultApprover.java
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultApprover.java
index 90969823e7..e240856eae 100644
---
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultApprover.java
+++
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultApprover.java
@@ -31,6 +31,7 @@ import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
@@ -47,9 +48,10 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.math.BigInteger;
import java.security.PrivateKey;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Date;
-import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import static
org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateSignRequest.getDistinguishedNameWithSN;
@@ -90,17 +92,17 @@ public class DefaultApprover extends BaseApprover {
*/
@SuppressWarnings("ParameterNumber")
@Override
- public X509CertificateHolder sign(
+ public X509Certificate sign(
SecurityConfig config,
PrivateKey caPrivate,
- X509CertificateHolder caCertificate,
+ X509Certificate caCertificate,
Date validFrom,
Date validTill,
PKCS10CertificationRequest certificationRequest,
String scmId,
String clusterId,
String certSerialId) throws IOException,
- OperatorCreationException {
+ OperatorCreationException, CertificateException {
AlgorithmIdentifier sigAlgId = new
DefaultSignatureAlgorithmIdentifierFinder().find(
@@ -147,7 +149,7 @@ public class DefaultApprover extends BaseApprover {
}
X509v3CertificateBuilder certificateGenerator =
new X509v3CertificateBuilder(
- caCertificate.getSubject(),
+ new X509CertificateHolder(caCertificate.getEncoded()).getSubject(),
new BigInteger(certSerialId),
validFrom,
validTill,
@@ -172,19 +174,9 @@ public class DefaultApprover extends BaseApprover {
ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId)
.build(asymmetricKP);
- return certificateGenerator.build(sigGen);
+ //TODO: as part of HDDS-10743 ensure that converter is instantiated only
once
+ return new
JcaX509CertificateConverter().getCertificate(certificateGenerator.build(sigGen));
}
- @Override
- public CompletableFuture<X509CertificateHolder> inspectCSR(String csr)
- throws IOException {
- return super.inspectCSR(csr);
- }
-
- @Override
- public CompletableFuture<X509CertificateHolder>
- inspectCSR(PKCS10CertificationRequest csr) {
- return super.inspectCSR(csr);
- }
}
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 03de925d06..a93bdb4e3d 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
@@ -31,7 +31,6 @@ import
org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
import
org.apache.hadoop.hdds.security.x509.certificate.utils.SelfSignedCertificate;
import org.apache.hadoop.hdds.security.x509.keys.HDDSKeyGenerator;
import org.apache.hadoop.hdds.security.x509.keys.KeyCodec;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.slf4j.Logger;
@@ -174,11 +173,10 @@ public class DefaultCAServer implements CertificateServer
{
}
@Override
- public X509CertificateHolder getCACertificate() throws IOException {
- CertificateCodec certificateCodec =
- new CertificateCodec(config, componentName);
+ public X509Certificate getCACertificate() throws IOException {
+ CertificateCodec certificateCodec = new CertificateCodec(config,
componentName);
try {
- return certificateCodec.getTargetCertHolder();
+ return certificateCodec.getTargetCert();
} catch (CertificateException e) {
throw new IOException(e);
}
@@ -196,16 +194,14 @@ public class DefaultCAServer implements CertificateServer
{
* exist. Return null if it doesn't exist.
*
* @param certSerialId - Certificate for this CA.
- * @return X509CertificateHolder
+ * @return X509Certificate
* @throws CertificateException - usually thrown if this CA is not
* initialized.
* @throws IOException - on Error.
*/
@Override
- public X509Certificate getCertificate(String certSerialId) throws
- IOException {
- return store.getCertificateByID(new BigInteger(certSerialId)
- );
+ public X509Certificate getCertificate(String certSerialId) throws
IOException {
+ return store.getCertificateByID(new BigInteger(certSerialId));
}
private KeyPair getCAKeys() throws IOException {
@@ -223,70 +219,54 @@ public class DefaultCAServer implements CertificateServer
{
CertificateApprover.ApprovalType approverType, NodeType role,
String certSerialId) {
LocalDateTime beginDate = LocalDateTime.now();
- LocalDateTime endDate;
- // When issuing certificates for sub-ca use the max certificate duration
- // similar to self signed root certificate.
- if (role == NodeType.SCM) {
- endDate = beginDate.plus(config.getMaxCertificateDuration());
- } else {
- endDate = beginDate.plus(config.getDefaultCertDuration());
- }
-
- CompletableFuture<X509CertificateHolder> xcertHolder =
- approver.inspectCSR(csr);
-
- CompletableFuture<CertPath> xCertHolders
- = new CompletableFuture<>();
+ LocalDateTime endDate = expiryFor(beginDate, role);
- if (xcertHolder.isCompletedExceptionally()) {
- // This means that approver told us there are things which it disagrees
- // with in this Certificate Request. Since the first set of sanity
- // checks failed, we just return the future object right here.
- xCertHolders.completeExceptionally(new SCMSecurityException("Failed to "
+
- "verify the CSR."));
+ CompletableFuture<Void> csrInspection = approver.inspectCSR(csr);
+ CompletableFuture<CertPath> certPathPromise = new CompletableFuture<>();
+ if (csrInspection.isCompletedExceptionally()) {
+ try {
+ csrInspection.get();
+ } catch (Exception e) {
+ certPathPromise.completeExceptionally(new SCMSecurityException("Failed
to verify the CSR.", e));
+ }
}
try {
switch (approverType) {
case MANUAL:
- xCertHolders.completeExceptionally(new SCMSecurityException("Manual " +
- "approval is not yet implemented."));
+ certPathPromise.completeExceptionally(new SCMSecurityException("Manual
approval is not yet implemented."));
break;
case KERBEROS_TRUSTED:
case TESTING_AUTOMATIC:
- X509CertificateHolder xcert;
- try {
- xcert = signAndStoreCertificate(
- beginDate, endDate, csr, role, certSerialId);
- } catch (SCMSecurityException e) {
- // Certificate with conflicting serial id, retry again may resolve
- // this issue.
- LOG.error("Certificate storage failed, retrying one more time.", e);
- xcert = signAndStoreCertificate(
- beginDate, endDate, csr, role, certSerialId);
- }
+ X509Certificate signedCertificate = signAndStoreCertificate(beginDate,
endDate, csr, role, certSerialId);
CertificateCodec codec = new CertificateCodec(config, componentName);
CertPath certPath = codec.getCertPath();
- CertPath updatedCertPath = codec.prependCertToCertPath(xcert,
certPath);
- xCertHolders.complete(updatedCertPath);
+ CertPath updatedCertPath =
codec.prependCertToCertPath(signedCertificate, certPath);
+ certPathPromise.complete(updatedCertPath);
break;
default:
return null; // cannot happen, keeping checkstyle happy.
}
} catch (CertificateException | IOException | OperatorCreationException e)
{
LOG.error("Unable to issue a certificate.", e);
- xCertHolders.completeExceptionally(
- new SCMSecurityException(e, UNABLE_TO_ISSUE_CERTIFICATE));
+ certPathPromise.completeExceptionally(new SCMSecurityException(e,
UNABLE_TO_ISSUE_CERTIFICATE));
+ }
+ return certPathPromise;
+ }
+
+ private LocalDateTime expiryFor(LocalDateTime beginDate, NodeType role) {
+ // When issuing certificates for sub-ca use the max certificate duration
similar to self-signed root certificate.
+ if (role == NodeType.SCM) {
+ return beginDate.plus(config.getMaxCertificateDuration());
}
- return xCertHolders;
+ return beginDate.plus(config.getDefaultCertDuration());
}
- private X509CertificateHolder signAndStoreCertificate(LocalDateTime
beginDate,
- LocalDateTime endDate, PKCS10CertificationRequest csr, NodeType role,
- String certSerialId) throws IOException, OperatorCreationException,
- CertificateException {
+ private X509Certificate signAndStoreCertificate(
+ LocalDateTime beginDate, LocalDateTime endDate,
PKCS10CertificationRequest csr, NodeType role, String certSerialId
+ ) throws IOException, OperatorCreationException, CertificateException {
lock.lock();
- X509CertificateHolder xcert;
+ X509Certificate xcert;
try {
Preconditions.checkState(!Strings.isNullOrEmpty(certSerialId));
xcert = approver.sign(config,
@@ -297,8 +277,7 @@ public class DefaultCAServer implements CertificateServer {
csr, scmID, clusterID, certSerialId);
if (store != null) {
store.checkValidCertID(xcert.getSerialNumber());
- store.storeValidCertificate(xcert.getSerialNumber(),
- CertificateCodec.getX509Certificate(xcert), role);
+ store.storeValidCertificate(xcert.getSerialNumber(), xcert, role);
}
} finally {
lock.unlock();
@@ -528,7 +507,7 @@ public class DefaultCAServer implements CertificateServer {
.setKey(key);
builder.addInetAddresses();
- X509CertificateHolder selfSignedCertificate = builder.build();
+ X509Certificate selfSignedCertificate = builder.build();
CertificateCodec certCodec =
new CertificateCodec(config, componentName);
@@ -551,8 +530,7 @@ public class DefaultCAServer implements CertificateServer {
throw new IOException("External cert path is not correct: " +
extCertPath);
}
- X509CertificateHolder certHolder = certificateCodec.getTargetCertHolder(
- extCertParent, extCertName.toString());
+ X509Certificate certificate =
certificateCodec.getTargetCert(extCertParent, extCertName.toString());
Path extPrivateKeyParent = extPrivateKeyPath.getParent();
Path extPrivateKeyFileName = extPrivateKeyPath.getFileName();
if (extPrivateKeyParent == null || extPrivateKeyFileName == null) {
@@ -563,9 +541,9 @@ public class DefaultCAServer implements CertificateServer {
extPrivateKeyFileName.toString());
PublicKey publicKey;
publicKey = readPublicKeyWithExternalData(
- externalPublicKeyLocation, keyCodec, certHolder);
+ externalPublicKeyLocation, keyCodec, certificate);
keyCodec.writeKey(new KeyPair(publicKey, privateKey));
- certificateCodec.writeCertificate(certHolder);
+ certificateCodec.writeCertificate(certificate);
} catch (IOException | CertificateException | NoSuchAlgorithmException |
InvalidKeySpecException e) {
LOG.error("External root CA certificate initialization failed", e);
@@ -573,14 +551,11 @@ public class DefaultCAServer implements CertificateServer
{
}
private PublicKey readPublicKeyWithExternalData(
- String externalPublicKeyLocation, KeyCodec keyCodec,
- X509CertificateHolder certHolder)
- throws CertificateException, NoSuchAlgorithmException,
- InvalidKeySpecException, IOException {
+ String externalPublicKeyLocation, KeyCodec keyCodec, X509Certificate
certificate
+ ) throws CertificateException, NoSuchAlgorithmException,
InvalidKeySpecException, IOException {
PublicKey publicKey;
if (externalPublicKeyLocation.isEmpty()) {
- publicKey = CertificateCodec.getX509Certificate(certHolder)
- .getPublicKey();
+ publicKey = certificate.getPublicKey();
} else {
Path publicKeyPath = Paths.get(externalPublicKeyLocation);
Path publicKeyPathFileName = publicKeyPath.getFileName();
diff --git
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java
index d3db81c71b..8c8c00f6e9 100644
---
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java
+++
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java
@@ -1466,7 +1466,7 @@ public abstract class DefaultCertificateClient implements
CertificateClient {
CertificateException.ErrorCode.ROLLBACK_ERROR) {
if (shutdownCallback != null) {
getLogger().error("Failed to rollback key and cert after an " +
- " unsuccessful renew try.", e);
+ "unsuccessful renew try.", e);
shutdownCallback.run();
}
}
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 c4c07fce83..8bad4f18ad 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
@@ -35,7 +35,6 @@ import
org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateSignReq
import org.apache.hadoop.hdds.security.x509.exception.CertificateException;
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.OzoneSecurityUtil;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -359,25 +358,19 @@ public class SCMCertificateClient extends
DefaultCertificateClient {
CertificateCodec.getPEMEncodedString(rootCACertificatePath);
PKCS10CertificationRequest csr = getCSRBuilder().build();
- CertPath subSCMCertHolderList = rootCAServer.requestCertificate(
- csr, KERBEROS_TRUSTED, SCM,
- BigInteger.ONE.add(BigInteger.ONE).toString()).get();
- String pemEncodedCert =
- CertificateCodec.getPEMEncodedString(subSCMCertHolderList);
+ String subCaSerialId = BigInteger.ONE.add(BigInteger.ONE).toString();
+ CertPath scmSubCACertPath = rootCAServer.requestCertificate(csr,
KERBEROS_TRUSTED, SCM, subCaSerialId).get();
+ String pemEncodedCert =
CertificateCodec.getPEMEncodedString(scmSubCACertPath);
storeCertificate(pemEncodedRootCert, CAType.SUBORDINATE);
storeCertificate(pemEncodedCert, CAType.NONE);
//note: this does exactly the same as store certificate
persistSubCACertificate(pemEncodedCert);
- X509Certificate cert =
- (X509Certificate) subSCMCertHolderList.getCertificates().get(0);
- X509CertificateHolder subSCMCertHolder =
- CertificateCodec.getCertificateHolder(cert);
+ X509Certificate cert = (X509Certificate)
scmSubCACertPath.getCertificates().get(0);
// Persist scm cert serial ID.
- saveCertIdCallback.accept(subSCMCertHolder.getSerialNumber().toString());
- } catch (InterruptedException | ExecutionException | IOException |
- java.security.cert.CertificateException e) {
+ saveCertIdCallback.accept(cert.getSerialNumber().toString());
+ } catch (InterruptedException | ExecutionException | IOException |
java.security.cert.CertificateException e) {
LOG.error("Error while fetching/storing SCM signed certificate.", e);
Thread.currentThread().interrupt();
throw new RuntimeException(e);
diff --git
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
index 4fae3686c9..2b83c4d059 100644
---
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
+++
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java
@@ -58,6 +58,7 @@ import org.apache.hadoop.hdds.scm.proxy.SCMClientConfig;
import org.apache.hadoop.hdds.scm.proxy.SecretKeyProtocolFailoverProxyProvider;
import
org.apache.hadoop.hdds.scm.proxy.SCMSecurityProtocolFailoverProxyProvider;
import org.apache.hadoop.hdds.scm.proxy.SingleSecretKeyProtocolProxyProvider;
+import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.server.ServerUtils;
import org.apache.hadoop.hdds.tracing.TracingUtil;
import org.apache.hadoop.hdds.utils.db.DBCheckpoint;
@@ -451,6 +452,7 @@ public final class HddsServerUtil {
*/
public static SCMSecurityProtocolClientSideTranslatorPB getScmSecurityClient(
ConfigurationSource conf) throws IOException {
+ SecurityConfig.initSecurityProvider(conf);
return new SCMSecurityProtocolClientSideTranslatorPB(
new SCMSecurityProtocolFailoverProxyProvider(conf,
UserGroupInformation.getCurrentUser()));
@@ -463,6 +465,7 @@ public final class HddsServerUtil {
// for ever. In this way DN start up is resilient to SCM service running
// status.
OzoneConfiguration configuration = new OzoneConfiguration(conf);
+ SecurityConfig.initSecurityProvider(configuration);
SCMClientConfig scmClientConfig =
conf.getObject(SCMClientConfig.class);
int retryCount = Integer.MAX_VALUE;
@@ -482,6 +485,7 @@ public final class HddsServerUtil {
*/
public static SCMSecurityProtocolClientSideTranslatorPB getScmSecurityClient(
OzoneConfiguration conf, UserGroupInformation ugi) throws IOException {
+ SecurityConfig.initSecurityProvider(conf);
SCMSecurityProtocolClientSideTranslatorPB scmSecurityClient =
new SCMSecurityProtocolClientSideTranslatorPB(
new SCMSecurityProtocolFailoverProxyProvider(conf, ugi));
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/MockApprover.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/MockApprover.java
deleted file mode 100644
index c9e520cdee..0000000000
---
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/MockApprover.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.authority;
-
-import org.apache.hadoop.hdds.security.SecurityConfig;
-import
org.apache.hadoop.hdds.security.x509.certificate.authority.profile.PKIProfile;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.pkcs.PKCS10CertificationRequest;
-
-import java.io.IOException;
-import java.security.PrivateKey;
-import java.util.Date;
-import java.util.concurrent.CompletableFuture;
-
-/**
- * A test approver class that makes testing easier.
- */
-public class MockApprover extends BaseApprover {
-
- public MockApprover(PKIProfile pkiProfile, SecurityConfig config) {
- super(pkiProfile, config);
- }
-
- @Override
- public CompletableFuture<X509CertificateHolder>
- inspectCSR(PKCS10CertificationRequest csr) {
- return super.inspectCSR(csr);
- }
-
- @Override
- public X509CertificateHolder sign(SecurityConfig config, PrivateKey
caPrivate,
- X509CertificateHolder caCertificate,
- Date validFrom, Date validTill,
- PKCS10CertificationRequest request,
- String scmId, String clusterId, String certId)
- throws IOException, OperatorCreationException {
- return null;
- }
-
-}
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 740c3258a5..56f84b9e3b 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
@@ -36,8 +36,6 @@ import
org.apache.hadoop.hdds.security.x509.keys.HDDSKeyGenerator;
import org.apache.hadoop.hdds.security.x509.keys.KeyCodec;
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -51,7 +49,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertPath;
import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -65,6 +63,7 @@ import java.util.function.Consumer;
import static org.apache.hadoop.hdds.HddsConfigKeys.OZONE_METADATA_DIRS;
import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeType.OM;
import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeType.SCM;
+import static
org.apache.hadoop.hdds.security.x509.certificate.authority.DefaultCAServer.VerificationStatus;
import static org.apache.hadoop.ozone.OzoneConsts.SCM_CA_CERT_STORAGE_DIR;
import static org.apache.hadoop.ozone.OzoneConsts.SCM_CA_PATH;
import static org.assertj.core.api.Assertions.assertThat;
@@ -90,19 +89,18 @@ public class TestDefaultCAServer {
}
@Test
- public void testInit() throws SCMSecurityException, CertificateException,
- IOException {
+ public void testInit() throws Exception {
CertificateServer testCA = new DefaultCAServer("testCA",
RandomStringUtils.randomAlphabetic(4),
RandomStringUtils.randomAlphabetic(4), caStore,
new DefaultProfile(),
Paths.get(SCM_CA_CERT_STORAGE_DIR, SCM_CA_PATH).toString());
testCA.init(securityConfig, CAType.ROOT);
- X509CertificateHolder first = testCA.getCACertificate();
+ X509Certificate first = testCA.getCACertificate();
assertNotNull(first);
//Init is idempotent.
testCA.init(securityConfig, CAType.ROOT);
- X509CertificateHolder second = testCA.getCACertificate();
+ X509Certificate second = testCA.getCACertificate();
assertEquals(first, second);
}
@@ -126,18 +124,16 @@ public class TestDefaultCAServer {
@Test
public void testMissingKey() {
- CertificateServer testCA = new DefaultCAServer("testCA",
+ DefaultCAServer testCA = new DefaultCAServer("testCA",
RandomStringUtils.randomAlphabetic(4),
RandomStringUtils.randomAlphabetic(4), caStore,
new DefaultProfile(),
Paths.get(SCM_CA_CERT_STORAGE_DIR, SCM_CA_PATH).toString());
Consumer<SecurityConfig> caInitializer =
- ((DefaultCAServer) testCA).processVerificationStatus(
- DefaultCAServer.VerificationStatus.MISSING_KEYS, CAType.ROOT);
- IllegalStateException e =
- assertThrows(IllegalStateException.class, () ->
caInitializer.accept(securityConfig));
- // This also is a runtime exception. Hence not caught by junit expected
- // exception.
+ testCA.processVerificationStatus(VerificationStatus.MISSING_KEYS,
CAType.ROOT);
+ IllegalStateException e = assertThrows(IllegalStateException.class, () ->
caInitializer.accept(securityConfig));
+
+ // This also is a runtime exception. Hence, not caught by junit expected
exception.
assertThat(e.toString()).contains("Missing Keys");
}
@@ -152,9 +148,7 @@ public class TestDefaultCAServer {
* @throws NoSuchAlgorithmException - on ERROR.
*/
@Test
- public void testRequestCertificate() throws IOException,
- ExecutionException, InterruptedException,
- NoSuchProviderException, NoSuchAlgorithmException, CertificateException {
+ public void testRequestCertificate() throws Exception {
String scmId = RandomStringUtils.randomAlphabetic(4);
String clusterId = RandomStringUtils.randomAlphabetic(4);
KeyPair keyPair =
@@ -186,8 +180,7 @@ public class TestDefaultCAServer {
// place
List<? extends Certificate> certBundle = holder.get().getCertificates();
X509Certificate caInReturnedBundle = (X509Certificate) certBundle.get(1);
- assertEquals(caInReturnedBundle,
- CertificateCodec.getX509Certificate(testCA.getCACertificate()));
+ assertEquals(caInReturnedBundle, testCA.getCACertificate());
X509Certificate signedCert =
CertificateCodec.firstCertificateFrom(holder.get());
//Test that the ca has signed of the returned certificate
@@ -208,9 +201,7 @@ public class TestDefaultCAServer {
* @throws NoSuchAlgorithmException - on ERROR.
*/
@Test
- public void testRequestCertificateWithInvalidSubject() throws IOException,
- ExecutionException, InterruptedException,
- NoSuchProviderException, NoSuchAlgorithmException {
+ public void testRequestCertificateWithInvalidSubject() throws Exception {
KeyPair keyPair =
new HDDSKeyGenerator(securityConfig).generateKey();
PKCS10CertificationRequest csr = new CertificateSignRequest.Builder()
@@ -238,8 +229,7 @@ public class TestDefaultCAServer {
}
@Test
- public void testRequestCertificateWithInvalidSubjectFailure()
- throws Exception {
+ public void testRequestCertificateWithInvalidSubjectFailure() throws
Exception {
KeyPair keyPair =
new HDDSKeyGenerator(securityConfig).generateKey();
PKCS10CertificationRequest csr = new CertificateSignRequest.Builder()
@@ -298,7 +288,7 @@ public class TestDefaultCAServer {
scmCertificateClient.getComponentName());
keyPEMWriter.writeKey(tempDir, keyPair, true);
- X509CertificateHolder externalCert = generateExternalCert(keyPair);
+ X509Certificate externalCert = generateExternalCert(keyPair);
CertificateCodec certificateCodec = new CertificateCodec(securityConfig,
scmCertificateClient.getComponentName());
@@ -365,18 +355,16 @@ public class TestDefaultCAServer {
.setConfiguration(securityConfig)
.setKey(keyPair)
.build();
- X509CertificateHolder externalCert = generateExternalCert(keyPair);
- X509CertificateHolder signedCert = approver.sign(securityConfig,
+ X509Certificate externalCert = generateExternalCert(keyPair);
+ X509Certificate signedCert = approver.sign(securityConfig,
keyPair.getPrivate(), externalCert,
java.sql.Date.valueOf(beginDate), java.sql.Date.valueOf(endDate),
csr,
scmId, clusterId, String.valueOf(System.nanoTime()));
- CertificateFactory certFactory = new CertificateFactory();
+ CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
CertificateCodec certificateCodec = new CertificateCodec(securityConfig,
scmCertificateClient.getComponentName());
- CertPath certPath = certFactory.engineGenerateCertPath(
- ImmutableList.of(CertificateCodec.getX509Certificate(signedCert),
- CertificateCodec.getX509Certificate(externalCert)));
+ CertPath certPath =
certFactory.generateCertPath(ImmutableList.of(signedCert, externalCert));
certificateCodec.writeCertificate(tempDir, externalCaCertFileName,
CertificateCodec.getPEMEncodedString(certPath));
@@ -432,44 +420,34 @@ public class TestDefaultCAServer {
assertTrue(holder.isDone());
X509Certificate certificate =
CertificateCodec.firstCertificateFrom(holder.get());
- X509CertificateHolder certificateHolder =
- CertificateCodec.getCertificateHolder(certificate);
- assertNotNull(certificateHolder);
- LocalDate invalidAfterDate = certificateHolder.getNotAfter().toInstant()
+ assertNotNull(certificate);
+ LocalDate invalidAfterDate = certificate.getNotAfter().toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
LocalDate now = LocalDate.now();
assertEquals(0, invalidAfterDate.compareTo(now.plusDays(3650)));
- X509CertificateHolder rootCertHolder = rootCA.getCACertificate();
-
- scmCertificateClient.storeCertificate(
- CertificateCodec.getPEMEncodedString(rootCertHolder),
- CAType.SUBORDINATE);
+ X509Certificate caCertificate = rootCA.getCACertificate();
+
scmCertificateClient.storeCertificate(CertificateCodec.getPEMEncodedString(caCertificate),
CAType.SUBORDINATE);
// Write to the location where Default CA Server reads from.
- scmCertificateClient.storeCertificate(
- CertificateCodec.getPEMEncodedString(certificateHolder),
CAType.NONE);
+
scmCertificateClient.storeCertificate(CertificateCodec.getPEMEncodedString(certificate),
CAType.NONE);
- CertificateCodec certCodec =
- new CertificateCodec(securityConfig,
- scmCertificateClient.getComponentName());
- certCodec.writeCertificate(certificateHolder);
+ CertificateCodec certCodec = new CertificateCodec(securityConfig,
scmCertificateClient.getComponentName());
+ certCodec.writeCertificate(certificate);
// The certificate generated by above cert client will be used by scmCA.
// Now scmCA init should be successful.
- CertificateServer scmCA = new DefaultCAServer("scmCA",
- clusterId, scmId, caStore, new DefaultProfile(),
- scmCertificateClient.getComponentName());
+ CertificateServer scmCA = new DefaultCAServer(
+ "scmCA", clusterId, scmId, caStore, new DefaultProfile(),
scmCertificateClient.getComponentName());
scmCA.init(securityConfig, CAType.SUBORDINATE);
}
}
- private X509CertificateHolder generateExternalCert(KeyPair keyPair)
- throws Exception {
+ private X509Certificate generateExternalCert(KeyPair keyPair) throws
Exception {
LocalDateTime notBefore = LocalDateTime.now();
LocalDateTime notAfter = notBefore.plusYears(1);
String clusterID = UUID.randomUUID().toString();
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultProfile.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultProfile.java
index 4e60d7e967..1204f90521 100644
---
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultProfile.java
+++
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultProfile.java
@@ -63,7 +63,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class TestDefaultProfile {
private SecurityConfig securityConfig;
private DefaultProfile defaultProfile;
- private MockApprover testApprover;
+ private DefaultApprover approver;
private KeyPair keyPair;
@BeforeEach
@@ -72,8 +72,7 @@ public class TestDefaultProfile {
configuration.set(OZONE_METADATA_DIRS, tempDir.toString());
securityConfig = new SecurityConfig(configuration);
defaultProfile = new DefaultProfile();
- testApprover = new MockApprover(defaultProfile,
- securityConfig);
+ approver = new DefaultApprover(defaultProfile, securityConfig);
keyPair = new HDDSKeyGenerator(securityConfig).generateKey();
}
@@ -114,7 +113,7 @@ public class TestDefaultProfile {
.setConfiguration(securityConfig)
.setKey(keyPair)
.build();
- assertTrue(testApprover.verifyPkcs10Request(csr));
+ assertTrue(approver.verifyPkcs10Request(csr));
}
@@ -148,7 +147,7 @@ public class TestDefaultProfile {
.build();
// Signature verification should fail here, since the public/private key
// does not match.
- assertFalse(testApprover.verifyPkcs10Request(csr));
+ assertFalse(approver.verifyPkcs10Request(csr));
}
/**
@@ -170,7 +169,7 @@ public class TestDefaultProfile {
.setConfiguration(securityConfig)
.setKey(keyPair)
.build();
- assertTrue(testApprover.verfiyExtensions(csr));
+ assertTrue(approver.verfiyExtensions(csr));
}
/**
@@ -192,7 +191,7 @@ public class TestDefaultProfile {
.setConfiguration(securityConfig)
.setKey(keyPair)
.build();
- assertFalse(testApprover.verfiyExtensions(csr));
+ assertFalse(approver.verfiyExtensions(csr));
}
/**
@@ -209,12 +208,12 @@ public class TestDefaultProfile {
Extensions emailExtension = getSANExtension(GeneralName.rfc822Name,
"[email protected]", false);
PKCS10CertificationRequest csr = getInvalidCSR(keyPair, emailExtension);
- assertFalse(testApprover.verfiyExtensions(csr));
+ assertFalse(approver.verfiyExtensions(csr));
emailExtension = getSANExtension(GeneralName.rfc822Name, "bilbo" +
"@apache.org", true);
csr = getInvalidCSR(keyPair, emailExtension);
- assertFalse(testApprover.verfiyExtensions(csr));
+ assertFalse(approver.verfiyExtensions(csr));
}
@@ -229,11 +228,11 @@ public class TestDefaultProfile {
Extensions oExtension = getSANExtension(
GeneralName.uniformResourceIdentifier, "s3g.ozone.org", false);
PKCS10CertificationRequest csr = getInvalidCSR(keyPair, oExtension);
- assertFalse(testApprover.verfiyExtensions(csr));
+ assertFalse(approver.verfiyExtensions(csr));
oExtension = getSANExtension(GeneralName.uniformResourceIdentifier,
"s3g.ozone.org", false);
csr = getInvalidCSR(keyPair, oExtension);
- assertFalse(testApprover.verfiyExtensions(csr));
+ assertFalse(approver.verfiyExtensions(csr));
}
/**
@@ -248,13 +247,13 @@ public class TestDefaultProfile {
"ozone.hadoop.org",
true);
PKCS10CertificationRequest csr = getInvalidCSR(keyPair, dnsExtension);
- assertFalse(testApprover.verfiyExtensions(csr));
+ assertFalse(approver.verfiyExtensions(csr));
// This tests should pass, hence the assertTrue
dnsExtension = getSANExtension(GeneralName.dNSName,
"ozone.hadoop.org",
false);
csr = getInvalidCSR(keyPair, dnsExtension);
- assertTrue(testApprover.verfiyExtensions(csr));
+ assertTrue(approver.verfiyExtensions(csr));
}
@@ -269,12 +268,12 @@ public class TestDefaultProfile {
Extensions extendedExtension =
getKeyUsageExtension(KeyPurposeId.id_kp_clientAuth, false);
PKCS10CertificationRequest csr = getInvalidCSR(keyPair, extendedExtension);
- assertTrue(testApprover.verfiyExtensions(csr));
+ assertTrue(approver.verfiyExtensions(csr));
extendedExtension = getKeyUsageExtension(KeyPurposeId.id_kp_serverAuth,
false);
csr = getInvalidCSR(keyPair, extendedExtension);
- assertTrue(testApprover.verfiyExtensions(csr));
+ assertTrue(approver.verfiyExtensions(csr));
}
@@ -289,12 +288,12 @@ public class TestDefaultProfile {
Extensions extendedExtension =
getKeyUsageExtension(KeyPurposeId.id_kp_clientAuth, true);
PKCS10CertificationRequest csr = getInvalidCSR(keyPair, extendedExtension);
- assertFalse(testApprover.verfiyExtensions(csr));
+ assertFalse(approver.verfiyExtensions(csr));
extendedExtension = getKeyUsageExtension(KeyPurposeId.id_kp_OCSPSigning,
false);
csr = getInvalidCSR(keyPair, extendedExtension);
- assertFalse(testApprover.verfiyExtensions(csr));
+ assertFalse(approver.verfiyExtensions(csr));
}
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/CertificateClientTestImpl.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/CertificateClientTestImpl.java
index c322aaf2a7..30bd9fc320 100644
---
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/CertificateClientTestImpl.java
+++
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/CertificateClientTestImpl.java
@@ -56,8 +56,6 @@ import
org.apache.hadoop.hdds.security.x509.exception.CertificateException;
import org.apache.hadoop.hdds.security.x509.keys.HDDSKeyGenerator;
import org.apache.hadoop.hdds.security.x509.keys.SecurityUtil;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_X509_DEFAULT_DURATION;
import static
org.apache.hadoop.hdds.HddsConfigKeys.HDDS_X509_DEFAULT_DURATION_DEFAULT;
@@ -106,18 +104,16 @@ public class CertificateClientTestImpl implements
CertificateClient {
LocalDateTime end = start.plus(Duration.parse(rootCACertDuration));
// Generate RootCA certificate
- SelfSignedCertificate.Builder builder =
- SelfSignedCertificate.newBuilder()
- .setBeginDate(start)
- .setEndDate(end)
- .setClusterID("cluster1")
- .setKey(rootKeyPair)
- .setSubject("rootCA@localhost")
- .setConfiguration(securityConfig)
- .setScmID("scm1")
- .makeCA();
- rootCert = new JcaX509CertificateConverter().getCertificate(
- builder.build());
+ rootCert = SelfSignedCertificate.newBuilder()
+ .setBeginDate(start)
+ .setEndDate(end)
+ .setClusterID("cluster1")
+ .setKey(rootKeyPair)
+ .setSubject("rootCA@localhost")
+ .setConfiguration(securityConfig)
+ .setScmID("scm1")
+ .makeCA()
+ .build();
certificateMap.put(rootCert.getSerialNumber().toString(), rootCert);
rootCerts.add(rootCert);
@@ -138,16 +134,13 @@ public class CertificateClientTestImpl implements
CertificateClient {
start = LocalDateTime.now();
String certDuration = conf.get(HDDS_X509_DEFAULT_DURATION,
HDDS_X509_DEFAULT_DURATION_DEFAULT);
- X509CertificateHolder certificateHolder =
- approver.sign(securityConfig, rootKeyPair.getPrivate(),
- new X509CertificateHolder(rootCert.getEncoded()),
+ x509Certificate = approver.sign(securityConfig, rootKeyPair.getPrivate(),
+ rootCert,
Date.from(start.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(start.plus(Duration.parse(certDuration))
.atZone(ZoneId.systemDefault()).toInstant()),
csrBuilder.build(), "scm1", "cluster1",
String.valueOf(System.nanoTime()));
- x509Certificate =
- new JcaX509CertificateConverter().getCertificate(certificateHolder);
certificateMap.put(x509Certificate.getSerialNumber().toString(),
x509Certificate);
@@ -280,18 +273,16 @@ public class CertificateClientTestImpl implements
CertificateClient {
Duration rootCACertDuration = securityConfig.getMaxCertificateDuration();
LocalDateTime end = start.plus(rootCACertDuration);
rootKeyPair = keyGen.generateKey();
- SelfSignedCertificate.Builder builder =
- SelfSignedCertificate.newBuilder()
- .setBeginDate(start)
- .setEndDate(end)
- .setClusterID("cluster1")
- .setKey(rootKeyPair)
- .setSubject("rootCA-new@localhost")
- .setConfiguration(securityConfig)
- .setScmID("scm1")
- .makeCA(BigInteger.ONE.add(BigInteger.ONE));
- rootCert = new JcaX509CertificateConverter().getCertificate(
- builder.build());
+ rootCert = SelfSignedCertificate.newBuilder()
+ .setBeginDate(start)
+ .setEndDate(end)
+ .setClusterID("cluster1")
+ .setKey(rootKeyPair)
+ .setSubject("rootCA-new@localhost")
+ .setConfiguration(securityConfig)
+ .setScmID("scm1")
+ .makeCA(BigInteger.ONE.add(BigInteger.ONE))
+ .build();
certificateMap.put(rootCert.getSerialNumber().toString(), rootCert);
rootCerts.add(rootCert);
}
@@ -310,14 +301,11 @@ public class CertificateClientTestImpl implements
CertificateClient {
Duration certDuration = securityConfig.getDefaultCertDuration();
Date start = new Date();
- X509CertificateHolder certificateHolder =
- approver.sign(securityConfig, rootKeyPair.getPrivate(),
- new X509CertificateHolder(rootCert.getEncoded()), start,
- new Date(start.getTime() + certDuration.toMillis()),
- csrBuilder.build(), "scm1", "cluster1",
- String.valueOf(System.nanoTime()));
X509Certificate newX509Certificate =
- new JcaX509CertificateConverter().getCertificate(certificateHolder);
+ approver.sign(securityConfig, rootKeyPair.getPrivate(), rootCert,
start,
+ new Date(start.getTime() + certDuration.toMillis()),
csrBuilder.build(), "scm1", "cluster1",
+ String.valueOf(System.nanoTime())
+ );
// Save the new private key and certificate to file
// Save certificate and private key to keyStore
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 b5d0425bec..59c623a53d 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
@@ -27,7 +27,6 @@ import
org.apache.hadoop.hdds.security.x509.certificate.authority.CAType;
import org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
import org.apache.hadoop.hdds.security.x509.exception.CertificateException;
import org.apache.hadoop.hdds.security.x509.keys.KeyCodec;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -404,10 +403,8 @@ public class TestDefaultCertificateClient {
dnSecurityConfig.getKeyLocation(DN_COMPONENT).toString(),
dnSecurityConfig.getCertificateFileName()).toFile());
- CertificateCodec dnCertCodec = new CertificateCodec(dnSecurityConfig,
- DN_COMPONENT);
- dnCertCodec.writeCertificate(new X509CertificateHolder(
- x509Certificate.getEncoded()));
+ CertificateCodec dnCertCodec = new CertificateCodec(dnSecurityConfig,
DN_COMPONENT);
+ dnCertCodec.writeCertificate(x509Certificate);
// Check for DN.
assertEquals(FAILURE, dnCertClient.init());
assertThat(dnClientLog.getOutput()).contains("Keypair validation failed");
@@ -468,8 +465,7 @@ public class TestDefaultCertificateClient {
// save the certificate on dn
CertificateCodec certCodec = new CertificateCodec(dnSecurityConfig,
dnSecurityConfig.getCertificateLocation(DN_COMPONENT));
- certCodec.writeCertificate(
- new X509CertificateHolder(x509Certificate.getEncoded()));
+ certCodec.writeCertificate(x509Certificate);
X509Certificate newCert = generateX509Cert(null);
String pemCert = CertificateCodec.getPEMEncodedString(newCert);
@@ -555,7 +551,7 @@ public class TestDefaultCertificateClient {
CertificateCodec certCodec = new CertificateCodec(conf, compName);
X509Certificate cert = generateX509Cert(null);
- certCodec.writeCertificate(new X509CertificateHolder(cert.getEncoded()));
+ certCodec.writeCertificate(cert);
Logger logger = mock(Logger.class);
String certId = cert.getSerialNumber().toString();
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDnCertificateClientInit.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDnCertificateClientInit.java
index 3c3330a2b2..9a39695b3a 100644
---
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDnCertificateClientInit.java
+++
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDnCertificateClientInit.java
@@ -28,7 +28,6 @@ import
org.apache.hadoop.hdds.security.x509.keys.HDDSKeyGenerator;
import org.apache.hadoop.hdds.security.x509.keys.KeyCodec;
import org.apache.hadoop.ozone.OzoneSecurityUtil;
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.io.TempDir;
@@ -130,10 +129,8 @@ public class TestDnCertificateClientInit {
}
if (certPresent) {
- CertificateCodec codec = new CertificateCodec(securityConfig,
- DN_COMPONENT);
- codec.writeCertificate(new X509CertificateHolder(
- x509Certificate.getEncoded()));
+ CertificateCodec codec = new CertificateCodec(securityConfig,
DN_COMPONENT);
+ codec.writeCertificate(x509Certificate);
} else {
FileUtils.deleteQuietly(Paths.get(
securityConfig.getKeyLocation(DN_COMPONENT).toString(),
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestRootCaRotationPoller.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestRootCaRotationPoller.java
index 4bcd60c855..3060422dcd 100644
---
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestRootCaRotationPoller.java
+++
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestRootCaRotationPoller.java
@@ -25,7 +25,6 @@ import
org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
import
org.apache.hadoop.hdds.security.x509.certificate.utils.SelfSignedCertificate;
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
import org.apache.ozone.test.GenericTestUtils;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.mockito.Mock;
@@ -181,10 +180,14 @@ public class TestRootCaRotationPoller {
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());
+ return SelfSignedCertificate.newBuilder()
+ .setBeginDate(start)
+ .setEndDate(end)
+ .setClusterID("cluster")
+ .setKey(keyPair)
+ .setSubject("localhost")
+ .setConfiguration(secConf)
+ .setScmID("test")
+ .build();
}
}
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/TestCertificateCodec.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/TestCertificateCodec.java
index f2ae1221f1..e0db7554fb 100644
---
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/TestCertificateCodec.java
+++
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/TestCertificateCodec.java
@@ -22,22 +22,16 @@ package
org.apache.hadoop.hdds.security.x509.certificate.utils;
import com.google.common.collect.ImmutableList;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
-import org.apache.hadoop.hdds.security.exception.SCMSecurityException;
import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.security.x509.keys.HDDSKeyGenerator;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import java.io.IOException;
import java.nio.file.Path;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
import java.security.cert.CertPath;
import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.LocalDateTime;
@@ -66,32 +60,17 @@ public class TestCertificateCodec {
* then creates a new X509Certificate object to verify that we are able to
* serialize and deserialize correctly. we follow up with converting these
* objects to standard JCA x509Certificate objects.
- *
- * @throws NoSuchProviderException - on Error.
- * @throws NoSuchAlgorithmException - on Error.
- * @throws IOException - on Error.
- * @throws SCMSecurityException - on Error.
- * @throws CertificateException - on Error.
*/
@Test
- public void testGetPEMEncodedString()
- throws NoSuchProviderException, NoSuchAlgorithmException,
- IOException, SCMSecurityException, CertificateException {
- X509CertificateHolder cert =
- generateTestCert();
+ public void testGetPEMEncodedString() throws Exception {
+ X509Certificate cert = generateTestCert();
String pemString = CertificateCodec.getPEMEncodedString(cert);
assertTrue(pemString.startsWith(CertificateCodec.BEGIN_CERT));
assertTrue(pemString.endsWith(CertificateCodec.END_CERT + "\n"));
// Read back the certificate and verify that all the comparisons pass.
- X509CertificateHolder newCert = CertificateCodec.getCertificateHolder(
- CertificateCodec.getX509Certificate(pemString));
+ X509Certificate newCert = CertificateCodec.getX509Certificate(pemString);
assertEquals(cert, newCert);
-
- // Just make sure we can decode both these classes to Java Std. lIb
classes.
- X509Certificate firstCert = CertificateCodec.getX509Certificate(cert);
- X509Certificate secondCert = CertificateCodec.getX509Certificate(newCert);
- assertEquals(firstCert, secondCert);
}
/**
@@ -99,19 +78,15 @@ public class TestCertificateCodec {
* we get back the same certificates.
*/
@Test
- public void testGetPemEncodedStringFromCertPath() throws IOException,
- NoSuchAlgorithmException, NoSuchProviderException, CertificateException {
- X509CertificateHolder certHolder1 = generateTestCert();
- X509CertificateHolder certHolder2 = generateTestCert();
- X509Certificate cert1 = CertificateCodec.getX509Certificate(certHolder1);
- X509Certificate cert2 = CertificateCodec.getX509Certificate(certHolder2);
- CertificateFactory certificateFactory = new CertificateFactory();
- CertPath pathToEncode =
- certificateFactory.engineGenerateCertPath(ImmutableList.of(cert1,
- cert2));
+ public void testGetPemEncodedStringFromCertPath() throws Exception {
+ X509Certificate cert1 = generateTestCert();
+ X509Certificate cert2 = generateTestCert();
+ CertificateFactory certificateFactory =
CertificateFactory.getInstance("X.509");
+
+ CertPath pathToEncode =
certificateFactory.generateCertPath(ImmutableList.of(cert1, cert2));
String encodedPath = CertificateCodec.getPEMEncodedString(pathToEncode);
- CertPath certPathDecoded =
- CertificateCodec.getCertPathFromPemEncodedString(encodedPath);
+ CertPath certPathDecoded =
CertificateCodec.getCertPathFromPemEncodedString(encodedPath);
+
assertEquals(cert1, certPathDecoded.getCertificates().get(0));
assertEquals(cert2, certPathDecoded.getCertificates().get(1));
}
@@ -120,19 +95,14 @@ public class TestCertificateCodec {
* Test prepending a new certificate to a cert path.
*/
@Test
- public void testPrependCertificateToCertPath() throws IOException,
- NoSuchAlgorithmException, NoSuchProviderException, CertificateException {
+ public void testPrependCertificateToCertPath() throws Exception {
CertificateCodec codec = new CertificateCodec(securityConfig, COMPONENT);
- X509CertificateHolder initialHolder = generateTestCert();
- X509CertificateHolder prependedHolder = generateTestCert();
- X509Certificate initialCert =
- CertificateCodec.getX509Certificate(initialHolder);
- X509Certificate prependedCert =
- CertificateCodec.getX509Certificate(prependedHolder);
- codec.writeCertificate(initialHolder);
+ X509Certificate initialCert = generateTestCert();
+ X509Certificate prependedCert = generateTestCert();
+ codec.writeCertificate(initialCert);
CertPath initialPath = codec.getCertPath();
CertPath pathWithPrependedCert =
- codec.prependCertToCertPath(prependedHolder, initialPath);
+ codec.prependCertToCertPath(prependedCert, initialPath);
assertEquals(prependedCert,
pathWithPrependedCert.getCertificates().get(0));
assertEquals(initialCert, pathWithPrependedCert.getCertificates().get(1));
@@ -140,124 +110,82 @@ public class TestCertificateCodec {
/**
* tests writing and reading certificates in PEM encoded form.
- *
- * @throws NoSuchProviderException - on Error.
- * @throws NoSuchAlgorithmException - on Error.
- * @throws IOException - on Error.
- * @throws SCMSecurityException - on Error.
- * @throws CertificateException - on Error.
*/
@Test
- public void testWriteCertificate(@TempDir Path basePath)
- throws NoSuchProviderException, NoSuchAlgorithmException,
- IOException, SCMSecurityException, CertificateException {
- X509CertificateHolder cert =
- generateTestCert();
+ public void testWriteCertificate(@TempDir Path basePath) throws Exception {
+ X509Certificate cert = generateTestCert();
CertificateCodec codec = new CertificateCodec(securityConfig, COMPONENT);
String pemString = CertificateCodec.getPEMEncodedString(cert);
- codec.writeCertificate(basePath, "pemcertificate.crt",
- pemString);
- X509CertificateHolder certHolder =
- codec.getTargetCertHolder(basePath, "pemcertificate.crt");
- assertNotNull(certHolder);
- assertEquals(cert.getSerialNumber(),
- certHolder.getSerialNumber());
+ codec.writeCertificate(basePath, "pemcertificate.crt", pemString);
+
+ X509Certificate loadedCertificate = codec.getTargetCert(basePath,
"pemcertificate.crt");
+
+ assertNotNull(loadedCertificate);
+ assertEquals(cert.getSerialNumber(), loadedCertificate.getSerialNumber());
}
/**
* Tests reading and writing certificates in DER form.
- *
- * @throws IOException - on Error.
- * @throws SCMSecurityException - on Error.
- * @throws CertificateException - on Error.
- * @throws NoSuchProviderException - on Error.
- * @throws NoSuchAlgorithmException - on Error.
*/
@Test
- public void testWriteCertificateDefault()
- throws IOException, SCMSecurityException, CertificateException,
- NoSuchProviderException, NoSuchAlgorithmException {
- X509CertificateHolder cert = generateTestCert();
+ public void testWriteCertificateDefault() throws Exception {
+ X509Certificate cert = generateTestCert();
CertificateCodec codec = new CertificateCodec(securityConfig, COMPONENT);
codec.writeCertificate(cert);
- X509CertificateHolder certHolder = codec.getTargetCertHolder();
- assertNotNull(certHolder);
- assertEquals(cert.getSerialNumber(), certHolder.getSerialNumber());
+
+ X509Certificate loadedCertificate = codec.getTargetCert();
+
+ assertNotNull(loadedCertificate);
+ assertEquals(cert.getSerialNumber(), loadedCertificate.getSerialNumber());
}
/**
* Tests writing to non-default certificate file name.
- *
- * @throws IOException - on Error.
- * @throws SCMSecurityException - on Error.
- * @throws NoSuchProviderException - on Error.
- * @throws NoSuchAlgorithmException - on Error.
- * @throws CertificateException - on Error.
*/
@Test
- public void writeCertificate2() throws IOException, SCMSecurityException,
- NoSuchProviderException, NoSuchAlgorithmException, CertificateException {
- X509CertificateHolder cert = generateTestCert();
- CertificateCodec codec =
- new CertificateCodec(securityConfig, "ca");
+ public void writeCertificate2() throws Exception {
+ X509Certificate cert = generateTestCert();
+ CertificateCodec codec = new CertificateCodec(securityConfig, "ca");
codec.writeCertificate(cert, "newcert.crt");
// Rewrite with force support
codec.writeCertificate(cert, "newcert.crt");
- X509CertificateHolder x509CertificateHolder =
- codec.getTargetCertHolder(codec.getLocation(), "newcert.crt");
- assertNotNull(x509CertificateHolder);
+
+ X509Certificate loadedCertificate =
codec.getTargetCert(codec.getLocation(), "newcert.crt");
+
+ assertNotNull(loadedCertificate);
}
/**
* Tests writing a certificate path to file and reading back the
certificates.
- *
- * @throws IOException
- * @throws NoSuchAlgorithmException
- * @throws NoSuchProviderException
- * @throws CertificateException
*/
@Test
- public void testMultipleCertReadWrite() throws IOException,
- NoSuchAlgorithmException, NoSuchProviderException, CertificateException {
+ public void testMultipleCertReadWrite() throws Exception {
//Given a certificate path of one certificate and another certificate
- X509CertificateHolder certToPrepend =
- generateTestCert();
-
- X509CertificateHolder initialCert =
- generateTestCert();
+ X509Certificate certToPrepend = generateTestCert();
+ X509Certificate initialCert = generateTestCert();
assertNotEquals(certToPrepend, initialCert);
- CertificateFactory certificateFactory = new CertificateFactory();
- CertPath certPath =
- certificateFactory.engineGenerateCertPath(
-
ImmutableList.of(CertificateCodec.getX509Certificate(initialCert)));
+ CertificateFactory certificateFactory =
CertificateFactory.getInstance("X.509");
+ CertPath certPath =
certificateFactory.generateCertPath(ImmutableList.of(initialCert));
//When prepending the second one before the first one and reading them back
- CertificateCodec codec =
- new CertificateCodec(securityConfig, "ca");
-
- CertPath updatedCertPath =
- codec.prependCertToCertPath(certToPrepend, certPath);
+ CertificateCodec codec = new CertificateCodec(securityConfig, "ca");
+ CertPath updatedCertPath = codec.prependCertToCertPath(certToPrepend,
certPath);
String certFileName = "newcert.crt";
- String pemEncodedStrings =
- CertificateCodec.getPEMEncodedString(updatedCertPath);
+ String pemEncodedStrings =
CertificateCodec.getPEMEncodedString(updatedCertPath);
codec.writeCertificate(certFileName, pemEncodedStrings);
- CertPath rereadCertPath =
- codec.getCertPath(certFileName);
+ CertPath rereadCertPath = codec.getCertPath(certFileName);
//Then the two certificates are the same as before
Certificate rereadPrependedCert = rereadCertPath.getCertificates().get(0);
Certificate rereadSecondCert = rereadCertPath.getCertificates().get(1);
- assertEquals(CertificateCodec.getCertificateHolder(
- (X509Certificate) rereadPrependedCert), certToPrepend);
- assertEquals(CertificateCodec.getCertificateHolder(
- (X509Certificate) rereadSecondCert), initialCert);
+ assertEquals(rereadPrependedCert, certToPrepend);
+ assertEquals(rereadSecondCert, initialCert);
}
- private X509CertificateHolder generateTestCert()
- throws IOException, NoSuchProviderException, NoSuchAlgorithmException {
+ private X509Certificate generateTestCert() throws Exception {
HDDSKeyGenerator keyGenerator =
new HDDSKeyGenerator(securityConfig);
LocalDateTime startDate = LocalDateTime.now();
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/TestRootCertificate.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/TestRootCertificate.java
index bba36fad81..992ed17926 100644
---
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/TestRootCertificate.java
+++
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/TestRootCertificate.java
@@ -23,9 +23,6 @@ import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.security.exception.SCMSecurityException;
import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.security.x509.keys.HDDSKeyGenerator;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -45,8 +42,8 @@ import java.util.UUID;
import static org.apache.hadoop.hdds.HddsConfigKeys.OZONE_METADATA_DIRS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@@ -55,6 +52,8 @@ import static org.junit.jupiter.api.Assertions.fail;
* Test Class for Root Certificate generation.
*/
public class TestRootCertificate {
+ private static final String BASIC_CONSTRAINTS_EXTENSION_OID = "2.5.29.19";
+
private SecurityConfig securityConfig;
@BeforeEach
@@ -85,39 +84,34 @@ public class TestRootCertificate {
.setKey(keyPair)
.setConfiguration(securityConfig);
- X509CertificateHolder certificateHolder = builder.build();
+ X509Certificate certificate = builder.build();
- //Assert that we indeed have a self signed certificate.
- assertEquals(certificateHolder.getIssuer(),
- certificateHolder.getSubject());
+ //Assert that we indeed have a self-signed certificate.
+ assertEquals(certificate.getIssuerDN(), certificate.getSubjectDN());
// Make sure that NotBefore is before the current Date
Date invalidDate = Date.from(
notBefore.minusDays(1).atZone(ZoneId.systemDefault()).toInstant());
- assertFalse(certificateHolder.getNotBefore().before(invalidDate));
+ assertFalse(certificate.getNotBefore().before(invalidDate));
//Make sure the end date is honored.
invalidDate = Date.from(
notAfter.plusDays(1).atZone(ZoneId.systemDefault()).toInstant());
- assertFalse(certificateHolder.getNotAfter().after(invalidDate));
+ assertFalse(certificate.getNotAfter().after(invalidDate));
// Check the Subject Name and Issuer Name is in the expected format.
- String dnName = String.format(SelfSignedCertificate.getNameFormat(),
- subject, scmID, clusterID, certificateHolder.getSerialNumber());
- assertEquals(dnName, certificateHolder.getIssuer().toString());
- assertEquals(dnName, certificateHolder.getSubject().toString());
-
- // We did not ask for this Certificate to be a CertificateServer
- // certificate, hence that
- // extension should be null.
- assertNull(certificateHolder.getExtension(Extension.basicConstraints));
-
- // Extract the Certificate and verify that certificate matches the public
- // key.
- X509Certificate cert =
- new JcaX509CertificateConverter().getCertificate(certificateHolder);
- cert.verify(keyPair.getPublic());
+ // Note that the X500Principal class correctly applies RFC-4512 on
distinguished names, and returns the RDNs in
+ // reverse order as defined in 2.1 in RFC-4512.
+ String dnName = String.format("SERIALNUMBER=%s, O=%s, OU=%s, CN=%s",
+ certificate.getSerialNumber(), clusterID, scmID, subject);
+ assertEquals(dnName, certificate.getIssuerDN().toString());
+ assertEquals(dnName, certificate.getSubjectDN().toString());
+
+ assertEquals(-1, certificate.getBasicConstraints(), "Non-CA cert contains
the CA flag in BasicConstraints.");
+
+ // Extract the Certificate and verify that certificate matches the public
key.
+ certificate.verify(keyPair.getPublic());
}
@Test
@@ -131,7 +125,7 @@ public class TestRootCertificate {
new HDDSKeyGenerator(securityConfig);
KeyPair keyPair = keyGen.generateKey();
- X509CertificateHolder certificateHolder =
+ X509Certificate certificate =
SelfSignedCertificate.newBuilder()
.setBeginDate(notBefore)
.setEndDate(notAfter)
@@ -144,29 +138,22 @@ public class TestRootCertificate {
.addInetAddresses()
.build();
- // This time we asked for a CertificateServer Certificate, make sure that
- // extension is
- // present and valid.
- Extension basicExt =
- certificateHolder.getExtension(Extension.basicConstraints);
-
- assertNotNull(basicExt);
- assertTrue(basicExt.isCritical());
+ assertNotEquals(-1, certificate.getBasicConstraints(), "CA cert does not
contain the CA flag in BasicConstraints.");
+
assertTrue(certificate.getCriticalExtensionOIDs().contains(BASIC_CONSTRAINTS_EXTENSION_OID));
// Since this code assigns ONE for the root certificate, we check if the
// serial number is the expected number.
- assertEquals(BigInteger.ONE, certificateHolder.getSerialNumber());
+ assertEquals(BigInteger.ONE, certificate.getSerialNumber());
CertificateCodec codec = new CertificateCodec(securityConfig, "scm");
- String pemString = CertificateCodec.getPEMEncodedString(certificateHolder);
+ String pemString = CertificateCodec.getPEMEncodedString(certificate);
codec.writeCertificate(basePath, "pemcertificate.crt",
pemString);
- X509CertificateHolder loadedCert =
- codec.getTargetCertHolder(basePath, "pemcertificate.crt");
+ X509Certificate loadedCert = codec.getTargetCert(basePath,
"pemcertificate.crt");
assertNotNull(loadedCert);
- assertEquals(certificateHolder.getSerialNumber(),
+ assertEquals(certificate.getSerialNumber(),
loadedCert.getSerialNumber());
}
@@ -234,9 +221,7 @@ public class TestRootCertificate {
KeyPair newKey = keyGen.generateKey();
KeyPair wrongKey = new KeyPair(newKey.getPublic(), keyPair.getPrivate());
builder.setKey(wrongKey);
- X509CertificateHolder certificateHolder = builder.build();
- X509Certificate cert =
- new JcaX509CertificateConverter().getCertificate(certificateHolder);
+ X509Certificate cert = builder.build();
cert.verify(wrongKey.getPublic());
fail("Invalid Key, should have thrown.");
} catch (SCMSecurityException | CertificateException
diff --git
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/security/RootCARotationManager.java
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/security/RootCARotationManager.java
index 8c1f7e22bf..c88abb5b8d 100644
---
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/security/RootCARotationManager.java
+++
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/security/RootCARotationManager.java
@@ -41,7 +41,6 @@ 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.keys.HDDSKeyGenerator;
import org.apache.hadoop.hdds.security.x509.keys.KeyCodec;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -405,7 +404,7 @@ public class RootCARotationManager extends StatefulService {
}
String newRootCertId = "";
- X509CertificateHolder newRootCertificate;
+ X509Certificate newRootCertificate;
try {
// prevent findbugs false alert
if (newRootCAServer == null) {
@@ -650,12 +649,11 @@ public class RootCARotationManager extends
StatefulService {
*/
public class WaitSubCARotationPrepareAckTask implements Runnable {
private String rootCACertId;
- private X509CertificateHolder rootCACertHolder;
+ private X509Certificate rootCACertificate;
- public WaitSubCARotationPrepareAckTask(
- X509CertificateHolder rootCertHolder) {
- this.rootCACertHolder = rootCertHolder;
- this.rootCACertId = rootCertHolder.getSerialNumber().toString();
+ public WaitSubCARotationPrepareAckTask(X509Certificate rootCACertificate) {
+ this.rootCACertificate = rootCACertificate;
+ this.rootCACertId = rootCACertificate.getSerialNumber().toString();
}
@Override
@@ -687,20 +685,16 @@ public class RootCARotationManager extends
StatefulService {
metrics.setSuccessTimeInNs(timeTaken);
processStartTime.set(null);
- // save root certificate to certStore
- X509Certificate rootCACert = null;
try {
if (scm.getCertificateStore().getCertificateByID(
- rootCACertHolder.getSerialNumber()) == null) {
+ rootCACertificate.getSerialNumber()) == null) {
LOG.info("Persist root certificate {} to cert store",
rootCACertId);
- rootCACert =
- CertificateCodec.getX509Certificate(rootCACertHolder);
scm.getCertificateStore().storeValidCertificate(
- rootCACertHolder.getSerialNumber(), rootCACert,
+ rootCACertificate.getSerialNumber(), rootCACertificate,
HddsProtos.NodeType.SCM);
}
- } catch (CertificateException | IOException e) {
+ } catch (IOException e) {
LOG.error("Failed to save root certificate {} to cert store",
rootCACertId);
scm.shutDown("Failed to save root certificate to cert store");
@@ -716,12 +710,13 @@ public class RootCARotationManager extends
StatefulService {
// signing in this period.
enterPostProcessing(rootCertPollInterval.toMillis());
// save the new root certificate to rocksdb through ratis
- if (rootCACert != null) {
- saveConfiguration(new CertInfo.Builder()
- .setX509Certificate(rootCACert)
- .setTimestamp(rootCACert.getNotBefore().getTime())
- .build().getProtobuf());
- }
+ saveConfiguration(
+ new CertInfo.Builder()
+ .setX509Certificate(rootCACertificate)
+ .setTimestamp(rootCACertificate.getNotBefore().getTime())
+ .build()
+ .getProtobuf()
+ );
} catch (Throwable e) {
LOG.error("Execution error", e);
handler.resetRotationPrepareAcks();
diff --git
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/ha/io/TestX509CertificateCodec.java
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/ha/io/TestX509CertificateCodec.java
index 952984db7b..3f9a6ca48f 100644
---
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/ha/io/TestX509CertificateCodec.java
+++
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/ha/io/TestX509CertificateCodec.java
@@ -20,7 +20,10 @@ package org.apache.hadoop.hdds.scm.ha.io;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Proto2Utils;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.security.KeyPair;
@@ -35,6 +38,11 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
*/
public class TestX509CertificateCodec {
+ @BeforeAll
+ public static void initSecurityProvider() {
+ SecurityConfig.initSecurityProvider(new OzoneConfiguration());
+ }
+
@Test
public void codec() throws Exception {
KeyPair keyPair = KeyStoreTestUtil.generateKeyPair("RSA");
diff --git
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/metadata/TestX509CertificateCodec.java
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/metadata/TestX509CertificateCodec.java
index 035138fb2b..aa9a9c3074 100644
---
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/metadata/TestX509CertificateCodec.java
+++
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/metadata/TestX509CertificateCodec.java
@@ -17,10 +17,13 @@
package org.apache.hadoop.hdds.scm.metadata;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
import org.apache.hadoop.hdds.utils.db.Codec;
import org.apache.hadoop.hdds.utils.db.CodecTestUtil;
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -52,6 +55,11 @@ public class TestX509CertificateCodec {
return keyGen.genKeyPair();
}
+ @BeforeAll
+ public static void initSecurityConfig() {
+ SecurityConfig.initSecurityProvider(new OzoneConfiguration());
+ }
+
@Test
public void testRSA() throws Exception {
for (int n = 512; n <= 4096; n <<= 1) {
diff --git
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/security/TestRootCARotationManager.java
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/security/TestRootCARotationManager.java
index b82ce15a38..5b4ed0c286 100644
---
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/security/TestRootCARotationManager.java
+++
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/security/TestRootCARotationManager.java
@@ -35,7 +35,6 @@ import
org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
import
org.apache.hadoop.hdds.security.x509.certificate.utils.SelfSignedCertificate;
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
import org.apache.ozone.test.GenericTestUtils;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -260,7 +259,7 @@ public class TestRootCARotationManager {
scmCertClient.setCACertificate(cert);
CertificateCodec certCodec = new CertificateCodec(securityConfig,
"scm/sub-ca");
- certCodec.writeCertificate(CertificateCodec.getCertificateHolder(cert));
+ certCodec.writeCertificate(cert);
rootCARotationManager = new RootCARotationManager(scm);
rootCARotationManager.setRootCARotationHandler(handler);
GenericTestUtils.LogCapturer logs =
@@ -316,7 +315,7 @@ public class TestRootCARotationManager {
KeyPair keyPair = KeyStoreTestUtil.generateKeyPair("RSA");
LocalDateTime start = startDate == null ? LocalDateTime.now() : startDate;
LocalDateTime end = start.plus(certLifetime);
- return new JcaX509CertificateConverter().getCertificate(
+ return
SelfSignedCertificate.newBuilder()
.setBeginDate(start)
.setEndDate(end)
@@ -326,6 +325,6 @@ public class TestRootCARotationManager {
.setConfiguration(new SecurityConfig(conf))
.setKey(keyPair)
.makeCA(certID)
- .build());
+ .build();
}
}
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java
index f099fd3a92..2b29701cf7 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java
@@ -37,6 +37,8 @@ import java.util.List;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.Callable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.commons.validator.routines.DomainValidator;
import org.apache.hadoop.hdds.HddsConfigKeys;
@@ -68,7 +70,6 @@ import
org.apache.hadoop.hdds.security.x509.certificate.authority.DefaultApprove
import
org.apache.hadoop.hdds.security.x509.certificate.authority.profile.DefaultProfile;
import
org.apache.hadoop.hdds.security.x509.certificate.client.CertificateClient;
import
org.apache.hadoop.hdds.security.x509.certificate.client.CertificateClientTestImpl;
-import
org.apache.hadoop.hdds.security.x509.certificate.client.DNCertificateClient;
import
org.apache.hadoop.hdds.security.x509.certificate.client.DefaultCertificateClient;
import org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
import
org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateSignRequest;
@@ -106,6 +107,7 @@ import org.apache.hadoop.security.UserGroupInformation;
import
org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
import org.apache.hadoop.security.token.Token;
+import org.apache.hadoop.util.ExitUtil;
import org.apache.ozone.test.GenericTestUtils;
import org.apache.ozone.test.GenericTestUtils.LogCapturer;
@@ -132,6 +134,7 @@ import static
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_RATIS_PORT_KEY;
import static
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_SECURITY_SERVICE_PORT_KEY;
import static
org.apache.hadoop.hdds.scm.server.SCMHTTPServerConfig.ConfigStrings.HDDS_SCM_HTTP_KERBEROS_KEYTAB_FILE_KEY;
import static
org.apache.hadoop.hdds.scm.server.SCMHTTPServerConfig.ConfigStrings.HDDS_SCM_HTTP_KERBEROS_PRINCIPAL_KEY;
+import static
org.apache.hadoop.hdds.security.x509.exception.CertificateException.ErrorCode.ROLLBACK_ERROR;
import static org.apache.hadoop.hdds.utils.HddsServerUtil.getScmSecurityClient;
import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ADMINISTRATORS;
import static
org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_CLIENT_FAILOVER_MAX_ATTEMPTS_KEY;
@@ -154,11 +157,6 @@ import org.apache.ozone.test.tag.Flaky;
import org.apache.ozone.test.tag.Unhealthy;
import org.apache.ratis.protocol.ClientId;
import org.apache.ratis.util.ExitUtils;
-import org.bouncycastle.asn1.x500.RDN;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x500.style.BCStyle;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -964,24 +962,23 @@ final class TestSecureOzoneCluster {
final int certificateLifetime = 20; // seconds
KeyCodec keyCodec =
new KeyCodec(securityConfig, securityConfig.getKeyLocation("om"));
- X509CertificateHolder certHolder = generateX509CertHolder(securityConfig,
+ X509Certificate cert = generateSelfSignedX509Cert(securityConfig,
new KeyPair(keyCodec.readPublicKey(), keyCodec.readPrivateKey()),
null, Duration.ofSeconds(certificateLifetime));
- String certId = certHolder.getSerialNumber().toString();
+ String certId = cert.getSerialNumber().toString();
omStorage.setOmCertSerialId(certId);
omStorage.forceInitialize();
CertificateCodec certCodec = new CertificateCodec(securityConfig, "om");
- certCodec.writeCertificate(certHolder);
- String caCertFileName = CAType.ROOT.getFileNamePrefix()
- + certHolder.getSerialNumber().toString() + ".crt";
- certCodec.writeCertificate(certHolder, caCertFileName);
+ certCodec.writeCertificate(cert);
+ String caCertFileName = CAType.ROOT.getFileNamePrefix() +
cert.getSerialNumber().toString() + ".crt";
+ certCodec.writeCertificate(cert, caCertFileName);
// first renewed cert
- X509CertificateHolder newCertHolder =
- generateX509CertHolder(securityConfig, null,
+ X509Certificate newCert =
+ generateSelfSignedX509Cert(securityConfig, null,
LocalDateTime.now().plus(securityConfig.getRenewalGracePeriod()),
Duration.ofSeconds(certificateLifetime));
- String pemCert = CertificateCodec.getPEMEncodedString(newCertHolder);
+ String pemCert = CertificateCodec.getPEMEncodedString(newCert);
SCMGetCertResponseProto responseProto =
SCMGetCertResponseProto.newBuilder()
.setResponseCode(SCMSecurityProtocolProtos
@@ -1005,16 +1002,15 @@ final class TestSecureOzoneCluster {
om.setCertClient(client);
// check after renew, client will have the new cert ID
- String id1 = newCertHolder.getSerialNumber().toString();
+ String id1 = newCert.getSerialNumber().toString();
GenericTestUtils.waitFor(() ->
id1.equals(client.getCertificate().getSerialNumber().toString()),
1000, certificateLifetime * 1000);
// test the second time certificate rotation
// second renewed cert
- newCertHolder = generateX509CertHolder(securityConfig,
- null, null, Duration.ofSeconds(certificateLifetime));
- pemCert = CertificateCodec.getPEMEncodedString(newCertHolder);
+ newCert = generateSelfSignedX509Cert(securityConfig, null, null,
Duration.ofSeconds(certificateLifetime));
+ pemCert = CertificateCodec.getPEMEncodedString(newCert);
responseProto = SCMGetCertResponseProto.newBuilder()
.setResponseCode(SCMSecurityProtocolProtos
.SCMGetCertResponseProto.ResponseCode.success)
@@ -1023,7 +1019,7 @@ final class TestSecureOzoneCluster {
.build();
when(scmClient.getOMCertChain(any(), anyString()))
.thenReturn(responseProto);
- String id2 = newCertHolder.getSerialNumber().toString();
+ String id2 = newCert.getSerialNumber().toString();
// check after renew, client will have the new cert ID
GenericTestUtils.waitFor(() ->
@@ -1049,7 +1045,7 @@ final class TestSecureOzoneCluster {
final int certificateLifetime = 20; // seconds
KeyCodec keyCodec =
new KeyCodec(securityConfig, securityConfig.getKeyLocation("om"));
- X509CertificateHolder certHolder = generateX509CertHolder(securityConfig,
+ X509Certificate certHolder = generateSelfSignedX509Cert(securityConfig,
new KeyPair(keyCodec.readPublicKey(), keyCodec.readPrivateKey()),
null, Duration.ofSeconds(certificateLifetime));
String certId = certHolder.getSerialNumber().toString();
@@ -1062,7 +1058,7 @@ final class TestSecureOzoneCluster {
mock(SCMSecurityProtocolClientSideTranslatorPB.class);
Duration gracePeriod = securityConfig.getRenewalGracePeriod();
- X509CertificateHolder newCertHolder = generateX509CertHolder(
+ X509Certificate newCertHolder = generateSelfSignedX509Cert(
securityConfig, null,
LocalDateTime.now().plus(gracePeriod),
Duration.ofSeconds(certificateLifetime));
@@ -1100,7 +1096,7 @@ final class TestSecureOzoneCluster {
.contains("Error while signing and storing SCM signed certificate.");
// provide a new valid SCMGetCertResponseProto
- newCertHolder = generateX509CertHolder(securityConfig, null, null,
+ newCertHolder = generateSelfSignedX509Cert(securityConfig, null, null,
Duration.ofSeconds(certificateLifetime));
pemCert = CertificateCodec.getPEMEncodedString(newCertHolder);
responseProto = SCMSecurityProtocolProtos.SCMGetCertResponseProto
@@ -1125,9 +1121,13 @@ final class TestSecureOzoneCluster {
* Test the directory rollback failure case.
*/
@Test
- @Unhealthy("Run it locally since it will terminate the process.")
void testCertificateRotationUnRecoverableFailure() throws Exception {
- LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
+ ExitUtils.disableSystemExit();
+ ExitUtil.disableSystemExit();
+ LogCapturer certClientLogs =
LogCapturer.captureLogs(OMCertificateClient.LOG);
+ LogCapturer exitUtilLog =
LogCapturer.captureLogs(LoggerFactory.getLogger(ExitUtil.class));
+
+
OMStorage omStorage = new OMStorage(conf);
omStorage.setClusterId(clusterId);
omStorage.setOmId(omId);
@@ -1136,44 +1136,48 @@ final class TestSecureOzoneCluster {
SecurityConfig securityConfig = new SecurityConfig(conf);
CertificateCodec certCodec = new CertificateCodec(securityConfig, "om");
try (OMCertificateClient client =
- new OMCertificateClient(
- securityConfig, null, omStorage, omInfo, "", scmId, null, null)
+ new OMCertificateClient(securityConfig, null, omStorage, omInfo,
"", scmId, null, null)
) {
client.init();
// save first cert
final int certificateLifetime = 20; // seconds
- X509CertificateHolder certHolder = generateX509CertHolder(securityConfig,
- new KeyPair(client.getPublicKey(), client.getPrivateKey()),
- null, Duration.ofSeconds(certificateLifetime));
- String certId = certHolder.getSerialNumber().toString();
- certCodec.writeCertificate(certHolder);
+ KeyPair newKeyPair = new KeyPair(client.getPublicKey(),
client.getPrivateKey());
+ X509Certificate newCert =
+ generateSelfSignedX509Cert(securityConfig, newKeyPair, null,
Duration.ofSeconds(certificateLifetime));
+ String certId = newCert.getSerialNumber().toString();
+ certCodec.writeCertificate(newCert);
omStorage.setOmCertSerialId(certId);
omStorage.forceInitialize();
- // second cert as renew response
- X509CertificateHolder newCertHolder = generateX509CertHolder(
- securityConfig, null,
- null, Duration.ofSeconds(certificateLifetime));
- DNCertificateClient mockClient = mock(DNCertificateClient.class);
- when(mockClient.getCertificate()).thenReturn(
- CertificateCodec.getX509Certificate(newCertHolder));
- when(mockClient.timeBeforeExpiryGracePeriod(any()))
- .thenReturn(Duration.ZERO);
- when(mockClient.renewAndStoreKeyAndCertificate(any())).thenThrow(
- new CertificateException("renewAndStoreKeyAndCert failed ",
- CertificateException.ErrorCode.ROLLBACK_ERROR));
-
// create Ozone Manager instance, it will start the monitor task
conf.set(OZONE_SCM_CLIENT_ADDRESS_KEY, "localhost");
om = OzoneManager.createOm(conf);
+ om.getCertificateClient().close();
om.setScmTopologyClient(new ScmTopologyClient(scmBlockClient));
+
+ OMCertificateClient mockClient = new OMCertificateClient(securityConfig,
null, omStorage, omInfo,
+ om.getOMServiceId(), scmId, null, om::terminateOM) {
+
+ @Override
+ public Duration timeBeforeExpiryGracePeriod(X509Certificate
certificate) {
+ return Duration.ZERO;
+ }
+
+ @Override
+ public String renewAndStoreKeyAndCertificate(boolean force) throws
CertificateException {
+ throw new CertificateException("renewAndStoreKeyAndCert failed",
ROLLBACK_ERROR);
+ }
+ };
om.setCertClient(mockClient);
// check error message during renew
- GenericTestUtils.waitFor(() -> omLogs.getOutput().contains(
- "OzoneManage shutdown because certificate rollback failure."),
+ GenericTestUtils.waitFor(() ->
+ certClientLogs.getOutput().contains("Failed to rollback key and
cert after an unsuccessful renew try."),
1000, certificateLifetime * 1000);
+
+ GenericTestUtils.waitFor(() -> exitUtilLog.getOutput().contains("Exiting
with status 1: ExitException"),
+ 100, 5000);
}
}
@@ -1267,6 +1271,7 @@ final class TestSecureOzoneCluster {
void testOMGrpcServerCertificateRenew() throws Exception {
initSCM();
try {
+ OzoneManager.setTestSecureOmFlag(false);
scm = HddsTestUtils.getScmSimple(conf);
scm.start();
@@ -1287,42 +1292,34 @@ final class TestSecureOzoneCluster {
CertificateCodec certCodec = new CertificateCodec(securityConfig, "om");
X509Certificate scmCert = scmCertClient.getCertificate();
X509Certificate rootCert = scmCertClient.getCACertificate();
- X509CertificateHolder certHolder =
- generateX509CertHolder(securityConfig, keyPair,
- new KeyPair(scmCertClient.getPublicKey(),
- scmCertClient.getPrivateKey()),
- scmCert, "om_cert", clusterId);
- String certId = certHolder.getSerialNumber().toString();
- certCodec.writeCertificate(certHolder);
-
certCodec.writeCertificate(CertificateCodec.getCertificateHolder(scmCert),
+ X509Certificate cert = signX509Cert(securityConfig, keyPair, new
KeyPair(scmCertClient.getPublicKey(),
+ scmCertClient.getPrivateKey()), scmCert, "om_cert", clusterId);
+ String certId = cert.getSerialNumber().toString();
+ certCodec.writeCertificate(cert);
+ certCodec.writeCertificate(scmCert,
String.format(DefaultCertificateClient.CERT_FILE_NAME_FORMAT,
+ CAType.SUBORDINATE.getFileNamePrefix() +
scmCert.getSerialNumber().toString()));
+ certCodec.writeCertificate(scmCertClient.getCACertificate(),
String.format(DefaultCertificateClient.CERT_FILE_NAME_FORMAT,
- CAType.SUBORDINATE.getFileNamePrefix() +
- scmCert.getSerialNumber().toString()));
- certCodec.writeCertificate(CertificateCodec.getCertificateHolder(
- scmCertClient.getCACertificate()),
- String.format(DefaultCertificateClient.CERT_FILE_NAME_FORMAT,
- CAType.ROOT.getFileNamePrefix() +
- rootCert.getSerialNumber().toString()));
+ CAType.ROOT.getFileNamePrefix() +
rootCert.getSerialNumber().toString()));
omStore.setOmCertSerialId(certId);
omStore.initialize();
conf.setBoolean(HDDS_GRPC_TLS_ENABLED, true);
conf.setBoolean(OZONE_OM_S3_GPRC_SERVER_ENABLED, true);
conf.setBoolean(HddsConfigKeys.HDDS_GRPC_TLS_TEST_CERT, true);
- OzoneManager.setTestSecureOmFlag(true);
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
- // In this process, SCM has already login using Kerberos. So pass
+ // In this process, SCM has already logged in using Kerberos. So pass a
// specific UGI to DefaultCertificateClient and OzoneManager to avoid
- // conflict with SCM procedure.
+ // conflict with SCM.
OzoneManager.setUgi(ugi);
om = OzoneManager.createOm(conf);
om.start();
CertificateClient omCertClient = om.getCertificateClient();
X509Certificate omCert = omCertClient.getCertificate();
- X509Certificate caCert = omCertClient.getCACertificate();
+ X509Certificate caCert = omCertClient.getRootCACertificate();
X509Certificate rootCaCert = omCertClient.getRootCACertificate();
- List certList = new ArrayList<>();
+ List<X509Certificate> certList = new ArrayList<>();
certList.add(caCert);
certList.add(rootCaCert);
// set certificates in GrpcOmTransport
@@ -1367,16 +1364,17 @@ final class TestSecureOzoneCluster {
}
void validateCertificate(X509Certificate cert) throws Exception {
-
- // Assert that we indeed have a self signed certificate.
- X500Name x500Issuer = new JcaX509CertificateHolder(cert).getIssuer();
- RDN cn = x500Issuer.getRDNs(BCStyle.CN)[0];
+ Matcher m =
Pattern.compile(".*CN=([^,]*).*").matcher(cert.getIssuerDN().getName());
+ String cn = "";
+ if (m.matches()) {
+ cn = m.group(1);
+ }
String hostName = InetAddress.getLocalHost().getHostName();
// Subject name should be om login user in real world but in this test
// UGI has scm user context.
- assertThat(cn.getFirst().getValue().toString()).contains(SCM_SUB_CA);
- assertThat(cn.getFirst().getValue().toString()).contains(hostName);
+ assertThat(cn).contains(SCM_SUB_CA);
+ assertThat(cn).contains(hostName);
LocalDate today = LocalDateTime.now().toLocalDate();
Date invalidDate;
@@ -1391,8 +1389,6 @@ final class TestSecureOzoneCluster {
assertThat(cert.getSubjectDN().toString()).contains(scmId);
assertThat(cert.getSubjectDN().toString()).contains(clusterId);
- assertThat(cn.getFirst().getValue().toString()).contains(SCM_SUB_CA);
- assertThat(cn.getFirst().getValue().toString()).contains(hostName);
assertThat(cert.getIssuerDN().toString()).contains(scmId);
assertThat(cert.getIssuerDN().toString()).contains(clusterId);
@@ -1413,7 +1409,7 @@ final class TestSecureOzoneCluster {
omStorage.initialize();
}
- private static X509CertificateHolder generateX509CertHolder(
+ private static X509Certificate generateSelfSignedX509Cert(
SecurityConfig conf, KeyPair keyPair, LocalDateTime startDate,
Duration certLifetime) throws Exception {
if (keyPair == null) {
@@ -1432,7 +1428,7 @@ final class TestSecureOzoneCluster {
.build();
}
- private static X509CertificateHolder generateX509CertHolder(
+ private static X509Certificate signX509Cert(
SecurityConfig conf, KeyPair keyPair, KeyPair rootKeyPair,
X509Certificate rootCert, String subject, String clusterId
) throws Exception {
@@ -1453,15 +1449,12 @@ final class TestSecureOzoneCluster {
addIpAndDnsDataToBuilder(csrBuilder);
LocalDateTime start = LocalDateTime.now();
Duration certDuration = conf.getDefaultCertDuration();
- X509CertificateHolder certificateHolder =
- approver.sign(conf, rootKeyPair.getPrivate(),
- new X509CertificateHolder(rootCert.getEncoded()),
+ return approver.sign(conf, rootKeyPair.getPrivate(), rootCert,
Date.from(start.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(start.plus(certDuration)
.atZone(ZoneId.systemDefault()).toInstant()),
csrBuilder.build(), "test", clusterId,
String.valueOf(System.nanoTime()));
- return certificateHolder;
}
private static void addIpAndDnsDataToBuilder(
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestSecureOzoneManager.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestSecureOzoneManager.java
index 82d22d783f..0238b3e3ec 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestSecureOzoneManager.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestSecureOzoneManager.java
@@ -27,7 +27,6 @@ import
org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
import org.apache.hadoop.hdds.security.x509.keys.KeyCodec;
import org.apache.hadoop.ozone.security.OMCertificateClient;
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
@@ -153,8 +152,7 @@ class TestSecureOzoneManager {
X509Certificate x509Certificate = KeyStoreTestUtil.generateCertificate(
"CN=Test", new KeyPair(publicKey, privateKey), 365,
securityConfig.getSignatureAlgo());
- certCodec.writeCertificate(new X509CertificateHolder(
- x509Certificate.getEncoded()));
+ certCodec.writeCertificate(x509Certificate);
omStorage.setOmCertSerialId(x509Certificate.getSerialNumber().toString());
client =
new OMCertificateClient(
diff --git
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOmCertificateClientInit.java
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOmCertificateClientInit.java
index b8ecc4fd7e..a604ebbd72 100644
---
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOmCertificateClientInit.java
+++
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOmCertificateClientInit.java
@@ -29,7 +29,6 @@ import org.apache.hadoop.ozone.OzoneSecurityUtil;
import org.apache.hadoop.ozone.om.OMStorage;
import org.apache.hadoop.ozone.om.OzoneManager;
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
-import org.bouncycastle.cert.X509CertificateHolder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.io.TempDir;
@@ -138,8 +137,7 @@ public class TestOmCertificateClientInit {
if (certPresent) {
CertificateCodec codec = new CertificateCodec(securityConfig,
OM_COMPONENT);
- codec.writeCertificate(new X509CertificateHolder(
- x509Certificate.getEncoded()));
+ codec.writeCertificate(x509Certificate);
} else {
FileUtils.deleteQuietly(Paths.get(
securityConfig.getKeyLocation(OM_COMPONENT).toString(),
diff --git
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSecretManager.java
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSecretManager.java
index d9e9952b92..d94f59b8fb 100644
---
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSecretManager.java
+++
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSecretManager.java
@@ -26,6 +26,7 @@ import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertPath;
+import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
@@ -69,7 +70,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.apache.ratis.protocol.RaftPeerId;
-import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -143,10 +143,8 @@ public class TestOzoneDelegationTokenSecretManager {
private OMCertificateClient setupCertificateClient() throws Exception {
KeyPair keyPair = KeyStoreTestUtil.generateKeyPair("RSA");
CertificateFactory fact = CertificateCodec.getCertFactory();
- X509Certificate singleCert = KeyStoreTestUtil
- .generateCertificate("CN=OzoneMaster", keyPair, 30, "SHA256withRSA");
- CertPath certPath = fact.engineGenerateCertPath(
- ImmutableList.of(singleCert));
+ X509Certificate singleCert =
KeyStoreTestUtil.generateCertificate("CN=OzoneMaster", keyPair, 30,
"SHA256withRSA");
+ CertPath certPath = fact.generateCertPath(ImmutableList.of(singleCert));
OMStorage omStorage = mock(OMStorage.class);
when(omStorage.getOmCertSerialId()).thenReturn(null);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]