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

Loading JKS keystore using non-null InputStream results in closed stream

XMLWordPrintable

    • b18
    • team
    • x86
    • windows_2008

        FULL PRODUCT VERSION :
        java version "1.8.0_60"
        Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
        Java HotSpot(TM) Client VM (build 25.60-b23, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Microsoft Windows [Version 6.3.9600]

        EXTRA RELEVANT SYSTEM CONFIGURATION :
        This issue relates to the following bug fix that was added in JRE 8 u60:
        http://bugs.java.com/view_bug.do?bug_id=8062552

        A DESCRIPTION OF THE PROBLEM :
        Following a call to KeyStore.load() with non-null InputStream and password, the input stream appears to be closed, when using JRE 8 u60 with a default value for security property "keystore.type.compat" (true).

        Using previous versions of JRE (e.g. u51) or with "keystore.type.compat" set to "false", the input stream remains open.

        I haven't seen anything in documentation for https://docs.oracle.com/javase/8/docs/api/java/security/KeyStore.html#load-java.io.InputStream-char:A- that talks about JRE closing the stream, I think that should be left to the caller to manage.

        REGRESSION. Last worked in version 8u51

        ADDITIONAL REGRESSION INFORMATION:
        java version "1.8.0_60"
        Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
        Java HotSpot(TM) Client VM (build 25.60-b23, mixed mode)

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        1. Create an instance of JKS keystore (ks1)
        2. Persist it on file system or in memory
        3. Create a new instance of JKS keystore (ks2)
        4. Open the input stream pointing at persisted keystore from step 2
        5. Load ks2, using the input stream from 4
        6. Attempt to access the input stream after the loading has completed (by performing a call to either .reset, .available, etc)

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        Expectation is that the stream can continue being used by the caller (e.g. in my application the stream was pointing to a JarInputStream, and the code was attempting to iterate through the Jar entries, processing some of them as keystores)
        ACTUAL -
        The actual result was IOException: Stream is closed being thrown when trying to use the stream that was passed to KeyStore.load.

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        java.io.IOException: Stream Closed
        at java.io.FileInputStream.available(Native Method)

        or

        java.io.IOException: Stream closed
        at java.util.zip.ZipInputStream.ensureOpen(Unknown Source) ~[na:1.8.0_60]
        at java.util.zip.ZipInputStream.getNextEntry(Unknown Source) ~[na:1.8.0_60]
        at java.util.jar.JarInputStream.getNextEntry(Unknown Source) ~[na:1.8.0_60]
        at java.util.jar.JarInputStream.getNextJarEntry(Unknown Source) ~[na:1.8.0_60]



        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        public class Foo {

        public static void main(String[] args) {
        try
        {
        KeyStore keystore1 = KeyStore.getInstance("JKS");
        keystore1.load(null, null);
        File temp = File.createTempFile("temp-file-name", ".tmp");
        FileOutputStream fos = new FileOutputStream(temp);
        keystore1.store(fos, "password".toCharArray());
        fos.close();

        FileInputStream fis = new FileInputStream(temp);
        KeyStore keystore2 = KeyStore.getInstance("JKS");
        keystore2.load(fis, "password".toCharArray());
        fis.available(); // this throws IOException: stream closed since jre8u60
        fis.close();
        }
        catch (Exception e)
        {
        System.out.println(e);
        }
        }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        Temporary workaround seems to be invoking:

        Security.setProperty("keystore.type.compat", "false");

        on application/applet initialization.

              vinnie Vincent Ryan
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              9 Start watching this issue

                Created:
                Updated:
                Resolved: