1/* 2 * Copyright (c) 2016, 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/* 25 * @test 26 * @bug 6968542 27 * @summary keytool -importcert cannot deal with duplicate certs 28 * @modules java.base/sun.security.tools.keytool 29 * @compile -XDignore.symbol.file DupImport.java 30 * @run main DupImport pkcs12 31 * @run main DupImport jks 32 */ 33 34import java.io.File; 35import java.nio.file.Files; 36import java.nio.file.Paths; 37import java.security.KeyStore; 38import java.security.cert.Certificate; 39import java.security.cert.X509Certificate; 40import java.util.ArrayList; 41import java.util.Arrays; 42import java.util.List; 43 44public class DupImport { 45 46 static String storeType = null; 47 48 public static void main(String[] args) throws Exception { 49 50 storeType = args[0]; 51 Files.deleteIfExists(Paths.get("dup.ks")); 52 53 // Create chain: root -> int -> me 54 run("-genkeypair -alias me -dname CN=Me"); 55 run("-genkeypair -alias int -dname CN=Int"); 56 run("-genkeypair -alias root -dname CN=Root"); 57 58 run("-certreq -alias int -file int.req"); 59 run("-gencert -infile int.req -alias root -rfc -outfile int.resp"); 60 run("-importcert -file int.resp -alias int"); 61 62 run("-certreq -alias me -file me.req"); 63 run("-gencert -infile me.req -alias int -rfc -outfile me.resp"); 64 run("-importcert -file me.resp -alias me"); 65 66 // Export certs 67 run("-exportcert -alias me -file me -rfc"); 68 run("-exportcert -alias int -file int -rfc"); 69 run("-exportcert -alias root -file root -rfc"); 70 71 // test 1: just the 3 certs 72 test("me", "int", "root"); 73 74 // test 2: 3 chains (without root) concatenated 75 test("me", "int", "int", "root"); 76 77 // test 3: 3 full chains concatenated 78 test("me", "int", "root", "int", "root", "root"); 79 80 // test 4: a mess 81 test("root", "me", "int", "int", "me", "me", "root", "int"); 82 } 83 84 // Run keytool command with common options 85 static void run(String s) throws Exception { 86 sun.security.tools.keytool.Main.main(( 87 "-keystore dup.ks -storepass changeit -keypass changeit " 88 + "-storetype " + storeType + " -debug " 89 + s).split(" ")); 90 } 91 92 // Test "cat files... | keytool -import" 93 static void test(String... files) throws Exception { 94 95 System.out.println("Testing " + Arrays.toString(files)); 96 97 List<String> all = new ArrayList<>(); 98 for (String file : files) { 99 all.addAll(Files.readAllLines(Paths.get(file))); 100 } 101 Files.write(Paths.get("reply"), all); 102 103 run("-importcert -file reply -alias me"); 104 KeyStore ks = KeyStore.getInstance( 105 new File("dup.ks"), "changeit".toCharArray()); 106 Certificate[] chain = ks.getCertificateChain("me"); 107 if (chain.length != 3) { 108 throw new Exception("Length is " + chain.length); 109 } 110 111 checkName(chain[0], "CN=Me"); 112 checkName(chain[1], "CN=Int"); 113 checkName(chain[2], "CN=Root"); 114 } 115 116 // Check if c's dname is expected 117 static void checkName(Certificate c, String expected) throws Exception { 118 X509Certificate x = (X509Certificate)c; 119 String name = x.getSubjectX500Principal().toString(); 120 if (!expected.equals(name)) { 121 throw new Exception("Expected " + expected + ", but " + name); 122 } 123 } 124} 125