Browse Source

Fix certutil http for empty password with JDK 11 and lower (#55437)

 Fix elasticseaerch-certutil http command so that it correctly accepts empty keystore password with JDK version 11 and lower.
Yang Wang 5 years ago
parent
commit
00b4d3dad6

+ 1 - 1
x-pack/plugin/security/cli/src/main/java/org/elasticsearch/xpack/security/cli/HttpCertificateCommand.java

@@ -864,7 +864,7 @@ class HttpCertificateCommand extends EnvironmentAwareCommand {
             terminal.println("IT IS IMPORTANT THAT YOU REMEMBER THIS PASSWORD AND KEEP IT SECURE");
             terminal.println("");
             final char[] password = readPassword(terminal, "CA password: ", true);
-            return new CertificateTool.CAInfo(caCert, keyPair.getPrivate(), true, password.length == 0 ? null : password);
+            return new CertificateTool.CAInfo(caCert, keyPair.getPrivate(), true, password);
         } catch (GeneralSecurityException | CertIOException | OperatorCreationException e) {
             throw new IllegalArgumentException("Cannot generate CA key pair", e);
         }

+ 4 - 4
x-pack/plugin/security/cli/src/test/java/org/elasticsearch/xpack/security/cli/CertificateToolTests.java

@@ -563,10 +563,10 @@ public class CertificateToolTests extends ESTestCase {
 
         final int days = randomIntBetween(7, 1500);
 
-        final String caPassword = randomAlphaOfLengthBetween(4, 16);
-        final String node1Password = randomAlphaOfLengthBetween(4, 16);
-        final String node2Password = randomAlphaOfLengthBetween(4, 16);
-        final String node3Password = randomAlphaOfLengthBetween(4, 16);
+        final String caPassword = randomFrom("", randomAlphaOfLengthBetween(4, 16));
+        final String node1Password = randomFrom("", randomAlphaOfLengthBetween(4, 16));
+        final String node2Password = randomFrom("", randomAlphaOfLengthBetween(4, 16));
+        final String node3Password = randomFrom("", randomAlphaOfLengthBetween(4, 16));
 
         final String node1Ip = "200.181." + randomIntBetween(1, 250) + "." + randomIntBetween(1, 250);
         final String node2Ip = "200.182." + randomIntBetween(1, 250) + "." + randomIntBetween(1, 250);

+ 51 - 17
x-pack/plugin/security/cli/src/test/java/org/elasticsearch/xpack/security/cli/HttpCertificateCommandTests.java

@@ -142,7 +142,9 @@ public class HttpCertificateCommandTests extends ESTestCase {
 
         final String password = randomPassword();
         terminal.addSecretInput(password);
-        terminal.addSecretInput(password); // confirm
+        if ("".equals(password) == false) {
+            terminal.addSecretInput(password);
+        } // confirm
 
         terminal.addTextInput(outFile.toString());
 
@@ -163,7 +165,9 @@ public class HttpCertificateCommandTests extends ESTestCase {
             wasEncrypted.set(true);
             return password.toCharArray();
         });
-        assertTrue("Password should have been required to decrypted key", wasEncrypted.get());
+        if ("".equals(password) == false) {
+            assertTrue("Password should have been required to decrypted key", wasEncrypted.get());
+        }
 
         final Path esReadmePath = zipRoot.resolve("elasticsearch/README.txt");
         assertThat(esReadmePath, isRegularFile());
@@ -186,19 +190,26 @@ public class HttpCertificateCommandTests extends ESTestCase {
         assertThat(esReadme, containsString(crtName));
         assertThat(esReadme, containsString(keyPath.getFileName().toString()));
         assertThat(esReadme, containsString(ymlPath.getFileName().toString()));
-        assertThat(esReadme, not(containsString(password)));
+        if ("".equals(password) == false) {
+            assertThat(esReadme, not(containsString(password)));
+        }
 
         // Verify the yml
         assertThat(yml, not(containsString(csrPath.getFileName().toString())));
         assertThat(yml, containsString(crtName));
         assertThat(yml, containsString(keyPath.getFileName().toString()));
-        assertThat(yml, not(containsString(password)));
+        if ("".equals(password) == false) {
+            assertThat(yml, not(containsString(password)));
+        }
 
         // Should not be a CA directory in CSR mode
         assertThat(zipRoot.resolve("ca"), not(pathExists()));
 
         // No CA in CSR mode
-        verifyKibanaDirectory(zipRoot, false, List.of("Certificate Signing Request"), List.of(password, csrPath.getFileName().toString()));
+
+        verifyKibanaDirectory(zipRoot, false, List.of("Certificate Signing Request"),
+            Stream.of(password, csrPath.getFileName().toString())
+            .filter(s -> "".equals(s) == false).collect(Collectors.toList()));
     }
 
     public void testGenerateSingleCertificateWithExistingCA() throws Exception {
@@ -257,7 +268,9 @@ public class HttpCertificateCommandTests extends ESTestCase {
 
         final String password = randomPassword();
         terminal.addSecretInput(password);
-        terminal.addSecretInput(password); // confirm
+        if ("".equals(password) == false) {
+            terminal.addSecretInput(password);
+        } // confirm
 
         terminal.addTextInput(outFile.toString());
 
@@ -292,19 +305,24 @@ public class HttpCertificateCommandTests extends ESTestCase {
         // Verify the README
         assertThat(readme, containsString(p12Path.getFileName().toString()));
         assertThat(readme, containsString(ymlPath.getFileName().toString()));
-        assertThat(readme, not(containsString(password)));
+        if ("".equals(password) == false) {
+            assertThat(readme, not(containsString(password)));
+        }
         assertThat(readme, not(containsString(caPassword)));
 
         // Verify the yml
         assertThat(yml, containsString(p12Path.getFileName().toString()));
-        assertThat(yml, not(containsString(password)));
+        if ("".equals(password) == false) {
+            assertThat(yml, not(containsString(password)));
+        }
         assertThat(yml, not(containsString(caPassword)));
 
         // Should not be a CA directory when using an existing CA.
         assertThat(zipRoot.resolve("ca"), not(pathExists()));
 
         verifyKibanaDirectory(zipRoot, true, List.of("2. elasticsearch-ca.pem"),
-            List.of(password, caPassword, caKeyPath.getFileName().toString()));
+            Stream.of(password, caPassword, caKeyPath.getFileName().toString())
+                .filter(s -> "".equals(s) == false).collect(Collectors.toList()));
     }
 
     public void testGenerateMultipleCertificateWithNewCA() throws Exception {
@@ -347,7 +365,9 @@ public class HttpCertificateCommandTests extends ESTestCase {
 
         final String caPassword = randomPassword();
         terminal.addSecretInput(caPassword);
-        terminal.addSecretInput(caPassword); // confirm
+        if ("".equals(caPassword) == false) {
+            terminal.addSecretInput(caPassword);
+        } // confirm
 
         final int certYears = randomIntBetween(1, 8);
         terminal.addTextInput(certYears + "y"); // node cert validity period
@@ -378,7 +398,9 @@ public class HttpCertificateCommandTests extends ESTestCase {
 
         final String password = randomPassword();
         terminal.addSecretInput(password);
-        terminal.addSecretInput(password); // confirm
+        if ("".equals(password) == false) {
+            terminal.addSecretInput(password);
+        } // confirm
 
         terminal.addTextInput(outFile.toString());
 
@@ -422,17 +444,26 @@ public class HttpCertificateCommandTests extends ESTestCase {
             // Verify the README
             assertThat(readme, containsString(p12Path.getFileName().toString()));
             assertThat(readme, containsString(ymlPath.getFileName().toString()));
-            assertThat(readme, not(containsString(password)));
-            assertThat(readme, not(containsString(caPassword)));
+            if ("".equals(password) == false) {
+                assertThat(readme, not(containsString(password)));
+            }
+            if ("".equals(caPassword) == false) {
+                assertThat(readme, not(containsString(caPassword)));
+            }
 
             // Verify the yml
             assertThat(yml, containsString(p12Path.getFileName().toString()));
-            assertThat(yml, not(containsString(password)));
-            assertThat(yml, not(containsString(caPassword)));
+            if ("".equals(password) == false) {
+                assertThat(yml, not(containsString(password)));
+            }
+            if ("".equals(caPassword) == false) {
+                assertThat(yml, not(containsString(caPassword)));
+            }
         }
 
         verifyKibanaDirectory(zipRoot, true, List.of("2. elasticsearch-ca.pem"),
-            List.of(password, caPassword, caPath.getFileName().toString()));
+            Stream.of(password, caPassword, caPath.getFileName().toString())
+                .filter(s -> "".equals(s) == false).collect(Collectors.toList()));
     }
 
     public void testParsingValidityPeriod() throws Exception {
@@ -589,7 +620,10 @@ public class HttpCertificateCommandTests extends ESTestCase {
     private String randomPassword() {
         // We want to assert that this password doesn't end up in any output files, so we need to make sure we
         // don't randomly generate a real word.
-        return randomAlphaOfLength(4) + randomFrom('~', '*', '%', '$', '|') + randomAlphaOfLength(4);
+        return randomFrom(
+            "",
+            randomAlphaOfLength(4) + randomFrom('~', '*', '%', '$', '|') + randomAlphaOfLength(4)
+        );
     }
 
     private void verifyCertificationRequest(PKCS10CertificationRequest csr, String certificateName, List<String> hostNames,