1 /*
2  * Copyright (c) 2012, 2018, 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 ../
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 
main(String[] args)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 
readTest(String name, String password, List<String> expectedValues)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 
exportTest(String name, String alias, String password, List<String> expectedValues)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 
runAndValidate(String[] command, List<String> expectedValues)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      */
convertToPFX(String name)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 }
158