From 422cd870ebea0a84aa7fdff2fa5a37190cb9d43a Mon Sep 17 00:00:00 2001 From: Duo Zhang Date: Mon, 29 Jun 2026 22:13:10 +0800 Subject: [PATCH] HBASE-30260 Polish X509TestContext to make it more stable (#8426) Signed-off-by: Xiao Liu (cherry picked from commit 3c446d70274bf9594b415198d6061fa48168ef74) --- .../tls/AbstractTestX509Parameterized.java | 3 +- .../io/crypto/tls/TestBCFKSFileLoader.java | 12 +- .../io/crypto/tls/TestJKSFileLoader.java | 10 +- .../io/crypto/tls/TestPEMFileLoader.java | 8 +- .../io/crypto/tls/TestPKCS12FileLoader.java | 10 +- .../hbase/io/crypto/tls/X509TestContext.java | 156 ++++++------------ .../hbase/io/crypto/tls/X509TestHelpers.java | 9 +- .../hadoop/hbase/ipc/TestNettyTlsIPC.java | 2 +- .../hbase/security/AbstractTestMutualTls.java | 7 +- .../security/TestMutualTlsClientSide.java | 6 +- .../TestMutualTlsClientSideNonLocalhost.java | 5 +- .../security/TestMutualTlsServerSide.java | 6 +- .../security/TestNettyTLSIPCFileWatcher.java | 11 +- 13 files changed, 89 insertions(+), 156 deletions(-) diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/AbstractTestX509Parameterized.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/AbstractTestX509Parameterized.java index a549e8322829..7e8fcb1c65d7 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/AbstractTestX509Parameterized.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/AbstractTestX509Parameterized.java @@ -18,7 +18,6 @@ package org.apache.hadoop.hbase.io.crypto.tls; import java.io.File; -import java.io.IOException; import java.security.Security; import java.util.ArrayList; import java.util.List; @@ -104,7 +103,7 @@ public static void cleanUpBaseClass() { } @BeforeEach - public void setUp() throws IOException { + public void setUp() throws Exception { x509TestContext = PROVIDER.get(caKeyType, certKeyType, keyPassword); x509TestContext.setConfigurations(KeyStoreFileType.JKS, KeyStoreFileType.JKS); conf = new Configuration(UTIL.getConfiguration()); diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestBCFKSFileLoader.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestBCFKSFileLoader.java index 645d5e2c7ea5..dabf1755edee 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestBCFKSFileLoader.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestBCFKSFileLoader.java @@ -52,7 +52,7 @@ public void testLoadKeyStore() throws Exception { } @TestTemplate - public void testLoadKeyStoreWithWrongPassword() throws IOException { + public void testLoadKeyStoreWithWrongPassword() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.BCFKS).getAbsolutePath(); assertThrows(IOException.class, () -> { new BCFKSFileLoader.Builder().setKeyStorePath(path) @@ -61,7 +61,7 @@ public void testLoadKeyStoreWithWrongPassword() throws IOException { } @TestTemplate - public void testLoadKeyStoreWithWrongFilePath() throws IOException { + public void testLoadKeyStoreWithWrongFilePath() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.BCFKS).getAbsolutePath(); assertThrows(IOException.class, () -> { new BCFKSFileLoader.Builder().setKeyStorePath(path + ".does_not_exist") @@ -78,7 +78,7 @@ public void testLoadKeyStoreWithNullFilePath() { } @TestTemplate - public void testLoadKeyStoreWithWrongFileType() throws IOException { + public void testLoadKeyStoreWithWrongFileType() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.PEM).getAbsolutePath(); assertThrows(IOException.class, () -> { // Trying to load a PEM file with BCFKS loader should fail @@ -96,7 +96,7 @@ public void testLoadTrustStore() throws Exception { } @TestTemplate - public void testLoadTrustStoreWithWrongPassword() throws IOException { + public void testLoadTrustStoreWithWrongPassword() throws Exception { String path = x509TestContext.getTrustStoreFile(KeyStoreFileType.BCFKS).getAbsolutePath(); assertThrows(IOException.class, () -> { @@ -106,7 +106,7 @@ public void testLoadTrustStoreWithWrongPassword() throws IOException { } @TestTemplate - public void testLoadTrustStoreWithWrongFilePath() throws IOException { + public void testLoadTrustStoreWithWrongFilePath() throws Exception { String path = x509TestContext.getTrustStoreFile(KeyStoreFileType.BCFKS).getAbsolutePath(); assertThrows(IOException.class, () -> { new BCFKSFileLoader.Builder().setTrustStorePath(path + ".does_not_exist") @@ -123,7 +123,7 @@ public void testLoadTrustStoreWithNullFilePath() { } @TestTemplate - public void testLoadTrustStoreWithWrongFileType() throws IOException { + public void testLoadTrustStoreWithWrongFileType() throws Exception { String path = x509TestContext.getTrustStoreFile(KeyStoreFileType.PEM).getAbsolutePath(); assertThrows(IOException.class, () -> { // Trying to load a PEM file with BCFKS loader should fail diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestJKSFileLoader.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestJKSFileLoader.java index 51867524c1d7..9fa3a14293af 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestJKSFileLoader.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestJKSFileLoader.java @@ -52,7 +52,7 @@ public void testLoadKeyStore() throws Exception { } @TestTemplate - public void testLoadKeyStoreWithWrongPassword() throws IOException { + public void testLoadKeyStoreWithWrongPassword() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.JKS).getAbsolutePath(); assertThrows(IOException.class, () -> { new JKSFileLoader.Builder().setKeyStorePath(path) @@ -61,7 +61,7 @@ public void testLoadKeyStoreWithWrongPassword() throws IOException { } @TestTemplate - public void testLoadKeyStoreWithWrongFilePath() throws IOException { + public void testLoadKeyStoreWithWrongFilePath() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.JKS).getAbsolutePath(); assertThrows(IOException.class, () -> { new JKSFileLoader.Builder().setKeyStorePath(path + ".does_not_exist") @@ -78,7 +78,7 @@ public void testLoadKeyStoreWithNullFilePath() { } @TestTemplate - public void testLoadKeyStoreWithWrongFileType() throws IOException { + public void testLoadKeyStoreWithWrongFileType() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.PEM).getAbsolutePath(); assertThrows(IOException.class, () -> { // Trying to load a PEM file with JKS loader should fail @@ -96,7 +96,7 @@ public void testLoadTrustStore() throws Exception { } @TestTemplate - public void testLoadTrustStoreWithWrongPassword() throws IOException { + public void testLoadTrustStoreWithWrongPassword() throws Exception { String path = x509TestContext.getTrustStoreFile(KeyStoreFileType.JKS).getAbsolutePath(); assertThrows(IOException.class, () -> { new JKSFileLoader.Builder().setTrustStorePath(path) @@ -105,7 +105,7 @@ public void testLoadTrustStoreWithWrongPassword() throws IOException { } @TestTemplate - public void testLoadTrustStoreWithWrongFilePath() throws IOException { + public void testLoadTrustStoreWithWrongFilePath() throws Exception { String path = x509TestContext.getTrustStoreFile(KeyStoreFileType.JKS).getAbsolutePath(); assertThrows(IOException.class, () -> { new JKSFileLoader.Builder().setTrustStorePath(path + ".does_not_exist") diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestPEMFileLoader.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestPEMFileLoader.java index 86a90cb40b33..be4bb3e5862b 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestPEMFileLoader.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestPEMFileLoader.java @@ -53,7 +53,7 @@ public void testLoadKeyStore() throws Exception { } @TestTemplate - public void testLoadKeyStoreWithWrongPassword() throws IOException { + public void testLoadKeyStoreWithWrongPassword() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.PEM).getAbsolutePath(); assertThrows(Exception.class, () -> { new PEMFileLoader.Builder().setKeyStorePath(path) @@ -62,7 +62,7 @@ public void testLoadKeyStoreWithWrongPassword() throws IOException { } @TestTemplate - public void testLoadKeyStoreWithWrongFilePath() throws IOException { + public void testLoadKeyStoreWithWrongFilePath() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.PEM).getAbsolutePath(); assertThrows(IOException.class, () -> { new PEMFileLoader.Builder().setKeyStorePath(path + ".does_not_exist") @@ -79,7 +79,7 @@ public void testLoadKeyStoreWithNullFilePath() { } @TestTemplate - public void testLoadKeyStoreWithWrongFileType() throws IOException { + public void testLoadKeyStoreWithWrongFileType() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.JKS).getAbsolutePath(); assertThrows(KeyStoreException.class, () -> { // Trying to load a JKS file with PEM loader should fail @@ -97,7 +97,7 @@ public void testLoadTrustStore() throws Exception { } @TestTemplate - public void testLoadTrustStoreWithWrongFilePath() throws IOException { + public void testLoadTrustStoreWithWrongFilePath() throws Exception { String path = x509TestContext.getTrustStoreFile(KeyStoreFileType.PEM).getAbsolutePath(); assertThrows(IOException.class, () -> { new PEMFileLoader.Builder().setTrustStorePath(path + ".does_not_exist") diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestPKCS12FileLoader.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestPKCS12FileLoader.java index fe8249356e65..005993a79e9f 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestPKCS12FileLoader.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/TestPKCS12FileLoader.java @@ -52,7 +52,7 @@ public void testLoadKeyStore() throws Exception { } @TestTemplate - public void testLoadKeyStoreWithWrongPassword() throws IOException { + public void testLoadKeyStoreWithWrongPassword() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.PKCS12).getAbsolutePath(); assertThrows(IOException.class, () -> { new PKCS12FileLoader.Builder().setKeyStorePath(path) @@ -61,7 +61,7 @@ public void testLoadKeyStoreWithWrongPassword() throws IOException { } @TestTemplate - public void testLoadKeyStoreWithWrongFilePath() throws IOException { + public void testLoadKeyStoreWithWrongFilePath() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.PKCS12).getAbsolutePath(); assertThrows(IOException.class, () -> { new PKCS12FileLoader.Builder().setKeyStorePath(path + ".does_not_exist") @@ -78,7 +78,7 @@ public void testLoadKeyStoreWithNullFilePath() { } @TestTemplate - public void testLoadKeyStoreWithWrongFileType() throws IOException { + public void testLoadKeyStoreWithWrongFileType() throws Exception { String path = x509TestContext.getKeyStoreFile(KeyStoreFileType.PEM).getAbsolutePath(); assertThrows(IOException.class, () -> { // Trying to load a PEM file with PKCS12 loader should fail @@ -96,7 +96,7 @@ public void testLoadTrustStore() throws Exception { } @TestTemplate - public void testLoadTrustStoreWithWrongPassword() throws IOException { + public void testLoadTrustStoreWithWrongPassword() throws Exception { String path = x509TestContext.getTrustStoreFile(KeyStoreFileType.PKCS12).getAbsolutePath(); assertThrows(IOException.class, () -> { new PKCS12FileLoader.Builder().setTrustStorePath(path) @@ -105,7 +105,7 @@ public void testLoadTrustStoreWithWrongPassword() throws IOException { } @TestTemplate - public void testLoadTrustStoreWithWrongFilePath() throws IOException { + public void testLoadTrustStoreWithWrongFilePath() throws Exception { String path = x509TestContext.getTrustStoreFile(KeyStoreFileType.PKCS12).getAbsolutePath(); assertThrows(IOException.class, () -> { new PKCS12FileLoader.Builder().setTrustStorePath(path + ".does_not_exist") diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/X509TestContext.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/X509TestContext.java index 86f9818f523d..8e6b998983f3 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/X509TestContext.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/X509TestContext.java @@ -20,16 +20,17 @@ import static java.util.Objects.requireNonNull; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.lang.invoke.MethodHandles; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.nio.file.StandardOpenOption; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.Security; import java.security.cert.X509Certificate; import java.util.Arrays; -import org.apache.commons.io.FileUtils; import org.apache.hadoop.conf.Configuration; import org.apache.yetus.audience.InterfaceAudience; import org.bouncycastle.asn1.x500.X500Name; @@ -165,13 +166,12 @@ public char[] getTrustStorePassword() { /** * Returns the path to the trust store file in the given format (JKS or PEM). Note that the file - * is created lazily, the first time this method is called. The trust store file is temporary and - * will be deleted on exit. + * is created lazily, the first time this method is called. * @param storeFileType the store file type (JKS or PEM). * @return the path to the trust store file. - * @throws IOException if there is an error creating the trust store file. + * @throws Exception if there is an error creating the trust store file. */ - public File getTrustStoreFile(KeyStoreFileType storeFileType) throws IOException { + public File getTrustStoreFile(KeyStoreFileType storeFileType) throws Exception { switch (storeFileType) { case JKS: return getTrustStoreJksFile(); @@ -187,85 +187,68 @@ public File getTrustStoreFile(KeyStoreFileType storeFileType) throws IOException } } - private File getTrustStoreJksFile() throws IOException { + private void atomicWriteFile(File file, byte[] content) throws IOException { + File tmpFile = new File(file.getParentFile(), file.getName().concat(".tmp")); + Files.write(tmpFile.toPath(), content, StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING); + Files.move(tmpFile.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING, + StandardCopyOption.ATOMIC_MOVE); + } + + private File getTrustStoreJksFile() throws Exception { if (trustStoreJksFile == null) { trustStoreJksFile = File.createTempFile(TRUST_STORE_PREFIX, KeyStoreFileType.JKS.getDefaultFileExtension(), tempDir); - trustStoreJksFile.deleteOnExit(); generateTrustStoreJksFile(); } return trustStoreJksFile; } - private void generateTrustStoreJksFile() throws IOException { - try (final FileOutputStream trustStoreOutputStream = new FileOutputStream(trustStoreJksFile)) { - byte[] bytes = - X509TestHelpers.certToJavaTrustStoreBytes(trustStoreCertificate, trustStorePassword); - trustStoreOutputStream.write(bytes); - trustStoreOutputStream.flush(); - } catch (GeneralSecurityException e) { - throw new IOException(e); - } + private void generateTrustStoreJksFile() throws Exception { + atomicWriteFile(trustStoreJksFile, + X509TestHelpers.certToJavaTrustStoreBytes(trustStoreCertificate, trustStorePassword)); } private File getTrustStorePemFile() throws IOException { if (trustStorePemFile == null) { trustStorePemFile = File.createTempFile(TRUST_STORE_PREFIX, KeyStoreFileType.PEM.getDefaultFileExtension(), tempDir); - trustStorePemFile.deleteOnExit(); generateTrustStorePemFile(); } return trustStorePemFile; } private void generateTrustStorePemFile() throws IOException { - FileUtils.writeStringToFile(trustStorePemFile, - X509TestHelpers.pemEncodeX509Certificate(trustStoreCertificate), StandardCharsets.US_ASCII, - false); + atomicWriteFile(trustStorePemFile, X509TestHelpers + .pemEncodeX509Certificate(trustStoreCertificate).getBytes(StandardCharsets.US_ASCII)); } - private File getTrustStorePkcs12File() throws IOException { + private File getTrustStorePkcs12File() throws Exception { if (trustStorePkcs12File == null) { trustStorePkcs12File = File.createTempFile(TRUST_STORE_PREFIX, KeyStoreFileType.PKCS12.getDefaultFileExtension(), tempDir); - trustStorePkcs12File.deleteOnExit(); generateTrustStorePkcs12File(); } return trustStorePkcs12File; } - private void generateTrustStorePkcs12File() throws IOException { - try ( - final FileOutputStream trustStoreOutputStream = new FileOutputStream(trustStorePkcs12File)) { - byte[] bytes = - X509TestHelpers.certToPKCS12TrustStoreBytes(trustStoreCertificate, trustStorePassword); - trustStoreOutputStream.write(bytes); - trustStoreOutputStream.flush(); - } catch (GeneralSecurityException e) { - throw new IOException(e); - } + private void generateTrustStorePkcs12File() throws Exception { + atomicWriteFile(trustStorePkcs12File, + X509TestHelpers.certToPKCS12TrustStoreBytes(trustStoreCertificate, trustStorePassword)); } - private File getTrustStoreBcfksFile() throws IOException { + private File getTrustStoreBcfksFile() throws Exception { if (trustStoreBcfksFile == null) { trustStoreBcfksFile = File.createTempFile(TRUST_STORE_PREFIX, KeyStoreFileType.BCFKS.getDefaultFileExtension(), tempDir); - trustStoreBcfksFile.deleteOnExit(); generateTrustStoreBcfksFile(); } return trustStoreBcfksFile; } - private void generateTrustStoreBcfksFile() throws IOException { - try ( - final FileOutputStream trustStoreOutputStream = new FileOutputStream(trustStoreBcfksFile)) { - byte[] bytes = - X509TestHelpers.certToBCFKSTrustStoreBytes(trustStoreCertificate, trustStorePassword); - trustStoreOutputStream.write(bytes); - trustStoreOutputStream.flush(); - } catch (GeneralSecurityException e) { - throw new IOException(e); - } + private void generateTrustStoreBcfksFile() throws Exception { + atomicWriteFile(trustStoreBcfksFile, + X509TestHelpers.certToBCFKSTrustStoreBytes(trustStoreCertificate, trustStorePassword)); } public X509Certificate getKeyStoreCertificate() { @@ -286,13 +269,12 @@ public Configuration getConf() { /** * Returns the path to the key store file in the given format (JKS, PEM, ...). Note that the file - * is created lazily, the first time this method is called. The key store file is temporary and - * will be deleted on exit. + * is created lazily, the first time this method is called. * @param storeFileType the store file type (JKS, PEM, ...). * @return the path to the key store file. - * @throws IOException if there is an error creating the key store file. + * @throws Exception if there is an error creating the key store file. */ - public File getKeyStoreFile(KeyStoreFileType storeFileType) throws IOException { + public File getKeyStoreFile(KeyStoreFileType storeFileType) throws Exception { switch (storeFileType) { case JKS: return getKeyStoreJksFile(); @@ -308,88 +290,60 @@ public File getKeyStoreFile(KeyStoreFileType storeFileType) throws IOException { } } - private File getKeyStoreJksFile() throws IOException { + private File getKeyStoreJksFile() throws Exception { if (keyStoreJksFile == null) { keyStoreJksFile = File.createTempFile(KEY_STORE_PREFIX, KeyStoreFileType.JKS.getDefaultFileExtension(), tempDir); - keyStoreJksFile.deleteOnExit(); generateKeyStoreJksFile(); } return keyStoreJksFile; } - private void generateKeyStoreJksFile() throws IOException { - try (final FileOutputStream keyStoreOutputStream = new FileOutputStream(keyStoreJksFile)) { - byte[] bytes = X509TestHelpers.certAndPrivateKeyToJavaKeyStoreBytes(keyStoreCertificate, - keyStoreKeyPair.getPrivate(), keyStorePassword); - keyStoreOutputStream.write(bytes); - keyStoreOutputStream.flush(); - } catch (GeneralSecurityException e) { - throw new IOException(e); - } + private void generateKeyStoreJksFile() throws Exception { + atomicWriteFile(keyStoreJksFile, X509TestHelpers.certAndPrivateKeyToJavaKeyStoreBytes( + keyStoreCertificate, keyStoreKeyPair.getPrivate(), keyStorePassword)); } - private File getKeyStorePemFile() throws IOException { + private File getKeyStorePemFile() throws Exception { if (keyStorePemFile == null) { - try { - keyStorePemFile = File.createTempFile(KEY_STORE_PREFIX, - KeyStoreFileType.PEM.getDefaultFileExtension(), tempDir); - keyStorePemFile.deleteOnExit(); - generateKeyStorePemFile(); - } catch (OperatorCreationException e) { - throw new IOException(e); - } + keyStorePemFile = File.createTempFile(KEY_STORE_PREFIX, + KeyStoreFileType.PEM.getDefaultFileExtension(), tempDir); + generateKeyStorePemFile(); } return keyStorePemFile; } - private void generateKeyStorePemFile() throws IOException, OperatorCreationException { - FileUtils.writeStringToFile(keyStorePemFile, - X509TestHelpers.pemEncodeCertAndPrivateKey(keyStoreCertificate, keyStoreKeyPair.getPrivate(), - keyStorePassword), - StandardCharsets.US_ASCII, false); + private void generateKeyStorePemFile() throws Exception { + atomicWriteFile(keyStorePemFile, X509TestHelpers.pemEncodeCertAndPrivateKey(keyStoreCertificate, + keyStoreKeyPair.getPrivate(), keyStorePassword).getBytes(StandardCharsets.US_ASCII)); } - private File getKeyStorePkcs12File() throws IOException { + private File getKeyStorePkcs12File() throws Exception { if (keyStorePkcs12File == null) { keyStorePkcs12File = File.createTempFile(KEY_STORE_PREFIX, KeyStoreFileType.PKCS12.getDefaultFileExtension(), tempDir); - keyStorePkcs12File.deleteOnExit(); generateKeyStorePkcs12File(); } return keyStorePkcs12File; } - private void generateKeyStorePkcs12File() throws IOException { - try (final FileOutputStream keyStoreOutputStream = new FileOutputStream(keyStorePkcs12File)) { - byte[] bytes = X509TestHelpers.certAndPrivateKeyToPKCS12Bytes(keyStoreCertificate, - keyStoreKeyPair.getPrivate(), keyStorePassword); - keyStoreOutputStream.write(bytes); - keyStoreOutputStream.flush(); - } catch (GeneralSecurityException e) { - throw new IOException(e); - } + private void generateKeyStorePkcs12File() throws Exception { + atomicWriteFile(keyStorePkcs12File, X509TestHelpers.certAndPrivateKeyToPKCS12Bytes( + keyStoreCertificate, keyStoreKeyPair.getPrivate(), keyStorePassword)); } - private File getKeyStoreBcfksFile() throws IOException { + private File getKeyStoreBcfksFile() throws Exception { if (keyStoreBcfksFile == null) { keyStoreBcfksFile = File.createTempFile(KEY_STORE_PREFIX, KeyStoreFileType.BCFKS.getDefaultFileExtension(), tempDir); - keyStoreBcfksFile.deleteOnExit(); generateKeyStoreBcfksFile(); } return keyStoreBcfksFile; } - private void generateKeyStoreBcfksFile() throws IOException { - try (final FileOutputStream keyStoreOutputStream = new FileOutputStream(keyStoreBcfksFile)) { - byte[] bytes = X509TestHelpers.certAndPrivateKeyToBCFKSBytes(keyStoreCertificate, - keyStoreKeyPair.getPrivate(), keyStorePassword); - keyStoreOutputStream.write(bytes); - keyStoreOutputStream.flush(); - } catch (GeneralSecurityException e) { - throw new IOException(e); - } + private void generateKeyStoreBcfksFile() throws Exception { + atomicWriteFile(keyStoreBcfksFile, X509TestHelpers.certAndPrivateKeyToBCFKSBytes( + keyStoreCertificate, keyStoreKeyPair.getPrivate(), keyStorePassword)); } /** @@ -407,10 +361,10 @@ private void generateKeyStoreBcfksFile() throws IOException { * * @param keyStoreFileType the store file type to use for the key store (JKS, PEM, ...). * @param trustStoreFileType the store file type to use for the trust store (JKS, PEM, ...). - * @throws IOException if there is an error creating the key store file or trust store file. + * @throws Exception if there is an error creating the key store file or trust store file. */ public void setConfigurations(KeyStoreFileType keyStoreFileType, - KeyStoreFileType trustStoreFileType) throws IOException { + KeyStoreFileType trustStoreFileType) throws Exception { setKeystoreConfigurations(keyStoreFileType, conf); conf.set(X509Util.TLS_CONFIG_TRUSTSTORE_LOCATION, this.getTrustStoreFile(trustStoreFileType).getAbsolutePath()); @@ -427,7 +381,7 @@ public void setConfigurations(KeyStoreFileType keyStoreFileType, * truststore and is more applicable to general use. */ public void setKeystoreConfigurations(KeyStoreFileType keyStoreFileType, Configuration confToSet) - throws IOException { + throws Exception { confToSet.set(X509Util.TLS_CONFIG_KEYSTORE_LOCATION, this.getKeyStoreFile(keyStoreFileType).getAbsolutePath()); @@ -462,9 +416,7 @@ public X509TestContext cloneWithNewKeystoreCert(X509Certificate cert) { public void regenerateStores(X509KeyType keyStoreKeyType, X509KeyType trustStoreKeyType, KeyStoreFileType keyStoreFileType, KeyStoreFileType trustStoreFileType, - String... subjectAltNames) - throws GeneralSecurityException, IOException, OperatorCreationException { - + String... subjectAltNames) throws Exception { trustStoreKeyPair = X509TestHelpers.generateKeyPair(trustStoreKeyType); keyStoreKeyPair = X509TestHelpers.generateKeyPair(keyStoreKeyType); createCertificates(subjectAltNames); diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/X509TestHelpers.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/X509TestHelpers.java index 78d70f8f581d..c297a2619f06 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/X509TestHelpers.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/io/crypto/tls/X509TestHelpers.java @@ -151,8 +151,9 @@ public static X509Certificate newCert(X509Certificate caCert, KeyPair caKeyPair, "CA private key does not match the public key in " + "the CA cert"); } LocalDate now = LocalDate.now(ZoneId.systemDefault()); - X509v3CertificateBuilder builder = initCertBuilder(new X500Name(caCert.getIssuerDN().getName()), - now, now.plusDays(1), certSubject, certPublicKey); + X509v3CertificateBuilder builder = + initCertBuilder(new X500Name(caCert.getIssuerX500Principal().getName()), now, now.plusDays(1), + certSubject, certPublicKey); builder.addExtension(Extension.basicConstraints, true, new BasicConstraints(false)); // not a CA builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment)); @@ -305,7 +306,7 @@ public static String pemEncodePrivateKey(PrivateKey key, char[] password) if (password != null && password.length > 0) { encryptor = new JceOpenSSLPKCS8EncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC) - .setProvider(BouncyCastleProvider.PROVIDER_NAME).setRandom(PRNG).setPasssword(password) + .setProvider(BouncyCastleProvider.PROVIDER_NAME).setRandom(PRNG).setPassword(password) .build(); } pemWriter.writeObject(new JcaPKCS8Generator(key, encryptor)); @@ -382,7 +383,7 @@ public static byte[] certToBCFKSTrustStoreBytes(X509Certificate cert, char[] key private static byte[] certToTrustStoreBytes(X509Certificate cert, char[] keyPassword, KeyStore trustStore) throws IOException, GeneralSecurityException { trustStore.load(null, keyPassword); - trustStore.setCertificateEntry(cert.getSubjectDN().toString(), cert); + trustStore.setCertificateEntry(cert.getSubjectX500Principal().toString(), cert); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); trustStore.store(outputStream, keyPassword); outputStream.flush(); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestNettyTlsIPC.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestNettyTlsIPC.java index 504ad92d794f..0067c3aa14d1 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestNettyTlsIPC.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/ipc/TestNettyTlsIPC.java @@ -133,7 +133,7 @@ public static void tearDownAfterClass() throws InterruptedException { } @BeforeEach - public void setUp() throws IOException { + public void setUp() throws Exception { x509TestContext = PROVIDER.get(caKeyType, certKeyType, keyPassword); x509TestContext.setConfigurations(KeyStoreFileType.JKS, KeyStoreFileType.JKS); CONF.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_SUPPORTPLAINTEXT, acceptPlainText); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/AbstractTestMutualTls.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/AbstractTestMutualTls.java index 00311c76eae7..c7082779cf3c 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/AbstractTestMutualTls.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/AbstractTestMutualTls.java @@ -25,7 +25,6 @@ import java.io.IOException; import java.lang.invoke.MethodHandles; import java.net.InetSocketAddress; -import java.security.GeneralSecurityException; import java.security.Security; import java.security.cert.X509Certificate; import javax.net.ssl.SSLHandshakeException; @@ -48,7 +47,6 @@ import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.operator.OperatorCreationException; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -143,7 +141,7 @@ public static void cleanUp() { } protected abstract void initialize(Configuration serverConf, Configuration clientConf) - throws IOException, GeneralSecurityException, OperatorCreationException; + throws Exception; @BeforeEach public void setUp() throws Exception { @@ -164,8 +162,7 @@ public void setUp() throws Exception { stub = TestProtobufRpcServiceImpl.newBlockingStub(rpcClient, rpcServer.getListenerAddress()); } - protected void handleCertConfig(Configuration confToSet) - throws GeneralSecurityException, IOException, OperatorCreationException { + protected void handleCertConfig(Configuration confToSet) throws Exception { switch (certConfig) { case NO_CLIENT_CERT: // clearing out the keystore location will cause no cert to be sent. diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsClientSide.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsClientSide.java index a0705a7046ae..14a30ac6715d 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsClientSide.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsClientSide.java @@ -17,8 +17,6 @@ */ package org.apache.hadoop.hbase.security; -import java.io.IOException; -import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; @@ -28,7 +26,6 @@ import org.apache.hadoop.hbase.io.crypto.tls.X509Util; import org.apache.hadoop.hbase.testclassification.RPCTests; import org.apache.hadoop.hbase.testclassification.SmallTests; -import org.bouncycastle.operator.OperatorCreationException; import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.provider.Arguments; @@ -72,8 +69,7 @@ public TestMutualTlsClientSide(X509KeyType caKeyType, X509KeyType certKeyType, S } @Override - protected void initialize(Configuration serverConf, Configuration clientConf) - throws IOException, GeneralSecurityException, OperatorCreationException { + protected void initialize(Configuration serverConf, Configuration clientConf) throws Exception { // client verifies server hostname, and injects bad certs into server conf clientConf.setBoolean(X509Util.HBASE_CLIENT_NETTY_TLS_VERIFY_SERVER_HOSTNAME, validateHostnames); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsClientSideNonLocalhost.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsClientSideNonLocalhost.java index fb974871ca4a..99f0ed409441 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsClientSideNonLocalhost.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsClientSideNonLocalhost.java @@ -23,7 +23,6 @@ import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; -import java.security.GeneralSecurityException; import java.security.Security; import java.util.stream.Stream; import org.apache.commons.io.FileUtils; @@ -46,7 +45,6 @@ import org.apache.hadoop.hbase.testclassification.RPCTests; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.operator.OperatorCreationException; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -144,8 +142,7 @@ public void setUp() throws Exception { stub = TestProtobufRpcServiceImpl.newBlockingStub(rpcClient, rpcServer.getListenerAddress()); } - private void initialize(Configuration serverConf, Configuration clientConf) - throws GeneralSecurityException, IOException, OperatorCreationException { + private void initialize(Configuration serverConf, Configuration clientConf) throws Exception { serverConf.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_SUPPORTPLAINTEXT, supportPlaintext); clientConf.setBoolean(X509Util.HBASE_CLIENT_NETTY_TLS_VERIFY_SERVER_HOSTNAME, true); x509TestContext.regenerateStores(X509KeyType.RSA, X509KeyType.RSA, KeyStoreFileType.JKS, diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsServerSide.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsServerSide.java index 4d9ee4307be9..6ab472dc575d 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsServerSide.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsServerSide.java @@ -17,8 +17,6 @@ */ package org.apache.hadoop.hbase.security; -import java.io.IOException; -import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; @@ -28,7 +26,6 @@ import org.apache.hadoop.hbase.io.crypto.tls.X509Util; import org.apache.hadoop.hbase.testclassification.RPCTests; import org.apache.hadoop.hbase.testclassification.SmallTests; -import org.bouncycastle.operator.OperatorCreationException; import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.provider.Arguments; @@ -106,8 +103,7 @@ public TestMutualTlsServerSide(X509KeyType caKeyType, X509KeyType certKeyType, S } @Override - protected void initialize(Configuration serverConf, Configuration clientConf) - throws IOException, GeneralSecurityException, OperatorCreationException { + protected void initialize(Configuration serverConf, Configuration clientConf) throws Exception { // server enables client auth mode and verifies client host names // inject bad certs into client side serverConf.set(X509Util.HBASE_SERVER_NETTY_TLS_CLIENT_AUTH_MODE, clientAuthMode.name()); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTLSIPCFileWatcher.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTLSIPCFileWatcher.java index 1a37bff1ad96..2dab876170a3 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTLSIPCFileWatcher.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTLSIPCFileWatcher.java @@ -29,7 +29,6 @@ import java.net.InetSocketAddress; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.GeneralSecurityException; import java.security.Security; import java.time.Duration; import java.util.ArrayList; @@ -64,7 +63,6 @@ import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.util.NettyEventLoopGroupConfig; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.operator.OperatorCreationException; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -76,7 +74,6 @@ import org.slf4j.LoggerFactory; import org.apache.hbase.thirdparty.com.google.common.collect.Lists; -import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException; import org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestProtos; import org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestRpcServiceProtos; @@ -139,7 +136,7 @@ public static void tearDownAfterClass() throws InterruptedException { } @BeforeEach - public void setUp() throws IOException { + public void setUp() throws Exception { x509TestContext = PROVIDER.get(keyType, keyType, "keyPa$$word".toCharArray()); x509TestContext.setConfigurations(storeFileType, storeFileType); CONF.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_SUPPORTPLAINTEXT, false); @@ -162,8 +159,7 @@ public void tearDown() { } @TestTemplate - public void testReplaceServerKeystore() throws IOException, ServiceException, - GeneralSecurityException, OperatorCreationException, InterruptedException { + public void testReplaceServerKeystore() throws Exception { Configuration clientConf = new Configuration(CONF); RpcServer rpcServer = createRpcServer("testRpcServer", Lists.newArrayList(new RpcServer.BlockingServiceAndInterface(SERVICE, null)), @@ -214,8 +210,7 @@ public void testReplaceServerKeystore() throws IOException, ServiceException, } @TestTemplate - public void testReplaceClientAndServerKeystore() throws GeneralSecurityException, IOException, - OperatorCreationException, ServiceException, InterruptedException { + public void testReplaceClientAndServerKeystore() throws Exception { Configuration clientConf = new Configuration(CONF); RpcServer rpcServer = createRpcServer("testRpcServer", Lists.newArrayList(new RpcServer.BlockingServiceAndInterface(SERVICE, null)),