1 /*
   2  * Copyright (c) 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.InputStream;
  25 import java.security.KeyStore;
  26 import java.security.Provider;
  27 import java.security.Security;
  28 import java.security.cert.CRL;
  29 import java.security.cert.CRLException;
  30 import java.security.cert.Certificate;
  31 import java.security.cert.CertificateException;
  32 import java.security.cert.CertificateFactorySpi;
  33 import java.util.Collection;
  34 import java.util.Enumeration;
  35 
  36 /*
  37  * @test
  38  * @bug 8139436
  39  * @summary This test validates an iteration over the Windows-ROOT certificate store
  40  *          and retrieving all certificates.
  41  *          Bug 8139436 reports an issue when 3rd party JCE providers would throw exceptions
  42  *          upon creating Certificate objects.
  43  *          This would for instance happen when using IAIK 3.15 and Elliptic Curve certificates
  44  *          are contained in the Windows-ROOT certificate store.
  45  *          The test uses a simple dummy provider which just throws Exceptions in its CertificateFactory.
  46  *          To test an external provider, you can use property sun.security.mscapi.testprovider and
  47  *          set it to the provider class name which has to be constructible by a constructor without
  48  *          arguments. The provider jar has to be added to the classpath.
  49  *          E.g. run jtreg with -javaoption:-Dsun.security.mscapi.testprovider=iaik.security.provider.IAIK and
  50  *          -cpa:<path to iaik_jce.jar>
  51  *
  52  * @requires os.family == "windows"
  53  * @author Christoph Langer
  54  * @run main IterateWindowsRootStore
  55  */
  56 public class IterateWindowsRootStore {
  57     public static class TestFactory extends CertificateFactorySpi {
  58         @Override
  59         public Certificate engineGenerateCertificate(InputStream inStream) throws CertificateException {
  60             throw new CertificateException("unimplemented");
  61         }
  62 
  63         @Override
  64         public Collection<? extends Certificate> engineGenerateCertificates(InputStream inStream) throws CertificateException {
  65             throw new CertificateException("unimplemented");
  66         }
  67 
  68         @Override
  69         public CRL engineGenerateCRL(InputStream inStream) throws CRLException {
  70             throw new CRLException("unimplemented");
  71         }
  72 
  73         @Override
  74         public Collection<? extends CRL> engineGenerateCRLs(InputStream inStream) throws CRLException {
  75             throw new CRLException("unimplemented");
  76         }
  77     }
  78 
  79     public static class TestProvider extends Provider {
  80         private static final long serialVersionUID = 1L;
  81 
  82         public TestProvider() {
  83             super("TestProvider", 0.1, "Test provider for IterateWindowsRootStore");
  84 
  85             /*
  86              * Certificates
  87              */
  88             this.put("CertificateFactory.X.509", "IterateWindowsRootStore$TestFactory");
  89             this.put("Alg.Alias.CertificateFactory.X509", "X.509");
  90         }
  91     }
  92 
  93     public static void main(String[] args) throws Exception {
  94         // Try to register a JCE provider from property sun.security.mscapi.testprovider in the first slot
  95         // otherwise register a dummy provider which would provoke the issue of bug 8139436
  96         boolean providerPrepended = false;
  97         String testprovider = System.getProperty("sun.security.mscapi.testprovider");
  98         if (testprovider != null && !testprovider.isEmpty()) {
  99             try {
 100                 System.out.println("Trying to prepend external JCE provider " + testprovider);
 101                 Class<?> providerclass = Class.forName(testprovider);
 102                 Object provider = providerclass.newInstance();
 103                 Security.insertProviderAt((Provider)provider, 1);
 104             } catch (Exception e) {
 105                 System.out.println("Could not load JCE provider " + testprovider +". Exception is:");
 106                 e.printStackTrace(System.out);
 107             }
 108             providerPrepended = true;
 109             System.out.println("Sucessfully prepended JCE provider " + testprovider);
 110         }
 111         if (!providerPrepended) {
 112             System.out.println("Trying to prepend dummy JCE provider");
 113             Security.insertProviderAt(new TestProvider(), 1);
 114             System.out.println("Sucessfully prepended dummy JCE provider");
 115         }
 116 
 117         // load Windows-ROOT KeyStore
 118         KeyStore keyStore = KeyStore.getInstance("Windows-ROOT", "SunMSCAPI");
 119         keyStore.load(null, null);
 120 
 121         // iterate KeyStore
 122         Enumeration<String> aliases = keyStore.aliases();
 123         while (aliases.hasMoreElements()) {
 124             String alias = aliases.nextElement();
 125             System.out.print("Reading certificate for alias: " + alias + "...");
 126             keyStore.getCertificate(alias);
 127             System.out.println(" done.");
 128         }
 129     }
 130 }