From 5d5ef39f51d9b0fcc5fe90b11670aa12a1270b27 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Fri, 18 Sep 2015 17:54:28 +0100 Subject: [PATCH] 8136534: Loading JKS keystore using non-null InputStream results in closed stream Reviewed-by: mullan, wetmore --- .../sun/security/util/KeyStoreDelegator.java | 94 +++++++++---------- .../security/KeyStore/CheckInputStream.java | 49 ++++++++++ 2 files changed, 95 insertions(+), 48 deletions(-) create mode 100644 jdk/test/java/security/KeyStore/CheckInputStream.java diff --git a/jdk/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java b/jdk/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java index 3c2b563be3f..81e52ae3448 100644 --- a/jdk/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java +++ b/jdk/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java @@ -210,62 +210,60 @@ public class KeyStoreDelegator extends KeyStoreSpi { } else { // First try the primary keystore then try the secondary keystore - try (InputStream bufferedStream = new BufferedInputStream(stream)) { - bufferedStream.mark(Integer.MAX_VALUE); + InputStream bufferedStream = new BufferedInputStream(stream); + bufferedStream.mark(Integer.MAX_VALUE); + + try { + keystore = primaryKeyStore.newInstance(); + type = primaryType; + keystore.engineLoad(bufferedStream, password); + + } catch (Exception e) { + + // incorrect password + if (e instanceof IOException && + e.getCause() instanceof UnrecoverableKeyException) { + throw (IOException)e; + } try { - keystore = primaryKeyStore.newInstance(); - type = primaryType; - keystore.engineLoad(bufferedStream, password); - - } catch (Exception e) { - - // incorrect password - if (e instanceof IOException && - e.getCause() instanceof UnrecoverableKeyException) { - throw (IOException)e; + // Ignore secondary keystore when no compatibility mode + if (!compatModeEnabled) { + throw e; } - try { - // Ignore secondary keystore when no compatibility mode - if (!compatModeEnabled) { - throw e; - } + keystore = secondaryKeyStore.newInstance(); + type = secondaryType; + bufferedStream.reset(); + keystore.engineLoad(bufferedStream, password); - keystore = secondaryKeyStore.newInstance(); - type = secondaryType; - bufferedStream.reset(); - keystore.engineLoad(bufferedStream, password); + if (debug != null) { + debug.println("WARNING: switching from " + + primaryType + " to " + secondaryType + + " keystore file format has altered the " + + "keystore security level"); + } - if (debug != null) { - debug.println("WARNING: switching from " + - primaryType + " to " + secondaryType + - " keystore file format has altered the " + - "keystore security level"); - } + } catch (InstantiationException | + IllegalAccessException e2) { + // can safely ignore - } catch (InstantiationException | - IllegalAccessException e2) { - // can safely ignore + } catch (IOException | + NoSuchAlgorithmException | + CertificateException e3) { - } catch (IOException | - NoSuchAlgorithmException | - CertificateException e3) { - - // incorrect password - if (e3 instanceof IOException && - e3.getCause() instanceof - UnrecoverableKeyException) { - throw (IOException)e3; - } - // rethrow the outer exception - if (e instanceof IOException) { - throw (IOException)e; - } else if (e instanceof CertificateException) { - throw (CertificateException)e; - } else if (e instanceof NoSuchAlgorithmException) { - throw (NoSuchAlgorithmException)e; - } + // incorrect password + if (e3 instanceof IOException && + e3.getCause() instanceof UnrecoverableKeyException) { + throw (IOException)e3; + } + // rethrow the outer exception + if (e instanceof IOException) { + throw (IOException)e; + } else if (e instanceof CertificateException) { + throw (CertificateException)e; + } else if (e instanceof NoSuchAlgorithmException) { + throw (NoSuchAlgorithmException)e; } } } diff --git a/jdk/test/java/security/KeyStore/CheckInputStream.java b/jdk/test/java/security/KeyStore/CheckInputStream.java new file mode 100644 index 00000000000..64b85391b5c --- /dev/null +++ b/jdk/test/java/security/KeyStore/CheckInputStream.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8136534 + * @summary The input stream supplied to KeyStore.load should remain open. + */ + +import java.io.*; +import java.security.*; + +public class CheckInputStream { + private final static String DIR = System.getProperty("test.src", "."); + private static final char[] PASSWORD = "passphrase".toCharArray(); + private static final String KEYSTORE = DIR + "/keystore.jks"; + + public static final void main(String[] args) throws Exception { + + KeyStore keystore = KeyStore.getInstance("JKS"); + try (FileInputStream inStream = new FileInputStream(KEYSTORE)) { + System.out.println("Loading JKS keystore: " + KEYSTORE); + keystore.load(inStream, PASSWORD); + // check that the stream is still open + inStream.available(); + System.out.println("OK"); + } + } +}