From 0ffed5e8b743a075f5d66c4fe6e9b8371eacfa14 Mon Sep 17 00:00:00 2001 From: Iwan Igonin <83668556+beanuwave@users.noreply.github.com> Date: Wed, 26 Feb 2025 20:43:38 +0100 Subject: [PATCH] =?UTF-8?q?Use=20BC=20libraries=20to=20parse=20PEM=20files?= =?UTF-8?q?,=20increase=20key=20length,=20allow=20gener=E2=80=A6=20(#17393?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use BC libraries to parse PEM files, increase key length, allow general use of known cryptographic binary extensions, remove unused BC dependencies Signed-off-by: Igonin * remove duplicated test permission Signed-off-by: Igonin --------- Signed-off-by: Igonin Co-authored-by: Igonin --- CHANGELOG-3.0.md | 1 + buildSrc/build.gradle | 4 - .../precommit/ForbiddenPatternsTask.java | 5 + .../gradle/testclusters/OpenSearchNode.java | 11 +- client/rest/build.gradle | 4 - distribution/tools/plugin-cli/build.gradle | 4 +- libs/ssl-config/build.gradle | 11 +- .../licenses/bcpkix-jdk18on-1.78.jar.sha1 | 0 .../licenses/bcprov-jdk18on-1.78.jar.sha1 | 0 .../licenses/bcutil-jdk18on-1.78.jar.sha1 | 1 + .../licenses/bouncycastle-LICENSE.txt | 14 + .../licenses/bouncycastle-NOTICE.txt | 1 + .../opensearch/common/ssl/PemKeyConfig.java | 4 +- .../org/opensearch/common/ssl/PemUtils.java | 658 +++--------------- .../common/ssl/SslConfiguration.java | 8 +- .../common/ssl/SslConfigurationLoader.java | 9 +- .../common/ssl/PemKeyConfigTests.java | 15 +- .../common/ssl/PemTrustConfigTests.java | 11 +- .../opensearch/common/ssl/PemUtilsTests.java | 95 ++- .../ssl/SslConfigurationLoaderTests.java | 5 +- .../common/ssl/SslDiagnosticsTests.java | 24 +- .../common/ssl/StoreKeyConfigTests.java | 37 +- .../common/ssl/StoreTrustConfigTests.java | 31 +- .../src/test/resources/certs/README.md | 155 +++++ .../src/test/resources/certs/README.txt | 85 --- .../test/resources/certs/cert-all/certs.p12 | Bin 4757 -> 4895 bytes .../test/resources/certs/cert-all/empty.jks | Bin 0 -> 32 bytes .../resources/certs/cert1/cert1-pkcs1.crt | 19 + .../resources/certs/cert1/cert1-pkcs1.key | 27 + .../resources/certs/cert1/cert1-pkcs8.key | 28 - .../src/test/resources/certs/cert1/cert1.crt | 34 +- .../src/test/resources/certs/cert1/cert1.key | 55 +- .../src/test/resources/certs/cert1/cert1.p12 | Bin 2456 -> 2606 bytes .../resources/certs/cert2/cert2-pkcs1.crt | 19 + .../resources/certs/cert2/cert2-pkcs1.key | 30 + .../resources/certs/cert2/cert2-pkcs8.key | 29 - .../src/test/resources/certs/cert2/cert2.crt | 34 +- .../src/test/resources/certs/cert2/cert2.key | 60 +- .../src/test/resources/certs/cert2/cert2.p12 | Bin 2456 -> 2606 bytes .../test/resources/certs/pem-utils/README.md | 108 ++- .../pem-utils/dsa_key_openssl_encrypted.pem | 30 +- .../certs/pem-utils/dsa_key_openssl_plain.pem | 28 +- .../dsa_key_openssl_plain_with_params.pem | 28 +- .../pem-utils/dsa_key_pkcs8_encrypted.pem | 18 + .../certs/pem-utils/dsa_key_pkcs8_plain.pem | 20 +- .../pem-utils/ec_key_openssl_encrypted.pem | 7 +- .../certs/pem-utils/ec_key_openssl_plain.pem | 5 +- .../ec_key_openssl_plain_with_params.pem | 7 +- .../pem-utils/ec_key_pkcs8_encrypted.pem | 6 + .../certs/pem-utils/key_DSA_enc_pbkdf2.pem | 18 + .../certs/pem-utils/key_EC_enc_pbkdf2.pem | 6 + .../certs/pem-utils/key_PKCS8_enc_pbkdf2.pem | 30 + .../resources/certs/pem-utils/testnode.jks | Bin 9360 -> 15253 bytes modules/reindex/build.gradle | 5 - .../reindex/ReindexRestClientSslTests.java | 10 +- .../org/opensearch/index/reindex/README.md | 48 ++ .../org/opensearch/index/reindex/README.txt | 16 - .../org/opensearch/index/reindex/ca.key | 30 + .../org/opensearch/index/reindex/ca.pem | 43 +- .../index/reindex/client/client.crt | 35 +- .../index/reindex/client/client.key | 60 +- .../opensearch/index/reindex/http/http.crt | 38 +- .../opensearch/index/reindex/http/http.key | 60 +- .../SecureNetty4HttpServerTransportTests.java | 2 +- .../ssl/SimpleSecureNetty4TransportTests.java | 2 +- .../src/test/resources/README.md | 26 + .../src/test/resources/README.txt | 17 - .../src/test/resources/netty4-secure.jks | Bin 2790 -> 2790 bytes .../src/test/resources/netty4-secure.p12 | Bin 0 -> 2790 bytes .../AzureDiscoveryClusterFormationTests.java | 4 +- plugins/ingest-attachment/build.gradle | 3 - .../licenses/bcmail-jdk18on-1.78.jar.sha1 | 1 - .../licenses/bcmail-jdk18on-LICENSE.txt | 23 - .../licenses/bcmail-jdk18on-NOTICE.txt | 0 .../licenses/bcpkix-jdk18on-LICENSE.txt | 23 - .../licenses/bcpkix-jdk18on-NOTICE.txt | 0 .../licenses/bcprov-jdk18on-LICENSE.txt | 22 - .../licenses/bcprov-jdk18on-NOTICE.txt | 0 plugins/repository-gcs/build.gradle | 2 +- .../gcs/GoogleCloudStorageServiceTests.java | 2 +- .../repositories/gcs/TestUtils.java | 2 +- ...ReactorNetty4HttpServerTransportTests.java | 16 +- .../src/test/resources/README.txt | 14 - .../src/test/resources/certificate.crt | 22 - .../src/test/resources/certificate.key | 28 - qa/evil-tests/build.gradle | 4 +- .../org/opensearch/bootstrap/test.policy | 21 +- .../resources/provision/kdc.conf.template | 7 +- .../resources/provision/krb5.conf.template | 13 +- test/framework/build.gradle | 3 + .../licenses/bcpkix-jdk18on-1.78.jar.sha1 | 1 + .../licenses/bcprov-jdk18on-1.78.jar.sha1 | 1 + .../licenses/bouncycastle-LICENSE.txt | 14 + .../licenses/bouncycastle-NOTICE.txt | 1 + .../org/opensearch/test/KeyStoreUtils.java | 68 ++ 95 files changed, 1214 insertions(+), 1312 deletions(-) rename {plugins/ingest-attachment => libs/ssl-config}/licenses/bcpkix-jdk18on-1.78.jar.sha1 (100%) rename {plugins/ingest-attachment => libs/ssl-config}/licenses/bcprov-jdk18on-1.78.jar.sha1 (100%) create mode 100644 libs/ssl-config/licenses/bcutil-jdk18on-1.78.jar.sha1 create mode 100644 libs/ssl-config/licenses/bouncycastle-LICENSE.txt create mode 100644 libs/ssl-config/licenses/bouncycastle-NOTICE.txt create mode 100644 libs/ssl-config/src/test/resources/certs/README.md delete mode 100644 libs/ssl-config/src/test/resources/certs/README.txt create mode 100644 libs/ssl-config/src/test/resources/certs/cert-all/empty.jks create mode 100644 libs/ssl-config/src/test/resources/certs/cert1/cert1-pkcs1.crt create mode 100644 libs/ssl-config/src/test/resources/certs/cert1/cert1-pkcs1.key delete mode 100644 libs/ssl-config/src/test/resources/certs/cert1/cert1-pkcs8.key create mode 100644 libs/ssl-config/src/test/resources/certs/cert2/cert2-pkcs1.crt create mode 100644 libs/ssl-config/src/test/resources/certs/cert2/cert2-pkcs1.key delete mode 100644 libs/ssl-config/src/test/resources/certs/cert2/cert2-pkcs8.key create mode 100644 libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_pkcs8_encrypted.pem create mode 100644 libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_pkcs8_encrypted.pem create mode 100644 libs/ssl-config/src/test/resources/certs/pem-utils/key_DSA_enc_pbkdf2.pem create mode 100644 libs/ssl-config/src/test/resources/certs/pem-utils/key_EC_enc_pbkdf2.pem create mode 100644 libs/ssl-config/src/test/resources/certs/pem-utils/key_PKCS8_enc_pbkdf2.pem create mode 100644 modules/reindex/src/test/resources/org/opensearch/index/reindex/README.md delete mode 100644 modules/reindex/src/test/resources/org/opensearch/index/reindex/README.txt create mode 100644 modules/reindex/src/test/resources/org/opensearch/index/reindex/ca.key create mode 100644 modules/transport-netty4/src/test/resources/README.md delete mode 100644 modules/transport-netty4/src/test/resources/README.txt create mode 100644 modules/transport-netty4/src/test/resources/netty4-secure.p12 delete mode 100644 plugins/ingest-attachment/licenses/bcmail-jdk18on-1.78.jar.sha1 delete mode 100644 plugins/ingest-attachment/licenses/bcmail-jdk18on-LICENSE.txt delete mode 100644 plugins/ingest-attachment/licenses/bcmail-jdk18on-NOTICE.txt delete mode 100644 plugins/ingest-attachment/licenses/bcpkix-jdk18on-LICENSE.txt delete mode 100644 plugins/ingest-attachment/licenses/bcpkix-jdk18on-NOTICE.txt delete mode 100644 plugins/ingest-attachment/licenses/bcprov-jdk18on-LICENSE.txt delete mode 100644 plugins/ingest-attachment/licenses/bcprov-jdk18on-NOTICE.txt delete mode 100644 plugins/transport-reactor-netty4/src/test/resources/README.txt delete mode 100644 plugins/transport-reactor-netty4/src/test/resources/certificate.crt delete mode 100644 plugins/transport-reactor-netty4/src/test/resources/certificate.key create mode 100644 test/framework/licenses/bcpkix-jdk18on-1.78.jar.sha1 create mode 100644 test/framework/licenses/bcprov-jdk18on-1.78.jar.sha1 create mode 100644 test/framework/licenses/bouncycastle-LICENSE.txt create mode 100644 test/framework/licenses/bouncycastle-NOTICE.txt create mode 100644 test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md index e4ae38e8da2ae..4c366d0c7714f 100644 --- a/CHANGELOG-3.0.md +++ b/CHANGELOG-3.0.md @@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Refactor the `:server` module `org.opensearch.client` to `org.opensearch.transport.client` to eliminate top level split packages for JPMS support ([#17272](https://github.com/opensearch-project/OpenSearch/pull/17272)) - Use Lucene `BM25Similarity` as default since the `LegacyBM25Similarity` is marked as deprecated ([#17306](https://github.com/opensearch-project/OpenSearch/pull/17306)) - Wildcard field index only 3gram of the input data [#17349](https://github.com/opensearch-project/OpenSearch/pull/17349) +- Use BC libraries to parse PEM files, increase key length, allow general use of known cryptographic binary extensions, remove unused BC dependencies ([#3420](https://github.com/opensearch-project/OpenSearch/pull/14912)) ### Deprecated diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 6e30bb0199086..65986f2361c9d 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -229,12 +229,8 @@ if (project != rootProject) { forbiddenPatterns { exclude '**/*.wav' - exclude '**/*.p12' - exclude '**/*.jks' - exclude '**/*.crt' // the file that actually defines nocommit exclude '**/ForbiddenPatternsTask.java' - exclude '**/*.bcfks' } testingConventions { diff --git a/buildSrc/src/main/java/org/opensearch/gradle/precommit/ForbiddenPatternsTask.java b/buildSrc/src/main/java/org/opensearch/gradle/precommit/ForbiddenPatternsTask.java index 1790b32fb2f36..fbf96483443ee 100644 --- a/buildSrc/src/main/java/org/opensearch/gradle/precommit/ForbiddenPatternsTask.java +++ b/buildSrc/src/main/java/org/opensearch/gradle/precommit/ForbiddenPatternsTask.java @@ -83,8 +83,13 @@ public class ForbiddenPatternsTask extends DefaultTask { .exclude("**/*.ico") .exclude("**/*.jar") .exclude("**/*.zip") + .exclude("**/*.p12") .exclude("**/*.jks") .exclude("**/*.crt") + .exclude("**/*.der") + .exclude("**/*.pem") + .exclude("**/*.key") + .exclude("**/*.bcfks") .exclude("**/*.keystore") .exclude("**/*.png"); diff --git a/buildSrc/src/main/java/org/opensearch/gradle/testclusters/OpenSearchNode.java b/buildSrc/src/main/java/org/opensearch/gradle/testclusters/OpenSearchNode.java index aaa2daef2a158..c7af3d0a155f7 100644 --- a/buildSrc/src/main/java/org/opensearch/gradle/testclusters/OpenSearchNode.java +++ b/buildSrc/src/main/java/org/opensearch/gradle/testclusters/OpenSearchNode.java @@ -548,7 +548,7 @@ public synchronized void start() { logToProcessStdout("Creating opensearch keystore with password set to [" + keystorePassword + "]"); if (keystorePassword.length() > 0) { - runOpenSearchBinScriptWithInput(keystorePassword + "\n" + keystorePassword, "opensearch-keystore", "create", "-p"); + runOpenSearchBinScriptWithInput(keystorePassword + "\n" + keystorePassword + "\n", "opensearch-keystore", "create", "-p"); } else { runOpenSearchBinScript("opensearch-keystore", "-v", "create"); } @@ -556,7 +556,7 @@ public synchronized void start() { if (keystoreSettings.isEmpty() == false || keystoreFiles.isEmpty() == false) { logToProcessStdout("Adding " + keystoreSettings.size() + " keystore settings and " + keystoreFiles.size() + " keystore files"); - keystoreSettings.forEach((key, value) -> runKeystoreCommandWithPassword(keystorePassword, value.toString(), "add", "-x", key)); + keystoreSettings.forEach((key, value) -> runKeystoreCommandWithPassword(keystorePassword, value.toString(), "add", key)); for (Map.Entry entry : keystoreFiles.entrySet()) { File file = entry.getValue(); @@ -738,7 +738,12 @@ private void runOpenSearchBinScriptWithInput(String input, String tool, CharSequ } private void runKeystoreCommandWithPassword(String keystorePassword, String input, CharSequence... args) { - final String actualInput = keystorePassword.length() > 0 ? keystorePassword + "\n" + input : input; + final String actualInput; + if (keystorePassword.length() > 0) { + actualInput = keystorePassword + "\n" + input + "\n" + input; + } else { + actualInput = input + "\n" + input; + } runOpenSearchBinScriptWithInput(actualInput, "opensearch-keystore", args); } diff --git a/client/rest/build.gradle b/client/rest/build.gradle index 93faf0024b51e..29d76e6910ee3 100644 --- a/client/rest/build.gradle +++ b/client/rest/build.gradle @@ -75,10 +75,6 @@ tasks.withType(CheckForbiddenApis).configureEach { replaceSignatureFiles('jdk-signatures', 'http-signatures') } -forbiddenPatterns { - exclude '**/*.der' -} - tasks.named('forbiddenApisTest').configure { //we are using jdk-internal instead of jdk-non-portable to allow for com.sun.net.httpserver.* usage bundledSignatures -= 'jdk-non-portable' diff --git a/distribution/tools/plugin-cli/build.gradle b/distribution/tools/plugin-cli/build.gradle index 784cdc457a1a9..ecb86ecb1eb0b 100644 --- a/distribution/tools/plugin-cli/build.gradle +++ b/distribution/tools/plugin-cli/build.gradle @@ -39,7 +39,9 @@ dependencies { compileOnly project(":libs:opensearch-cli") api "org.bouncycastle:bcpg-fips:2.0.9" api "org.bouncycastle:bc-fips:2.0.0" - testImplementation project(":test:framework") + testImplementation(project(":test:framework")) { + exclude group: 'org.bouncycastle' + } testImplementation 'com.google.jimfs:jimfs:1.3.0' testRuntimeOnly("com.google.guava:guava:${versions.guava}") { transitive = false diff --git a/libs/ssl-config/build.gradle b/libs/ssl-config/build.gradle index 3226ec12ff6f7..da0829cb533da 100644 --- a/libs/ssl-config/build.gradle +++ b/libs/ssl-config/build.gradle @@ -34,6 +34,9 @@ apply plugin: "opensearch.publish" dependencies { api project(':libs:opensearch-common') + api "org.bouncycastle:bcprov-jdk18on:${versions.bouncycastle}" + api "org.bouncycastle:bcpkix-jdk18on:${versions.bouncycastle}" + runtimeOnly "org.bouncycastle:bcutil-jdk18on:${versions.bouncycastle}" testImplementation(project(":test:framework")) { exclude group: 'org.opensearch', module: 'opensearch-ssl-config' @@ -44,16 +47,12 @@ dependencies { testImplementation "org.hamcrest:hamcrest:${versions.hamcrest}" } - tasks.named('forbiddenApisMain').configure { replaceSignatureFiles 'jdk-signatures' } -forbiddenPatterns { - exclude '**/*.key' - exclude '**/*.pem' - exclude '**/*.p12' - exclude '**/*.jks' +tasks.named("dependencyLicenses").configure { + mapping from: /bc.*/, to: 'bouncycastle' } tasks.test { diff --git a/plugins/ingest-attachment/licenses/bcpkix-jdk18on-1.78.jar.sha1 b/libs/ssl-config/licenses/bcpkix-jdk18on-1.78.jar.sha1 similarity index 100% rename from plugins/ingest-attachment/licenses/bcpkix-jdk18on-1.78.jar.sha1 rename to libs/ssl-config/licenses/bcpkix-jdk18on-1.78.jar.sha1 diff --git a/plugins/ingest-attachment/licenses/bcprov-jdk18on-1.78.jar.sha1 b/libs/ssl-config/licenses/bcprov-jdk18on-1.78.jar.sha1 similarity index 100% rename from plugins/ingest-attachment/licenses/bcprov-jdk18on-1.78.jar.sha1 rename to libs/ssl-config/licenses/bcprov-jdk18on-1.78.jar.sha1 diff --git a/libs/ssl-config/licenses/bcutil-jdk18on-1.78.jar.sha1 b/libs/ssl-config/licenses/bcutil-jdk18on-1.78.jar.sha1 new file mode 100644 index 0000000000000..9c88eef3ace17 --- /dev/null +++ b/libs/ssl-config/licenses/bcutil-jdk18on-1.78.jar.sha1 @@ -0,0 +1 @@ +81c1f5e06f206be5dad137d563609dbe66c81d31 \ No newline at end of file diff --git a/libs/ssl-config/licenses/bouncycastle-LICENSE.txt b/libs/ssl-config/licenses/bouncycastle-LICENSE.txt new file mode 100644 index 0000000000000..5c7c14696849d --- /dev/null +++ b/libs/ssl-config/licenses/bouncycastle-LICENSE.txt @@ -0,0 +1,14 @@ +Copyright (c) 2000 - 2023 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/libs/ssl-config/licenses/bouncycastle-NOTICE.txt b/libs/ssl-config/licenses/bouncycastle-NOTICE.txt new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/libs/ssl-config/licenses/bouncycastle-NOTICE.txt @@ -0,0 +1 @@ + diff --git a/libs/ssl-config/src/main/java/org/opensearch/common/ssl/PemKeyConfig.java b/libs/ssl-config/src/main/java/org/opensearch/common/ssl/PemKeyConfig.java index bfc29a5801b11..d957ffa457149 100644 --- a/libs/ssl-config/src/main/java/org/opensearch/common/ssl/PemKeyConfig.java +++ b/libs/ssl-config/src/main/java/org/opensearch/common/ssl/PemKeyConfig.java @@ -32,6 +32,8 @@ package org.opensearch.common.ssl; +import org.bouncycastle.pkcs.PKCSException; + import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.X509ExtendedKeyManager; @@ -91,7 +93,7 @@ private PrivateKey getPrivateKey() { throw new SslConfigException("the configured ssl private key file [" + key.toAbsolutePath() + "] does not exist", e); } catch (IOException e) { throw new SslConfigException("the configured ssl private key file [" + key.toAbsolutePath() + "] cannot be read", e); - } catch (GeneralSecurityException e) { + } catch (PKCSException e) { throw new SslConfigException("cannot load ssl private key file [" + key.toAbsolutePath() + "]", e); } } diff --git a/libs/ssl-config/src/main/java/org/opensearch/common/ssl/PemUtils.java b/libs/ssl-config/src/main/java/org/opensearch/common/ssl/PemUtils.java index 8a3730ee554f9..441e17b808feb 100644 --- a/libs/ssl-config/src/main/java/org/opensearch/common/ssl/PemUtils.java +++ b/libs/ssl-config/src/main/java/org/opensearch/common/ssl/PemUtils.java @@ -32,628 +32,136 @@ package org.opensearch.common.ssl; -import org.opensearch.common.CharArrays; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.PEMEncryptedKeyPair; +import org.bouncycastle.openssl.PEMKeyPair; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; +import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; +import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; +import org.bouncycastle.pkcs.PKCSException; +import org.bouncycastle.pkcs.jcajce.JcePKCSPBEInputDecryptorProviderBuilder; -import javax.crypto.Cipher; -import javax.crypto.EncryptedPrivateKeyInfo; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.PBEKeySpec; -import javax.crypto.spec.SecretKeySpec; - -import java.io.BufferedReader; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.NoSuchFileException; import java.nio.file.Path; -import java.security.GeneralSecurityException; -import java.security.KeyFactory; -import java.security.KeyPairGenerator; -import java.security.MessageDigest; import java.security.PrivateKey; +import java.security.Provider; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; -import java.security.interfaces.ECKey; -import java.security.spec.AlgorithmParameterSpec; -import java.security.spec.DSAPrivateKeySpec; -import java.security.spec.ECGenParameterSpec; -import java.security.spec.ECParameterSpec; -import java.security.spec.ECPrivateKeySpec; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.RSAPrivateCrtKeySpec; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Base64; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; +import java.util.Locale; import java.util.function.Supplier; final class PemUtils { - private static final String PKCS1_HEADER = "-----BEGIN RSA PRIVATE KEY-----"; - private static final String PKCS1_FOOTER = "-----END RSA PRIVATE KEY-----"; - private static final String OPENSSL_DSA_HEADER = "-----BEGIN DSA PRIVATE KEY-----"; - private static final String OPENSSL_DSA_FOOTER = "-----END DSA PRIVATE KEY-----"; - private static final String OPENSSL_DSA_PARAMS_HEADER = "-----BEGIN DSA PARAMETERS-----"; - private static final String OPENSSL_DSA_PARAMS_FOOTER = "-----END DSA PARAMETERS-----"; - private static final String PKCS8_HEADER = "-----BEGIN PRIVATE KEY-----"; - private static final String PKCS8_FOOTER = "-----END PRIVATE KEY-----"; - private static final String PKCS8_ENCRYPTED_HEADER = "-----BEGIN ENCRYPTED PRIVATE KEY-----"; - private static final String PKCS8_ENCRYPTED_FOOTER = "-----END ENCRYPTED PRIVATE KEY-----"; - private static final String OPENSSL_EC_HEADER = "-----BEGIN EC PRIVATE KEY-----"; - private static final String OPENSSL_EC_FOOTER = "-----END EC PRIVATE KEY-----"; - private static final String OPENSSL_EC_PARAMS_HEADER = "-----BEGIN EC PARAMETERS-----"; - private static final String OPENSSL_EC_PARAMS_FOOTER = "-----END EC PARAMETERS-----"; - private static final String HEADER = "-----BEGIN"; + private static final Provider BC = new BouncyCastleProvider(); - private PemUtils() { + PemUtils() { throw new IllegalStateException("Utility class should not be instantiated"); } /** * Creates a {@link PrivateKey} from the contents of a file. Supports PKCS#1, PKCS#8 - * encoded formats of encrypted and plaintext RSA, DSA and EC(secp256r1) keys + * encoded formats of encrypted and plaintext RSA, DSA and EC(secp256r1) keys. * * @param keyPath the path for the key file - * @param passwordSupplier A password supplier for the potentially encrypted (password protected) key + * @param passwordSupplier A password supplier for the potentially encrypted (password protected) key. Unencrypted keys ignore this value. * @return a private key from the contents of the file */ - public static PrivateKey readPrivateKey(Path keyPath, Supplier passwordSupplier) throws IOException, GeneralSecurityException { - try (BufferedReader bReader = Files.newBufferedReader(keyPath, StandardCharsets.UTF_8)) { - String line = bReader.readLine(); - while (null != line && line.startsWith(HEADER) == false) { - line = bReader.readLine(); - } - if (null == line) { - throw new SslConfigException("Error parsing Private Key [" + keyPath.toAbsolutePath() + "], file is empty"); - } - if (PKCS8_ENCRYPTED_HEADER.equals(line.trim())) { - char[] password = passwordSupplier.get(); - if (password == null) { - throw new SslConfigException("cannot read encrypted key [" + keyPath.toAbsolutePath() + "] without a password"); - } - return parsePKCS8Encrypted(bReader, password); - } else if (PKCS8_HEADER.equals(line.trim())) { - return parsePKCS8(bReader); - } else if (PKCS1_HEADER.equals(line.trim())) { - return parsePKCS1Rsa(bReader, passwordSupplier); - } else if (OPENSSL_DSA_HEADER.equals(line.trim())) { - return parseOpenSslDsa(bReader, passwordSupplier); - } else if (OPENSSL_DSA_PARAMS_HEADER.equals(line.trim())) { - return parseOpenSslDsa(removeDsaHeaders(bReader), passwordSupplier); - } else if (OPENSSL_EC_HEADER.equals(line.trim())) { - return parseOpenSslEC(bReader, passwordSupplier); - } else if (OPENSSL_EC_PARAMS_HEADER.equals(line.trim())) { - return parseOpenSslEC(removeECHeaders(bReader), passwordSupplier); - } else { - throw new SslConfigException( - "error parsing Private Key [" + keyPath.toAbsolutePath() + "], file does not contain a supported key format" - ); - } - } catch (FileNotFoundException | NoSuchFileException e) { - throw new SslConfigException("private key file [" + keyPath.toAbsolutePath() + "] does not exist", e); - } catch (IOException | GeneralSecurityException e) { - throw new SslConfigException("private key file [" + keyPath.toAbsolutePath() + "] cannot be parsed", e); - } - } - - /** - * Removes the EC Headers that OpenSSL adds to EC private keys as the information in them - * is redundant - * - * @throws IOException if the EC Parameter footer is missing - */ - private static BufferedReader removeECHeaders(BufferedReader bReader) throws IOException { - String line = bReader.readLine(); - while (line != null) { - if (OPENSSL_EC_PARAMS_FOOTER.equals(line.trim())) { - break; - } - line = bReader.readLine(); - } - if (null == line || OPENSSL_EC_PARAMS_FOOTER.equals(line.trim()) == false) { - throw new IOException("Malformed PEM file, EC Parameters footer is missing"); - } - // Verify that the key starts with the correct header before passing it to parseOpenSslEC - if (OPENSSL_EC_HEADER.equals(bReader.readLine()) == false) { - throw new IOException("Malformed PEM file, EC Key header is missing"); - } - return bReader; - } - - /** - * Removes the DSA Params Headers that OpenSSL adds to DSA private keys as the information in them - * is redundant - * - * @throws IOException if the EC Parameter footer is missing - */ - private static BufferedReader removeDsaHeaders(BufferedReader bReader) throws IOException { - String line = bReader.readLine(); - while (line != null) { - if (OPENSSL_DSA_PARAMS_FOOTER.equals(line.trim())) { - break; - } - line = bReader.readLine(); - } - if (null == line || OPENSSL_DSA_PARAMS_FOOTER.equals(line.trim()) == false) { - throw new IOException("Malformed PEM file, DSA Parameters footer is missing"); - } - // Verify that the key starts with the correct header before passing it to parseOpenSslDsa - if (OPENSSL_DSA_HEADER.equals(bReader.readLine()) == false) { - throw new IOException("Malformed PEM file, DSA Key header is missing"); - } - return bReader; - } - - /** - * Creates a {@link PrivateKey} from the contents of {@code bReader} that contains an plaintext private key encoded in - * PKCS#8 - * - * @param bReader the {@link BufferedReader} containing the key file contents - * @return {@link PrivateKey} - * @throws IOException if the file can't be read - * @throws GeneralSecurityException if the private key can't be generated from the {@link PKCS8EncodedKeySpec} - */ - private static PrivateKey parsePKCS8(BufferedReader bReader) throws IOException, GeneralSecurityException { - StringBuilder sb = new StringBuilder(); - String line = bReader.readLine(); - while (line != null) { - if (PKCS8_FOOTER.equals(line.trim())) { - break; - } - sb.append(line.trim()); - line = bReader.readLine(); - } - if (null == line || PKCS8_FOOTER.equals(line.trim()) == false) { - throw new IOException("Malformed PEM file, PEM footer is invalid or missing"); - } - byte[] keyBytes = Base64.getDecoder().decode(sb.toString()); - String keyAlgo = getKeyAlgorithmIdentifier(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(keyAlgo); - return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes)); + public static PrivateKey readPrivateKey(Path keyPath, Supplier passwordSupplier) throws IOException, PKCSException { + PrivateKeyInfo pki = loadPrivateKeyFromFile(keyPath, passwordSupplier); + JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); + return converter.getPrivateKey(pki); } - /** - * Creates a {@link PrivateKey} from the contents of {@code bReader} that contains an EC private key encoded in - * OpenSSL traditional format. - * - * @param bReader the {@link BufferedReader} containing the key file contents - * @param passwordSupplier A password supplier for the potentially encrypted (password protected) key - * @return {@link PrivateKey} - * @throws IOException if the file can't be read - * @throws GeneralSecurityException if the private key can't be generated from the {@link ECPrivateKeySpec} - */ - private static PrivateKey parseOpenSslEC(BufferedReader bReader, Supplier passwordSupplier) throws IOException, - GeneralSecurityException { - StringBuilder sb = new StringBuilder(); - String line = bReader.readLine(); - Map pemHeaders = new HashMap<>(); - while (line != null) { - if (OPENSSL_EC_FOOTER.equals(line.trim())) { - break; - } - // Parse PEM headers according to https://www.ietf.org/rfc/rfc1421.txt - if (line.contains(":")) { - String[] header = line.split(":"); - pemHeaders.put(header[0].trim(), header[1].trim()); - } else { - sb.append(line.trim()); - } - line = bReader.readLine(); - } - if (null == line || OPENSSL_EC_FOOTER.equals(line.trim()) == false) { - throw new IOException("Malformed PEM file, PEM footer is invalid or missing"); - } - byte[] keyBytes = possiblyDecryptPKCS1Key(pemHeaders, sb.toString(), passwordSupplier); - KeyFactory keyFactory = KeyFactory.getInstance("EC"); - ECPrivateKeySpec ecSpec = parseEcDer(keyBytes); - return keyFactory.generatePrivate(ecSpec); - } - - /** - * Creates a {@link PrivateKey} from the contents of {@code bReader} that contains an RSA private key encoded in - * OpenSSL traditional format. - * - * @param bReader the {@link BufferedReader} containing the key file contents - * @param passwordSupplier A password supplier for the potentially encrypted (password protected) key - * @return {@link PrivateKey} - * @throws IOException if the file can't be read - * @throws GeneralSecurityException if the private key can't be generated from the {@link RSAPrivateCrtKeySpec} - */ - private static PrivateKey parsePKCS1Rsa(BufferedReader bReader, Supplier passwordSupplier) throws IOException, - GeneralSecurityException { - StringBuilder sb = new StringBuilder(); - String line = bReader.readLine(); - Map pemHeaders = new HashMap<>(); - - while (line != null) { - if (PKCS1_FOOTER.equals(line.trim())) { - // Unencrypted - break; - } - // Parse PEM headers according to https://www.ietf.org/rfc/rfc1421.txt - if (line.contains(":")) { - String[] header = line.split(":"); - pemHeaders.put(header[0].trim(), header[1].trim()); - } else { - sb.append(line.trim()); + static List readCertificates(Collection certPaths) throws CertificateException, IOException { + CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + List certificates = new ArrayList<>(certPaths.size()); + for (Path path : certPaths) { + try (InputStream input = Files.newInputStream(path)) { + final Collection parsed = certFactory.generateCertificates(input); + if (parsed.isEmpty()) { + throw new SslConfigException("Failed to parse any certificate from [" + path.toAbsolutePath() + "]"); + } + certificates.addAll(parsed); } - line = bReader.readLine(); } - if (null == line || PKCS1_FOOTER.equals(line.trim()) == false) { - throw new IOException("Malformed PEM file, PEM footer is invalid or missing"); - } - byte[] keyBytes = possiblyDecryptPKCS1Key(pemHeaders, sb.toString(), passwordSupplier); - RSAPrivateCrtKeySpec spec = parseRsaDer(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - return keyFactory.generatePrivate(spec); + return certificates; } /** - * Creates a {@link PrivateKey} from the contents of {@code bReader} that contains an DSA private key encoded in - * OpenSSL traditional format. + * Creates a {@link PrivateKey} from the private key, with or without encryption. + * When enforcing the approved-only mode in Java security settings, some functionalities might be restricted due to the limited + * set of allowed algorithms. One such restriction includes Password Based Key Derivation Functions (PBKDF) like those used by OpenSSL + * and PKCS#12 formats. Since these formats rely on PBKDF algorithms, they cannot operate correctly within the approved-only mode. + * Consequently, attempting to utilize them could result in a {@link java.security.NoSuchAlgorithmException}. * - * @param bReader the {@link BufferedReader} containing the key file contents - * @param passwordSupplier A password supplier for the potentially encrypted (password protected) key + * @param passwordSupplier The password supplier for the encrypted (password protected) key * @return {@link PrivateKey} - * @throws IOException if the file can't be read - * @throws GeneralSecurityException if the private key can't be generated from the {@link DSAPrivateKeySpec} - */ - private static PrivateKey parseOpenSslDsa(BufferedReader bReader, Supplier passwordSupplier) throws IOException, - GeneralSecurityException { - StringBuilder sb = new StringBuilder(); - String line = bReader.readLine(); - Map pemHeaders = new HashMap<>(); - - while (line != null) { - if (OPENSSL_DSA_FOOTER.equals(line.trim())) { - // Unencrypted - break; - } - // Parse PEM headers according to https://www.ietf.org/rfc/rfc1421.txt - if (line.contains(":")) { - String[] header = line.split(":"); - pemHeaders.put(header[0].trim(), header[1].trim()); + * @throws IOException If the file can't be read + */ + private static PrivateKeyInfo loadPrivateKeyFromFile(Path keyPath, Supplier passwordSupplier) throws IOException, + PKCSException { + + try (PEMParser pemParser = new PEMParser(Files.newBufferedReader(keyPath, StandardCharsets.UTF_8))) { + Object object = readObject(keyPath, pemParser); + + if (object instanceof PKCS8EncryptedPrivateKeyInfo) { // encrypted private key in pkcs8-format + var privateKeyInfo = (PKCS8EncryptedPrivateKeyInfo) object; + var inputDecryptorProvider = new JcePKCSPBEInputDecryptorProviderBuilder().setProvider(BC).build(passwordSupplier.get()); + return privateKeyInfo.decryptPrivateKeyInfo(inputDecryptorProvider); + } else if (object instanceof PEMEncryptedKeyPair) { // encrypted private key + var encryptedKeyPair = (PEMEncryptedKeyPair) object; + var decryptorProvider = new JcePEMDecryptorProviderBuilder().setProvider(BC).build(passwordSupplier.get()); + var keyPair = encryptedKeyPair.decryptKeyPair(decryptorProvider); + return keyPair.getPrivateKeyInfo(); + } else if (object instanceof PEMKeyPair) { // unencrypted private key + return ((PEMKeyPair) object).getPrivateKeyInfo(); + } else if (object instanceof PrivateKeyInfo) { // unencrypted private key in pkcs8-format + return (PrivateKeyInfo) object; } else { - sb.append(line.trim()); - } - line = bReader.readLine(); - } - if (null == line || OPENSSL_DSA_FOOTER.equals(line.trim()) == false) { - throw new IOException("Malformed PEM file, PEM footer is invalid or missing"); - } - byte[] keyBytes = possiblyDecryptPKCS1Key(pemHeaders, sb.toString(), passwordSupplier); - DSAPrivateKeySpec spec = parseDsaDer(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance("DSA"); - return keyFactory.generatePrivate(spec); - } - - /** - * Creates a {@link PrivateKey} from the contents of {@code bReader} that contains an encrypted private key encoded in - * PKCS#8 - * - * @param bReader the {@link BufferedReader} containing the key file contents - * @param keyPassword The password for the encrypted (password protected) key - * @return {@link PrivateKey} - * @throws IOException if the file can't be read - * @throws GeneralSecurityException if the private key can't be generated from the {@link PKCS8EncodedKeySpec} - */ - private static PrivateKey parsePKCS8Encrypted(BufferedReader bReader, char[] keyPassword) throws IOException, GeneralSecurityException { - StringBuilder sb = new StringBuilder(); - String line = bReader.readLine(); - while (line != null) { - if (PKCS8_ENCRYPTED_FOOTER.equals(line.trim())) { - break; - } - sb.append(line.trim()); - line = bReader.readLine(); - } - if (null == line || PKCS8_ENCRYPTED_FOOTER.equals(line.trim()) == false) { - throw new IOException("Malformed PEM file, PEM footer is invalid or missing"); - } - byte[] keyBytes = Base64.getDecoder().decode(sb.toString()); - - EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(keyBytes); - SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(encryptedPrivateKeyInfo.getAlgName()); - SecretKey secretKey = secretKeyFactory.generateSecret(new PBEKeySpec(keyPassword)); - Cipher cipher = Cipher.getInstance(encryptedPrivateKeyInfo.getAlgName()); - cipher.init(Cipher.DECRYPT_MODE, secretKey, encryptedPrivateKeyInfo.getAlgParameters()); - PKCS8EncodedKeySpec keySpec = encryptedPrivateKeyInfo.getKeySpec(cipher); - String keyAlgo = getKeyAlgorithmIdentifier(keySpec.getEncoded()); - KeyFactory keyFactory = KeyFactory.getInstance(keyAlgo); - return keyFactory.generatePrivate(keySpec); - } - - /** - * Decrypts the password protected contents using the algorithm and IV that is specified in the PEM Headers of the file - * - * @param pemHeaders The Proc-Type and DEK-Info PEM headers that have been extracted from the key file - * @param keyContents The key as a base64 encoded String - * @param passwordSupplier A password supplier for the encrypted (password protected) key - * @return the decrypted key bytes - * @throws GeneralSecurityException if the key can't be decrypted - * @throws IOException if the PEM headers are missing or malformed - */ - private static byte[] possiblyDecryptPKCS1Key(Map pemHeaders, String keyContents, Supplier passwordSupplier) - throws GeneralSecurityException, IOException { - byte[] keyBytes = Base64.getDecoder().decode(keyContents); - String procType = pemHeaders.get("Proc-Type"); - if ("4,ENCRYPTED".equals(procType)) { - // We only handle PEM encryption - String encryptionParameters = pemHeaders.get("DEK-Info"); - if (null == encryptionParameters) { - // malformed pem - throw new IOException("Malformed PEM File, DEK-Info header is missing"); - } - char[] password = passwordSupplier.get(); - if (password == null) { - throw new IOException("cannot read encrypted key without a password"); + throw new SslConfigException( + String.format( + Locale.ROOT, + "error parsing private key [%s], invalid encrypted private key class: [%s]", + keyPath.toAbsolutePath(), + object.getClass().getName() + ) + ); } - Cipher cipher = getCipherFromParameters(encryptionParameters, password); - byte[] decryptedKeyBytes = cipher.doFinal(keyBytes); - return decryptedKeyBytes; } - return keyBytes; } /** - * Creates a {@link Cipher} from the contents of the DEK-Info header of a PEM file. RFC 1421 indicates that supported algorithms are - * defined in RFC 1423. RFC 1423 only defines DES-CBS and triple DES (EDE) in CBC mode. AES in CBC mode is also widely used though ( 3 - * different variants of 128, 192, 256 bit keys ) + * Supports PEM files that includes parameters. * - * @param dekHeaderValue The value of the DEK-Info PEM header - * @param password The password with which the key is encrypted - * @return a cipher of the appropriate algorithm and parameters to be used for decryption - * @throws GeneralSecurityException if the algorithm is not available in the used security provider, or if the key is inappropriate - * for the cipher - * @throws IOException if the DEK-Info PEM header is invalid - */ - private static Cipher getCipherFromParameters(String dekHeaderValue, char[] password) throws GeneralSecurityException, IOException { - final String padding = "PKCS5Padding"; - final SecretKey encryptionKey; - final String[] valueTokens = dekHeaderValue.split(","); - if (valueTokens.length != 2) { - throw new IOException("Malformed PEM file, DEK-Info PEM header is invalid"); - } - final String algorithm = valueTokens[0]; - final String ivString = valueTokens[1]; - final byte[] iv; - try { - iv = hexStringToByteArray(ivString); - } catch (IllegalArgumentException e) { - throw new IOException("Malformed PEM file, DEK-Info IV is invalid", e); - } - if ("DES-CBC".equals(algorithm)) { - byte[] key = generateOpenSslKey(password, iv, 8); - encryptionKey = new SecretKeySpec(key, "DES"); - } else if ("DES-EDE3-CBC".equals(algorithm)) { - byte[] key = generateOpenSslKey(password, iv, 24); - encryptionKey = new SecretKeySpec(key, "DESede"); - } else if ("AES-128-CBC".equals(algorithm)) { - byte[] key = generateOpenSslKey(password, iv, 16); - encryptionKey = new SecretKeySpec(key, "AES"); - } else if ("AES-192-CBC".equals(algorithm)) { - byte[] key = generateOpenSslKey(password, iv, 24); - encryptionKey = new SecretKeySpec(key, "AES"); - } else if ("AES-256-CBC".equals(algorithm)) { - byte[] key = generateOpenSslKey(password, iv, 32); - encryptionKey = new SecretKeySpec(key, "AES"); - } else { - throw new GeneralSecurityException("Private Key encrypted with unsupported algorithm [" + algorithm + "]"); - } - String transformation = encryptionKey.getAlgorithm() + "/" + "CBC" + "/" + padding; - Cipher cipher = Cipher.getInstance(transformation); - cipher.init(Cipher.DECRYPT_MODE, encryptionKey, new IvParameterSpec(iv)); - return cipher; - } - - /** - * Performs key stretching in the same manner that OpenSSL does. This is basically a KDF - * that uses n rounds of salted MD5 (as many times as needed to get the necessary number of key bytes) - *

- * https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_PrivateKey_traditional.html - */ - private static byte[] generateOpenSslKey(char[] password, byte[] salt, int keyLength) { - byte[] passwordBytes = CharArrays.toUtf8Bytes(password); - MessageDigest md5 = SslUtil.messageDigest("md5"); - byte[] key = new byte[keyLength]; - int copied = 0; - int remaining; - while (copied < keyLength) { - remaining = keyLength - copied; - md5.update(passwordBytes, 0, passwordBytes.length); - md5.update(salt, 0, 8);// AES IV (salt) is longer but we only need 8 bytes - byte[] tempDigest = md5.digest(); - int bytesToCopy = (remaining > 16) ? 16 : remaining; // MD5 digests are 16 bytes - System.arraycopy(tempDigest, 0, key, copied, bytesToCopy); - copied += bytesToCopy; - if (remaining == 0) { - break; - } - md5.update(tempDigest, 0, 16); // use previous round digest as IV - } - Arrays.fill(passwordBytes, (byte) 0); - return key; - } - - /** - * Converts a hexadecimal string to a byte array - */ - private static byte[] hexStringToByteArray(String hexString) { - int len = hexString.length(); - if (len % 2 == 0) { - byte[] data = new byte[len / 2]; - for (int i = 0; i < len; i += 2) { - final int k = Character.digit(hexString.charAt(i), 16); - final int l = Character.digit(hexString.charAt(i + 1), 16); - if (k == -1 || l == -1) { - throw new IllegalStateException("String [" + hexString + "] is not hexadecimal"); + * @return high-level Object from the content + */ + private static Object readObject(Path keyPath, PEMParser pemParser) throws IOException { + while (pemParser.ready()) { + try { + var object = pemParser.readObject(); + if (object == null) { // ignore unknown objects; + continue; } - data[i / 2] = (byte) ((k << 4) + l); - } - return data; - } else { - throw new IllegalStateException( - "Hexadecimal string [" + hexString + "] has odd length and cannot be converted to a byte array" - ); - } - } - - /** - * Parses a DER encoded EC key to an {@link ECPrivateKeySpec} using a minimal {@link DerParser} - * - * @param keyBytes the private key raw bytes - * @return {@link ECPrivateKeySpec} - * @throws IOException if the DER encoded key can't be parsed - */ - private static ECPrivateKeySpec parseEcDer(byte[] keyBytes) throws IOException, GeneralSecurityException { - DerParser parser = new DerParser(keyBytes); - DerParser.Asn1Object sequence = parser.readAsn1Object(); - parser = sequence.getParser(); - parser.readAsn1Object().getInteger(); // version - String keyHex = parser.readAsn1Object().getString(); - BigInteger privateKeyInt = new BigInteger(keyHex, 16); - DerParser.Asn1Object choice = parser.readAsn1Object(); - parser = choice.getParser(); - String namedCurve = getEcCurveNameFromOid(parser.readAsn1Object().getOid()); - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC"); - AlgorithmParameterSpec algorithmParameterSpec = new ECGenParameterSpec(namedCurve); - keyPairGenerator.initialize(algorithmParameterSpec); - ECParameterSpec parameterSpec = ((ECKey) keyPairGenerator.generateKeyPair().getPrivate()).getParams(); - return new ECPrivateKeySpec(privateKeyInt, parameterSpec); - } - - /** - * Parses a DER encoded RSA key to a {@link RSAPrivateCrtKeySpec} using a minimal {@link DerParser} - * - * @param keyBytes the private key raw bytes - * @return {@link RSAPrivateCrtKeySpec} - * @throws IOException if the DER encoded key can't be parsed - */ - private static RSAPrivateCrtKeySpec parseRsaDer(byte[] keyBytes) throws IOException { - DerParser parser = new DerParser(keyBytes); - DerParser.Asn1Object sequence = parser.readAsn1Object(); - parser = sequence.getParser(); - parser.readAsn1Object().getInteger(); // (version) We don't need it but must read to get to modulus - BigInteger modulus = parser.readAsn1Object().getInteger(); - BigInteger publicExponent = parser.readAsn1Object().getInteger(); - BigInteger privateExponent = parser.readAsn1Object().getInteger(); - BigInteger prime1 = parser.readAsn1Object().getInteger(); - BigInteger prime2 = parser.readAsn1Object().getInteger(); - BigInteger exponent1 = parser.readAsn1Object().getInteger(); - BigInteger exponent2 = parser.readAsn1Object().getInteger(); - BigInteger coefficient = parser.readAsn1Object().getInteger(); - return new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, prime1, prime2, exponent1, exponent2, coefficient); - } - - /** - * Parses a DER encoded DSA key to a {@link DSAPrivateKeySpec} using a minimal {@link DerParser} - * - * @param keyBytes the private key raw bytes - * @return {@link DSAPrivateKeySpec} - * @throws IOException if the DER encoded key can't be parsed - */ - private static DSAPrivateKeySpec parseDsaDer(byte[] keyBytes) throws IOException { - DerParser parser = new DerParser(keyBytes); - DerParser.Asn1Object sequence = parser.readAsn1Object(); - parser = sequence.getParser(); - parser.readAsn1Object().getInteger(); // (version) We don't need it but must read to get to p - BigInteger p = parser.readAsn1Object().getInteger(); - BigInteger q = parser.readAsn1Object().getInteger(); - BigInteger g = parser.readAsn1Object().getInteger(); - parser.readAsn1Object().getInteger(); // we don't need x - BigInteger x = parser.readAsn1Object().getInteger(); - return new DSAPrivateKeySpec(x, p, q, g); - } - - /** - * Parses a DER encoded private key and reads its algorithm identifier Object OID. - * - * @param keyBytes the private key raw bytes - * @return A string identifier for the key algorithm (RSA, DSA, or EC) - * @throws GeneralSecurityException if the algorithm oid that is parsed from ASN.1 is unknown - * @throws IOException if the DER encoded key can't be parsed - */ - private static String getKeyAlgorithmIdentifier(byte[] keyBytes) throws IOException, GeneralSecurityException { - DerParser parser = new DerParser(keyBytes); - DerParser.Asn1Object sequence = parser.readAsn1Object(); - parser = sequence.getParser(); - parser.readAsn1Object().getInteger(); // version - DerParser.Asn1Object algSequence = parser.readAsn1Object(); - parser = algSequence.getParser(); - String oidString = parser.readAsn1Object().getOid(); - switch (oidString) { - case "1.2.840.10040.4.1": - return "DSA"; - case "1.2.840.113549.1.1.1": - return "RSA"; - case "1.2.840.10045.2.1": - return "EC"; - } - throw new GeneralSecurityException( - "Error parsing key algorithm identifier. Algorithm with OID [" + oidString + "] is not żsupported" - ); - } - - static List readCertificates(Collection certPaths) throws CertificateException, IOException { - CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); - List certificates = new ArrayList<>(certPaths.size()); - for (Path path : certPaths) { - try (InputStream input = Files.newInputStream(path)) { - final Collection parsed = certFactory.generateCertificates(input); - if (parsed.isEmpty()) { - throw new SslConfigException("failed to parse any certificates from [" + path.toAbsolutePath() + "]"); + if (object instanceof ASN1ObjectIdentifier) { // ignore -----BEGIN EC PARAMETERS----- + continue; } - certificates.addAll(parsed); + return object; + } catch (IOException e) { // ignore -----BEGIN DSA PARAMETERS----- + // ignore } } - return certificates; - } - - private static String getEcCurveNameFromOid(String oidString) throws GeneralSecurityException { - switch (oidString) { - // see https://tools.ietf.org/html/rfc5480#section-2.1.1.1 - case "1.2.840.10045.3.1": - return "secp192r1"; - case "1.3.132.0.1": - return "sect163k1"; - case "1.3.132.0.15": - return "sect163r2"; - case "1.3.132.0.33": - return "secp224r1"; - case "1.3.132.0.26": - return "sect233k1"; - case "1.3.132.0.27": - return "sect233r1"; - case "1.2.840.10045.3.1.7": - return "secp256r1"; - case "1.3.132.0.16": - return "sect283k1"; - case "1.3.132.0.17": - return "sect283r1"; - case "1.3.132.0.34": - return "secp384r1"; - case "1.3.132.0.36": - return "sect409k1"; - case "1.3.132.0.37": - return "sect409r1"; - case "1.3.132.0.35": - return "secp521r1"; - case "1.3.132.0.38": - return "sect571k1"; - case "1.3.132.0.39": - return "sect571r1"; - } - throw new GeneralSecurityException( - "Error parsing EC named curve identifier. Named curve with OID: " + oidString + " is not supported" + throw new SslConfigException( + "Error parsing Private Key [" + keyPath.toAbsolutePath() + "]. The file is empty, or does not contain expected key format." ); } diff --git a/libs/ssl-config/src/main/java/org/opensearch/common/ssl/SslConfiguration.java b/libs/ssl-config/src/main/java/org/opensearch/common/ssl/SslConfiguration.java index 23acb0ff269e2..546d7f0ebd994 100644 --- a/libs/ssl-config/src/main/java/org/opensearch/common/ssl/SslConfiguration.java +++ b/libs/ssl-config/src/main/java/org/opensearch/common/ssl/SslConfiguration.java @@ -38,7 +38,6 @@ import java.nio.file.Path; import java.security.GeneralSecurityException; -import java.security.NoSuchAlgorithmException; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -66,12 +65,7 @@ public class SslConfiguration { static final Map ORDERED_PROTOCOL_ALGORITHM_MAP; static { LinkedHashMap protocolAlgorithmMap = new LinkedHashMap<>(); - try { - SSLContext.getInstance("TLSv1.3"); - protocolAlgorithmMap.put("TLSv1.3", "TLSv1.3"); - } catch (NoSuchAlgorithmException e) { - // ignore since we support JVMs (and BC JSSE in FIPS mode) that do not support TLSv1.3 - } + protocolAlgorithmMap.put("TLSv1.3", "TLSv1.3"); protocolAlgorithmMap.put("TLSv1.2", "TLSv1.2"); protocolAlgorithmMap.put("TLSv1.1", "TLSv1.1"); protocolAlgorithmMap.put("TLSv1", "TLSv1"); diff --git a/libs/ssl-config/src/main/java/org/opensearch/common/ssl/SslConfigurationLoader.java b/libs/ssl-config/src/main/java/org/opensearch/common/ssl/SslConfigurationLoader.java index 0b06a0692197e..433bec734e0b8 100644 --- a/libs/ssl-config/src/main/java/org/opensearch/common/ssl/SslConfigurationLoader.java +++ b/libs/ssl-config/src/main/java/org/opensearch/common/ssl/SslConfigurationLoader.java @@ -360,14 +360,11 @@ private List resolveListSetting(String key, Function parser, L private static List loadDefaultCiphers() { final boolean has256BitAES = has256BitAES(); - final boolean tlsV13Supported = DEFAULT_PROTOCOLS.contains("TLSv1.3"); List ciphers = new ArrayList<>(); - if (tlsV13Supported) { // TLSv1.3 cipher has PFS, AEAD, hardware support - if (has256BitAES) { - ciphers.add("TLS_AES_256_GCM_SHA384"); - } - ciphers.add("TLS_AES_128_GCM_SHA256"); + if (has256BitAES) { + ciphers.add("TLS_AES_256_GCM_SHA384"); } + ciphers.add("TLS_AES_128_GCM_SHA256"); // use GCM: PFS, AEAD, hardware support if (has256BitAES) { ciphers.addAll( diff --git a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemKeyConfigTests.java b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemKeyConfigTests.java index 688f03a1e51fa..70cb76ceaec51 100644 --- a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemKeyConfigTests.java +++ b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemKeyConfigTests.java @@ -41,11 +41,11 @@ import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.StandardCopyOption; -import java.security.GeneralSecurityException; import java.security.PrivateKey; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Arrays; +import java.util.function.Supplier; import static org.hamcrest.Matchers.arrayWithSize; import static org.hamcrest.Matchers.containsInAnyOrder; @@ -58,6 +58,7 @@ public class PemKeyConfigTests extends OpenSearchTestCase { private static final int IP_NAME = 7; private static final int DNS_NAME = 2; + private static final Supplier STRONG_PRIVATE_SECRET = "6!6428DQXwPpi7@$ggeg/="::toCharArray; public void testBuildKeyConfigFromPkcs1PemFilesWithoutPassword() throws Exception { final Path cert = getDataPath("/certs/cert1/cert1.crt"); @@ -68,8 +69,8 @@ public void testBuildKeyConfigFromPkcs1PemFilesWithoutPassword() throws Exceptio } public void testBuildKeyConfigFromPkcs1PemFilesWithPassword() throws Exception { - final Path cert = getDataPath("/certs/cert2/cert2.crt"); - final Path key = getDataPath("/certs/cert2/cert2.key"); + final Path cert = getDataPath("/certs/cert2/cert2-pkcs1.crt"); + final Path key = getDataPath("/certs/cert2/cert2-pkcs1.key"); final PemKeyConfig keyConfig = new PemKeyConfig(cert, key, "c2-pass".toCharArray()); assertThat(keyConfig.getDependentFiles(), Matchers.containsInAnyOrder(cert, key)); assertCertificateAndKey(keyConfig, "CN=cert2"); @@ -77,7 +78,7 @@ public void testBuildKeyConfigFromPkcs1PemFilesWithPassword() throws Exception { public void testBuildKeyConfigFromPkcs8PemFilesWithoutPassword() throws Exception { final Path cert = getDataPath("/certs/cert1/cert1.crt"); - final Path key = getDataPath("/certs/cert1/cert1-pkcs8.key"); + final Path key = getDataPath("/certs/cert1/cert1.key"); final PemKeyConfig keyConfig = new PemKeyConfig(cert, key, new char[0]); assertThat(keyConfig.getDependentFiles(), Matchers.containsInAnyOrder(cert, key)); assertCertificateAndKey(keyConfig, "CN=cert1"); @@ -86,8 +87,8 @@ public void testBuildKeyConfigFromPkcs8PemFilesWithoutPassword() throws Exceptio public void testBuildKeyConfigFromPkcs8PemFilesWithPassword() throws Exception { assumeFalse("Can't run in a FIPS JVM, PBE KeySpec is not available", inFipsJvm()); final Path cert = getDataPath("/certs/cert2/cert2.crt"); - final Path key = getDataPath("/certs/cert2/cert2-pkcs8.key"); - final PemKeyConfig keyConfig = new PemKeyConfig(cert, key, "c2-pass".toCharArray()); + final Path key = getDataPath("/certs/cert2/cert2.key"); + final PemKeyConfig keyConfig = new PemKeyConfig(cert, key, STRONG_PRIVATE_SECRET.get()); assertThat(keyConfig.getDependentFiles(), Matchers.containsInAnyOrder(cert, key)); assertCertificateAndKey(keyConfig, "CN=cert2"); } @@ -166,7 +167,7 @@ private void assertPasswordIsIncorrect(PemKeyConfig keyConfig, Path key) { final SslConfigException exception = expectThrows(SslConfigException.class, keyConfig::createKeyManager); assertThat(exception.getMessage(), containsString("private key file")); assertThat(exception.getMessage(), containsString(key.toAbsolutePath().toString())); - assertThat(exception.getCause(), instanceOf(GeneralSecurityException.class)); + assertThat(exception, instanceOf(SslConfigException.class)); } private void assertFileNotFound(PemKeyConfig keyConfig, String type, Path file) { diff --git a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemTrustConfigTests.java b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemTrustConfigTests.java index e664e379d1e97..4175b0ee424b7 100644 --- a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemTrustConfigTests.java +++ b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemTrustConfigTests.java @@ -81,7 +81,7 @@ public void testEmptyFileFails() throws Exception { final Path ca = createTempFile("ca", ".crt"); final PemTrustConfig trustConfig = new PemTrustConfig(Collections.singletonList(ca)); assertThat(trustConfig.getDependentFiles(), Matchers.containsInAnyOrder(ca)); - assertEmptyFile(trustConfig, ca); + assertFailedToParse(trustConfig, ca); } public void testMissingFileFailsWithMeaningfulMessage() throws Exception { @@ -135,21 +135,16 @@ private void assertCertificateChain(PemTrustConfig trustConfig, String... caName assertThat(issuerNames, Matchers.containsInAnyOrder(caNames)); } - private void assertEmptyFile(PemTrustConfig trustConfig, Path file) { + private void assertFailedToParse(PemTrustConfig trustConfig, Path file) { final SslConfigException exception = expectThrows(SslConfigException.class, trustConfig::createTrustManager); logger.info("failure", exception); assertThat(exception.getMessage(), Matchers.containsString(file.toAbsolutePath().toString())); - assertThat(exception.getMessage(), Matchers.containsString("failed to parse any certificates")); + assertThat(exception.getMessage(), Matchers.containsString("Failed to parse any certificate from")); } private void assertInvalidFileFormat(PemTrustConfig trustConfig, Path file) { final SslConfigException exception = expectThrows(SslConfigException.class, trustConfig::createTrustManager); assertThat(exception.getMessage(), Matchers.containsString(file.toAbsolutePath().toString())); - // When running on BC-FIPS, an invalid file format *might* just fail to parse, without any errors (just like an empty file) - // or it might behave per the SUN provider, and throw a GSE (depending on exactly what was invalid) - if (inFipsJvm() && exception.getMessage().contains("failed to parse any certificates")) { - return; - } assertThat(exception.getMessage(), Matchers.containsString("cannot create trust")); assertThat(exception.getMessage(), Matchers.containsString("PEM")); assertThat(exception.getCause(), Matchers.instanceOf(GeneralSecurityException.class)); diff --git a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemUtilsTests.java b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemUtilsTests.java index c7ca19bb679d3..f1255ab64f672 100644 --- a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemUtilsTests.java +++ b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/PemUtilsTests.java @@ -32,8 +32,11 @@ package org.opensearch.common.ssl; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.opensearch.test.OpenSearchTestCase; +import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; @@ -44,6 +47,7 @@ import java.security.interfaces.ECPrivateKey; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; +import java.util.Locale; import java.util.function.Supplier; import static org.hamcrest.Matchers.equalTo; @@ -55,6 +59,7 @@ public class PemUtilsTests extends OpenSearchTestCase { private static final Supplier EMPTY_PASSWORD = () -> new char[0]; private static final Supplier TESTNODE_PASSWORD = "testnode"::toCharArray; + private static final Supplier STRONG_PRIVATE_SECRET = "6!6428DQXwPpi7@$ggeg/="::toCharArray; public void testReadPKCS8RsaKey() throws Exception { Key key = getKeyFromKeystore("RSA"); @@ -82,6 +87,16 @@ public void testReadPKCS8DsaKey() throws Exception { assertThat(privateKey, equalTo(key)); } + public void testReadEncryptedPKCS8DsaKey() throws Exception { + Key key = getKeyFromKeystore("DSA"); + assertThat(key, notNullValue()); + assertThat(key, instanceOf(PrivateKey.class)); + PrivateKey privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/dsa_key_pkcs8_encrypted.pem"), TESTNODE_PASSWORD); + + assertThat(privateKey, notNullValue()); + assertThat(privateKey, equalTo(key)); + } + public void testReadEcKeyCurves() throws Exception { String curve = randomFrom("secp256r1", "secp384r1", "secp521r1"); PrivateKey privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/private_" + curve + ".pem"), ""::toCharArray); @@ -102,6 +117,16 @@ public void testReadPKCS8EcKey() throws Exception { assertThat(privateKey, equalTo(key)); } + public void testReadEncryptedPKCS8EcKey() throws Exception { + var key = getKeyFromKeystore("EC"); + assertThat(key, notNullValue()); + assertThat(key, instanceOf(PrivateKey.class)); + var privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/ec_key_pkcs8_encrypted.pem"), TESTNODE_PASSWORD); + + assertThat(privateKey, notNullValue()); + assertThat(privateKey, equalTo(key)); + } + public void testReadEncryptedPKCS8Key() throws Exception { assumeFalse("Can't run in a FIPS JVM, PBE KeySpec is not available", inFipsJvm()); Key key = getKeyFromKeystore("RSA"); @@ -176,13 +201,12 @@ public void testReadEncryptedOpenSslDsaKey() throws Exception { } public void testReadOpenSslEcKey() throws Exception { - Key key = getKeyFromKeystore("EC"); + var key = getKeyFromKeystore("EC"); assertThat(key, notNullValue()); assertThat(key, instanceOf(PrivateKey.class)); - PrivateKey privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/ec_key_openssl_plain.pem"), EMPTY_PASSWORD); + var privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/ec_key_openssl_plain.pem"), EMPTY_PASSWORD); - assertThat(privateKey, notNullValue()); - assertThat(privateKey, equalTo(key)); + assertTrue(isCryptographicallyEqual((ECPrivateKey) key, (ECPrivateKey) privateKey)); } public void testReadOpenSslEcKeyWithParams() throws Exception { @@ -194,16 +218,41 @@ public void testReadOpenSslEcKeyWithParams() throws Exception { EMPTY_PASSWORD ); + assertTrue(isCryptographicallyEqual((ECPrivateKey) key, (ECPrivateKey) privateKey)); + } + + public void testReadEncryptedOpenSslEcKey() throws Exception { + var key = getKeyFromKeystore("EC"); + assertThat(key, notNullValue()); + assertThat(key, instanceOf(PrivateKey.class)); + var privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/ec_key_openssl_encrypted.pem"), TESTNODE_PASSWORD); + + assertTrue(isCryptographicallyEqual((ECPrivateKey) key, (ECPrivateKey) privateKey)); + } + + public void testReadEncryptedPKCS8KeyWithPBKDF2() throws Exception { + Key key = getKeyFromKeystore("PKCS8_PBKDF2"); + assertThat(key, notNullValue()); + assertThat(key, instanceOf(PrivateKey.class)); + PrivateKey privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/key_PKCS8_enc_pbkdf2.pem"), STRONG_PRIVATE_SECRET); assertThat(privateKey, notNullValue()); assertThat(privateKey, equalTo(key)); } - public void testReadEncryptedOpenSslEcKey() throws Exception { - Key key = getKeyFromKeystore("EC"); + public void testReadEncryptedDsaKeyWithPBKDF2() throws Exception { + Key key = getKeyFromKeystore("DSA_PBKDF2"); assertThat(key, notNullValue()); assertThat(key, instanceOf(PrivateKey.class)); - PrivateKey privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/ec_key_openssl_encrypted.pem"), TESTNODE_PASSWORD); + PrivateKey privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/key_DSA_enc_pbkdf2.pem"), STRONG_PRIVATE_SECRET); + assertThat(privateKey, notNullValue()); + assertThat(privateKey, equalTo(key)); + } + public void testReadEncryptedEcKeyWithPBKDF2() throws Exception { + Key key = getKeyFromKeystore("EC_PBKDF2"); + assertThat(key, notNullValue()); + assertThat(key, instanceOf(PrivateKey.class)); + PrivateKey privateKey = PemUtils.readPrivateKey(getDataPath("/certs/pem-utils/key_EC_enc_pbkdf2.pem"), EMPTY_PASSWORD); assertThat(privateKey, notNullValue()); assertThat(privateKey, equalTo(key)); } @@ -211,24 +260,24 @@ public void testReadEncryptedOpenSslEcKey() throws Exception { public void testReadUnsupportedKey() { final Path path = getDataPath("/certs/pem-utils/key_unsupported.pem"); SslConfigException e = expectThrows(SslConfigException.class, () -> PemUtils.readPrivateKey(path, TESTNODE_PASSWORD)); - assertThat(e.getMessage(), containsString("file does not contain a supported key format")); + assertThat(e.getMessage(), containsString("Error parsing Private Key")); assertThat(e.getMessage(), containsString(path.toAbsolutePath().toString())); + assertThat(e.getMessage(), containsString("file is empty")); } public void testReadPemCertificateAsKey() { final Path path = getDataPath("/certs/pem-utils/testnode.crt"); SslConfigException e = expectThrows(SslConfigException.class, () -> PemUtils.readPrivateKey(path, TESTNODE_PASSWORD)); - assertThat(e.getMessage(), containsString("file does not contain a supported key format")); + assertThat(e.getMessage(), containsString("invalid encrypted private key class")); assertThat(e.getMessage(), containsString(path.toAbsolutePath().toString())); } public void testReadCorruptedKey() { final Path path = getDataPath("/certs/pem-utils/corrupted_key_pkcs8_plain.pem"); SslConfigException e = expectThrows(SslConfigException.class, () -> PemUtils.readPrivateKey(path, TESTNODE_PASSWORD)); - assertThat(e.getMessage(), containsString("private key")); - assertThat(e.getMessage(), containsString("cannot be parsed")); + assertThat(e.getMessage(), containsString("Error parsing Private Key")); assertThat(e.getMessage(), containsString(path.toAbsolutePath().toString())); - assertThat(e.getCause().getMessage(), containsString("PEM footer is invalid or missing")); + assertThat(e.getMessage(), containsString("file is empty")); } public void testReadEmptyFile() { @@ -239,11 +288,27 @@ public void testReadEmptyFile() { } private Key getKeyFromKeystore(String algo) throws Exception { - Path keystorePath = getDataPath("/certs/pem-utils/testnode.jks"); + var keystorePath = getDataPath("/certs/pem-utils/testnode.jks"); + var alias = "testnode_" + algo.toLowerCase(Locale.ROOT); + var password = "testnode".toCharArray(); try (InputStream in = Files.newInputStream(keystorePath)) { KeyStore keyStore = KeyStore.getInstance("jks"); - keyStore.load(in, "testnode".toCharArray()); - return keyStore.getKey("testnode_" + algo, "testnode".toCharArray()); + keyStore.load(in, password); + return keyStore.getKey(alias, password); } } + + private boolean isCryptographicallyEqual(ECPrivateKey key1, ECPrivateKey key2) throws IOException { + var pki1 = PrivateKeyInfo.getInstance(key1.getEncoded()); + var pki2 = PrivateKeyInfo.getInstance(key2.getEncoded()); + + var privateKey1 = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(pki1.parsePrivateKey()).getKey(); + var privateKey2 = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(pki2.parsePrivateKey()).getKey(); + + var oid1 = ASN1ObjectIdentifier.getInstance(pki1.getPrivateKeyAlgorithm().getParameters()); + var oid2 = ASN1ObjectIdentifier.getInstance(pki2.getPrivateKeyAlgorithm().getParameters()); + + return privateKey1.equals(privateKey2) && oid1.equals(oid2); + } + } diff --git a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/SslConfigurationLoaderTests.java b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/SslConfigurationLoaderTests.java index 5af7ddc73e680..366e936ca4852 100644 --- a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/SslConfigurationLoaderTests.java +++ b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/SslConfigurationLoaderTests.java @@ -53,6 +53,7 @@ public class SslConfigurationLoaderTests extends OpenSearchTestCase { + private final String STRONG_PRIVATE_SECRET = "6!6428DQXwPpi7@$ggeg/="; private final Path certRoot = getDataPath("/certs/ca1/ca.crt").getParent().getParent(); private Settings settings; @@ -166,9 +167,9 @@ public void testLoadKeysFromPemFiles() { .put("test.ssl.key", certName + "/" + certName + ".key"); if (usePassword) { if (useLegacyPassword) { - builder.put("test.ssl.key_passphrase", "c2-pass"); + builder.put("test.ssl.key_passphrase", STRONG_PRIVATE_SECRET); } else { - secureSettings.setString("test.ssl.secure_key_passphrase", "c2-pass"); + secureSettings.setString("test.ssl.secure_key_passphrase", STRONG_PRIVATE_SECRET); } } settings = builder.build(); diff --git a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/SslDiagnosticsTests.java b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/SslDiagnosticsTests.java index c966b4259219f..e19fa91f7773e 100644 --- a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/SslDiagnosticsTests.java +++ b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/SslDiagnosticsTests.java @@ -70,6 +70,12 @@ public class SslDiagnosticsTests extends OpenSearchTestCase { private static final byte[] MOCK_ENCODING_4 = { 0x64, 0x65, 0x66, 0x67, 0x68, 0x69 }; private static final String MOCK_FINGERPRINT_4 = "5d96965bfae50bf2be0d6259eb87a6cc9f5d0b26"; + public void testTrustEmptyStore() { + var fileName = "cert-all/empty.jks"; + var exception = assertThrows(CertificateException.class, () -> loadCertificate(fileName)); + assertThat(exception.getMessage(), Matchers.equalTo("No certificate data found")); + } + public void testDiagnosticMessageWhenServerProvidesAFullCertChainThatIsTrusted() throws Exception { X509Certificate[] chain = loadCertChain("cert1/cert1.crt", "ca1/ca.crt"); final SSLSession session = session("192.168.1.1"); @@ -85,7 +91,7 @@ public void testDiagnosticMessageWhenServerProvidesAFullCertChainThatIsTrusted() message, Matchers.equalTo( "failed to establish trust with server at [192.168.1.1];" - + " the server provided a certificate with subject name [CN=cert1] and fingerprint [3bebe388a66362784afd6c51a9000961a4e10050];" + + " the server provided a certificate with subject name [CN=cert1] and fingerprint [7e0919348e566651a136f2a1d5974585d5b3712e];" + " the certificate has subject alternative names [DNS:localhost,IP:127.0.0.1];" + " the certificate is issued by [CN=Test CA 1];" + " the certificate is signed by" @@ -110,7 +116,7 @@ public void testDiagnosticMessageWhenServerProvidesAFullCertChainThatIsntTrusted message, Matchers.equalTo( "failed to establish trust with server at [192.168.1.1];" - + " the server provided a certificate with subject name [CN=cert1] and fingerprint [3bebe388a66362784afd6c51a9000961a4e10050];" + + " the server provided a certificate with subject name [CN=cert1] and fingerprint [7e0919348e566651a136f2a1d5974585d5b3712e];" + " the certificate has subject alternative names [DNS:localhost,IP:127.0.0.1];" + " the certificate is issued by [CN=Test CA 1];" + " the certificate is signed by (subject [CN=Test CA 1] fingerprint [2b7b0416391bdf86502505c23149022d2213dadc])" @@ -134,7 +140,7 @@ public void testDiagnosticMessageWhenServerFullCertChainIsntTrustedButMimicIssue message, Matchers.equalTo( "failed to establish trust with server at [192.168.1.1];" - + " the server provided a certificate with subject name [CN=cert1] and fingerprint [3bebe388a66362784afd6c51a9000961a4e10050];" + + " the server provided a certificate with subject name [CN=cert1] and fingerprint [7e0919348e566651a136f2a1d5974585d5b3712e];" + " the certificate has subject alternative names [DNS:localhost,IP:127.0.0.1];" + " the certificate is issued by [CN=Test CA 1];" + " the certificate is signed by (subject [CN=Test CA 1] fingerprint [2b7b0416391bdf86502505c23149022d2213dadc])" @@ -160,7 +166,7 @@ public void testDiagnosticMessageWhenServerProvidesEndCertificateOnlyAndTheCertA message, Matchers.equalTo( "failed to establish trust with server at [192.168.1.1];" - + " the server provided a certificate with subject name [CN=cert1] and fingerprint [3bebe388a66362784afd6c51a9000961a4e10050];" + + " the server provided a certificate with subject name [CN=cert1] and fingerprint [7e0919348e566651a136f2a1d5974585d5b3712e];" + " the certificate has subject alternative names [DNS:localhost,IP:127.0.0.1];" + " the certificate is issued by [CN=Test CA 1]" + " but the server did not provide a copy of the issuing certificate in the certificate chain;" @@ -185,7 +191,7 @@ public void testDiagnosticMessageWhenServerProvidesEndCertificateOnlyButTheCertA message, Matchers.equalTo( "failed to establish trust with server at [192.168.1.1];" - + " the server provided a certificate with subject name [CN=cert1] and fingerprint [3bebe388a66362784afd6c51a9000961a4e10050];" + + " the server provided a certificate with subject name [CN=cert1] and fingerprint [7e0919348e566651a136f2a1d5974585d5b3712e];" + " the certificate has subject alternative names [DNS:localhost,IP:127.0.0.1];" + " the certificate is issued by [CN=Test CA 1]" + " but the server did not provide a copy of the issuing certificate in the certificate chain;" @@ -209,7 +215,7 @@ public void testDiagnosticMessageWhenServerProvidesEndCertificateOnlyWithMimicIs message, Matchers.equalTo( "failed to establish trust with server at [192.168.1.1];" - + " the server provided a certificate with subject name [CN=cert1] and fingerprint [3bebe388a66362784afd6c51a9000961a4e10050];" + + " the server provided a certificate with subject name [CN=cert1] and fingerprint [7e0919348e566651a136f2a1d5974585d5b3712e];" + " the certificate has subject alternative names [DNS:localhost,IP:127.0.0.1];" + " the certificate is issued by [CN=Test CA 1]" + " but the server did not provide a copy of the issuing certificate in the certificate chain;" @@ -235,7 +241,7 @@ public void testDiagnosticMessageWhenServerProvidesEndCertificateWithMultipleMim message, Matchers.equalTo( "failed to establish trust with server at [192.168.1.9];" - + " the server provided a certificate with subject name [CN=cert1] and fingerprint [3bebe388a66362784afd6c51a9000961a4e10050];" + + " the server provided a certificate with subject name [CN=cert1] and fingerprint [7e0919348e566651a136f2a1d5974585d5b3712e];" + " the certificate has subject alternative names [DNS:localhost,IP:127.0.0.1];" + " the certificate is issued by [CN=Test CA 1]" + " but the server did not provide a copy of the issuing certificate in the certificate chain;" @@ -538,7 +544,7 @@ public void testDiagnosticMessageForClientCertificate() throws Exception { Matchers.equalTo( "failed to establish trust with client at [192.168.1.7];" + " the client provided a certificate with subject name [CN=cert1]" - + " and fingerprint [3bebe388a66362784afd6c51a9000961a4e10050];" + + " and fingerprint [7e0919348e566651a136f2a1d5974585d5b3712e];" + " the certificate is issued by [CN=Test CA 1]" + " but the client did not provide a copy of the issuing certificate in the certificate chain;" + " the issuing certificate with fingerprint [2b7b0416391bdf86502505c23149022d2213dadc]" @@ -571,7 +577,7 @@ public void testDiagnosticMessageWhenCaHasNewIssuingCertificate() throws Excepti message, Matchers.equalTo( "failed to establish trust with server at [192.168.1.4];" - + " the server provided a certificate with subject name [CN=cert1] and fingerprint [3bebe388a66362784afd6c51a9000961a4e10050];" + + " the server provided a certificate with subject name [CN=cert1] and fingerprint [7e0919348e566651a136f2a1d5974585d5b3712e];" + " the certificate has subject alternative names [DNS:localhost,IP:127.0.0.1];" + " the certificate is issued by [CN=Test CA 1];" + " the certificate is signed by (subject [CN=Test CA 1]" diff --git a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/StoreKeyConfigTests.java b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/StoreKeyConfigTests.java index 7806671d02793..1745c547d04ee 100644 --- a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/StoreKeyConfigTests.java +++ b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/StoreKeyConfigTests.java @@ -48,6 +48,7 @@ import java.security.cert.X509Certificate; import java.util.Arrays; +import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.arrayWithSize; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; @@ -95,7 +96,7 @@ public void testLoadMultipleKeyJksWithSeparateKeyPassword() throws Exception { assertKeysLoaded(keyConfig, "cert1", "cert2"); } - public void testKeyManagerFailsWithIncorrectStorePassword() throws Exception { + public void testKeyManagerFailsWithIncorrectJksStorePassword() throws Exception { assumeFalse("Can't use JKS/PKCS12 keystores in a FIPS JVM", inFipsJvm()); final Path jks = getDataPath("/certs/cert-all/certs.jks"); final StoreKeyConfig keyConfig = new StoreKeyConfig( @@ -109,7 +110,7 @@ public void testKeyManagerFailsWithIncorrectStorePassword() throws Exception { assertPasswordIsIncorrect(keyConfig, jks); } - public void testKeyManagerFailsWithIncorrectKeyPassword() throws Exception { + public void testKeyManagerFailsWithIncorrectJksKeyPassword() throws Exception { assumeFalse("Can't use JKS/PKCS12 keystores in a FIPS JVM", inFipsJvm()); final Path jks = getDataPath("/certs/cert-all/certs.jks"); final StoreKeyConfig keyConfig = new StoreKeyConfig(jks, JKS_PASS, "jks", JKS_PASS, KeyManagerFactory.getDefaultAlgorithm()); @@ -125,21 +126,20 @@ public void testKeyManagerFailsWithMissingKeystoreFile() throws Exception { assertFileNotFound(keyConfig, path); } - public void testMissingKeyEntriesFailsWithMeaningfulMessage() throws Exception { + public void testMissingKeyEntriesFailsForJksWithMeaningfulMessage() throws Exception { assumeFalse("Can't use JKS/PKCS12 keystores in a FIPS JVM", inFipsJvm()); - final Path ks; - final char[] password; - final String type; - if (randomBoolean()) { - type = "PKCS12"; - ks = getDataPath("/certs/ca-all/ca.p12"); - password = P12_PASS; - } else { - type = "jks"; - ks = getDataPath("/certs/ca-all/ca.jks"); - password = JKS_PASS; - } - final StoreKeyConfig keyConfig = new StoreKeyConfig(ks, password, type, password, KeyManagerFactory.getDefaultAlgorithm()); + final Path ks = getDataPath("/certs/ca-all/ca.jks"); + final char[] password = JKS_PASS; + final StoreKeyConfig keyConfig = new StoreKeyConfig(ks, password, "jks", password, KeyManagerFactory.getDefaultAlgorithm()); + assertThat(keyConfig.getDependentFiles(), Matchers.containsInAnyOrder(ks)); + assertNoPrivateKeyEntries(keyConfig, ks); + } + + public void testMissingKeyEntriesFailsForP12WithMeaningfulMessage() throws Exception { + assumeFalse("Can't use JKS/PKCS12 keystores in a FIPS JVM", inFipsJvm()); + final Path ks = getDataPath("/certs/ca-all/ca.p12"); + final char[] password = P12_PASS; + final StoreKeyConfig keyConfig = new StoreKeyConfig(ks, password, "PKCS12", password, KeyManagerFactory.getDefaultAlgorithm()); assertThat(keyConfig.getDependentFiles(), Matchers.containsInAnyOrder(ks)); assertNoPrivateKeyEntries(keyConfig, ks); } @@ -211,7 +211,10 @@ private void assertPasswordIsIncorrect(StoreKeyConfig keyConfig, Path key) { assertThat(exception.getMessage(), containsString("password")); } else { assertThat(exception.getCause(), instanceOf(IOException.class)); - assertThat(exception.getCause().getMessage(), containsString("password")); + assertThat( + exception.getCause().getMessage(), + anyOf(containsString("Keystore was tampered with, or password was incorrect"), containsString("BCFKS KeyStore corrupted")) + ); } } diff --git a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/StoreTrustConfigTests.java b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/StoreTrustConfigTests.java index 5609f0fa2c877..8058ffe95dc93 100644 --- a/libs/ssl-config/src/test/java/org/opensearch/common/ssl/StoreTrustConfigTests.java +++ b/libs/ssl-config/src/test/java/org/opensearch/common/ssl/StoreTrustConfigTests.java @@ -58,7 +58,7 @@ public class StoreTrustConfigTests extends OpenSearchTestCase { private static final char[] JKS_PASS = "jks-pass".toCharArray(); private static final String DEFAULT_ALGORITHM = TrustManagerFactory.getDefaultAlgorithm(); - public void testBuildTrustConfigFromPKCS12() throws Exception { + public void testBuildTrustConfigFromP12() throws Exception { assumeFalse("Can't use JKS/PKCS12 keystores in a FIPS JVM", inFipsJvm()); final Path ks = getDataPath("/certs/ca1/ca.p12"); final StoreTrustConfig trustConfig = new StoreTrustConfig(ks, P12_PASS, "PKCS12", DEFAULT_ALGORITHM); @@ -66,7 +66,7 @@ public void testBuildTrustConfigFromPKCS12() throws Exception { assertCertificateChain(trustConfig, "CN=Test CA 1"); } - public void testBuildTrustConfigFromJKS() throws Exception { + public void testBuildTrustConfigFromJks() throws Exception { assumeFalse("Can't use JKS/PKCS12 keystores in a FIPS JVM", inFipsJvm()); final Path ks = getDataPath("/certs/ca-all/ca.jks"); final StoreTrustConfig trustConfig = new StoreTrustConfig(ks, JKS_PASS, "jks", DEFAULT_ALGORITHM); @@ -91,28 +91,25 @@ public void testMissingKeyStoreFailsWithMeaningfulMessage() throws Exception { assertFileNotFound(trustConfig, ks); } - public void testIncorrectPasswordFailsWithMeaningfulMessage() throws Exception { + public void testIncorrectPasswordFailsForP12WithMeaningfulMessage() throws Exception { final Path ks = getDataPath("/certs/ca1/ca.p12"); final StoreTrustConfig trustConfig = new StoreTrustConfig(ks, new char[0], "PKCS12", DEFAULT_ALGORITHM); assertThat(trustConfig.getDependentFiles(), Matchers.containsInAnyOrder(ks)); assertPasswordIsIncorrect(trustConfig, ks); } - public void testMissingTrustEntriesFailsWithMeaningfulMessage() throws Exception { + public void testMissingTrustEntriesFailsForJksKeystoreWithMeaningfulMessage() throws Exception { assumeFalse("Can't use JKS/PKCS12 keystores in a FIPS JVM", inFipsJvm()); - final Path ks; - final char[] password; - final String type; - if (randomBoolean()) { - type = "PKCS12"; - ks = getDataPath("/certs/cert-all/certs.p12"); - password = P12_PASS; - } else { - type = "jks"; - ks = getDataPath("/certs/cert-all/certs.jks"); - password = JKS_PASS; - } - final StoreTrustConfig trustConfig = new StoreTrustConfig(ks, password, type, DEFAULT_ALGORITHM); + final Path ks = getDataPath("/certs/cert-all/certs.jks"); + final StoreTrustConfig trustConfig = new StoreTrustConfig(ks, JKS_PASS, "jks", DEFAULT_ALGORITHM); + assertThat(trustConfig.getDependentFiles(), Matchers.containsInAnyOrder(ks)); + assertNoCertificateEntries(trustConfig, ks); + } + + public void testMissingTrustEntriesFailsForP12KeystoreWithMeaningfulMessage() throws Exception { + assumeFalse("Can't use JKS/PKCS12 keystores in a FIPS JVM", inFipsJvm()); + final Path ks = getDataPath("/certs/cert-all/certs.p12"); + final StoreTrustConfig trustConfig = new StoreTrustConfig(ks, P12_PASS, "PKCS12", DEFAULT_ALGORITHM); assertThat(trustConfig.getDependentFiles(), Matchers.containsInAnyOrder(ks)); assertNoCertificateEntries(trustConfig, ks); } diff --git a/libs/ssl-config/src/test/resources/certs/README.md b/libs/ssl-config/src/test/resources/certs/README.md new file mode 100644 index 0000000000000..79790a4918f3e --- /dev/null +++ b/libs/ssl-config/src/test/resources/certs/README.md @@ -0,0 +1,155 @@ +# Create first CA PEM ("ca1") + +```bash +opensearch-certutil ca --pem --out ca1.zip --days 9999 --ca-dn "CN=Test CA 1" +unzip ca1.zip +mv ca ca1 +``` + +# Create first CA PEM ("ca2") + +```bash +opensearch-certutil ca --pem --out ca2.zip --days 9999 --ca-dn "CN=Test CA 2" +unzip ca2.zip +mv ca ca2 +``` + +# Create first CA PEM ("ca3") + +```bash +opensearch-certutil ca --pem --out ca3.zip --days 9999 --ca-dn "CN=Test CA 3" +unzip ca3.zip +mv ca ca3 +``` + +# Create "cert1-pkcs1" PEM + +```bash +opensearch-certutil cert --pem --out cert1-pkcs1.zip --name cert1 --ip 127.0.0.1 --dns localhost --days 9999 --ca-key ca1/ca.key --ca-cert ca1/ca.crt +unzip cert1.zip +``` + +# Create "cert2-pkcs1" PEM (same as cert1, but with a password) + +```bash +opensearch-certutil cert --pem --out cert2-pkcs1.zip --name cert2 --ip 127.0.0.1 --dns localhost --days 9999 --ca-key ca1/ca.key --ca-cert ca1/ca.crt --pass "c2-pass" +unzip cert2.zip +``` + +# Create "cert1" PEM + +```bash +openssl genpkey -algorithm RSA -out cert1/cert1.key +openssl req -new \ + -key cert1/cert1.key \ + -subj "/CN=cert1" \ + -out cert1/cert1.csr +openssl x509 -req \ + -in cert1/cert1.csr \ + -CA ca1/ca.crt \ + -CAkey ca1/ca.key \ + -CAcreateserial \ + -out cert1/cert1.crt \ + -days 3650 \ + -sha256 \ + -extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1") +rm cert1/cert1.csr +``` + +# Create "cert2" PEM (same as cert1, but with a password) + +```bash +openssl genpkey -algorithm RSA -out cert2/cert2.key -aes256 -pass pass:"$KEY_PW" +openssl req -new \ +-key cert2/cert2.key \ +-subj "/CN=cert2" \ +-out cert2/cert2.csr \ +-passin pass:"$KEY_PW" +openssl x509 -req \ +-in cert2/cert2.csr \ +-CA ca1/ca.crt \ +-CAkey ca1/ca.key \ +-CAcreateserial \ +-out cert2/cert2.crt \ +-days 3650 \ +-sha256 \ +-extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1") \ +-passin pass:"$KEY_PW" +rm cert2/cert2.csr +``` + +# Convert CAs to PKCS#12 + +```bash +for n in 1 2 3 +do + keytool -importcert -file ca${n}/ca.crt -alias ca -keystore ca${n}/ca.p12 -storetype PKCS12 -storepass p12-pass -v + keytool -importcert -file ca${n}/ca.crt -alias ca${n} -keystore ca-all/ca.p12 -storetype PKCS12 -storepass p12-pass -v +done +``` + +# Convert CAs to JKS + +```bash +for n in 1 2 3 +do + keytool -importcert -file ca${n}/ca.crt -alias ca${n} -keystore ca-all/ca.jks -storetype jks -storepass jks-pass -v +done +``` + +# Convert Certs to PKCS#12 + +```bash +for Cert in cert1 cert2 +do + openssl pkcs12 -export -out $Cert/$Cert.p12 -inkey $Cert/$Cert.key -in $Cert/$Cert.crt -name $Cert -passout pass:p12-pass +done +``` + +# Import Certs into single PKCS#12 keystore + +```bash +for Cert in cert1 cert2 +do + keytool -importkeystore -noprompt \ + -srckeystore $Cert/$Cert.p12 -srcstoretype PKCS12 -srcstorepass p12-pass \ + -destkeystore cert-all/certs.p12 -deststoretype PKCS12 -deststorepass p12-pass +done +``` + +# Import Certs into single JKS keystore with separate key-password + +```bash +for Cert in cert1 cert2 +do + keytool -importkeystore -noprompt \ + -srckeystore $Cert/$Cert.p12 -srcstoretype PKCS12 -srcstorepass p12-pass \ + -destkeystore cert-all/certs.jks -deststoretype jks -deststorepass jks-pass + keytool -keypasswd -keystore cert-all/certs.jks -alias $Cert -keypass p12-pass -new key-pass -storepass jks-pass +done +``` + +# Create a mimic of the first CA ("ca1b") for testing certificates with the same name but different keys + +```bash +opensearch-certutil ca --pem --out ${PWD}/ca1-b.zip --days 9999 --ca-dn "CN=Test CA 1" +unzip ca1-b.zip +mv ca ca1-b +``` + +# Create empty KeyStore + +```bash +keytool -genkeypair \ + -alias temp \ + -storetype JKS \ + -keyalg rsa \ + -storepass storePassword \ + -keypass secretPassword \ + -keystore cert-all/empty.jks \ + -dname "CN=foo,DC=example,DC=com" +keytool -delete \ + -alias temp \ + -storepass storePassword \ + -keystore cert-all/empty.jks +``` diff --git a/libs/ssl-config/src/test/resources/certs/README.txt b/libs/ssl-config/src/test/resources/certs/README.txt deleted file mode 100644 index 09910e99a132e..0000000000000 --- a/libs/ssl-config/src/test/resources/certs/README.txt +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash -# -# This is README describes how the certificates in this directory were created. -# This file can also be executed as a script -# - -# 1. Create first CA PEM ("ca1") - -opensearch-certutil ca --pem --out ca1.zip --days 9999 --ca-dn "CN=Test CA 1" -unzip ca1.zip -mv ca ca1 - -# 2. Create first CA PEM ("ca2") - -opensearch-certutil ca --pem --out ca2.zip --days 9999 --ca-dn "CN=Test CA 2" -unzip ca2.zip -mv ca ca2 - -# 3. Create first CA PEM ("ca3") - -opensearch-certutil ca --pem --out ca3.zip --days 9999 --ca-dn "CN=Test CA 3" -unzip ca3.zip -mv ca ca3 - -# 4. Create "cert1" PEM - -opensearch-certutil cert --pem --out cert1.zip --name cert1 --ip 127.0.0.1 --dns localhost --days 9999 --ca-key ca1/ca.key --ca-cert ca1/ca.crt -unzip cert1.zip - -# 5. Create "cert2" PEM (same as cert1, but with a password) - -opensearch-certutil cert --pem --out cert2.zip --name cert2 --ip 127.0.0.1 --dns localhost --days 9999 --ca-key ca1/ca.key --ca-cert ca1/ca.crt --pass "c2-pass" -unzip cert2.zip - -# 6. Convert CAs to PKCS#12 - -for n in 1 2 3 -do - keytool -importcert -file ca${n}/ca.crt -alias ca -keystore ca${n}/ca.p12 -storetype PKCS12 -storepass p12-pass -v - keytool -importcert -file ca${n}/ca.crt -alias ca${n} -keystore ca-all/ca.p12 -storetype PKCS12 -storepass p12-pass -v -done - -# 7. Convert CAs to JKS - -for n in 1 2 3 -do - keytool -importcert -file ca${n}/ca.crt -alias ca${n} -keystore ca-all/ca.jks -storetype jks -storepass jks-pass -v -done - -# 8. Convert Certs to PKCS#12 - -for Cert in cert1 cert2 -do - openssl pkcs12 -export -out $Cert/$Cert.p12 -inkey $Cert/$Cert.key -in $Cert/$Cert.crt -name $Cert -passout pass:p12-pass -done - -# 9. Import Certs into single PKCS#12 keystore - -for Cert in cert1 cert2 -do - keytool -importkeystore -noprompt \ - -srckeystore $Cert/$Cert.p12 -srcstoretype PKCS12 -srcstorepass p12-pass \ - -destkeystore cert-all/certs.p12 -deststoretype PKCS12 -deststorepass p12-pass -done - -# 10. Import Certs into single JKS keystore with separate key-password - -for Cert in cert1 cert2 -do - keytool -importkeystore -noprompt \ - -srckeystore $Cert/$Cert.p12 -srcstoretype PKCS12 -srcstorepass p12-pass \ - -destkeystore cert-all/certs.jks -deststoretype jks -deststorepass jks-pass - keytool -keypasswd -keystore cert-all/certs.jks -alias $Cert -keypass p12-pass -new key-pass -storepass jks-pass -done - -# 11. Create a mimic of the first CA ("ca1b") for testing certificates with the same name but different keys - -opensearch-certutil ca --pem --out ${PWD}/ca1-b.zip --days 9999 --ca-dn "CN=Test CA 1" -unzip ca1-b.zip -mv ca ca1-b - -# 12. Convert certifcate keys to pkcs8 - -openssl pkcs8 -topk8 -inform PEM -in cert1/cert1.key -outform PEM -out cert1/cert1-pkcs8.key -nocrypt -openssl pkcs8 -topk8 -inform PEM -in cert2/cert2.key -outform PEM -out cert2/cert2-pkcs8.key -passin pass:"c2-pass" -passout pass:"c2-pass" diff --git a/libs/ssl-config/src/test/resources/certs/cert-all/certs.p12 b/libs/ssl-config/src/test/resources/certs/cert-all/certs.p12 index b971a1e39c83baeea8e4fab3cf6b76804047ee48..73912976ca7cc61d310d02f1f8805d35ea75f612 100644 GIT binary patch literal 4895 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 delta 2438 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 E018}lU;qFB diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/README.md b/libs/ssl-config/src/test/resources/certs/pem-utils/README.md index 28602ac097f78..576b34317bd0a 100644 --- a/libs/ssl-config/src/test/resources/certs/pem-utils/README.md +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/README.md @@ -3,14 +3,15 @@ The certificates in this directory have been generated using the following openssl configuration and commands. -OpenSSL Configuration File is located in this directory as -`openssl_config.cnf`. +OpenSSL Configuration File is `openssl_config.cnf`. The `alt_names` section provides the Subject Alternative Names for each certificate. This is necessary for testing with hostname verification enabled. - openssl req -new -x509 -extensions v3_req -out .cert -keyout .pem -days 1460 -config config.cnf +```bash + openssl req -new -x509 -extensions v3_req -out .cert -keyout .pem -days 1460 -config openssl_config.cnf +``` When prompted the password is always set to the value of <NAME>. @@ -18,13 +19,18 @@ Because we intend to import these certificates into a Java Keystore file, they certificate and private key must be combined in a PKCS12 certificate. + +```bash openssl pkcs12 -export -name -in .cert -inkey .pem -out .p12 +``` # Creating the Keystore We need to create a keystore from the created PKCS12 certificate. +```bash keytool -importkeystore -destkeystore .jks -srckeystore .p12 -srcstoretype pkcs12 -alias +``` The keystore is now created and has the private/public key pair. You can import additional trusted certificates using `keytool -importcert`. When @@ -35,91 +41,141 @@ keystore if necessary. `testnode-unprotected.pem` is simply the decrypted `testnode.pem` +```bash openssl rsa -in testnode.pem -out testnode-unprotected.pem +``` `rsa_key_pkcs8_plain.pem` is the same plaintext key encoded in `PKCS#8` +```bash openssl pkcs8 -topk8 -inform PEM -outform PEM -in testnode-unprotected.pem -out rsa_key_pkcs8_plain.pem -nocrypt +``` `testnode-aes{128,192,256}.pem` is the testnode.pem private key, encrypted with `AES-128`, `AES-192` and `AES-256` respectively, encoded in `PKCS#1` +```bash openssl rsa -aes128 -in testnode-unprotected.pem -out testnode-aes128.pem openssl rsa -aes192 -in testnode-unprotected.pem -out testnode-aes192.pem openssl rsa -aes256 -in testnode-unprotected.pem -out testnode-aes256.pem +``` -Adding `DSA` and `EC` Keys to the Keystore +# Adding `DSA` and `EC` Keys to the Keystore +```bash keytool -genkeypair -keyalg DSA -alias testnode_dsa -keystore testnode.jks -storepass testnode \ - -keypass testnode -validity 10000 -keysize 1024 -dname "CN=OpenSearch Test Node" \ + -keypass testnode -validity 10000 -keysize 2048 -dname "CN=OpenSearch Test Node" \ -ext SAN=dns:localhost,dns:localhost.localdomain,dns:localhost4,dns:localhost4.localdomain4,dns:localhost6,dns:localhost6.localdomain6,ip:127.0.0.1,ip:0:0:0:0:0:0:0:1 keytool -genkeypair -keyalg EC -alias testnode_ec -keystore testnode.jks -storepass testnode \ - -keypass testnode -validity 10000 -keysize 256 -dname "CN=OpenSearch Test Node" \ + -keypass testnode -validity 10000 -groupname secp256r1 -dname "CN=OpenSearch Test Node" \ -ext SAN=dns:localhost,dns:localhost.localdomain,dns:localhost4,dns:localhost4.localdomain4,dns:localhost6,dns:localhost6.localdomain6,ip:127.0.0.1,ip:0:0:0:0:0:0:0:1 +``` -Exporting the `DSA` and `EC` private keys from the keystore +# Export the `DSA` and `EC` private keys from `JKS` to `PKCS#12` +```bash keytool -importkeystore -srckeystore testnode.jks -destkeystore dsa.p12 -deststoretype PKCS12 \ -srcalias testnode_dsa -deststorepass testnode -destkeypass testnode + keytool -importkeystore -srckeystore testnode.jks -destkeystore ec.p12 -deststoretype PKCS12 \ + -srcalias testnode_ec -deststorepass testnode -destkeypass testnode +``` + +# Export the `DSA` and `EC` private keys from `PKCS#12` keystore into `PKCS#8` format + +```bash openssl pkcs12 -in dsa.p12 -nodes -nocerts | openssl pkcs8 -topk8 -nocrypt -outform pem \ -out dsa_key_pkcs8_plain.pem - keytool -importkeystore -srckeystore testnode.jks -destkeystore ec.p12 -deststoretype PKCS12 \ - -srcalias testnode_ec -deststorepass testnode -destkeypass testnode + openssl pkcs12 -in dsa.p12 -nodes -nocerts | openssl pkcs8 -topk8 -outform pem \ + -out dsa_key_pkcs8_encrypted.pem openssl pkcs12 -in ec.p12 -nodes -nocerts | openssl pkcs8 -topk8 -nocrypt -outform pem \ - -out ec_key_pkcs8_plain.pem + -out ec_key_pkcs8_plain.pem -Create `PKCS#8` encrypted key from the encrypted `PKCS#1` encoded -`testnode.pem` + openssl pkcs12 -in ec.p12 -nodes -nocerts | openssl pkcs8 -topk8 -outform pem \ + -out ec_key_pkcs8_encrypted.pem +``` - openssl pkcs8 -topk8 -inform PEM -outform PEM -in testnode.pem -out key_pkcs8_encrypted.pem +# Export the `DSA` and `EC` private keys from `PKCS#12` keystore into `PKCS#1` format - ssh-keygen -t ed25519 -f key_unsupported.pem +```bash + openssl pkcs12 -in dsa.p12 -nodes -nocerts | openssl dsa -out dsa_key_openssl_plain.pem + + openssl pkcs12 -in dsa.p12 -nodes -nocerts | openssl dsa -des3 -out dsa_key_openssl_encrypted.pem -Convert `prime256v1-key-noparam.pem` to `PKCS#8` format + openssl pkcs12 -in ec.p12 -nodes -nocerts | openssl ec -out ec_key_openssl_plain.pem - openssl pkcs8 -topk8 -in prime256v1-key-noparam.pem -nocrypt -out prime256v1-key-noparam-pkcs8.pem + openssl pkcs12 -in ec.p12 -nodes -nocerts | openssl ec -des3 -out ec_key_openssl_encrypted.pem +``` -Generate the keys and self-signed certificates in `nodes/self/` : +# Create SSH key +```bash + ssh-keygen -t ed25519 -f key_unsupported.pem +``` +# Generate the keys and self-signed certificates in `nodes/self/` : +```bash openssl req -newkey rsa:2048 -keyout n1.c1.key -x509 -days 3650 -subj "/CN=n1.c1" -reqexts SAN \ -extensions SAN -config <(cat /etc/ssl/openssl.cnf \ <(printf "[SAN]\nsubjectAltName=otherName.1:2.5.4.3;UTF8:node1.cluster1")) -out n1.c1.crt +``` -Create a `CA` keypair for testing - +# Create a `CA` keypair for testing +```bash openssl req -newkey rsa:2048 -nodes -keyout ca.key -x509 -subj "/CN=certAuth" -days 10000 -out ca.crt +``` -Generate Certificates signed with our CA for testing - -  openssl req -new -newkey rsa:2048 -keyout n2.c2.key -reqexts SAN -extensions SAN \ +# Generate Certificates signed with our CA for testing +```bash + openssl req -new -newkey rsa:2048 -keyout n2.c2.key -reqexts SAN -extensions SAN \ -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=otherName.1:2.5.4.3;UTF8:node2.cluster2"))\ -out n2.c2.csr - openssl x509 -req -in n2.c2.csr -extensions SAN -CA ca.crt -CAkey ca.key -CAcreateserial \ -extfile <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=otherName.1:2.5.4.3;UTF8:node2.cluster2"))\ -out n2.c2.crt -days 10000 +``` # Generate EC keys using various curves for testing - +```bash openssl ecparam -list_curves +``` will list all the available curves in a given system. For the purposes of the tests here, the following curves were used to generate ec keys named accordingly: - +```bash openssl ecparam -name secp256r1 -genkey -out private_secp256r1.pem openssl ecparam -name secp384r1 -genkey -out private_secp384r1.pem openssl ecparam -name secp521r1 -genkey -out private_secp521r1.pem +``` and the respective certificates - +```bash openssl req -x509 -extensions v3_req -key private_secp256r1.pem -out certificate_secp256r1.pem -days 1460 -config openssl_config.cnf openssl req -x509 -extensions v3_req -key private_secp384r1.pem -out certificate_secp384r1.pem -days 1460 -config openssl_config.cnf openssl req -x509 -extensions v3_req -key private_secp521r1.pem -out certificate_secp521r1.pem -days 1460 -config openssl_config.cnf +``` + +# Generate encrypted keys with `PBKDF2` standard + +## RSA PKCS#8 +```bash + openssl genrsa -out key-temp.pem 2048 + openssl pkcs8 -in key-temp.pem -topk8 -v2 aes-256-cbc -v2prf hmacWithSHA512 -out key_PKCS8_enc_pbkdf2.pem +``` + +## DSA +```bash + openssl genpkey -genparam -algorithm DSA -out param_temp.pem -pkeyopt pbits:2048 -pkeyopt qbits:224 -pkeyopt digest:SHA256 -pkeyopt gindex:1 -text + openssl genpkey -paramfile param_temp.pem -out key_DSA_enc_pbkdf2.pem -aes256 -pass stdin +``` + +## EC +```bash + openssl genpkey -algorithm EC -out key_EC_enc_pbkdf2.pem -pkeyopt ec_paramgen_curve:secp384r1 -pkeyopt ec_param_enc:named_curve -pass stdin +``` diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_encrypted.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_encrypted.pem index a251de23f4879..6dafbae6a7785 100644 --- a/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_encrypted.pem +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_encrypted.pem @@ -1,15 +1,23 @@ -----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,BE9A0B63873F6B7A +DEK-Info: DES-EDE3-CBC,0DE7DF3D64FBE0C5 -lGSpJkwN0J9p+2Wm58706EYz6mmjgz7okjMtsR87GMIiK/wVwjKmyUa73QTVVs15 -N/EOySftBk3VUSPx9G1ZMxKpp3l/hvkIcsDDfCPAZFqwdQQJ8BEeF9jDd5ZoI6Yz -Yus1+X8A1OpX1O7PCZ08e2fLeVuEWg62/JQcNukuvL7AKm+qa1sda5/ktquv2eMZ -nbTiOE3Xe+uDsgABQdy1h4EsMEaMdE6QrWdxLGWDGcdzSzfltvnhmmsK2CQsV4e1 -huQeb8ylShJuIr+mgtKgUlIlJwSd7ka8hIdmGt1LO9+NZOPUGN04daQkETtfwsmu -YIYkh66CuLbT4nZny64Spa7AeINSmf9GA72/QtRSo3M7Khlw/95Lz24iKAy7/Lbt -AKYenSQeJtlNgWzPcDIeUrIzXXmAXHN5YGMg/7X0h7EGu5BxYbLydkBRvSkV9gzU -Ms6JD5aON10DQhjIUwUcBnhSnwPPpIVa2xf9mqytkcg+zDgr57ygZ9n4D+iv4jiC -ZJuFCFrgeqHrCEKRphWRckyhPo25ix9XXv7FmUw8jxb/3uTk93CS4Wv5LK4JkK6Z -AyF99S2kDqsE1u71qHJU2w== +sKlL1ZyhrDo/7CF2bVHPNJMZqbbfQ55ZAB+T2x63j1ssu3c9arMVFiNTm3gl29DX +6PtYopDglgZhK7YYLck5batMjSqwpl+lm6MgTDqzgZAMcCPl5KJd0ScuCP9nw/yE +uAzBBmhhHrxUtyGLZWX/RNq+pIv3rMs2MGrLjidJW4VkIXczEjoVbayzHqdOHzPa +GVeGfm68ykFO94KcJZWsGFQMCtm7DyYLNusC4P6O9hpYNsK09kqwqMiQFKUstIO7 +lyemCDCQa2wikO22wum6PgrSosIU2CoSo7AYgb7zpGOJdtQ15F6mC4+NOFY4Xk3d +N5ZB7vc/1Y4vqKBDMF9DANtK8LjYt13p9mVv2ZDH48qM9EadCtN26PeARlqwFBJv +hrVyVm7GOywY43XTVQqrF8MVDggunyGubEH1Endhh0PmVCL+hG9djQWLuCIUGON4 +6/2mA7dbyxzRi5qgC00BRjrpmti+vddVArFCoKvaOlELaGR1mSkpeKdfuI+WeZ6u +/GJ/tvG/4yWKoRxxsZ5JFj1njMVhgsgicaHV3r+jF4SjDkjDJ4TXcU1QgP0jnNEd +5O2Yn85MuUg99T6r/3lgW8WLelrRKuGocYDMi/huWaBwhA+FsB/5eCm0nwWgNpw5 +Z/aylu/XHqx9pE5veAzXajGkg0z3MbBp2Ig+q0XWxznbQZnMZSuLMlnIbmo77v86 +pAoLumTBaG8unmwPc3WDvyEC4/znx7aJwcLqMLwnDB7+qtNqG6OLzskARQ5+TqXk +6SFn2JX2EhJZ4X3yKqDs93haSlQlOxszEvoz9J94xtHdeTQ1EE8dFwSBU4UrCxmP +kTTTB/p9IfRXyXn7Bp00EfDPc+0+I0pZrnQLA3CLP8oxGngh7RBGE1BtjNU9mxCu +P2dn2lQBh1bB5u5Ggm7T87BEpWmTMaU7wrp5drrbzuS91OQf9UGRxVt0UZwApNBh +tqabqXourZ4NOERuy8WL9wFG8IAymSAEd7noVCXcv25SxBng2tyo9nI272Ufq1JM +ymn1Bf2aDDJsb/n17dAcfxwbnx6GdB0jEIoUaWMkSWh8FfjLpE29uUraVBBYTmd8 +TlkFmodWG8ctHpwDXSmQ80lcKC7lZ1M3NCjKwdKpcM+q8HG3VuFmrg== -----END DSA PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_plain.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_plain.pem index a64642fc9ab0c..40290ff1c2b1d 100644 --- a/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_plain.pem +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_plain.pem @@ -1,12 +1,20 @@ -----BEGIN DSA PRIVATE KEY----- -MIIBuwIBAAKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR -+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb -+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdg -UI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlX -TAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCj -rh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQB -TDv+z0kqAoGAd0xuuUUSAXsXaQ/dp9ThBTVzdVhGk6VAcWb403uMXUyXKsnCIAST -m6bVWKjNxO1EsP3Slyd5CwbqIRUBK5NjzdQP/hHGtEIbqtYKY1VZI7T91Lk8/Dc/ -p9Vgh27bPR8Yq8wPKU3EIJzYi0Nw8AxZf10yK+5tQ6pPUa3dH6lXt5oCFF1LyfuB -qBYh7hyIsfkb+cZoQ57t +MIIDTQIBAAKCAQEAj3k12bmq6b+r7Yh6z0lRtvMuxZ47rzcY6OrElh8+/TYG50NR +qcQYMzm4CefCrhxTm6dHW4XQEa24tHmHdUmEaVysDo8UszYIKKIv+icRCj1iqZNF +NAmg/mlsRlj4S90ggZw3CaAQV7GVrc0AIz26VIS2KR+dZI74g0SGd5ec7AS0NKas +LnXpmF3iPbApL8ERjJ/6nYGB5zONt5K3MNe540lZL2gJmHIVORXqPWuLRlPGM0WP +gDsypMLg8nKQJW5OP4o7CDihxFDk4YwaKaN9316hQ95LZv8EkD7VzxYj4VjUh8YI +6X8hHNgdyiPLbjgHZfgi40K+SEwFdjk5YBzWZwIdALr2lqaFePff3uf6Z8l3x4Xv +MrIzuuWAwLzVaV0CggEAFqZcWCBIUHBOdQKjl1cEDTTaOjR4wVTU5KXALSQu4E+W +5h5L0JBKvayPN+6x4J8xgtI8kEPLZC+IAEFg7fnKCbMgdqecMqYn8kc+kYebosTn +RL0ggVRMtVuALDaNH6g+1InpTg+gaI4yQopceMR4xo0FJ7ccmjq7CwvhLERoljnn +08502xAaZaorh/ZMaCbbPscvS1WZg0u07bAvfJDppJbTpV1TW+v8RdT2GfY/Pe27 +hzklwvIk4HcxKW2oh+weR0j4fvtf3rdUhDFrIjLe5VPdrwIRKw0fAtowlzIk/ieu +2oudSyki2bqL457Z4QOmPFKBC8aIt+LtQxbh7xfb3gKCAQBVB6bce7VXrIhB9hEE +jRlAUTm/Zezsl1CfaCjr+lejlxFybg5pkNQCvPsgpELnWXWz/8TXkbzAxSA3yGB0 +LSTp7gfucdFleJrGGZ94RTaIZFslDvk5HtFaZvjvUavyY3wCbMu+T1QUtfpQMQpP +qikplvg/2mzYhh3cMpdhFqj6EQcC12gHPPA7qC2jXnvsW1qqx0wtIxbBJvCqFqmA +gnOj/FoxqpTmMsMDG+8cwkOQ3PZTv1JbqVeJGFMvfsqb05SfZlO8XzXOvTm7Wexc +IXHTUTsXb36rH4tNpBqxCc+l1LOd3vXXPtxxBXsGDV2UeDOLWnMKp+FXj77vh0bc +W3aeAhw3xacY9KJHUobKmnlsyfgPhURZXWxg0U9oSzOr -----END DSA PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_plain_with_params.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_plain_with_params.pem index 0a2ea861b9b66..a57dbe80015c6 100644 --- a/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_plain_with_params.pem +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_openssl_plain_with_params.pem @@ -5,14 +5,22 @@ fexykg9Kxe/QBfDtcj3CEJNH/xoptJQVx3hi+0BPPK8+eUXTjwkQerGMwUD7UQak xuUS/22GakHZV5G/kCc= -----END DSA PARAMETERS----- -----BEGIN DSA PRIVATE KEY----- -MIIBuwIBAAKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR -+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb -+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdg -UI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlX -TAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCj -rh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQB -TDv+z0kqAoGAd0xuuUUSAXsXaQ/dp9ThBTVzdVhGk6VAcWb403uMXUyXKsnCIAST -m6bVWKjNxO1EsP3Slyd5CwbqIRUBK5NjzdQP/hHGtEIbqtYKY1VZI7T91Lk8/Dc/ -p9Vgh27bPR8Yq8wPKU3EIJzYi0Nw8AxZf10yK+5tQ6pPUa3dH6lXt5oCFF1LyfuB -qBYh7hyIsfkb+cZoQ57t +MIIDTQIBAAKCAQEAj3k12bmq6b+r7Yh6z0lRtvMuxZ47rzcY6OrElh8+/TYG50NR +qcQYMzm4CefCrhxTm6dHW4XQEa24tHmHdUmEaVysDo8UszYIKKIv+icRCj1iqZNF +NAmg/mlsRlj4S90ggZw3CaAQV7GVrc0AIz26VIS2KR+dZI74g0SGd5ec7AS0NKas +LnXpmF3iPbApL8ERjJ/6nYGB5zONt5K3MNe540lZL2gJmHIVORXqPWuLRlPGM0WP +gDsypMLg8nKQJW5OP4o7CDihxFDk4YwaKaN9316hQ95LZv8EkD7VzxYj4VjUh8YI +6X8hHNgdyiPLbjgHZfgi40K+SEwFdjk5YBzWZwIdALr2lqaFePff3uf6Z8l3x4Xv +MrIzuuWAwLzVaV0CggEAFqZcWCBIUHBOdQKjl1cEDTTaOjR4wVTU5KXALSQu4E+W +5h5L0JBKvayPN+6x4J8xgtI8kEPLZC+IAEFg7fnKCbMgdqecMqYn8kc+kYebosTn +RL0ggVRMtVuALDaNH6g+1InpTg+gaI4yQopceMR4xo0FJ7ccmjq7CwvhLERoljnn +08502xAaZaorh/ZMaCbbPscvS1WZg0u07bAvfJDppJbTpV1TW+v8RdT2GfY/Pe27 +hzklwvIk4HcxKW2oh+weR0j4fvtf3rdUhDFrIjLe5VPdrwIRKw0fAtowlzIk/ieu +2oudSyki2bqL457Z4QOmPFKBC8aIt+LtQxbh7xfb3gKCAQBVB6bce7VXrIhB9hEE +jRlAUTm/Zezsl1CfaCjr+lejlxFybg5pkNQCvPsgpELnWXWz/8TXkbzAxSA3yGB0 +LSTp7gfucdFleJrGGZ94RTaIZFslDvk5HtFaZvjvUavyY3wCbMu+T1QUtfpQMQpP +qikplvg/2mzYhh3cMpdhFqj6EQcC12gHPPA7qC2jXnvsW1qqx0wtIxbBJvCqFqmA +gnOj/FoxqpTmMsMDG+8cwkOQ3PZTv1JbqVeJGFMvfsqb05SfZlO8XzXOvTm7Wexc +IXHTUTsXb36rH4tNpBqxCc+l1LOd3vXXPtxxBXsGDV2UeDOLWnMKp+FXj77vh0bc +W3aeAhw3xacY9KJHUobKmnlsyfgPhURZXWxg0U9oSzOr -----END DSA PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_pkcs8_encrypted.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_pkcs8_encrypted.pem new file mode 100644 index 0000000000000..bd97ea336952d --- /dev/null +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_pkcs8_encrypted.pem @@ -0,0 +1,18 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIC1TBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQZyhaVfFi46pW+9xj +VTztDAICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEDmoN7JMaRafBZpK +ARWFoW4EggJwiqa8cBsGLJ/o3Q/54SR2CCAJ+UJbtylFwZ+GgvnKrzuqd2vSVSfm +mG/xC1h5hE6miYuZXpMZuNlCAeZi0odBVXzIMMkTXCC5ifufor4bb5EeMwQLder2 +NK4IW9QkOu8IzO/ohuT+xJwiWxnyItX3bh68GFDHJH+z0+WHILHNihoUBg+HZJZc +RDGSU9GATjcX4WMnDJUnaRVJ71umBZ35RJliKKm6oJYgEmbQpytd03paMttvYUD7 +zaRAZFBXXudNVV3GM/+KlJX4huyjKbaJOv99piUwrPr9WK9OqYd//tdU+TjJKZ4/ +8yMEmTfoEUJFtQTuJ7bp74EgrqtN2FtP4v7ZQ32Js/fL0TlS9SuxHY6XnyQAZm8A +C8rSql5nQD2RBfY+OZ8k2ixVUx2kNFBZS3GZds6aRX4AG5dFBajQOJ4sAQVHGLL5 +qB7xNblgL0tepApTQ9teD/O53fSMkbxEROxipG0ukiL2hMq4s1sMZzIHEq5U+wWs +HyqNIRBbrYv2zgE5TT6o+yszddtZcH5spRT22bmNGNrREWP9KMiCuOrfgcBEeLwa +KrWS+0cA0nzmGVxaw6tf5SzQHOy2t/+L93oDSBs/9uq89PpcMrYtW37EE0z9vcNO +PqDFfJOKNtaN45s2cG/iCpMOF5EaII86gCODgl+sUaITtNrOy5OROnsuJJV5Qlom +kRf2p6b1EF41UcF94dvYnMJrumeWfNltMhhDOHF0qiuL+iCwoMPD2M6VyWCypGLc +BNXNA6/pmw+o08blonOJ8grXQ3LWj6LmZdWkPorpwiepmzmKH9wIowSC1j+AddrG +a59Z6s9wFrIl +-----END ENCRYPTED PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_pkcs8_plain.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_pkcs8_plain.pem index fc5f17ce89897..d9f6e6108d227 100644 --- a/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_pkcs8_plain.pem +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/dsa_key_pkcs8_plain.pem @@ -1,9 +1,15 @@ -----BEGIN PRIVATE KEY----- -MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdS -PO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVCl -pJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith -1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7L -vKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3 -zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo -g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUXUvJ+4GoFiHuHIix+Rv5xmhDnu0= +MIICXAIBADCCAjUGByqGSM44BAEwggIoAoIBAQCPeTXZuarpv6vtiHrPSVG28y7F +njuvNxjo6sSWHz79NgbnQ1GpxBgzObgJ58KuHFObp0dbhdARrbi0eYd1SYRpXKwO +jxSzNggooi/6JxEKPWKpk0U0CaD+aWxGWPhL3SCBnDcJoBBXsZWtzQAjPbpUhLYp +H51kjviDRIZ3l5zsBLQ0pqwudemYXeI9sCkvwRGMn/qdgYHnM423krcw17njSVkv +aAmYchU5Feo9a4tGU8YzRY+AOzKkwuDycpAlbk4/ijsIOKHEUOThjBopo33fXqFD +3ktm/wSQPtXPFiPhWNSHxgjpfyEc2B3KI8tuOAdl+CLjQr5ITAV2OTlgHNZnAh0A +uvaWpoV499/e5/pnyXfHhe8ysjO65YDAvNVpXQKCAQAWplxYIEhQcE51AqOXVwQN +NNo6NHjBVNTkpcAtJC7gT5bmHkvQkEq9rI837rHgnzGC0jyQQ8tkL4gAQWDt+coJ +syB2p5wypifyRz6Rh5uixOdEvSCBVEy1W4AsNo0fqD7UielOD6BojjJCilx4xHjG +jQUntxyaOrsLC+EsRGiWOefTznTbEBplqiuH9kxoJts+xy9LVZmDS7TtsC98kOmk +ltOlXVNb6/xF1PYZ9j897buHOSXC8iTgdzEpbaiH7B5HSPh++1/et1SEMWsiMt7l +U92vAhErDR8C2jCXMiT+J67ai51LKSLZuovjntnhA6Y8UoELxoi34u1DFuHvF9ve +BB4CHDfFpxj0okdShsqaeWzJ+A+FRFldbGDRT2hLM6s= -----END PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_encrypted.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_encrypted.pem index 69dfde4b3c502..374467e05e280 100644 --- a/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_encrypted.pem +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_encrypted.pem @@ -1,7 +1,8 @@ -----BEGIN EC PRIVATE KEY----- Proc-Type: 4,ENCRYPTED -DEK-Info: AES-128-CBC,692E4272CB077E56A0D4772B323EFB14 +DEK-Info: DES-EDE3-CBC,0E2911A50F45B630 -BXvDiK0ulUFKw1fDq5TMVb9gAXCeWCGUGOg/+A65aaxd1zU+aR2dxhCGXjsiLzRn -YFSZR2J/L7YP1qvWC7f0NQ== +msSD9vAzUme59T7C1AL9XVLlcjnEEsA5v5fKvIr39GyJ0WeWTz7OaygM67xlkjGr +zBCabxgE4qL4Ydra8kEUZAbIYmdXs0kHBFlu2UFv8yltVfoWa8FR3VPEBrpq99L2 +NTuiWUEo9wvfLj7h4DiD5o3ejbMyomx8+V4uzWpCHbk= -----END EC PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_plain.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_plain.pem index e1d0a6a8319c0..e8009c1d2d520 100644 --- a/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_plain.pem +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_plain.pem @@ -1,4 +1,5 @@ -----BEGIN EC PRIVATE KEY----- -MDECAQEEILEXCgqp9wZqKVmG6HTESPeCyx2O4TDoFqyILz7OGocEoAoGCCqGSM49 -AwEH +MHcCAQEEILEXCgqp9wZqKVmG6HTESPeCyx2O4TDoFqyILz7OGocEoAoGCCqGSM49 +AwEHoUQDQgAE7mUZVxp/0TnDu8hSSedG9tGL4Fd1PhaUcdJ8f8ooFo+sYhDCp1m2 +1JzNJihfHNxhxpOYPDlz52yvero+raTAeQ== -----END EC PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_plain_with_params.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_plain_with_params.pem index 2ad57473236b3..c5bed51ef1f86 100644 --- a/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_plain_with_params.pem +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_openssl_plain_with_params.pem @@ -1,7 +1,8 @@ -----BEGIN EC PARAMETERS----- -Notvalidbutnotparsed +BggqhkjOPQMBBw== -----END EC PARAMETERS----- -----BEGIN EC PRIVATE KEY----- -MDECAQEEILEXCgqp9wZqKVmG6HTESPeCyx2O4TDoFqyILz7OGocEoAoGCCqGSM49 -AwEH +MHcCAQEEILEXCgqp9wZqKVmG6HTESPeCyx2O4TDoFqyILz7OGocEoAoGCCqGSM49 +AwEHoUQDQgAE7mUZVxp/0TnDu8hSSedG9tGL4Fd1PhaUcdJ8f8ooFo+sYhDCp1m2 +1JzNJihfHNxhxpOYPDlz52yvero+raTAeQ== -----END EC PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_pkcs8_encrypted.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_pkcs8_encrypted.pem new file mode 100644 index 0000000000000..bfef68d57a722 --- /dev/null +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/ec_key_pkcs8_encrypted.pem @@ -0,0 +1,6 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIGzMF8GCSqGSIb3DQEFDTBSMDEGCSqGSIb3DQEFDDAkBBBJgd9ei6iSF+3O6nhk +A/CTAgIIADAMBggqhkiG9w0CCQUAMB0GCWCGSAFlAwQBKgQQezbgAPm2wh2vFE6l +bGKePwRQZub5Evev8F/53CGRXhF0sdL+i/2zCJcmqrauwPr6VtgQdXmBlJcur3ft +4PDXCe1R+3jhk56gmOBDjnOepPnWge62lKO/nfff6lpgr/uXUe0= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/key_DSA_enc_pbkdf2.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/key_DSA_enc_pbkdf2.pem new file mode 100644 index 0000000000000..bb1655d2e9548 --- /dev/null +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/key_DSA_enc_pbkdf2.pem @@ -0,0 +1,18 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIC1TBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQ9WLcmXfK4mQgb8z0 +VEFgnAICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEGUh9m77oFyis8j5 +VedmDqIEggJwymDZJmHaNgIiJAI/psd+hR4n03oMwUaV72DmQewEdMhI2sEy36WU +Pup7X8VmRLb4tyiSiEUlh8FIX3cMpQ11e1j/lwW7wF+W3Qb6CHcMu8FCz3LN/CS4 +M+sQttfXiHh70qZvRx0SNaJo8A+e8HRGmYrbz6VqdlslSdB4fDT8Igls45rDZbch +LJlHQfy9XQSgCFR6J+6/6Q8GyW07+WnkuYnbixN8ZdZ4jPE5mrZYMMQrQY0l4ThG +vpb7U6VnWepDnXgeNWZTjHVLSAx3bbLUpbwotJnZISyTlRCxFSnunrRIkgaWPNMr +qE78FfE8I8Y/3Ft3AURgM+o/AvgyNCNM9g6DCqjaYpuaK0aJpdvaez9BiiANosBq +Powto+vuaDyYVIEhZ+GbokkvXx9muzvyA3KpqN1dg18au7Mqpkrenrw7Z5J8TnS2 +Pv686vSxCmisInC7c7uQYVxhze7fYMDUsyvWNPNUUrYnqrVtZtjD+VjkuZHJrBnL +haz5xQ0cw7pPY9r8R1y5jxMCVKxMBvbOsQJ+MBqGXseYmeB8qBBMYVdC+bNdEzga +rWD6FCX/k0PH2nP6KaU3qWLh3ueEtwTh0KO4yXgKyiLzF1KXoF93+4i9hX2w+t/W +Y5jgNErriqrW5WOQFDrSlVmMx1dLNFzM1cB7TKygZrzytULAYAg/0el8Gjbw7nKP +HInVUFKWhpNipEhDCGnGKoBvSz88AYAHS2I4fnFg3AfZCWEkkKJg++Y4Wip4+KTC +XjECqMqv6hwNbvMf3JkmqTPZVh8MtLIAiR1rUIWdZMq18+4vnHtW0FXzLb2nYn3u +ZrtXtOGxpBUY +-----END ENCRYPTED PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/key_EC_enc_pbkdf2.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/key_EC_enc_pbkdf2.pem new file mode 100644 index 0000000000000..b851058d17217 --- /dev/null +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/key_EC_enc_pbkdf2.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDA0+sj4ekT4h5OgmLaj +idCmLthqOUDdUNf67bBLjRSapUedsBIqSCx2u5E9ca2uGXKhZANiAAS6mhP+8zyk +CYIaOgF35O1KeRxrPsvWfm8tb5+KjuepPI+WR33xiBQcnYfeNrYMgP000Ifk8gfS +mv5aCHa5dBdgTzixsupMng0R8/jLPtS73Fzhi6G+KlRIe58c0xcVB5o= +-----END PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/key_PKCS8_enc_pbkdf2.pem b/libs/ssl-config/src/test/resources/certs/pem-utils/key_PKCS8_enc_pbkdf2.pem new file mode 100644 index 0000000000000..445d50f1cafe2 --- /dev/null +++ b/libs/ssl-config/src/test/resources/certs/pem-utils/key_PKCS8_enc_pbkdf2.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQ86A6gbRa4DZIX+cz +TSf/DAICCAAwDAYIKoZIhvcNAgsFADAdBglghkgBZQMEASoEEABJ5byRdWBpd1Ho +U/5ukYAEggTQoJkyyzwsns3QvYy4hIuwge7G867QPSCnHXhKInOYNDgbTnf36ia/ +eO5PELfEW0sW6ZZt/D9h28vssT0RI4PTyCQCv3DaVym6f9JbmnfvJePlaWkheieN +j2Y1gth4fEFWKQK6Px3hkZCCjc1LGrSSKoqy3YhWlxbjrj0UfCpF60MY0TLcegZ1 +Zdl4HVjROcDpSBC/OyWb9LXtyUM5NJVEjHqr138iP/S/qtkn7kovJEVqUSIZd2T9 +BQwzCDzZD8Rl3W/ivZnCn/3lHkDl2JgQ9gVXrk1QhtKy0XF8z1lrKbYPkCL4nXR7 +2qOScFSvF/JjbmhxlnfjyrpCv4ckcvT/+KFvbNQP1p8/OFfIsapG6wTz2XGcwgA/ +c4uxrnB/110KO2m1zexsasxRTfvyHaTIPHl6NNh565cjieqdvp5KbzZBs9eJA19e +NTeLVbXYZA5Ols0FF9cG5eeU7NPVFVMS7UILHnq9v+i1eKO1VPUWmCZhR8Sje0M2 +DpzSnQmrErVaH/lbZ9ZOklFhpL+UvW+g8IBSLLdCo+MlyOr/Ydr0HiADBb5zSiUo +iWOrzgA9lLDG7VSHrpTU0I+PE+QctLVTPX2f+S+/pErnQ7Y+DE+OOsM37jGt8Zsi +r+XcxxTZUmiakr6fUDEVG0NxbErTRgpHdSoT3RFgcs37MlrC88JbOs1cOiwma7/e +56gqx/3uHJWyPKjVC/RUfIqsSpTx1EjqHeGYnJ9DTW+Yft+d7/HEZOr0Nl+3Qmoa +b6Bxw+5c6Of7HYhEKoi37l7O1//bmrs0pURPWPmawPZtlfwd03ifFTZDOvn8cKEL +TUFHBYd3V8kNmqRI/oUq28gk7uFd0Wby4epXcSVgSX2hAloSMYGfzcUU5u38v18J +JxYgg3DyJAMH3V/GHV98XU0zscbaTKreKMUaXduDS3ktk9maq6Mne/fpI/ZZP7pr +C7c1RJWKbSSdwAchQCMcIHUSZjA0iI7dIde9VP8e1DlErdWch3i7wdJQV4YqMM8v +3sR3fV31vkZcSUDRCcBJPlNd/j6+AaIU0zVt3yWUUSCExSAOCybrlu0JPCSjjyOu +Kkp0xEa6xt240QA+PyeUl7aov1wKZ1P95aek0y1AJy9SmcBUwBBVaeG+ETO/C5gv +g6VqjG18BX6ulzJsOsLnQCxvbQajB/eF7dvex2OzU+jPUPuvZ1IRu4SHw88eyGz6 +r8RzQ1d7sCr+kV6pWXrEaNnwyFhOhwdNMxaYwSUItrfb3+4jPDoHa/di0sJ4Dkr/ +UVuqnc7TAdW9x+PTtUWMQfaX7S8o6XDNXkhcWznhNP7OmkQpT2K5kkaGfLeHKRbz +7NHCwRXEm49ZPfDCnI9kddnejU60vDHW1uBGH2S5kn71noAe7R07s9qeKW50eLOf +Pe9BlOPb205gnibRYjjj0pUZ1YJwD4rkiXaX/fXHkPpgpyUEbw3tAZW+FqXUZSaW +TwAj41oXms0VoaUi/TcvsIDjnldVvZ0MkHUwMtfOvHb/lbrafHKoTHIuBbRAHSNf +uQXvBDwiq2uv3v0EZdz4mouqcp8aNZmunVHu7c22HCaf4s608BIq4FBqrq6XRdqo +cAOcq+WGk+F/helMKaRWo737062tq3dlhtRpGLXbZUcYThUNY4SjR6Q= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/libs/ssl-config/src/test/resources/certs/pem-utils/testnode.jks b/libs/ssl-config/src/test/resources/certs/pem-utils/testnode.jks index ebe6146124e8fd607e46a1a3129bdf9b4de0370d..1502bbad4eaedce7194d7e28acfe87e6b86c29b4 100644 GIT binary patch delta 6649 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 HG#>GrQ0C_2 diff --git a/modules/reindex/build.gradle b/modules/reindex/build.gradle index a44e1004d93ad..00931848d0644 100644 --- a/modules/reindex/build.gradle +++ b/modules/reindex/build.gradle @@ -87,11 +87,6 @@ thirdPartyAudit.ignoreMissingClasses( 'org.apache.log.Logger', ) -forbiddenPatterns { - // PKCS#12 file are not UTF-8 - exclude '**/*.p12' -} - tasks.named("bundlePlugin").configure { dependsOn("copyParentJoinMetadata") dependsOn("copyTransportNetty4Metadata") diff --git a/modules/reindex/src/test/java/org/opensearch/index/reindex/ReindexRestClientSslTests.java b/modules/reindex/src/test/java/org/opensearch/index/reindex/ReindexRestClientSslTests.java index 1123ae4623300..d0b0403874c7a 100644 --- a/modules/reindex/src/test/java/org/opensearch/index/reindex/ReindexRestClientSslTests.java +++ b/modules/reindex/src/test/java/org/opensearch/index/reindex/ReindexRestClientSslTests.java @@ -84,6 +84,7 @@ @SuppressForbidden(reason = "use http server") public class ReindexRestClientSslTests extends OpenSearchTestCase { + private static final String STRONG_PRIVATE_SECRET = "6!6428DQXwPpi7@$ggeg/="; private static HttpsServer server; private static Consumer handler = ignore -> {}; @@ -115,11 +116,10 @@ public static void shutdownHttpServer() { private static SSLContext buildServerSslContext() throws Exception { final SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); - final char[] password = "http-password".toCharArray(); final Path cert = PathUtils.get(ReindexRestClientSslTests.class.getResource("http/http.crt").toURI()); final Path key = PathUtils.get(ReindexRestClientSslTests.class.getResource("http/http.key").toURI()); - final X509ExtendedKeyManager keyManager = new PemKeyConfig(cert, key, password).createKeyManager(); + final X509ExtendedKeyManager keyManager = new PemKeyConfig(cert, key, STRONG_PRIVATE_SECRET.toCharArray()).createKeyManager(); final Path ca = PathUtils.get(ReindexRestClientSslTests.class.getResource("ca.pem").toURI()); final X509ExtendedTrustManager trustManager = new PemTrustConfig(Collections.singletonList(ca)).createTrustManager(); @@ -184,7 +184,7 @@ public void testClientPassesClientCertificate() throws IOException { .putList("reindex.ssl.certificate_authorities", ca.toString()) .put("reindex.ssl.certificate", cert) .put("reindex.ssl.key", key) - .put("reindex.ssl.key_passphrase", "client-password") + .put("reindex.ssl.key_passphrase", STRONG_PRIVATE_SECRET) .put("reindex.ssl.supported_protocols", "TLSv1.2") .build(); AtomicReference clientCertificates = new AtomicReference<>(); @@ -206,8 +206,8 @@ public void testClientPassesClientCertificate() throws IOException { assertThat(certs, Matchers.arrayWithSize(1)); assertThat(certs[0], Matchers.instanceOf(X509Certificate.class)); final X509Certificate clientCert = (X509Certificate) certs[0]; - assertThat(clientCert.getSubjectDN().getName(), Matchers.is("CN=client")); - assertThat(clientCert.getIssuerDN().getName(), Matchers.is("CN=Elastic Certificate Tool Autogenerated CA")); + assertThat(clientCert.getSubjectDN().getName(), Matchers.is("CN=localhost, OU=UNIT, O=ORG, L=TORONTO, ST=ONTARIO, C=CA")); + assertThat(clientCert.getIssuerDN().getName(), Matchers.is("CN=OpenSearch Test Node")); } } diff --git a/modules/reindex/src/test/resources/org/opensearch/index/reindex/README.md b/modules/reindex/src/test/resources/org/opensearch/index/reindex/README.md new file mode 100644 index 0000000000000..f2ff25d41a890 --- /dev/null +++ b/modules/reindex/src/test/resources/org/opensearch/index/reindex/README.md @@ -0,0 +1,48 @@ +# generate self-signed CA key + cert +```bash +export KEY_PW='6!6428DQXwPpi7@$ggeg/=' +openssl genpkey -algorithm RSA -out ca.key -aes256 -pass pass:"$KEY_PW" +openssl req -x509 -key ca.key -sha256 -days 3650 -subj "/CN=OpenSearch Test Node" -passin pass:"$KEY_PW" \ + -addext "subjectAltName=DNS:localhost,DNS:localhost.localdomain,DNS:localhost4,DNS:localhost4.localdomain4,DNS:localhost6,DNS:localhost6.localdomain6,IP:127.0.0.1,IP:0:0:0:0:0:0:0:1" \ + -out ca.pem +``` +# generate client key + cert +```bash +export NAME='client' +openssl genpkey -algorithm RSA -out "$NAME".key -aes256 -pass pass:"$KEY_PW" +openssl req -new \ + -key "$NAME".key \ + -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=localhost" \ + -out "$NAME".csr \ + -passin pass:"$KEY_PW" +openssl x509 -req \ + -in "$NAME".csr \ + -CA ../ca.pem \ + -CAkey ../ca.key \ + -CAcreateserial \ + -out "$NAME".crt \ + -days 3650 \ + -sha256 \ + -passin pass:"$KEY_PW" +rm "$NAME".csr +``` +# repeat the same for server key + cert +```bash +export NAME='http' +openssl genpkey -algorithm RSA -out "$NAME".key -aes256 -pass pass:"$KEY_PW" +openssl req -new \ + -key "$NAME".key \ + -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=localhost" \ + -out "$NAME".csr \ + -passin pass:"$KEY_PW" +openssl x509 -req \ + -in "$NAME".csr \ + -CA ../ca.pem \ + -CAkey ../ca.key \ + -CAcreateserial \ + -out "$NAME".crt \ + -days 3650 \ + -sha256 \ + -passin pass:"$KEY_PW" +rm "$NAME".csr +``` diff --git a/modules/reindex/src/test/resources/org/opensearch/index/reindex/README.txt b/modules/reindex/src/test/resources/org/opensearch/index/reindex/README.txt deleted file mode 100644 index efd5e4c20ffd3..0000000000000 --- a/modules/reindex/src/test/resources/org/opensearch/index/reindex/README.txt +++ /dev/null @@ -1,16 +0,0 @@ -# ca.p12 - - -# ca.pem - -openssl pkcs12 -info -in ./ca.p12 -nokeys -out ca.pem -passin "pass:ca-password" - -# http.p12 - -unzip http.zip -rm http.zip - -# client.p12 - -unzip client.zip -rm client.zip diff --git a/modules/reindex/src/test/resources/org/opensearch/index/reindex/ca.key b/modules/reindex/src/test/resources/org/opensearch/index/reindex/ca.key new file mode 100644 index 0000000000000..a04c18c994359 --- /dev/null +++ b/modules/reindex/src/test/resources/org/opensearch/index/reindex/ca.key @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQ8TSOq343U8BV3rEt +vOpSPQICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEFXKi3C3VJzsGiCw +Lh2zY40EggTQwtBoa+e+J/UAA/mVv50rVH7oqvs5t9wRfznrldPtUgTR7r06TxNB +DXN1spBSmJjrohC3RbEO4169YqCwAk2HsptENM3MV5A9EwTuXPVBW/ic2SDOwmiP +wvRRKUujjaYZTfVeVJi0LqnCtyv7/hc33MJ3IMeNefEwmYRH3u/ktp+NBXZPEp1G +sdbPLpCxUqtq8zE84ev+RyURbErWVvjI8ma20Hn2gACkQazYTSVMVMxvj4+m0oBd +hzQ54GjRypm6Tc+CkJXGbCp+3sCONUqKARZYo+oiL5wEdGTLOcCwaCZxVkftDZ4V +oGrHVlgFrYgADaOuokjMf178ymMJX1+kTYze/k/ajXHd8qBKRD1X49dDhrHjnlhV +2sGOTKk16fBXSoM/q4vfmBKkd+BxDcdbsDkLDdT266XBy9hdRnL6e3Qk6ag6i0dB +faJwyXHIhiS87nFLpYeXY47DABBvmKVqafdHJDab7GYmLb+2J33EbmQX+tMgKrI+ +l5FjPX0Lz6/c74M6jYGHhbii3fZKGzb9BwWCEG7eIMONfv7IoaP2HI/P5G1WheQ+ +Ocd4lsb+pCmy+tzQcB7+GtWX0sG4ugCTsKIofN9ZmkvdQsvQvjT/oubDtBXUMgIL +/6GpYr7f535wD8jp4qHjSNyiNf93XiepxUsKBh0xvcGRRfhEjrZhnDm8DYP014bL +HhWzPVUgQwDJMa92wzsqFpXCujhLDb3BzLZLCGWDUkDsPjX2hUzNRWw+nN0FEwkD +ezxZOpK7m/ZfZi0rI94oYpmanwLNH5tvwr7pKLJ2SAP2WTNYRtff7vgeKOmgDG97 +pSm49phrSdM/VbwWgoPHpGxn6De5mfp+52dz5sCZMP0tsYMa947z2VDAU9f7+AQL +V73HGQKu8eny2ofOvQiKMK7sVo9dDvf6O4fGUCZh55YmQYzNq1cYh5lgQgPJ/CDb +c2mUVhwPfd4gvmKzBQ+nxjo5Jbh0vJwqOxk0SMCwWqQW5+Y9mdcDseyJwL7iyiTd +xyN9rUdro86foF85Xja+MZ0hVW/q1xwrZSiunWuvg0uaGMdSuknn7skLnKrdbfIU +RocweZPetFxzCm7XeikCaKucoNLNSPjAKW13doZSOc4OxS4hXep211dGVvK43XwX +B6xp8WtquZaGk01J789H1XU/sz6AssuCrMvql0Gd/GeFz+Ql9dMd4bH2ZzjpRcWL +FMZvsxXzqp5zodsn/j26h+WKZYmLSnxvE+WjQHyECt1JgSyYD2I84CxKj9I5ezX7 +1PIc3/OPl14p+ni/lfx6UM5WmbrHcuLM5a2ml/9e+HQci2xDNflkCiRQ1jcXYSB4 +p5mAaxSPbC33mi7jvBtUF1Yk9CiIRW941pKhn5YSj4bEMs6h8tB4M9wfXn9HPe/X +0KdYFMzf5sc9nmDZt2A1EoZexYwMk56wVQ7gnekw9ECCs6OLUmXkAmKojvbNXG0C ++t0W3LSoFsMM6vnINVooK+dQgRLqXFe57HY8j7zTmFh69Kh3/Cv24gQ21xwPYB6y +A9AVrrxRUV4Nlqkw5A4kVKXRry9/xj5DGgZ4SI2rJZ3vhfD2jiLFnl+JBT/Cw2xL +NL32subXNGqY4ymnq1HSG3SO/Jgh21XZL8rl2kZ+QiT7QvRVFWefRdA= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/modules/reindex/src/test/resources/org/opensearch/index/reindex/ca.pem b/modules/reindex/src/test/resources/org/opensearch/index/reindex/ca.pem index ee758ca3e6370..615f00e468ae6 100644 --- a/modules/reindex/src/test/resources/org/opensearch/index/reindex/ca.pem +++ b/modules/reindex/src/test/resources/org/opensearch/index/reindex/ca.pem @@ -1,25 +1,22 @@ -Bag Attributes - friendlyName: ca - localKeyID: 54 69 6D 65 20 31 35 34 37 30 38 36 32 32 39 31 30 37 -subject=/CN=Elastic Certificate Tool Autogenerated CA -issuer=/CN=Elastic Certificate Tool Autogenerated CA -----BEGIN CERTIFICATE----- -MIIDSTCCAjGgAwIBAgIUacmv5ElKJ1cs9n61tEpy5KM3Dv0wDQYJKoZIhvcNAQEL -BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l -cmF0ZWQgQ0EwHhcNMTkwMTEwMDIxMDI5WhcNNDYwNTI3MDIxMDI5WjA0MTIwMAYD -VQQDEylFbGFzdGljIENlcnRpZmljYXRlIFRvb2wgQXV0b2dlbmVyYXRlZCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0rA35tPl0FN+BPk2YfmET9 -MvDWFLvfL2Z1aw1q1vnd12K9zumjN6veilHA2Iw/P4LG/mkQZvY4bDPgibRD7hbE -vwPoju4vr614tw60+FlkpO6HezYo2I3cni1//Gehhs5EW2P3g7Lw7UNCOAfcR2QQ -p/dtwXYWzXHY9jTevQSv2q/x5jWKZT4ltaQExzvXAcxRGqyWV6d5vol3KH/GpCSI -SQvRmRVNQGXhxi66MjCglGAM2oicd1qCUDCrljdFD/RQ1UzqIJRTXZQKOno1/Em9 -xR0Cd5KQapqttPusAO6uZblMO2Ru+XjCD6Y0o41eCDbkd0xA3/wgP3MD5n41yncC -AwEAAaNTMFEwHQYDVR0OBBYEFJTry9da5RZbbELYCaWVVFllSm8DMB8GA1UdIwQY -MBaAFJTry9da5RZbbELYCaWVVFllSm8DMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI -hvcNAQELBQADggEBADA6qhC35PwuL7LRddbhjjW8U/cCmG9m7AIvH6N+Mw/k76gt -tJkEDxztMHUG+A2IPyEcYm7MLr1D8xEQYsq0x4pzFcQnMSQDv4WTK35vRxMtaqwA -WZTyA+DibBknbaP1z3gNhR9A0TKx4cPagN3OYFvAi/24abf8qS6D/bcOiPDQ4oPb -DVhmhqt5zduDM+Xsf6d4nsA6sf9+4AzneaZKGAMgCXgo4mYeP7M4nMQk0L3ao9Ts -+Usr8WRxc4xHGyb09fsXWSz7ZmiJ6iXK2NvRUq46WCINLONLzNkx29WEKQpI3wh4 -kyx6wF9lwBF06P1raFIBMeMOCkqDc+nj7A91PEA= +MIIDszCCApugAwIBAgIUOpUOL6Dz5+T+y+SIDknp8nOB2x4wDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUT3BlblNlYXJjaCBUZXN0IE5vZGUwHhcNMjQwODI3MTgy +MDE2WhcNMzQwODI1MTgyMDE2WjAfMR0wGwYDVQQDDBRPcGVuU2VhcmNoIFRlc3Qg +Tm9kZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2bmzHyMB705hS2 +Vu02WaTz7iWU11aVlNwAEVWIpjarDsk1IeICYe2vtv7e9qAp5IAMC6y9Db4XAx6A +PKJHZ5XcrWKpJqanMUwMi7dJ7wLWauMlx4WdyWSdJ3KRVO0Xzdr6My6dV+LCiiYX +cQCFYzEQYX02kU8M8NZ3J9t5OK3MF8/f0gta5vMs/1akPJzTMYyLva+hcNyGC9pW +Ly0w2kWxqze00KjT8wnmUz3h6gxxRwwdocsyZ1AE635anRu2MuAo94sA8kwQdl6z +cKtTzlzbLmrBQzusnuQtJCKGzvH+uBGodFpQhi5JpYVbuSvqI1Lumg7RA524cb0t +OKnijBECAwEAAaOB5jCB4zAdBgNVHQ4EFgQU41fNVZMW0Kc5nmv53kKTINZT0CMw +HwYDVR0jBBgwFoAU41fNVZMW0Kc5nmv53kKTINZT0CMwDwYDVR0TAQH/BAUwAwEB +/zCBjwYDVR0RBIGHMIGEgglsb2NhbGhvc3SCFWxvY2FsaG9zdC5sb2NhbGRvbWFp +boIKbG9jYWxob3N0NIIXbG9jYWxob3N0NC5sb2NhbGRvbWFpbjSCCmxvY2FsaG9z +dDaCF2xvY2FsaG9zdDYubG9jYWxkb21haW42hwR/AAABhxAAAAAAAAAAAAAAAAAA +AAABMA0GCSqGSIb3DQEBCwUAA4IBAQBObbHtMsaa0XTJAlJk4DE9kHgZoxF8ImFI +c1huhnCr2X+XkKxYDF/QUA1XRDWI9S4/6xBDKZdD+RhZ6ds3CbG4JVtoJa1Vvjla +dk11uirkKCqbYrdyc/+KeLS4ruYhG/JoqycTp/G5aCrThZgIgf0jm4peJwd9nqaz ++yjP4L4sDR4rfdLIsk96hPKDImD+5uuJ9KqMj8DO589uqJwhTehfPcNfL4hVdQ66 +IEKK6HM5DMXYzRFr7yAseKZbXngn5QJ+ZBldikP0hgGFYbT1kbNtFOqwpYNvgGvr +ptei46poM3WCB04puszm62E4Jora6rxaLwWGp+6TWELLwUUs9so7 -----END CERTIFICATE----- diff --git a/modules/reindex/src/test/resources/org/opensearch/index/reindex/client/client.crt b/modules/reindex/src/test/resources/org/opensearch/index/reindex/client/client.crt index 337d24e2493ac..9111fb215a448 100644 --- a/modules/reindex/src/test/resources/org/opensearch/index/reindex/client/client.crt +++ b/modules/reindex/src/test/resources/org/opensearch/index/reindex/client/client.crt @@ -1,19 +1,20 @@ -----BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIUNOREYZadZ2EVkJ1m8Y9jnVmWmtAwDQYJKoZIhvcNAQEL -BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l -cmF0ZWQgQ0EwHhcNMTkwMTEwMDIxMDMyWhcNNDYwNTI3MDIxMDMyWjARMQ8wDQYD -VQQDEwZjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCCP2LE -nws2+ZIwSQ3IvIhVfrueUmNt7Y5TdhhwO32p2wC4ZA62J9L8klAzt7R+izcL/qbF -65inbXM0A7ge/2wZ09kbqBk5uS8jDetJS8lQmWVZDHfVi8g/yDMWklz2mQYleYmU -HPyIplai3P3KBoT8HurzHw2C953EZ2HiANFnGoEPZZ5ytcT2WenxuU5kSXSxuDyn -8/dCVHEQL1Yipr2LQKYQAHotjo56OhyL9KS5YPjzSFREeyRfQinssTmpGFsua/PK -Vqj+hRdkaqRfiqPq3wxn8oOSpZLQe58O1e7OlqgjkPuZdjZ0pQ7KJj7N3fUQNSeg -2VC2tk8zv/C/Qr2bAgMBAAGjTTBLMB0GA1UdDgQWBBQziDNuD83ZLwEt1e1txYJu -oSseEDAfBgNVHSMEGDAWgBSU68vXWuUWW2xC2AmllVRZZUpvAzAJBgNVHRMEAjAA -MA0GCSqGSIb3DQEBCwUAA4IBAQAPpyWyR4w6GvfvPmA1nk1qd7fsQ1AucrYweIJx -dTeXg3Ps1bcgNq9Us9xtsKmsoKD8UhtPN6e8W8MkMmri+MSzlEemE+pJZrjHEudi -Sj0AFVOK6jaE0lerbCnTQZvYH+J9Eb1i9RP7XHRShkR4MWgy2BzlENk9/LRbr84W -Yf5TuM9+ApiiiOoX9UfSGBzNnqwhJNpG9yJ+HnQSqTnJJc/wL0211zLme9I/nhf0 -kQx6mPedJ3gGoJ8gqz38djIrhJDxq+0Bd9SsdlR6yT+1+bY7hinYx2eLV91AybZ4 -x07Kyl174DD41PYaE1AtoLlrMrQ5BG7Md50Am+XXOR1X1dkZ +MIIDUTCCAjmgAwIBAgIURxNp9ImDloxqOPNAP0ySBZN/BDQwDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUT3BlblNlYXJjaCBUZXN0IE5vZGUwHhcNMjQwODI4MTA0 +MzUwWhcNMzQwODI2MTA0MzUwWjBiMQswCQYDVQQGEwJDQTEQMA4GA1UECAwHT05U +QVJJTzEQMA4GA1UEBwwHVE9ST05UTzEMMAoGA1UECgwDT1JHMQ0wCwYDVQQLDARV +TklUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCp7qyGufu1cQYWJJGZ04XulVdwsKytMeLNSDHT90ratfsAy5WP3CRy +fug0E6nB7eykSHnE8aYomrghJIL0oP3v7b7vV/iasZ17Q2uiY67fQb4s6Rvrcov5 +R7ak5/B22uslDrDY0BaSWKCxHREb55rMhVWlVTXpm91kdGvo4Q61Gcxe45mweKR8 +UMbUlNuXrW/xwTwYI4pdDxha2ZXgTBrBJXppEh/KQp0rdy4Be3KG5IbqrH/Bh6cG +4CZ/di0i6xWxAhQOlOKlcTHpMAtXx0eBjha/Y9+p3/7z9fmE/JsYozw56r75CPDG +VpNiSDoPMPed4uhpbXQVYeCTUe3Hh8WRAgMBAAGjQjBAMB0GA1UdDgQWBBTm5Cel +/aWnBGFDUnZKNYs+BVFHFzAfBgNVHSMEGDAWgBTjV81VkxbQpzmea/neQpMg1lPQ +IzANBgkqhkiG9w0BAQsFAAOCAQEAjaXJN+NyS74cDTAtjVqo4e+h2K/LfYyIpdYp +mTDi+wRBlprJUDl18TK26c0hV6T4MN8QxqoqCXoEVJZWDjBYOUsl3OfSgPpT0aww +3Z/mIPOLb9mR1zOO9tXZhgNdFCLRRepiLyPRsRVQ3K3klle42DHaEIOUlwtqAArF +d9MKg9PShrRjqJwlm8vL3E8KjNeC8gAvebF3e7ADIatXjRK5Rc/LQhgPCaCZKSDF +w36AhGBnXsCgi3IR00E9CWOsC2UVeAhgHHaN1oJjuLfFupG/2Vx6Ii+PAgueE7ec +VWQeasxHihc0VjEYtSiNlYO6A8rcH7lg+0OCzGr97DC+zfFZwQ== -----END CERTIFICATE----- diff --git a/modules/reindex/src/test/resources/org/opensearch/index/reindex/client/client.key b/modules/reindex/src/test/resources/org/opensearch/index/reindex/client/client.key index 95e11f79cea24..ca0c6ba868047 100644 --- a/modules/reindex/src/test/resources/org/opensearch/index/reindex/client/client.key +++ b/modules/reindex/src/test/resources/org/opensearch/index/reindex/client/client.key @@ -1,30 +1,30 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,81AB10154C04B38F - -0L6Buvpeg6QHh/mbYp/3bXDCsu0k0j5xPdIGWd6NCOdb24OQFsOjeA2WuPqs0WWF -gzVrjh984biS3IqeglEr6X6PfVJ0QOgBkq0XgSBXhuoRJL/302N9oPGsf8T8oW9t -pqR/JIB2L7lMbJlJYSjMl0YQT3hWpo2BlrtSIc/GWOKfjDNWc9BL+oHvKJwql1lb -n4yMvYFYJDqgzgxa3r4IIQNsCn3SP+gqbTx9vF6StOIroV51BdSL4IGWRvqnMJrh -ybk1EHSLR1oGcONLU4Ksi33UxdImG70SsnoH/NnInDvV2bxmxmgf5SfYKtxFhoxz -0hISKTMTerPGtRQ5p8wtEi/ULKyInK+qF3tLgZa+S5VbByjDnUo2dCcbDDSkH5pO -uczJ2bs1kJegpCrUueJdbi9OX2upmF+tJb9+5hzFTvey8dUWTEpdiN0xbp4BLfNd -Yp4sMHZovsDJKIjDb0NbXRgLeFh1ijlLPhKwIXWTF3BaCKcSw34Qv22YPwn3qNuw -0KuUPAo0B65R/hoJguvtks8QAXe0S1jZS/fAlQCoIB0TIduy1qkyje+AnSW+1RL0 -ysBxLqbvRUqWlgnu7/28V4FD8JNu3O+UGBEelXlfokLgCBZ6lSys2d3Zy/XVBnG0 -cPl59if+fxKaMWlhFvMLFBup1Y4a/1zA7Sx6kkhvawekHr40NcG4kLHJ+O6UoM4d -/ibnbfIksLNkuo/nwoEcKp7W6SxafV0hROdxClkGKild66rnHtk4IGATjaBqt9nr -FuO3vRtLuUMS+/4kpvhMwl0RhX2/i6xgV+klWNYNu1JTGDFvdG3qfiY2w88EIbGe -rn8JEvRtaH/XNeGdhBwbuObvTifiHyYzA1i5Zh8zvE2+Dthlk19jbBoOUx//LOi2 -JrNkAsqQCF4HXh7n9HWA/ZrKTP7Xvkig6Vf7M2Y/tO361LSJfzKcRFLpl0P2ntEv -XwFOqTvOURERTVr4sBLOVPRAhIs3yvkI5xfurXzbRWtSeLgrMoDgJlXIQbuXd8sq -zIBLqvYf2bcroB66XJqX1IFWEstym/NHGcbrwjR5Fn2p3YAtXnIbw8VhHwV+LIOl -ky/wH9vbnML/DE81qFqRe8vNZw2sGn9skOyU/QvKeV1NRHYZSV3hMx82bPnjgFeB -ilzkb8FEPOAOJ0m44Q3C9eUoazJT8aCuRIAgSL43se1E2pFlIXQTfYRARaWEkSf9 -0hXqQJc17b+Hj0ire3PUqbG3+/l1qMhhIHwq7Kuyy2neTuW/DXbXp2AMv/bLcnHH -apVeRZaYXVSnGXJNk2CeRnCs8OGir8g5zkH+fmVb9knt6TL2oFIsQqULyrLolhfe -6Q8mLzq/sd+w+VuN1n/5+RQqOJZWEkLFzQPx8wTqeTB19OE0gjncrqzCHq7INqRe -tGClWOj/yL0Sciu3ctVGz1VAbgeBKnLdKm2TX4oFB4OG4E7GMXIL7hGxjtjLAVMW -XNc3ZYNQra+iPqJtFxnmbrF2Sn0Wr0hcAT1V0A0TRKe/n0lpUrfhTy/q4DUlOVKG -qdCsTGoYXObpUWU5G9GyCVWWRJyrTxJcBZ9KWJu9Y/aMFzoa2n0HQw== ------END RSA PRIVATE KEY----- +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQO04hOVF1REJsgAkP +xkFZ/gICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEENoXPnjByIDKjwqz +3+WRgNsEggTQuv3EOfjFwF8f0fac2GjJJxN3L2b88CeKxbjTL/6kQ1bvWSI1+L45 +0zP6CQ+5lI3N9/0YFoCWX5y57e+OXafAWivkUp/LiGkYWcRnqGVhZgSQTFQP9rly ++3PUDLlM5FuGylKvoqYmTIBud1puBiChYj0FKImOyHgPH3/GEGbTSrtvCSZkCw72 +XkkF32/OtSbqTuGlGgl+pGLTtnS2+RhgiCzXMCtvHJqjhAh22J7uoYYqk02QKEme +GMWM4anxmLPBr/Rw04NrlEfgRl8mTIhgrgwKV/mwfK++kqboWpzfXPs/S4KHJxmv +WvVcxHovoyovBA87C8cY4Qz/PZzm9vZr/+hQCF0OJgvZejWiUiuRJ9HgeteKTEMo +CrOlyZXcaMHPCa8CK6U+lUBwTZbAAzMYSazfaf8524yDGksOA4J/KGC3uvviYW09 +hTaqhq0yGqBUe5mrgEEhSV2vIpjK6MKxMtvjKvc1fjfrYIL9BGiiHOCGaljQTQAA +yLZqQwlj//v4om3onR6HOfZeYsQxzH5zNFSIJa96/kBBWG9Q0ZMmqEqB52rNUT28 +ZapjaqqRkos/rBdvzDQzlyx+NjZnOsueEkC+cX/1psIoE+6vLbonMrlzl+SSqtxB +EuSD7dekZ7o3eQLzRI13ohRtzMv4ojWMpr769WsQ4KKflK7pLVdIYFZbL0Q44s/w +Bc9ByiwSGymhEO6uqqfBT1baj19yTrc3FU/jaJyIsRNs/EAc7c6nPejiiwxtE7Ex +oVSwbKoD2CXB/DYlenenBGvuP1jyHSkQqv2YWdL1bm9Rp8DNJ+HG0OP913fTuE3V +7ScOt2ZnR2B+VWN3Eu8MdiX16vi/ub/4H1HihANw/W5HSwuW88V7fGcbSzRWxyCN +5Od7b5y2zAD/tl+x4GXFZ9k+di2sZc7W6zzVqHr55nfxvsFvHt5dWipTxZFdVhRh +tXhGnYCfr1gKN4FdTW/MuYa3otHL4gVpnVdQ10C48bCljCaVdep/AhC5dj0GaTyx +VJBzzD5vp6zt6jsfjI059+zVyR5zxhEKeotURVTqzhz08TOHCkyQP0KRQ+U5ve80 +9cj1odt43JBXFq5w9/aUQWG6ZnBJQup/zlDdGncPd0+3Eh0WoQyDh/XlFosrxt7L +QF9SqN9oTIp9Fgr6yOFrDOamQAb6f+5Ms5XNegHmlqSkGcpJxf2JBNinrY4drrQ8 +GuVCQ94GhjdGMdSM8Vv8Yi+8RHyqn6R2hjiY4PX+86J+xFNOGr5RiXk8NUp5kM5s +ZfffpB0ELlgBQzEv2PV9hdh66M8EGjyQl4ItzXg3JhbiXOKAQLbpPOD22zcZsmm2 +r5E4vgRwYfHnmwqJsrIcvMK1m4USlGuwJYP5ExuwE4xdsaUNwKEd3gZAXzhV1YKn +HyBfJFwYJsBR+l9G9kt/ZWpEd2DNnfss7ujQYTHGQ6WT1zbKbCsb8aE1CNXXs93C +DtuMUvG+BRTwuSAtvWTf+XPcTjgTrrAKQq2tmsbDe3CEgW5r/4+OL6s3nxI/mVVg +4jOcUZ0bePBvu+4/jIRqlx2MZIFRp+vvR4RiQ0wYBcihW7Wed8y+ZWdHxg6eUlJP +WXwdmXsz+NFMXpJvBX0OgntVzxEdJAyGEeBArBJPAKmcbR3JfDWMQ8M= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/modules/reindex/src/test/resources/org/opensearch/index/reindex/http/http.crt b/modules/reindex/src/test/resources/org/opensearch/index/reindex/http/http.crt index 309ade87fbd78..317991a707a16 100644 --- a/modules/reindex/src/test/resources/org/opensearch/index/reindex/http/http.crt +++ b/modules/reindex/src/test/resources/org/opensearch/index/reindex/http/http.crt @@ -1,22 +1,20 @@ -----BEGIN CERTIFICATE----- -MIIDsjCCApqgAwIBAgIUXxlg/0/g3UYekXWBRpkHM84EYfIwDQYJKoZIhvcNAQEL -BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l -cmF0ZWQgQ0EwHhcNMTkwMTEwMDIxMDMwWhcNNDYwNTI3MDIxMDMwWjAPMQ0wCwYD -VQQDEwRodHRwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi8VQaSR6 -uqgT1Rkw+a39OSXcXuhJBVdoO+AyYPK7hdUTxj1aqnXkKeAiNGpe/J+uXZ837Spy -rmBZS3k6S5hLEceF2xug8yrR7RYEZ+JvGlRgg/jj+61gGbHAD314+vvu0YUo06YG -wbz9AnjJA/sMbsCp3iSzWIkwZBZcCoZ/YsG4I89LSjYL3YmRi2193WMX6/OfQYMN -Fkv61r/iwBEkgJ14cUSYe3norGuQfZuXSh5kI5D5R7q7Bmb0um+jzY/l62kj3oR1 -YWo3g6DdU/Bc/3/KmEEVXIfdTonMBMyL8PvYORoMKrYdph3E8e39ZQhPeBJNJKw0 -XzsZFzIUlTw0kQIDAQABo4HgMIHdMB0GA1UdDgQWBBTiqknjZLa5E1BneHRvTkNa -Bm4nNTAfBgNVHSMEGDAWgBSU68vXWuUWW2xC2AmllVRZZUpvAzCBjwYDVR0RBIGH -MIGEgglsb2NhbGhvc3SCF2xvY2FsaG9zdDYubG9jYWxkb21haW42hwR/AAABhxAA -AAAAAAAAAAAAAAAAAAABggpsb2NhbGhvc3Q0ggpsb2NhbGhvc3Q2ghVsb2NhbGhv -c3QubG9jYWxkb21haW6CF2xvY2FsaG9zdDQubG9jYWxkb21haW40MAkGA1UdEwQC -MAAwDQYJKoZIhvcNAQELBQADggEBAIZr8EhhCbNyc6iHzUJ/NrUGht5RDHUKN9WU -2fd+SJlWijQYGoFW6LfabmYxIVPAFtYzUiA378NFoOZZ4kdC3gQng8izvS2UDcO6 -cAG5q/dxop3VXqcLeK3NpH2jd83M8VZaOThPj/F07eTkVX+sGu+7VL5Lc/XPe8JS -HhH2QtcTPGPpzPnWOUMLpRy4mh5sDyeftWr2PTFgMXFD6dtzDvaklGJvr1TmcOVb -BFYyVyXRq6v8YsrRPp0GIl+X3zd3KgwUMuEzRKkJgeI1lZRjmHMIyFcqxlwMaHpv -r1XUmz02ycy6t3n+2kCgfU6HnjbeFh55KzNCEv8TXQFg8Z8YpDA= +MIIDUTCCAjmgAwIBAgIURxNp9ImDloxqOPNAP0ySBZN/BDUwDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUT3BlblNlYXJjaCBUZXN0IE5vZGUwHhcNMjQwODI4MTA0 +NDE1WhcNMzQwODI2MTA0NDE1WjBiMQswCQYDVQQGEwJDQTEQMA4GA1UECAwHT05U +QVJJTzEQMA4GA1UEBwwHVE9ST05UTzEMMAoGA1UECgwDT1JHMQ0wCwYDVQQLDARV +TklUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCk1Ot2RGbUS3yJchvdtrcGJPoR8cTTUfVVMMRT+btXayllbLQd/cHV +jP1DxauXiLQs77R3NGfPs/Sk7fGQh6p/4F52F5wlNqG/Hq0MquqjXEo/ey8i+p5Y +zTB8v2Hv6RwN0HLB2uiAUOWjHvddiz36nfPmQ5jlF+IsR36KMb6AWHaB60kUabZL +vPOrtw7KZMkHRC+3tXvvepNe3uAKTIOEeHJneNNc76ShPnjANev7ONpNHgvMTJDY +nbNtDL2WnHvnyEwIgWLOnJ1WgOAsiSpebPqibi+25FirFKGTB2qp2NfU+tCoK7hG +1nPfPSCxBEqhwoJOywft2AxhDoicvo+HAgMBAAGjQjBAMB0GA1UdDgQWBBQ2Dr4v +2/aWi1JSmXfRITKOTlwa+DAfBgNVHSMEGDAWgBTjV81VkxbQpzmea/neQpMg1lPQ +IzANBgkqhkiG9w0BAQsFAAOCAQEAXEmxgNViixLWVQx9EgWscxaiI4d4OFd7Dfb/ +11qRtKoobEuSK5lOhDim8hZfs+iueKHuT/bRJ59Yu/p4GS+ZeJRgEXfCdY9S3Zeb +qGCi/IBRT1oq4vD3OSWA88C3I+pGXRb7R3fvtIcfy42o1FdHAg3MOlRx7fZHtAdE +GJ4SRsKTex7phWvKZ14R+wj45B8dA8Ty6/6nzPqb5+SLa5w37jU/gdew2cW2lEaN +tZb/aj1l5LmxXje3mvVag5SR2ussDrARcRu+uW7qYq0IzzQDxyzwpEWPC/QsgEme +9GFPd3xNu4tSoM0arrK8xjNtEh4P2gokhNJwy+vDGvKMrrWjVg== -----END CERTIFICATE----- diff --git a/modules/reindex/src/test/resources/org/opensearch/index/reindex/http/http.key b/modules/reindex/src/test/resources/org/opensearch/index/reindex/http/http.key index 8b8d3b4083c67..68b61c6d6e03e 100644 --- a/modules/reindex/src/test/resources/org/opensearch/index/reindex/http/http.key +++ b/modules/reindex/src/test/resources/org/opensearch/index/reindex/http/http.key @@ -1,30 +1,30 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,127A4142FA81C5A1 - -dP6oSAUl47KCnP0YZSX108qcX5s2nVGpD0qtnVQg89mLVFd7IxpKQaIuODSadRTo -AD0KINITy3ZwUr/TTJgERu88baBsTHv3PLEe7TpQI2DGGDz3aZfO9e6Jvglbdi5b -CBLaxRXGGhhH9YH0E87Lp3JEwg4udWmlNahGIhbqNheZNTtDKt+Lx80TyyIml2r/ -GAhjT4UPvIRrATFAcL/3EKOjRqvb6SeGnZu21n2TSmsBEr02gC0Ox3qmsnRM3kvU -jCuUzWTzJSQLXZwZuMtv5srOSFAbU8EklFXNhWJU/7GBy215aAAW48hCzkPMVEbg -oeH4nuze/Uulih9UxJGCBIpvfTnksyMRGP/zdy1mnKuqQk+yI0n7JWMJL8QoDQc8 -XvzqOmKLdBVezmzOVP/PyMAhYWetILh/1UesjyJot2hwSXPAxqBHPVA9bnmel6CQ -VccNSwaK120yT5YhkUMFc0AmUpztzNMQzJ10g1dW+Qsr+n4vtFmAuTvBgogNNVXn -eX1hbbiXGO1Fw4OMu6qTJ4T/P+VFb0CxoxETWeqdjcs4LGbeqF68nayEsW0ZzhbI -W5c+JAbW18Kb+k/KzKZTtJEXBw6B/2FMe9x9z3BIpVhplM2KsNk7joWnumD8LfUT -ORRHUPV7bkdiDsn2CRaevubDQiChcjsdLWhG7JLm54ttyif7/X7htGOXPZLDLK8B -Vxe09B006f7lM0tXEx8BLFDNroMLlrxB4K5MlwWpS3LLqy4zDbHka2I3s/ST/BD4 -0EURHefiXJkR6bRsfGCl3JDk0EakcUXM+Ob5/2rC/rPXO2pC0ksiQ2DSBm7ak9om -vlC7dIzVipL0LZTd4SUDJyvmK4Ws6V98O5b+79To6oZnVs5CjvcmpSFVePZa5gm/ -DB8LOpW4jklz+ybJtHJRbEIzmpfwpizThto/zLbhPRyvJkagJfWgXI0j+jjKZj+w -sy1V8S44aXJ3GX9p4d/Grnx6WGvEJSV0na7m3YQCPEi5sUgr+EMizGUYstSSUPtU -XhxQRZ95K2cKORul9vzG3zZqqvi73Ju5vu9DLmmlI00sLzyVGFtvkuhrF2p7XclM -GU/rMOeMClMb6qyCzldSs84Anhlh/6mYri6uYPhIGvxqtH44FTbu1APvZp0s2rVm -ueClHG78lat+oqWFpbA8+peT0dMPdSKDAFDiHsGoeWCIoCF44a84bJX35OZk+Y4a -+fDFuSiKYBMfAgqf/ZNzV4+ySka7dWdRQ2TDgIuxnvFV1NgC/ir3/mPgkf0xZU5d -w8T+TW6T8PmJfHnW4nxgHaqgxMoEoPm8zn0HNpRFKwsDYRFfobpCXnoyx50JXxa4 -jg095zlp8X0JwconlGJB1gfeqvS2I50WEDR+2ZtDf7fUEnQ3LYJzP4lSwiSKiQsQ -MPjy0SMQnqmWijylLYKunTl3Uh2DdYg4MOON662H3TxQW8TCYwK2maKujwS9VFLN -GtRGlLrOtrOfHBSwDCujFjqEmQBsF/y2C6XfMoNq6xi5NzREGmNXYrHbLvl2Njwm -WB1ouB4JzmEmb1QNwxkllBAaUp1SJGhW2+fYOe0zjWOP9R4sUq4rRw== ------END RSA PRIVATE KEY----- +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQprhRDFFTnmWmHgAB +ULpI4wICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEEuzT8itQgHZfKb/ +ReywEdIEggTQD117YFYRhSSivErIhTKQSuofhH/ZgW6nYnKlcDT08bgNQjbEg94a +QZqsPl9D6tfcmg7XlNTEiQpnSnsh6LrrhQbNkt3PvJxfUUy0ATVXXdH538RcPLAC +K2NHi1iwSbnqdcBU+/Be8M1F9e9P5hx6HbJGEF/JIkpWDDmOoCGvlwfH0PSiliY4 +uqxsmekvNgz2GBhELZj4sEJ7C7/I26vOuzS6suDn6xGF8JZIg8i7upamUgLoBtG/ +waxlmfTx+hkYFDQGcy9jvkV043sK/hLTOycUGhmS1ybQSf9ANbsM8RjOIq6QxpIZ +wtV/7EzqDWYradQBRrhAP24yzEj6H1cTr8yMmD6JuxvGZ7uQpTCRiFopB6TgK+x+ +2HqEgeRyBz4hU0i22kyGHC9sSG9WwKhmXhfcBtzJi3JABbkeg9LarwOzbh51DaxN +/gTop4UYRTYbJB9bhcIU0Y5xPSSphphCWmGuBU6CinsBj1w+UBP137GzgnXvV6PL +S8tai963P38Oafw/T2IyFTyAkuHJJ5MjVc71Q+vYLzfu4SfBdSIb1oFPT4otNwHP +NbPvTYq0DWnHFNeIc5vmLJJTWVemBTkxvHr+WfU8meFsjxZT05gzgOk+5BZFya5h +oV53mYQYPSyJiBUz0icHyyzUWaEHQLXHrmE6i+kW7+b4lrhi7KV1AMGRSJXUS9/Q +I7NuCQG3+iCyMd+CupvsiK7xjOytgCstwWIGeHlSmYwS+txi1wpbBJ4X6NQLlHyy +KZoFxyWTKtEdX1QKioBxeoKVy5G5LOh7S/jd9jEsZ2C8snFnDbNHALBmXIH3fshA +bo4keel427V6W3f9/u0nT1RWrYiBK12XJiS3/kXg8krln1Xb/MkgTKmLEZF+VDXO +Y3QwAICNM6/235siHuQG+uJ/WoL9xd1R22/+2mxNy1Rdhd49n8GFg0Kjsbmd+hL9 +aMwRU09SNNPCwdAIHmoMCIYS6uTX1bcGSzMir16JepmIYQllwdOoLk2nxtBCaHwj +ZLYO21W+iFgo4TwXzkuaI2q3Ll0n79BJUVdOnz8hBCq0Ox7sTEY7g1vQGHIsBx98 +PYZmaaXVh+u2chHKrwp6L9mRikXQiNWwtqTH/kp7BydRnYIcaP27SCM8HbaYfV/x +02FjBbpZ7u1PwS3jlGmcxE/qTd+cLkk3pm7WPPMlOnMh/X5N3/OpznUgJnVRtGqk +uDy4HSE5vEhHDp0F67R0ph8/HfIBamvJIoonYzoC2iEMgL4yqL0x44SOCioXScgz +hluYX1kQRfyXWjoP+vBBOUapwYDwk1gGXap5iQjtiVq6FN8DspckHRVI5B1voVIC +37Mn2OXH9JloObouLYMRa1dDm7h+/3Cb9UAhKpOjpLc1apA49+Rjtq1gBExhac74 +9SwrcQJdRx0NDJjoMHKrGUFkg/W+R7OTad7+l98M473nWuV3mzJDXcuxmam9llRI +2O+1QsV5hjd4/zCtIka+pOALp+cVSmktTjKNh105asX7d4XIxtg3M+FJWTEODZfy +VulvKri/rkrbCBwMQyj3TpF4AkVjhSM2P5j7LRsivfGc8VL00OqYJp9pYfav38gs +EpYOmaDEV/Ls744WSJJo5Qq0EpDclBTFjky6kZx7RDfySUzfN/Nhv6A= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/modules/transport-netty4/src/test/java/org/opensearch/http/netty4/ssl/SecureNetty4HttpServerTransportTests.java b/modules/transport-netty4/src/test/java/org/opensearch/http/netty4/ssl/SecureNetty4HttpServerTransportTests.java index f80ad901ce765..563f89b70545e 100644 --- a/modules/transport-netty4/src/test/java/org/opensearch/http/netty4/ssl/SecureNetty4HttpServerTransportTests.java +++ b/modules/transport-netty4/src/test/java/org/opensearch/http/netty4/ssl/SecureNetty4HttpServerTransportTests.java @@ -127,7 +127,7 @@ public Optional buildSecureHttpServerEngine(Settings settings, HttpSe "password".toCharArray() ); - final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); + final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, "password".toCharArray()); SSLEngine engine = SslContextBuilder.forServer(keyManagerFactory) diff --git a/modules/transport-netty4/src/test/java/org/opensearch/transport/netty4/ssl/SimpleSecureNetty4TransportTests.java b/modules/transport-netty4/src/test/java/org/opensearch/transport/netty4/ssl/SimpleSecureNetty4TransportTests.java index e0600aebd90e5..e573a9d018862 100644 --- a/modules/transport-netty4/src/test/java/org/opensearch/transport/netty4/ssl/SimpleSecureNetty4TransportTests.java +++ b/modules/transport-netty4/src/test/java/org/opensearch/transport/netty4/ssl/SimpleSecureNetty4TransportTests.java @@ -83,7 +83,7 @@ public Optional buildSecureServerTransportEngine(Settings settings, T "password".toCharArray() ); - final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); + final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, "password".toCharArray()); SSLEngine engine = SslContextBuilder.forServer(keyManagerFactory) diff --git a/modules/transport-netty4/src/test/resources/README.md b/modules/transport-netty4/src/test/resources/README.md new file mode 100644 index 0000000000000..50cbd432d32c6 --- /dev/null +++ b/modules/transport-netty4/src/test/resources/README.md @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# +# This is README describes how the certificates in this directory were created. +# This file can also be executed as a script +# + +# 1. Create certificate key + +`openssl req -x509 -sha256 -newkey rsa:2048 -keyout certificate.key -out certificate.crt -days 1024 -nodes` + +# 2. Export the certificate in pkcs12 format + +`openssl pkcs12 -export -in certificate.crt -inkey certificate.key -out netty4-secure.p12 -name netty4-secure -password pass:password` + +# 3. Migrate from P12 to JKS keystore + +``` +keytool -importkeystore -noprompt \ + -srckeystore netty4-secure.p12 \ + -srcstoretype PKCS12 \ + -srcstorepass password \ + -alias netty4-secure \ + -destkeystore netty4-secure.jks \ + -deststoretype JKS \ + -deststorepass password +``` diff --git a/modules/transport-netty4/src/test/resources/README.txt b/modules/transport-netty4/src/test/resources/README.txt deleted file mode 100644 index c8cec5d3803a4..0000000000000 --- a/modules/transport-netty4/src/test/resources/README.txt +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -# -# This is README describes how the certificates in this directory were created. -# This file can also be executed as a script -# - -# 1. Create certificate key - -openssl req -x509 -sha256 -newkey rsa:2048 -keyout certificate.key -out certificate.crt -days 1024 -nodes - -# 2. Export the certificate in pkcs12 format - -openssl pkcs12 -export -in certificate.crt -inkey certificate.key -out server.p12 -name netty4-secure -password pass:password - -# 3. Import the certificate into JDK keystore (PKCS12 type) - -keytool -importkeystore -srcstorepass password -destkeystore netty4-secure.jks -srckeystore server.p12 -srcstoretype PKCS12 -alias netty4-secure -deststorepass password \ No newline at end of file diff --git a/modules/transport-netty4/src/test/resources/netty4-secure.jks b/modules/transport-netty4/src/test/resources/netty4-secure.jks index 59dfd31c2a1567c6fbae386aa8f15c563bc66ae0..d158f1fe60ef73fdaa610ce8e92a398e4212f20a 100644 GIT binary patch delta 2521 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 buildHttpServerExceptionHandler(Setti @Override public Optional buildSecureHttpServerEngine(Settings settings, HttpServerTransport transport) throws SSLException { try { - SSLEngine engine = SslContextBuilder.forServer( - SecureReactorNetty4HttpServerTransportTests.class.getResourceAsStream("/certificate.crt"), - SecureReactorNetty4HttpServerTransportTests.class.getResourceAsStream("/certificate.key") - ).trustManager(InsecureTrustManagerFactory.INSTANCE).build().newEngine(NettyAllocator.getAllocator()); + var keyManagerFactory = KeyManagerFactory.getInstance("PKIX"); + keyManagerFactory.init(KeyStoreUtils.createServerKeyStore(), KEYSTORE_PASSWORD); + SSLEngine engine = SslContextBuilder.forServer(keyManagerFactory) + .trustManager(InsecureTrustManagerFactory.INSTANCE) + .build() + .newEngine(NettyAllocator.getAllocator()); return Optional.of(engine); - } catch (final IOException ex) { + } catch (final Exception ex) { throw new SSLException(ex); } } diff --git a/plugins/transport-reactor-netty4/src/test/resources/README.txt b/plugins/transport-reactor-netty4/src/test/resources/README.txt deleted file mode 100644 index a4353cee45a97..0000000000000 --- a/plugins/transport-reactor-netty4/src/test/resources/README.txt +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# -# This is README describes how the certificates in this directory were created. -# This file can also be executed as a script -# - -# 1. Create certificate key - -openssl req -x509 -sha256 -newkey rsa:2048 -keyout certificate.key -out certificate.crt -days 1024 -nodes - -# 2. Export the certificate in pkcs12 format - -openssl pkcs12 -export -in certificate.crt -inkey certificate.key -out server.p12 -name netty4-secure -password pass:password - diff --git a/plugins/transport-reactor-netty4/src/test/resources/certificate.crt b/plugins/transport-reactor-netty4/src/test/resources/certificate.crt deleted file mode 100644 index 54c78fdbcf6de..0000000000000 --- a/plugins/transport-reactor-netty4/src/test/resources/certificate.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDkzCCAnugAwIBAgIUddAawr5zygcd+Dcn9WVDpO4BJ7YwDQYJKoZIhvcNAQEL -BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X -DTI0MDMxNDE5NDQzOVoXDTI3MDEwMjE5NDQzOVowWTELMAkGA1UEBhMCQVUxEzAR -BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 -IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAzjOKkg6Iba5zfZ8b/RYw+PGmGEfbdGuuF10Wz4Jmx/Nk4VfDLxdh -TW8VllUL2JD7uPkjABj7pW3awAbvIJ+VGbKqfBr1Nsz0mPPzhT8cfuMH/FDZgQs3 -4HuqDKr0LfC1Kw5E3WF0GVMBDNu0U+nKoeqySeYjGdxDnd3W4cqK5AnUxL0RnIny -Bw7ZuhcU55XndH/Xauro/2EpvJduDsWMdqt7ZfIf1TOmaiQHK+82yb/drVaJbczK -uTpn1Kv2bnzkQEckgq+z1dLNOOyvP2xf+nsziw5ilJe92e5GJOUJYFAlEgUAGpfD -dv6j/gTRYvdJCJItOQEQtektNCAZsoc0wwIDAQABo1MwUTAdBgNVHQ4EFgQUzHts -wIt+zhB/R4U4Do2P6rr0YhkwHwYDVR0jBBgwFoAUzHtswIt+zhB/R4U4Do2P6rr0 -YhkwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAveh870jJX7vt -oLCrdugsyo79pR4f7Nr1kUy3jJrfoaoUmrjiiiHWgT22fGwp7j1GZF2mVfo8YVaK -63YNn5gB2NNZhguPOFC4AdvHRYOKRBOaOvWK8oq7BcJ//18JYI/pPnpgkYvJjqv4 -gFKaZX9qWtujHpAmKiVGs7pwYGNXfixPHRNV4owcfHMIH5dhbbqT49j94xVpjbXs -OymKtFl4kpCE/0LzKFrFcuu55Am1VLBHx2cPpHLOipgUcF5BHFlQ8AXiCMOwfPAw -d22mLB6Gt1oVEpyvQHYd3e04FetEXQ9E8T+NKWZx/8Ucf+IWBYmZBRxch6O83xgk -bAbGzqkbzQ== ------END CERTIFICATE----- diff --git a/plugins/transport-reactor-netty4/src/test/resources/certificate.key b/plugins/transport-reactor-netty4/src/test/resources/certificate.key deleted file mode 100644 index 228350180935d..0000000000000 --- a/plugins/transport-reactor-netty4/src/test/resources/certificate.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDOM4qSDohtrnN9 -nxv9FjD48aYYR9t0a64XXRbPgmbH82ThV8MvF2FNbxWWVQvYkPu4+SMAGPulbdrA -Bu8gn5UZsqp8GvU2zPSY8/OFPxx+4wf8UNmBCzfge6oMqvQt8LUrDkTdYXQZUwEM -27RT6cqh6rJJ5iMZ3EOd3dbhyorkCdTEvRGcifIHDtm6FxTnled0f9dq6uj/YSm8 -l24OxYx2q3tl8h/VM6ZqJAcr7zbJv92tVoltzMq5OmfUq/ZufORARySCr7PV0s04 -7K8/bF/6ezOLDmKUl73Z7kYk5QlgUCUSBQAal8N2/qP+BNFi90kIki05ARC16S00 -IBmyhzTDAgMBAAECggEAVOdiElvLjyX6xeoC00YU6hxOIMdNtHU2HMamwtDV01UD -38mMQ9KjrQelYt4n34drLrHe2IZw75/5J4JzagJrmUY47psHBwaDXItuZRokeJaw -zhLYTEs7OcKRtV+a5WOspUrdzi33aQoFb67zZG3qkpsZyFXrdBV+/fy/Iv+MCvLH -xR0jQ5mzE3cw20R7S4nddChBA/y8oKGOo6QRf2SznC1jL/+yolHvJPEn1v8AUxYm -BMPHxj1O0c4M4IxnJQ3Y5Jy9OaFMyMsFlF1hVhc/3LDDxDyOuBsVsFDicojyrRea -GKngIke0yezy7Wo4NUcp8YQhafonpWVsSJJdOUotcQKBgQD0rihFBXVtcG1d/Vy7 -FvLHrmccD56JNV744LSn2CDM7W1IulNbDUZINdCFqL91u5LpxozeE1FPY1nhwncJ -N7V7XYCaSLCuV1YJzRmUCjnzk2RyopGpzWog3f9uUFGgrk1HGbNAv99k/REya6Iu -IRSkuQhaJOj3bRXzonh0K4GjewKBgQDXvamtCioOUMSP8vq919YMkBw7F+z/fr0p -pamO8HL9eewAUg6N92JQ9kobSo/GptdmdHIjs8LqnS5C3H13GX5Qlf5GskOlCpla -V55ElaSp0gvKwWE168U7gQH4etPQAXXJrOGFaGbPj9W81hTUud7HVE88KYdfWTBo -I7TuE25tWQKBgBRjcr2Vn9xXsvVTCGgamG5lLPhcoNREGz7X0pXt34XT/vhBdnKu -331i5pZMom+YCrzqK5DRwUPBPpseTjb5amj2OKIijn5ojqXQbmI0m/GdBZC71TF2 -CXLlrMQvcy3VeGEFVjd+BYpvwAAYkfIQFZ1IQdbpHnSHpX2guzLK8UmDAoGBANUy -PIcf0EetUVHfkCIjNQfdMcjD8BTcLhsF9vWmcDxFTA9VB8ULf0D64mjt2f85yQsa -b+EQN8KZ6alxMxuLOeRxFYLPj0F9o+Y/R8wHBV48kCKhz2r1v0b6SfQ/jSm1B61x -BrxLW64qOdIOzS8bLyhUDKkrcPesr8V548aRtUKhAoGBAKlNJFd8BCGKD9Td+3dE -oP1iHTX5XZ+cQIqL0e+GMQlK4HnQP566DFZU5/GHNNAfmyxd5iSRwhTqPMHRAmOb -pqQwsyufx0dFeIBxeSO3Z6jW5h2sl4nBipZpw9bzv6EBL1xRr0SfMNZzdnf4JFzc -0htGo/VO93Z2pv8w7uGUz1nN ------END PRIVATE KEY----- diff --git a/qa/evil-tests/build.gradle b/qa/evil-tests/build.gradle index 681ca0c712bb2..1720b21b45d68 100644 --- a/qa/evil-tests/build.gradle +++ b/qa/evil-tests/build.gradle @@ -41,7 +41,9 @@ apply plugin: 'opensearch.standalone-test' dependencies { testImplementation 'com.google.jimfs:jimfs:1.3.0' - testImplementation project(':distribution:tools:plugin-cli') + testImplementation(project(':distribution:tools:plugin-cli')) { + exclude group: 'org.bouncycastle' + } } // TODO: give each evil test its own fresh JVM for more isolation. diff --git a/server/src/main/resources/org/opensearch/bootstrap/test.policy b/server/src/main/resources/org/opensearch/bootstrap/test.policy index e0a183b7eac88..9e1d5cebffc0e 100644 --- a/server/src/main/resources/org/opensearch/bootstrap/test.policy +++ b/server/src/main/resources/org/opensearch/bootstrap/test.policy @@ -7,10 +7,29 @@ */ grant { - // allow to use JVM tooling (Java Compiler) in tests for annotation processing + // allow to use JVM tooling (Java Compiler) in tests for annotation processing permission java.io.FilePermission "${java.home}/lib/*", "read"; permission java.io.FilePermission "${java.home}/lib/modules/*", "read"; permission java.lang.RuntimePermission "accessSystemModules"; permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.lang.RuntimePermission "accessClassInPackage.*"; + + // security + permission java.io.FilePermission "${java.home}/lib/security/cacerts", "read"; + permission java.io.FilePermission "${java.home}/lib/security/jssecacerts", "read"; + permission java.lang.RuntimePermission "accessClassInPackage.sun.security.internal.spec"; + permission java.lang.RuntimePermission "closeClassLoader"; + permission java.lang.RuntimePermission "getProtectionDomain"; + permission java.security.SecurityPermission "getProperty.jdk.certpath.disabledAlgorithms"; + permission java.security.SecurityPermission "getProperty.jdk.tls.disabledAlgorithms"; + permission java.security.SecurityPermission "getProperty.jdk.tls.server.defaultDHEParameters"; + permission java.security.SecurityPermission "getProperty.keystore.type.compat"; + permission java.security.SecurityPermission "getProperty.org.bouncycastle.*"; + permission java.security.SecurityPermission "putProviderProperty.BC"; + permission java.security.SecurityPermission "removeProvider.SunJCE"; + permission java.security.SecurityPermission "removeProviderProperty.BC"; + permission java.util.PropertyPermission "java.runtime.name", "read"; + permission org.bouncycastle.crypto.CryptoServicesPermission "defaultRandomConfig"; + permission org.bouncycastle.crypto.CryptoServicesPermission "exportPrivateKey"; + permission org.bouncycastle.crypto.CryptoServicesPermission "exportSecretKey"; }; diff --git a/test/fixtures/krb5kdc-fixture/src/main/resources/provision/kdc.conf.template b/test/fixtures/krb5kdc-fixture/src/main/resources/provision/kdc.conf.template index 22909ddf60013..69be28f4548c3 100644 --- a/test/fixtures/krb5kdc-fixture/src/main/resources/provision/kdc.conf.template +++ b/test/fixtures/krb5kdc-fixture/src/main/resources/provision/kdc.conf.template @@ -16,8 +16,8 @@ # under the License. [kdcdefaults] - kdc_listen = 88 - kdc_tcp_listen = 88 + kdc_ports = 88 + kdc_tcp_ports = 88 [realms] ${REALM_NAME} = { @@ -25,8 +25,7 @@ max_life = 12h 0m 0s max_renewable_life = 7d 0h 0m 0s master_key_type = aes256-cts - # remove aes256-cts:normal since unlimited strength policy needs installed for java to use it. - supported_enctypes = aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal + supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal } [logging] diff --git a/test/fixtures/krb5kdc-fixture/src/main/resources/provision/krb5.conf.template b/test/fixtures/krb5kdc-fixture/src/main/resources/provision/krb5.conf.template index 207fe939fb7a5..a87c5b50d5cf3 100644 --- a/test/fixtures/krb5kdc-fixture/src/main/resources/provision/krb5.conf.template +++ b/test/fixtures/krb5kdc-fixture/src/main/resources/provision/krb5.conf.template @@ -33,18 +33,15 @@ dns_canonicalize_hostname = false dns_lookup_kdc = false dns_lookup_realm = false - dns_uri_lookup = false forwardable = true ignore_acceptor_hostname = true rdns = false - default_tgs_enctypes = rc4-hmac - default_tkt_enctypes = rc4-hmac - permitted_enctypes = rc4-hmac + default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 + default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 + permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 # udp_preference_limit = 1 - kdc_timeout = 3000 canonicalize = true - # See please https://seanjmullan.org/blog/2021/09/14/jdk17 (deprecate 3DES and RC4 in Kerberos) - allow_weak_crypto = true + allow_weak_crypto = false [realms] ${REALM_NAME} = { @@ -52,6 +49,8 @@ kdc = 127.0.0.1:${MAPPED_PORT} admin_server = ${KDC_NAME}:749 default_domain = ${BUILD_ZONE} + master_key_type = aes256-cts + supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal } [domain_realm] diff --git a/test/framework/build.gradle b/test/framework/build.gradle index 84a536fdf62c8..47addd36318a4 100644 --- a/test/framework/build.gradle +++ b/test/framework/build.gradle @@ -49,6 +49,9 @@ dependencies { api "org.mockito:mockito-core:${versions.mockito}" api "net.bytebuddy:byte-buddy:${versions.bytebuddy}" api "org.objenesis:objenesis:${versions.objenesis}" + api "org.bouncycastle:bcprov-jdk18on:${versions.bouncycastle}" + api "org.bouncycastle:bcpkix-jdk18on:${versions.bouncycastle}" + api "org.bouncycastle:bcutil-jdk18on:${versions.bouncycastle}" annotationProcessor "org.apache.logging.log4j:log4j-core:${versions.log4j}" } diff --git a/test/framework/licenses/bcpkix-jdk18on-1.78.jar.sha1 b/test/framework/licenses/bcpkix-jdk18on-1.78.jar.sha1 new file mode 100644 index 0000000000000..385a9d930eede --- /dev/null +++ b/test/framework/licenses/bcpkix-jdk18on-1.78.jar.sha1 @@ -0,0 +1 @@ +dd61bcdb87678451dd42d42e267979bd4b4451a1 \ No newline at end of file diff --git a/test/framework/licenses/bcprov-jdk18on-1.78.jar.sha1 b/test/framework/licenses/bcprov-jdk18on-1.78.jar.sha1 new file mode 100644 index 0000000000000..47fb5fd5e5f5d --- /dev/null +++ b/test/framework/licenses/bcprov-jdk18on-1.78.jar.sha1 @@ -0,0 +1 @@ +619aafb92dc0b4c6cc4cf86c487ca48ee2d67a8e \ No newline at end of file diff --git a/test/framework/licenses/bouncycastle-LICENSE.txt b/test/framework/licenses/bouncycastle-LICENSE.txt new file mode 100644 index 0000000000000..5c7c14696849d --- /dev/null +++ b/test/framework/licenses/bouncycastle-LICENSE.txt @@ -0,0 +1,14 @@ +Copyright (c) 2000 - 2023 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/test/framework/licenses/bouncycastle-NOTICE.txt b/test/framework/licenses/bouncycastle-NOTICE.txt new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/test/framework/licenses/bouncycastle-NOTICE.txt @@ -0,0 +1 @@ + diff --git a/test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java b/test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java new file mode 100644 index 0000000000000..c90b2b872f8ba --- /dev/null +++ b/test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java @@ -0,0 +1,68 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.test; + +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v1CertificateBuilder; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; + +import javax.security.auth.x500.X500Principal; +import javax.security.auth.x500.X500PrivateCredential; + +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.Date; + +public class KeyStoreUtils { + + public static final char[] KEYSTORE_PASSWORD = "keystore_password".toCharArray(); + + public static KeyStore createServerKeyStore() throws Exception { + var serverCred = createCredential(); + var keyStore = KeyStore.getInstance("JKS"); + keyStore.load(null, null); + keyStore.setKeyEntry( + serverCred.getAlias(), + serverCred.getPrivateKey(), + KEYSTORE_PASSWORD, + new X509Certificate[] { serverCred.getCertificate() } + ); + return keyStore; + } + + private static X500PrivateCredential createCredential() throws Exception { + var keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + var keyPair = keyPairGenerator.generateKeyPair(); + var rootCert = new JcaX509CertificateConverter().getCertificate(generateCert(keyPair)); + return new X500PrivateCredential(rootCert, keyPair.getPrivate(), "server-ca"); + } + + private static X509CertificateHolder generateCert(KeyPair pair) throws Exception { + var baseTime = System.currentTimeMillis(); + // 10 years in milliseconds + var validityPeriod = 10L * 365 * 24 * 60 * 60 * 1000; + + var certBuilder = new JcaX509v1CertificateBuilder( + new X500Principal("CN=Test CA Certificate"), + BigInteger.valueOf(1), + new Date(baseTime), + new Date(baseTime + validityPeriod), + new X500Principal("CN=Test CA Certificate"), + pair.getPublic() + ); + var signer = new JcaContentSignerBuilder("SHA256withRSA").build(pair.getPrivate()); + return certBuilder.build(signer); + } + +}