ReadCertificates.java revision 4479:cb83fe13af98
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 6414980
27 * @summary Make sure that we can parse certificates using various named curves
28 *   and verify their signatures
29 * @author Andreas Sterbenz
30 * @library ..
31 * @library ../../../../java/security/testlibrary
32 */
33
34import java.io.*;
35import java.util.*;
36
37import java.security.cert.*;
38import java.security.*;
39import java.security.interfaces.*;
40
41import javax.security.auth.x500.X500Principal;
42
43public class ReadCertificates extends PKCS11Test {
44
45    private static CertificateFactory factory;
46
47    private static SecureRandom random;
48
49    private static Collection<X509Certificate> readCertificates(File file) throws Exception {
50        System.out.println("Loading " + file.getName() + "...");
51        InputStream in = new FileInputStream(file);
52        Collection<X509Certificate> certs = (Collection<X509Certificate>)factory.generateCertificates(in);
53        in.close();
54        return certs;
55    }
56
57    public static void main(String[] args) throws Exception {
58        main(new ReadCertificates());
59    }
60
61    public void main(Provider p) throws Exception {
62        if (p.getService("Signature", "SHA1withECDSA") == null) {
63            System.out.println("Provider does not support ECDSA, skipping...");
64            return;
65        }
66        Providers.setAt(p, 1);
67
68        random = new SecureRandom();
69        factory = CertificateFactory.getInstance("X.509");
70        try {
71            // clear certificate cache in from a previous run with a different
72            // provider (undocumented hack for the Sun provider)
73            factory.generateCertificate(null);
74        } catch (CertificateException e) {
75            // ignore
76        }
77        Map<X500Principal,X509Certificate> certs = new LinkedHashMap<X500Principal,X509Certificate>();
78
79        File dir = new File(BASE, "certs");
80        File closedDir = new File(CLOSED_BASE, "certs");
81        File[] files = concat(dir.listFiles(), closedDir.listFiles());
82        Arrays.sort(files);
83        for (File file : files) {
84            if (file.isFile() == false) {
85                continue;
86            }
87            Collection<X509Certificate> certList = readCertificates(file);
88            for (X509Certificate cert : certList) {
89                X509Certificate old = certs.put(cert.getSubjectX500Principal(), cert);
90                if (old != null) {
91                    System.out.println("Duplicate subject:");
92                    System.out.println("Old Certificate: " + old);
93                    System.out.println("New Certificate: " + cert);
94                    throw new Exception(file.getPath());
95                }
96            }
97        }
98        System.out.println("OK: " + certs.size() + " certificates.");
99
100        for (X509Certificate cert : certs.values()) {
101            X509Certificate issuer = certs.get(cert.getIssuerX500Principal());
102            System.out.println("Verifying " + cert.getSubjectX500Principal() + "...");
103            PublicKey key = issuer.getPublicKey();
104            // First try the provider under test (if it does not support the
105            // necessary algorithm then try any registered provider).
106            try {
107                cert.verify(key, p.getName());
108            } catch (NoSuchAlgorithmException e) {
109                System.out.println("Warning: " + e.getMessage() +
110                ". Trying another provider...");
111                cert.verify(key);
112            }
113        }
114
115        // try some random invalid signatures to make sure we get the correct
116        // error
117        System.out.println("Checking incorrect signatures...");
118        List<X509Certificate> certList = new ArrayList<X509Certificate>(certs.values());
119        for (int i = 0; i < 20; i++) {
120            X509Certificate cert, signer;
121            do {
122                cert = getRandomCert(certList);
123                signer = getRandomCert(certList);
124            } while (cert.getIssuerX500Principal().equals(signer.getSubjectX500Principal()));
125            try {
126                cert.verify(signer.getPublicKey());
127                throw new Exception("Verified invalid signature");
128            } catch (SignatureException e) {
129                System.out.println("OK: " + e);
130            } catch (InvalidKeyException e) {
131                System.out.println("OK: " + e);
132            }
133        }
134
135        Security.removeProvider(p.getName());
136        System.out.println("OK");
137    }
138
139    private static X509Certificate getRandomCert(List<X509Certificate> certs) {
140        int n = random.nextInt(certs.size());
141        return certs.get(n);
142    }
143
144}
145