1 /*
   2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.io.File;
  25 import java.io.IOException;
  26 import java.nio.file.Files;
  27 import java.nio.file.StandardOpenOption;
  28 import java.util.Base64;
  29 import jdk.test.lib.process.OutputAnalyzer;
  30 import static java.lang.System.out;
  31 import java.nio.file.Paths;
  32 import java.util.List;
  33 
  34 /**
  35  * @test
  36  * @bug 8048830
  37  * @summary Test for PKCS12 keystore list , export commands. Refer README for
  38  * keystore files information
  39  * @library /lib/testlibrary ../
  40  * @library /test/lib
  41  * @run main KeytoolReaderP12Test
  42  */
  43 public class KeytoolReaderP12Test {
  44     private static final String WORKING_DIRECTORY = System.getProperty(
  45             "test.classes", "."+ File.separator);
  46     //private static final String KS_PASSWD = "pass";
  47     private static final String KS_PASSWD = "storepass";
  48     private static final String CERT_CHAIN_PASSWD = "password";
  49     private static final String SOURCE_DIRECTORY =
  50             System.getProperty("test.src", "." + File.separator);
  51 
  52     public static void main(String[] args) throws Exception {
  53         List<String> expectedValues = null;
  54         out.println("Self signed test");
  55         expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
  56                 "api_private_key.p12_expected.data"));
  57         readTest("api_private_key.p12.data", KS_PASSWD, expectedValues);
  58         out.println("Self signed test Passed");
  59 
  60         out.println("private key with selfsigned cert, key pair not match");
  61         expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
  62                 "api_private_key_not_match.p12_expected.data"));
  63         readTest("api_private_key_not_match.p12.data", KS_PASSWD,
  64                 expectedValues);
  65         out.println("private key with selfsigned cert, key pair "
  66                 + "not match passed");
  67 
  68         out.println("cert chain test");
  69         expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
  70                 "api_cert_chain.p12_expected.data"));
  71         readTest("api_cert_chain.p12.data", CERT_CHAIN_PASSWD, expectedValues);
  72         out.println("cert chain test passed");
  73 
  74         out.println("IE self test");
  75         expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
  76                 "ie_self.pfx.pem"));
  77         exportTest("ie_self.pfx.data", "pkcs12testenduser1",
  78                 KS_PASSWD, expectedValues);
  79         out.println("IE self test passed");
  80 
  81         out.println("IE chain test");
  82         expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
  83                 "ie_chain.pfx.pem"));
  84         exportTest("ie_chain.pfx.data", "servercert",
  85                 CERT_CHAIN_PASSWD, expectedValues);
  86         out.println("IE chain test passed");
  87 
  88         out.println("Netscape self");
  89         expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
  90                 "netscape_self.p12.pem"));
  91         exportTest("netscape_self.p12.data", "pkcs12testenduser1",
  92                 KS_PASSWD, expectedValues);
  93         out.println("Netscape self passed");
  94 
  95         out.println("Mozilla self test");
  96         expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
  97                 "mozilla_self.p12.pem"));
  98         exportTest("mozilla_self.p12.data", "pkcs12testenduser1",
  99                 KS_PASSWD, expectedValues);
 100         out.println("Mozilla self test passed");
 101 
 102         out.println("Openssl test");
 103         expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
 104                 "openssl.p12.pem"));
 105         exportTest("openssl.p12.data", "servercert", CERT_CHAIN_PASSWD, expectedValues);
 106         out.println("openssl test passed");
 107 
 108         out.println("with different keystore and entrykey password");
 109         expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
 110                 "api_two_pass.p12_expected.data"));
 111         readTest("api_two_pass.p12.data", KS_PASSWD,
 112                 expectedValues);
 113         out.println("two pass test passed");
 114     }
 115 
 116     private static void readTest(String name, String password,
 117             List<String> expectedValues)
 118             throws IOException {
 119         convertToPFX(name);
 120         final String[] command = new String[]{"-debug", "-list", "-v",
 121             "-keystore", WORKING_DIRECTORY + File.separator + name,
 122             "-storetype", "pkcs12", "-storepass", password};
 123         runAndValidate(command, expectedValues);
 124     }
 125 
 126     private static void exportTest(String name, String alias,
 127             String password, List<String> expectedValues)
 128             throws IOException {
 129         convertToPFX(name);
 130         final String[] command = new String[]{"-debug", "-export", "-alias",
 131             alias, "-keystore", WORKING_DIRECTORY + File.separator + name,
 132             "-storepass", password, "-storetype", "pkcs12", "-rfc"};
 133         runAndValidate(command, expectedValues);
 134     }
 135 
 136     private static void runAndValidate(String[] command,
 137             List<String> expectedValues) throws IOException {
 138         OutputAnalyzer output = Utils.executeKeytoolCommand(command);
 139         if (expectedValues != null) {
 140             expectedValues.stream().forEach(line -> {
 141                 output.shouldContain(line);
 142             });
 143         }
 144     }
 145 
 146     /**
 147      * Decodes the base64 encoded keystore and writes into new file
 148      * @param name base64 encoded keystore name
 149      */
 150     private static void convertToPFX(String name) throws IOException{
 151         File base64File = new File(SOURCE_DIRECTORY, name);
 152         File pkcs12File = new File(WORKING_DIRECTORY, name);
 153         byte[] input = Files.readAllBytes(base64File.toPath());
 154         Files.write(pkcs12File.toPath(), Base64.getMimeDecoder().
 155                 decode(input), StandardOpenOption.CREATE);
 156     }
 157 }