You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by lm...@apache.org on 2018/11/30 16:28:10 UTC

knox git commit: KNOX-1646 - Improve export-cert command - JKS, PEM, JCEKS, PKCS12 (Lars Francke via lmccay)

Repository: knox
Updated Branches:
  refs/heads/master 660b5bca0 -> 3760da52f


KNOX-1646 - Improve export-cert command - JKS, PEM, JCEKS, PKCS12 (Lars Francke via lmccay)


Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/3760da52
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/3760da52
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/3760da52

Branch: refs/heads/master
Commit: 3760da52f4164efcf0db9dc4794c46cc80fdf65c
Parents: 660b5bc
Author: Larry McCay <lm...@apache.org>
Authored: Fri Nov 30 11:26:31 2018 -0500
Committer: Larry McCay <lm...@apache.org>
Committed: Fri Nov 30 11:27:58 2018 -0500

----------------------------------------------------------------------
 .../resources/build-tools/spotbugs-filter.xml   |  2 +-
 .../org/apache/knox/gateway/util/KnoxCLI.java   | 77 +++++++-------------
 .../apache/knox/gateway/util/KnoxCLITest.java   | 27 +++++++
 .../security/impl/X509CertificateUtil.java      | 22 +++++-
 4 files changed, 75 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/3760da52/build-tools/src/main/resources/build-tools/spotbugs-filter.xml
----------------------------------------------------------------------
diff --git a/build-tools/src/main/resources/build-tools/spotbugs-filter.xml b/build-tools/src/main/resources/build-tools/spotbugs-filter.xml
index c779bac..3a32686 100644
--- a/build-tools/src/main/resources/build-tools/spotbugs-filter.xml
+++ b/build-tools/src/main/resources/build-tools/spotbugs-filter.xml
@@ -37,7 +37,7 @@ limitations under the License.
 
   <Match>
     <Class name="org.apache.knox.gateway.services.security.impl.X509CertificateUtil" />
-    <Method name="writeCertificateToJKS" />
+    <Method name="writeCertificateToKeyStore" />
     <Bug pattern="HARD_CODE_PASSWORD" />
   </Match>
 

http://git-wip-us.apache.org/repos/asf/knox/blob/3760da52/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java b/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java
index 652e90c..108961a 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java
@@ -181,29 +181,10 @@ public class KnoxCLI extends Configured implements Tool {
   }
 
   /**
-   * Parse the command line arguments and initialize the data
-   * <pre>
-   * % knoxcli version
-   * % knoxcli list-topologies
-   * % knoxcli master-create keyName [--size size] [--master mastersecret] [--generate]
-   * % knoxcli create-alias alias [--cluster clustername] [--generate] [--value v]
-   * % knoxcli list-alias [--cluster clustername]
-   * % knoxcli delete=alias alias [--cluster clustername]
-   * % knoxcli create-cert alias [--hostname h]
-   * % knoxcli redeploy [--cluster clustername]
-   * % knoxcli validate-topology [--cluster clustername] | [--path <path/to/file>]
-   * % knoxcli user-auth-test [--cluster clustername] [--u username] [--p password]
-   * % knoxcli system-user-auth-test [--cluster clustername] [--d]
-   * % knoxcli service-test [--u user] [--p password] [--cluster clustername] [--hostname name] [--port port]
-   * % knoxcli list-registry-clients
-   * % knoxcli get-registry-acl entryName --registry-client name
-   * % knoxcli list-provider-configs --registry-client
-   * % knoxcli upload-provider-config filePath --registry-client name [--entry-name entryName]
-   * % knoxcli list-descriptors --registry-client
-   * % knoxcli upload-descriptor filePath --registry-client name [--entry-name entryName]
-   * % knoxcli delete-provider-config providerConfig --registry-client name
-   * % knoxcli delete-descriptor descriptor --registry-client name
-   * </pre>
+   * Parse the command line arguments and initialize the data.
+   *
+   * See the usage information for the commands itself for information on which parameters they take.
+   *
    * @param args command line arguments
    * @return return exit code
    * @throws IOException exception on starting KnoxCLI
@@ -581,22 +562,21 @@ public class KnoxCLI extends Configured implements Tool {
    }
  }
 
- public class CertExportCommand extends Command {
+  public class CertExportCommand extends Command {
 
-   public static final String USAGE = "export-cert";
-   public static final String DESC = "The export-cert command exports the public certificate\n" +
-                                     "from the a gateway.jks keystore with the alias of gateway-identity.";
-   private static final String GATEWAY_CREDENTIAL_STORE_NAME = "__gateway";
-   private static final String GATEWAY_IDENTITY_PASSPHRASE = "gateway-identity-passphrase";
-
-    public CertExportCommand() {
-    }
+    public static final String USAGE = "export-cert [--type PEM|JKS|JCEKS|PKCS12]";
+    public static final String DESC = "The export-cert command exports the public certificate\n" +
+                                      "from the a gateway.jks keystore with the alias of gateway-identity.\n" +
+                                      "It will be exported to `{GATEWAY_HOME}/data/security/keystores/` with a name of `gateway-client-trust.<type>`" +
+                                      "Using the --type option you can specify which keystore type you need (default: PEM)\n" +
+                                      "NOTE: The password for the JKS, JCEKS and PKCS12 types is `changeit`.\n" +
+                                      "It can be changed using: `keytool -storepasswd -storetype <type> -keystore gateway-client-trust.<type>`";
 
     private GatewayConfig getGatewayConfig() {
       GatewayConfig result;
       Configuration conf = getConf();
-      if( conf != null && conf instanceof GatewayConfig ) {
-        result = (GatewayConfig)conf;
+      if (conf instanceof GatewayConfig) {
+        result = (GatewayConfig) conf;
       } else {
         result = new GatewayConfigImpl();
       }
@@ -607,37 +587,36 @@ public class KnoxCLI extends Configured implements Tool {
     public void execute() throws Exception {
       KeystoreService ks = getKeystoreService();
 
-      AliasService as = getAliasService();
-
       if (ks != null) {
         try {
           if (!ks.isKeystoreForGatewayAvailable()) {
             out.println("No keystore has been created for the gateway. Please use the create-cert command or populate with a CA signed cert of your own.");
           }
-          char[] passphrase = as.getPasswordFromAliasForCluster(GATEWAY_CREDENTIAL_STORE_NAME, GATEWAY_IDENTITY_PASSPHRASE);
-          if (passphrase == null) {
-            MasterService ms = services.getService("MasterService");
-            passphrase = ms.getMasterSecret();
-          }
+
           Certificate cert = ks.getKeystoreForGateway().getCertificate("gateway-identity");
           String keyStoreDir = getGatewayConfig().getGatewaySecurityDir() + File.separator + "keystores" + File.separator;
           File ksd = new File(keyStoreDir);
           if (!ksd.exists()) {
-            if( !ksd.mkdirs() ) {
+            if (!ksd.mkdirs()) {
               // certainly should not happen if the keystore is known to be available
               throw new ServiceLifecycleException("Unable to create keystores directory" + ksd.getAbsolutePath());
             }
           }
-          if ("PEM".equals(type) || type == null) {
+
+          if ("PEM".equalsIgnoreCase(type) || type == null) {
             X509CertificateUtil.writeCertificateToFile(cert, new File(keyStoreDir + "gateway-identity.pem"));
             out.println("Certificate gateway-identity has been successfully exported to: " + keyStoreDir + "gateway-identity.pem");
-          }
-          else if ("JKS".equals(type)) {
-            X509CertificateUtil.writeCertificateToJKS(cert, new File(keyStoreDir + "gateway-client-trust.jks"));
+          } else if ("JKS".equalsIgnoreCase(type)) {
+            X509CertificateUtil.writeCertificateToJks(cert, new File(keyStoreDir + "gateway-client-trust.jks"));
             out.println("Certificate gateway-identity has been successfully exported to: " + keyStoreDir + "gateway-client-trust.jks");
-          }
-          else {
-            out.println("Invalid type for export file provided. Export has not been done. Please use: [PEM|JKS] default value is PEM.");
+          } else if ("JCEKS".equalsIgnoreCase(type)) {
+            X509CertificateUtil.writeCertificateToJceks(cert, new File(keyStoreDir + "gateway-client-trust.jceks"));
+            out.println("Certificate gateway-identity has been successfully exported to: " + keyStoreDir + "gateway-client-trust.jceks");
+          } else if ("PKCS12".equalsIgnoreCase(type)) {
+            X509CertificateUtil.writeCertificateToPkcs12(cert, new File(keyStoreDir + "gateway-client-trust.pkcs12"));
+            out.println("Certificate gateway-identity has been successfully exported to: " + keyStoreDir + "gateway-client-trust.pkcs12");
+          } else {
+            out.println("Invalid type for export file provided. Export has not been done. Please use: [PEM|JKS|JCEKS|PKCS12] default value is PEM.");
           }
         } catch (KeystoreServiceException e) {
           throw new ServiceLifecycleException("Keystore was not loaded properly - the provided (or persisted) master secret may not match the password for the keystore.", e);

http://git-wip-us.apache.org/repos/asf/knox/blob/3760da52/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java b/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
index e40125e..42dbc63 100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
@@ -717,6 +717,33 @@ public class KnoxCLITest {
     assertTrue(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("Certificate gateway-identity has been successfully exported to"));
     assertTrue(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("gateway-identity.pem"));
 
+    // case insensitive
+    outContent.reset();
+    String[] gwCreateArgs2_6 = {"export-cert", "--type", "pem"};
+    rc = 0;
+    rc = cli.run(gwCreateArgs2_6);
+    assertEquals(0, rc);
+    assertTrue(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("Certificate gateway-identity has been successfully exported to"));
+    assertTrue(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("gateway-identity.pem"));
+
+    // pkcs12
+    outContent.reset();
+    String[] gwCreateArgs2_7 = {"export-cert", "--type", "pkcs12"};
+    rc = 0;
+    rc = cli.run(gwCreateArgs2_7);
+    assertEquals(0, rc);
+    assertTrue(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("Certificate gateway-identity has been successfully exported to"));
+    assertTrue(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("gateway-identity.pkcs12"));
+
+    // jceks
+    outContent.reset();
+    String[] gwCreateArgs2_8 = {"export-cert", "--type", "jceks"};
+    rc = 0;
+    rc = cli.run(gwCreateArgs2_8);
+    assertEquals(0, rc);
+    assertTrue(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("Certificate gateway-identity has been successfully exported to"));
+    assertTrue(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("gateway-identity.jceks"));
+
     outContent.reset();
     String[] gwCreateArgs2_5 = {"export-cert"};
     rc = 0;

http://git-wip-us.apache.org/repos/asf/knox/blob/3760da52/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/impl/X509CertificateUtil.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/impl/X509CertificateUtil.java b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/impl/X509CertificateUtil.java
index 19d0dd0..1cce280 100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/impl/X509CertificateUtil.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/impl/X509CertificateUtil.java
@@ -39,9 +39,9 @@ import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.Date;
 
-import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.knox.gateway.i18n.GatewaySpiMessages;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 
 public class X509CertificateUtil {
 
@@ -283,9 +283,9 @@ public class X509CertificateUtil {
     }
   }
 
-  public static void writeCertificateToJKS(Certificate cert, final File file)
+  private static void writeCertificateToKeyStore(Certificate cert, final File file, String type)
       throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
-    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+    KeyStore ks = KeyStore.getInstance(type);
 
     char[] password = "changeit".toCharArray();
     ks.load(null, password);
@@ -295,5 +295,21 @@ public class X509CertificateUtil {
       ks.store(fos, password);
     }
   }
+
+  public static void writeCertificateToJks(Certificate cert, final File file)
+      throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
+    writeCertificateToKeyStore(cert, file, "jks");
+  }
+
+  public static void writeCertificateToJceks(Certificate cert, final File file)
+      throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
+    writeCertificateToKeyStore(cert, file, "jceks");
+  }
+
+  public static void writeCertificateToPkcs12(Certificate cert, final File file)
+      throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
+    writeCertificateToKeyStore(cert, file, "pkcs12");
+  }
+
 }