Search code examples
javasecurityclassloaderbufferedinputstream

BufferedInputStream won't work after KeyStore.load()


My JavaWS application will run in an intern network and so it is signed with the company's own certificate and also the SSL certificate is from the company's root CA. So because of the huge amount of computers its unlikely to import the certificates on each comupter manually. So I extended my app with a class which should automatically import the certificates, this works from the console and the IDE but not if the application is executed by java web start :(

Code

        cf = CertificateFactory.getInstance("X.509");

        signCertIn = ClassLoader.class.getResourceAsStream((pack + signCertName + ".cer"));
        sslCertIn = ClassLoader.class.getResourceAsStream((pack + sslCertName) + ".crt");

        File file = new File(new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security"), "cacerts");
        javaCertIn = new FileInputStream(file);

        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
        keystore.load(javaCertIn, passphrase);

        javaCertIn.close();

        if (!keystore.containsAlias(signCertName)) {
            bis = new BufferedInputStream(signCertIn); // <<<<<<< Exception thrown here
            while (bis.available() > 0) {
                Certificate cert = cf.generateCertificate(bis);
                keystore.setCertificateEntry(signCertName, cert);
            }
            save = true;
            signCertIn.close();
        }

        if (!keystore.containsAlias(sslCertName)) {
            bis = new BufferedInputStream(sslCertIn);
            while (bis.available() > 0) {
                Certificate cert = cf.generateCertificate(bis);
                keystore.setCertificateEntry(sslCertName, cert);
            }
            save = true;
            sslCertIn.close();
        }

        if (save) {
            OutputStream out = new FileOutputStream(file);
            keystore.store(out, passphrase);
            out.close();
        }

JavaWS console output

java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(Unknown Source)
at java.io.BufferedInputStream.available(Unknown Source)
at at.sviss.util.cert.Certificates.install(Certificates.java:48)
at at.sviss.Main.main(Main.java:91)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
at com.sun.javaws.Launcher.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Solution

  • Instead of the ClassLoader:

    signCertIn = ClassLoader.class.getResourceAsStream((pack + signCertName + ".cer"));
    

    Use the class itselfe:

    signCertIn = Certificates.class.getResourceAsStream((pack + signCertName + ".cer"));
    

    Worked for me ...