Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8080102

Java 8 cannot load its cacerts in FIPS. no such provider: SunEC

    XMLWordPrintable

    Details

    • Subcomponent:
    • CPU:
      x86_64
    • OS:
      linux_suse_sles_11

      Backports

        Description

        FULL PRODUCT VERSION :

        java version "1.8.0_31"
        Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
        Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)


        ADDITIONAL OS VERSION INFORMATION :
        Linux sentinel-dev-25 2.6.32.12-0.7-default #1 SMP 2010-05-20 11:14:20 +0200 x86_64 x86_64 x86_64 GNU/Linux


        A DESCRIPTION OF THE PROBLEM :
        Cannot load cacerts in java8 when FIPS is enabled.

        I was able to load the same in jre7u72 builds. It shouldnt be a cacerts issue since i copied the java7 cacerts to java8 and the problem still remains. Suspecting the changes to sunpkcs11 in java8 to cause this.

        Following exception is seen while loading cacerts using a test tool. The same works fine in

        Exception in thread "main" java.lang.RuntimeException: java.security.NoSuchProviderException: no such provider: SunEC
                at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:96)
                at sun.security.util.ECUtil.decodeX509ECPublicKey(ECUtil.java:102)
                at sun.security.pkcs11.P11ECKeyFactory.engineGeneratePublic(P11ECKeyFactory.java:170)
                at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
                at sun.security.x509.X509Key.buildX509Key(X509Key.java:223)
                at sun.security.x509.X509Key.parse(X509Key.java:170)
                at sun.security.x509.CertificateX509Key.<init>(CertificateX509Key.java:75)
                at sun.security.x509.X509CertInfo.parse(X509CertInfo.java:667)
                at sun.security.x509.X509CertInfo.<init>(X509CertInfo.java:167)
                at sun.security.x509.X509CertImpl.parse(X509CertImpl.java:1806)
                at sun.security.x509.X509CertImpl.<init>(X509CertImpl.java:195)
                at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:99)
                at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
                at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:747)
                at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
                at java.security.KeyStore.load(KeyStore.java:1433)
                at TestKeyStoreFIPS.main(TestKeyStoreFIPS.java:46)
        Caused by: java.security.NoSuchProviderException: no such provider: SunEC
                at sun.security.jca.GetInstance.getService(GetInstance.java:83)
                at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
                at java.security.KeyFactory.getInstance(KeyFactory.java:211)
                at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:94)


        REGRESSION. Last worked in version 7u76

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Setup and NSS DB:
        1. export LD_LIBRARY_PATH=/usr/lib64
        2. mkdir /tmp/fips/nssdb
        3. modutil -create -dbdir nssdb/
        4. modutil -fips true -dbdir nssdb
        5. modutil -changepw "NSS FIPS 140-2 Certificate DB" -dbdir nssdb
                     (provide a complex password like password1!)

        Run the testcase provided to load cacerts. First run it using java7 and then run with java8

        /tmp/java7/bin/java -Dnss.lib=/usr/lib64 -Dnss.db=/tmp/fips/nssdb -Djavax.net.ssl.keyStorePassword=password1! TestKeyStoreFIPS /tmp/jre8/lib/security/cacerts changeit

        /tmp/java8/jbin/ava -Dnss.lib=/usr/lib64 -Dnss.db=/tmp/fips/nssdb -Djavax.net.ssl.keyStorePassword=password1! TestKeyStoreFIPS /tmp/jre8/lib/security/cacerts changeit




        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        The list of all certificates in ca certs. While running the tool, output should be following.

        FIPS test success
        digicertassuredidrootca : X.509
        trustcenterclass2caii : X.509
        thawtepremiumserverca : X.509
        swisssignplatinumg2ca : X.509
        swisssignsilverg2ca : X.509
        thawteserverca : X.509
        equifaxsecureebusinessca1 : X.509
        ....
        ACTUAL -
        FIPS test success
        Exception in thread "main" java.lang.RuntimeException: java.security.NoSuchProviderException: no such provider: SunEC
                at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:96)
                at sun.security.util.ECUtil.decodeX509ECPublicKey(ECUtil.java:102)
                at sun.security.pkcs11.P11ECKeyFactory.engineGeneratePublic(P11ECKeyFactory.java:170)
                at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
                at sun.security.x509.X509Key.buildX509Key(X509Key.java:223)
                at sun.security.x509.X509Key.parse(X509Key.java:170)
                at sun.security.x509.CertificateX509Key.<init>(CertificateX509Key.java:75)
                at sun.security.x509.X509CertInfo.parse(X509CertInfo.java:667)
                at sun.security.x509.X509CertInfo.<init>(X509CertInfo.java:167)
                at sun.security.x509.X509CertImpl.parse(X509CertImpl.java:1806)
                at sun.security.x509.X509CertImpl.<init>(X509CertImpl.java:195)
                at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:99)
                at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
                at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:747)
                at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
                at java.security.KeyStore.load(KeyStore.java:1433)
                at TestKeyStoreFIPS.main(TestKeyStoreFIPS.java:46)
        Caused by: java.security.NoSuchProviderException: no such provider: SunEC
                at sun.security.jca.GetInstance.getService(GetInstance.java:83)
                at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
                at java.security.KeyFactory.getInstance(KeyFactory.java:211)
                at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:94)
                ... 16 more


        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        FIPS test success
        Exception in thread "main" java.lang.RuntimeException: java.security.NoSuchProviderException: no such provider: SunEC
                at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:96)
                at sun.security.util.ECUtil.decodeX509ECPublicKey(ECUtil.java:102)
                at sun.security.pkcs11.P11ECKeyFactory.engineGeneratePublic(P11ECKeyFactory.java:170)
                at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
                at sun.security.x509.X509Key.buildX509Key(X509Key.java:223)
                at sun.security.x509.X509Key.parse(X509Key.java:170)
                at sun.security.x509.CertificateX509Key.<init>(CertificateX509Key.java:75)
                at sun.security.x509.X509CertInfo.parse(X509CertInfo.java:667)
                at sun.security.x509.X509CertInfo.<init>(X509CertInfo.java:167)
                at sun.security.x509.X509CertImpl.parse(X509CertImpl.java:1806)
                at sun.security.x509.X509CertImpl.<init>(X509CertImpl.java:195)
                at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:99)
                at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
                at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:747)
                at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
                at java.security.KeyStore.load(KeyStore.java:1433)
                at TestKeyStoreFIPS.main(TestKeyStoreFIPS.java:46)
        Caused by: java.security.NoSuchProviderException: no such provider: SunEC
                at sun.security.jca.GetInstance.getService(GetInstance.java:83)
                at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
                at java.security.KeyFactory.getInstance(KeyFactory.java:211)
                at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:94)
                ... 16 more


        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.io.ByteArrayInputStream;
        import java.io.ByteArrayOutputStream;
        import java.io.FileInputStream;
        import java.io.IOException;
        import java.security.KeyStore;
        import java.security.Provider;
        import java.security.Security;
        import java.util.ArrayList;
        import java.util.Enumeration;
        import java.util.List;
        import java.util.Map;
        import java.util.Properties;
        import java.util.logging.Level;
        import java.util.logging.Logger;

        import sun.security.provider.Sun;
        import sun.security.rsa.SunRsaSign;

        public class TestKeyStoreFIPS {

            public static final String NSS_LIB_DIR_PROP = "nss.lib";
            public static final String NSS_DB_DIR_PROP = "nss.db";
            public static final String SUN_JSSE = "SunJSSE";
            public static List<String> disabledAlgs = new ArrayList<String>();
        public static final String CONFIG = "config/configuration.properties";

            private static final Logger logger = Logger.getLogger(TestKeyStoreFIPS.class.getName());
            
        /**
        * @param args
        */
        public static void main(String[] args) throws Exception{
        if(args.length != 2){
        System.out.println("Usage eg: java -Dnss.lib=/usr/lib64 -Dnss.db=/tmp/fips/nssdb -Djavax.net.ssl.keyStorePassword=password1! TestKeyStoreFIPS /tmp/jre8/lib/security/cacerts changeit");
        System.exit(1);
        }

                enablePkcs11Jsse(System.getProperty(NSS_LIB_DIR_PROP), System.getProperty(NSS_DB_DIR_PROP));
                testFips();

        String file = args[0];
        char[] keystorePassword = args[1].toCharArray();
        FileInputStream keystoreStream = new FileInputStream(file);

        KeyStore keyStore = KeyStore.getInstance("JKS");
        keyStore.load(keystoreStream, keystorePassword);

        Enumeration<String> aliases = keyStore.aliases();

        while(aliases.hasMoreElements()){
        String alias = aliases.nextElement();
        System.out.println(alias + " : " + keyStore.getCertificate(alias).getType());

        }

        }

        private static void testFips(){
        String keyPass = System.getProperty("javax.net.ssl.keyStorePassword");
                KeyStore store;

                try {
                    store = KeyStore.getInstance("PKCS11");
                    if (keyPass != null) {
                        store.load(null, keyPass.toCharArray());
                    } else {
                        store.load(null, null);
                    }
                    System.out.println("FIPS test success");
                } catch (Throwable e) {
                    e.printStackTrace();
                    store = null;
                    System.out.println("FIPS test failed");
                }
        }

            /**
             * Configures a PKCS11 based provider and replace the existing JSSE provider
             * with one configured against the newly added PKCS11 based provider.
             */
            public static void enablePkcs11Jsse( String libDir, String dbDir) throws Exception {
             removeAllProviders();
            
                Provider nss = getNSSFIPSProvider( libDir, dbDir);
                removeDisabledAlgos(nss);
                Security.insertProviderAt(nss, 1);

                Provider sunJsse = new com.sun.net.ssl.internal.ssl.Provider(nss);
                removeDisabledAlgos(sunJsse);
                Security.insertProviderAt(sunJsse,2);
                
                Sun sun = new Sun();
                removeDisabledAlgos(sun);
                Security.insertProviderAt(sun,3);
                
                SunRsaSign sunrsa = new SunRsaSign();
                removeDisabledAlgos(sunrsa);
                Security.insertProviderAt(sunrsa,4);
            }
            
            
            /**
            * Loads and returns an instance of the NSS provider in FIPS mode
            *
            * @return
            * @throws IOException
            */
           private static Provider getNSSFIPSProvider( String libDir, String dbDir) throws Exception {
               
               if(libDir == null || dbDir == null) {
                   throw new Exception(NSS_LIB_DIR_PROP + " or " + NSS_DB_DIR_PROP + " not set.");
               }

               Properties props = new Properties();
               props.put("name", "NSSfips");
               props.put("nssLibraryDirectory", libDir);
               props.put("nssSecmodDirectory", dbDir);
               props.put("nssModule", "fips");
               props.put("nssDbMode", "readWrite");

               return createProvider(props);
           }

           private static Provider createProvider(Properties props) throws IOException {
               ByteArrayOutputStream out = new ByteArrayOutputStream();
               props.store(out, null);
               ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

               Provider ret = new sun.security.pkcs11.SunPKCS11(in);
               if (logger.isLoggable(Level.FINE)) {
                   // Log all of the registered services
                   for (Map.Entry<Object, Object> entry : ret.entrySet()) {
                       logger.log(Level.FINE, "{0} = {1}", new Object[]{entry.getKey(), entry.getValue()});
                   }
               }
               return ret;
           }
           
           /**
            * Remove all default providers except Sun and SunRsaSign
            */
           private static void removeAllProviders(){
            Provider[] providers = Security.getProviders();
            for(Provider prov : providers){
            Security.removeProvider(prov.getName());
            }
           }
           
            /**
             * Remove invalid algorithms
             * @param provider
             */
            private static void removeDisabledAlgos(Provider provider){
             for(String alg : disabledAlgs){
             if(provider.getProperty(alg) != null){
             logger.info("Removing algorithm " + alg + " from provider " + provider);
                 provider.remove(alg);
             }
             }
            }

        }

        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        Replace cacerts with a dummy keystore.

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                coffeys Sean Coffey
                Reporter:
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved: