diff options
author | andrew <unknown> | 2020-01-03 18:09:11 +0000 |
---|---|---|
committer | bell-sw <liberica@bell-sw.com> | 2020-01-19 09:13:25 +0300 |
commit | 1e7b93fa2b8e39e94a309474d1e0729340a88e87 (patch) | |
tree | 6cf27af39c1479a909a856107fc01e1fcd20d350 /src/share/classes/sun | |
parent | b8399b9b0cc2ae1fe94d7d7b203c24a6504bdce8 (diff) | |
download | jdk8u_jdk-1e7b93fa2b8e39e94a309474d1e0729340a88e87.tar.gz |
8231139: Improved keystore support
Reviewed-by: mbalao
Diffstat (limited to 'src/share/classes/sun')
5 files changed, 33 insertions, 51 deletions
diff --git a/src/share/classes/sun/misc/IOUtils.java b/src/share/classes/sun/misc/IOUtils.java index 3bc78f0ec8..327477d912 100644 --- a/src/share/classes/sun/misc/IOUtils.java +++ b/src/share/classes/sun/misc/IOUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, 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 @@ -51,46 +51,31 @@ public class IOUtils { private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; /** - * Read up to {@code length} of bytes from {@code in} - * until EOF is detected. + * Read exactly {@code length} of bytes from {@code in}. + * + * <p> Note that this method is safe to be called with unknown large + * {@code length} argument. The memory used is proportional to the + * actual bytes available. An exception is thrown if there are not + * enough bytes in the stream. + * * @param is input stream, must not be null * @param length number of bytes to read - * @param readAll if true, an EOFException will be thrown if not enough - * bytes are read. * @return bytes read - * @throws IOException Any IO error or a premature EOF is detected + * @throws EOFException if there are not enough bytes in the stream + * @throws IOException if an I/O error occurs or {@code length} is negative + * @throws OutOfMemoryError if an array of the required size cannot be + * allocated. */ - public static byte[] readFully(InputStream is, int length, boolean readAll) + public static byte[] readExactlyNBytes(InputStream is, int length) throws IOException { if (length < 0) { - throw new IOException("Invalid length"); + throw new IOException("length cannot be negative: " + length); } - byte[] output = {}; - int pos = 0; - while (pos < length) { - int bytesToRead; - if (pos >= output.length) { // Only expand when there's no room - bytesToRead = Math.min(length - pos, output.length + 1024); - if (output.length < pos + bytesToRead) { - output = Arrays.copyOf(output, pos + bytesToRead); - } - } else { - bytesToRead = output.length - pos; - } - int cc = is.read(output, pos, bytesToRead); - if (cc < 0) { - if (readAll) { - throw new EOFException("Detect premature EOF"); - } else { - if (output.length != pos) { - output = Arrays.copyOf(output, pos); - } - break; - } - } - pos += cc; + byte[] data = readNBytes(is, length); + if (data.length < length) { + throw new EOFException(); } - return output; + return data; } /** diff --git a/src/share/classes/sun/security/krb5/internal/NetClient.java b/src/share/classes/sun/security/krb5/internal/NetClient.java index 62243560ca..ab4fe40c3f 100644 --- a/src/share/classes/sun/security/krb5/internal/NetClient.java +++ b/src/share/classes/sun/security/krb5/internal/NetClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -103,7 +103,7 @@ class TCPClient extends NetClient { } try { - return IOUtils.readFully(in, len, true); + return IOUtils.readExactlyNBytes(in, len); } catch (IOException ioe) { if (Krb5.DEBUG) { System.out.println( diff --git a/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java b/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java index c7d9d2adef..a73af4614f 100644 --- a/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java +++ b/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java @@ -128,7 +128,7 @@ public class CCacheInputStream extends KrbDataInputStream implements FileCCacheC length--; for (int i = 0; i <= length; i++) { namelength = readLength4(); - byte[] bytes = IOUtils.readFully(this, namelength, true); + byte[] bytes = IOUtils.readExactlyNBytes(this, namelength); result.add(new String(bytes)); } if (result.isEmpty()) { @@ -186,7 +186,7 @@ public class CCacheInputStream extends KrbDataInputStream implements FileCCacheC if (version == KRB5_FCC_FVNO_3) read(2); /* keytype recorded twice in fvno 3 */ keyLen = readLength4(); - byte[] bytes = IOUtils.readFully(this, keyLen, true); + byte[] bytes = IOUtils.readExactlyNBytes(this, keyLen); return new EncryptionKey(bytes, keyType, new Integer(version)); } @@ -239,7 +239,7 @@ public class CCacheInputStream extends KrbDataInputStream implements FileCCacheC for (int i = 0; i < num; i++) { adtype = read(2); adlength = readLength4(); - data = IOUtils.readFully(this, adlength, true); + data = IOUtils.readExactlyNBytes(this, adlength); auData.add(new AuthorizationDataEntry(adtype, data)); } return auData.toArray(new AuthorizationDataEntry[auData.size()]); @@ -253,7 +253,7 @@ public class CCacheInputStream extends KrbDataInputStream implements FileCCacheC if (length == 0) { return null; } else { - return IOUtils.readFully(this, length, true); + return IOUtils.readExactlyNBytes(this, length); } } diff --git a/src/share/classes/sun/security/provider/JavaKeyStore.java b/src/share/classes/sun/security/provider/JavaKeyStore.java index 409af47cdf..6befb54d68 100644 --- a/src/share/classes/sun/security/provider/JavaKeyStore.java +++ b/src/share/classes/sun/security/provider/JavaKeyStore.java @@ -691,7 +691,7 @@ abstract class JavaKeyStore extends KeyStoreSpi { // Read the private key entry.protectedPrivKey = - IOUtils.readFully(dis, dis.readInt(), true); + IOUtils.readExactlyNBytes(dis, dis.readInt()); // Read the certificate chain int numOfCerts = dis.readInt(); @@ -716,7 +716,7 @@ abstract class JavaKeyStore extends KeyStoreSpi { } } // instantiate the certificate - encoded = IOUtils.readFully(dis, dis.readInt(), true); + encoded = IOUtils.readExactlyNBytes(dis, dis.readInt()); bais = new ByteArrayInputStream(encoded); certs.add(cf.generateCertificate(bais)); bais.close(); @@ -755,7 +755,7 @@ abstract class JavaKeyStore extends KeyStoreSpi { cfs.put(certType, cf); } } - encoded = IOUtils.readFully(dis, dis.readInt(), true); + encoded = IOUtils.readExactlyNBytes(dis, dis.readInt()); bais = new ByteArrayInputStream(encoded); entry.cert = cf.generateCertificate(bais); bais.close(); @@ -776,16 +776,13 @@ abstract class JavaKeyStore extends KeyStoreSpi { if (password != null) { byte computed[], actual[]; computed = md.digest(); - actual = new byte[computed.length]; - dis.readFully(actual); - for (int i = 0; i < computed.length; i++) { - if (computed[i] != actual[i]) { - Throwable t = new UnrecoverableKeyException + actual = IOUtils.readExactlyNBytes(dis, computed.length); + if (!MessageDigest.isEqual(computed, actual)) { + Throwable t = new UnrecoverableKeyException ("Password verification failed"); - throw (IOException)new IOException + throw (IOException) new IOException ("Keystore was tampered with, or " - + "password was incorrect").initCause(t); - } + + "password was incorrect").initCause(t); } } } diff --git a/src/share/classes/sun/security/util/DerValue.java b/src/share/classes/sun/security/util/DerValue.java index 46dcbd34f3..595c011693 100644 --- a/src/share/classes/sun/security/util/DerValue.java +++ b/src/share/classes/sun/security/util/DerValue.java @@ -409,7 +409,7 @@ public class DerValue { if (fullyBuffered && in.available() != length) throw new IOException("extra data given to DerValue constructor"); - byte[] bytes = IOUtils.readFully(in, length, true); + byte[] bytes = IOUtils.readExactlyNBytes(in, length); buffer = new DerInputBuffer(bytes, allowBER); return new DerInputStream(buffer); |