ReadPKCS12.java revision 5798:0a2565113920
1/*
2 * Copyright (c) 2006, 2007, 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 6405536
27 * @summary Verify that we can parse ECPrivateKeys from PKCS#12 and use them
28 * @author Andreas Sterbenz
29 * @library ..
30 * @library ../../../../java/security/testlibrary
31 */
32
33import java.io.*;
34import java.util.*;
35
36import java.security.*;
37import java.security.interfaces.*;
38import java.security.cert.*;
39import java.security.cert.Certificate;
40
41import javax.security.auth.x500.X500Principal;
42
43public class ReadPKCS12 extends PKCS11Test {
44
45    private final static boolean COPY = false;
46
47    public static void main(String[] args) throws Exception {
48        main(new ReadPKCS12());
49    }
50
51    public void main(Provider p) throws Exception {
52        if (p.getService("Signature", "SHA1withECDSA") == null) {
53            System.out.println("Provider does not support ECDSA, skipping...");
54            return;
55        }
56
57        /*
58         * PKCS11Test.main will remove this provider if needed
59         */
60        Providers.setAt(p, 1);
61
62        CertificateFactory factory = CertificateFactory.getInstance("X.509");
63        try {
64            // undocumented way to clear the Sun internal certificate cache
65            factory.generateCertificate(null);
66        } catch (CertificateException e) {
67            // ignore
68        }
69
70        KeyStore ks2;
71        if (COPY) {
72            ks2 = KeyStore.getInstance("JKS");
73            InputStream in = new FileInputStream("keystore.old");
74            ks2.load(in, "passphrase".toCharArray());
75            in.close();
76        }
77
78        File dir = new File(BASE, "pkcs12");
79        File closedDir = new File(CLOSED_BASE, "pkcs12");
80
81        Map<String,char[]> passwords = new HashMap<String,char[]>();
82        BufferedReader reader = new BufferedReader(new FileReader((new File(BASE, "p12passwords.txt"))));
83        while (true) {
84            String line = reader.readLine();
85            if (line == null) {
86                break;
87            }
88            line = line.trim();
89            if ((line.length() == 0) || line.startsWith("#")) {
90                continue;
91            }
92            String[] s = line.split(" ");
93            passwords.put(s[0], s[1].toCharArray());
94        }
95        reader.close();
96
97        for (File file : concat(dir.listFiles(), closedDir.listFiles())) {
98            String name = file.getName();
99            if (file.isFile() == false) {
100                continue;
101            }
102            System.out.println();
103            System.out.println("Reading " + name + "...");
104
105            char[] password = passwords.get(name);
106            if (password == null) {
107                password = passwords.get("*");
108            }
109
110            InputStream in = new FileInputStream(file);
111            KeyStore ks = KeyStore.getInstance("PKCS12");
112            ks.load(in, password);
113            in.close();
114            List<String> aliases = Collections.list(ks.aliases());
115            System.out.println("Aliases: " + aliases);
116
117            for (String alias : aliases) {
118                PrivateKey privateKey = (PrivateKey)ks.getKey(alias, password);
119                Certificate[] certs = ks.getCertificateChain(alias);
120                PublicKey publicKey = certs[0].getPublicKey();
121                System.out.println("Certificates: " + certs.length);
122                System.out.println(privateKey);
123                System.out.println(publicKey);
124                if (COPY) {
125                    ks2.setKeyEntry(alias, privateKey, "passphrase".toCharArray(), certs);
126                }
127
128                verifyCerts(certs);
129
130                Random random = new Random();
131                byte[] data = new byte[1024];
132                random.nextBytes(data);
133
134                Signature s = Signature.getInstance("SHA1withECDSA");
135                s.initSign(privateKey);
136                s.update(data);
137                byte[] sig = s.sign();
138
139                s.initVerify(publicKey);
140                s.update(data);
141                if (s.verify(sig) == false) {
142                    throw new Exception("Signature does not verify");
143                }
144                System.out.println("Verified public/private key match");
145            }
146        }
147
148        if (COPY) {
149            OutputStream out = new FileOutputStream("keystore.new");
150            ks2.store(out, "passphrase".toCharArray());
151            out.close();
152        }
153
154        System.out.println("OK");
155    }
156
157    private static void verifyCerts(Certificate[] certs) throws Exception {
158        int n = certs.length;
159        for (int i = 0; i < n - 1; i++) {
160            X509Certificate cert = (X509Certificate)certs[i];
161            X509Certificate issuer = (X509Certificate)certs[i + 1];
162            if (cert.getIssuerX500Principal().equals(issuer.getSubjectX500Principal()) == false) {
163                throw new Exception("Certificates do not chain");
164            }
165            cert.verify(issuer.getPublicKey());
166            System.out.println("Verified: " + cert.getSubjectX500Principal());
167        }
168        X509Certificate last = (X509Certificate)certs[n - 1];
169        // if self-signed, verify the final cert
170        if (last.getIssuerX500Principal().equals(last.getSubjectX500Principal())) {
171            last.verify(last.getPublicKey());
172            System.out.println("Verified: " + last.getSubjectX500Principal());
173        }
174    }
175
176}
177