Mercurial > hg > openjdk > jdk6 > jdk
changeset 1718:ce758cf960f3
8171252: Improve exception checking
8158517: Minor optimizations to ISO10126PADDING
Reviewed-by: ascarpino, mschoene
author | igerasim |
---|---|
date | Thu, 23 Mar 2017 15:00:29 -0700 |
parents | 2e4da5489155 |
children | a52e30264abb |
files | src/share/classes/com/sun/crypto/provider/AESCipher.java src/share/classes/com/sun/crypto/provider/AESWrapCipher.java src/share/classes/com/sun/crypto/provider/ARCFOURCipher.java src/share/classes/com/sun/crypto/provider/BlowfishCipher.java src/share/classes/com/sun/crypto/provider/CipherCore.java src/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java src/share/classes/com/sun/crypto/provider/ISO10126Padding.java src/share/classes/com/sun/crypto/provider/PBECipherCore.java src/share/classes/com/sun/crypto/provider/PKCS5Padding.java |
diffstat | 9 files changed, 90 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/crypto/provider/AESCipher.java Thu May 18 17:01:00 2017 +0100 +++ b/src/share/classes/com/sun/crypto/provider/AESCipher.java Thu Mar 23 15:00:29 2017 -0700 @@ -28,7 +28,6 @@ import java.security.*; import java.security.spec.*; import javax.crypto.*; -import javax.crypto.spec.*; import javax.crypto.BadPaddingException; /** @@ -140,7 +139,7 @@ throw new InvalidKeyException("Key encoding must not be null"); } else if (value.length != fixedKeySize) { throw new InvalidKeyException("The key must be " + - fixedKeySize*8 + " bits"); + fixedKeySize + " bytes"); } } } @@ -479,7 +478,7 @@ throw new InvalidKeyException("Invalid AES key length: " + encoded.length + " bytes"); } - return encoded.length * 8; + return CipherCore.multiplyExact(encoded.length, 8); } /**
--- a/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java Thu May 18 17:01:00 2017 +0100 +++ b/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java Thu Mar 23 15:00:29 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2017, 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 @@ -25,11 +25,9 @@ package com.sun.crypto.provider; -import java.util.Arrays; import java.security.*; import java.security.spec.*; import javax.crypto.*; -import javax.crypto.spec.*; /** * This class implements the AES KeyWrap algorithm as defined @@ -156,7 +154,7 @@ if (decrypting) { result = inputLen - 8; } else { - result = inputLen + 8; + result = CipherCore.addExact(inputLen, 8); } return (result < 0? 0:result); } @@ -378,7 +376,7 @@ throw new InvalidKeyException("Invalid key length: " + encoded.length + " bytes"); } - return encoded.length * 8; + return CipherCore.multiplyExact(encoded.length, 8); } /** @@ -404,7 +402,7 @@ throw new InvalidKeyException("Cannot get an encoding of " + "the key to be wrapped"); } - byte[] out = new byte[keyVal.length + 8]; + byte[] out = new byte[CipherCore.addExact(keyVal.length, 8)]; if (keyVal.length == 8) { System.arraycopy(IV, 0, out, 0, IV.length);
--- a/src/share/classes/com/sun/crypto/provider/ARCFOURCipher.java Thu May 18 17:01:00 2017 +0100 +++ b/src/share/classes/com/sun/crypto/provider/ARCFOURCipher.java Thu Mar 23 15:00:29 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, 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 @@ -256,7 +256,7 @@ // see JCE spec protected int engineGetKeySize(Key key) throws InvalidKeyException { byte[] encodedKey = getEncodedKey(key); - return encodedKey.length << 3; + return CipherCore.multiplyExact(encodedKey.length, 8); } }
--- a/src/share/classes/com/sun/crypto/provider/BlowfishCipher.java Thu May 18 17:01:00 2017 +0100 +++ b/src/share/classes/com/sun/crypto/provider/BlowfishCipher.java Thu Mar 23 15:00:29 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2017, 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 @@ -27,9 +27,7 @@ import java.security.*; import java.security.spec.*; -import sun.security.util.*; import javax.crypto.*; -import javax.crypto.spec.*; import javax.crypto.BadPaddingException; /** @@ -373,7 +371,7 @@ * @exception InvalidKeyException if <code>key</code> is invalid. */ protected int engineGetKeySize(Key key) throws InvalidKeyException { - return (key.getEncoded().length * 8); + return CipherCore.multiplyExact(key.getEncoded().length, 8); } /**
--- a/src/share/classes/com/sun/crypto/provider/CipherCore.java Thu May 18 17:01:00 2017 +0100 +++ b/src/share/classes/com/sun/crypto/provider/CipherCore.java Thu Mar 23 15:00:29 2017 -0700 @@ -268,7 +268,7 @@ * @return the required output buffer size (in bytes) */ int getOutputSize(int inputLen) { - int totalLen = buffered + inputLen; + int totalLen = addExact(buffered, inputLen); if (padding == null) return totalLen; @@ -277,13 +277,14 @@ return totalLen; if (unitBytes != blockSize) { - if (totalLen < diffBlocksize) + if (totalLen < diffBlocksize) { return diffBlocksize; - else - return (totalLen + blockSize - - ((totalLen - diffBlocksize) % blockSize)); + } else { + int residue = (totalLen - diffBlocksize) % blockSize; + return addExact(totalLen, (blockSize - residue)); + } } else { - return totalLen + padding.padLength(totalLen); + return addExact(totalLen, padding.padLength(totalLen)); } } @@ -568,7 +569,8 @@ int update(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException { // figure out how much can be sent to crypto function - int len = buffered + inputLen - minBytes; + int len = addExact(buffered, inputLen); + len -= minBytes; if (padding != null && decrypting) { // do not include the padding bytes when decrypting len -= blockSize; @@ -619,8 +621,8 @@ } inputLen -= inputConsumed; - inputOffset += inputConsumed; - outputOffset += len; + inputOffset = addExact(inputOffset, inputConsumed); + outputOffset = addExact(outputOffset, len); buffered -= bufferedConsumed; if (buffered > 0) { System.arraycopy(buffer, bufferedConsumed, buffer, 0, @@ -632,7 +634,7 @@ System.arraycopy(input, inputOffset, buffer, buffered, inputLen); } - buffered += inputLen; + buffered = addExact(buffered, inputLen); return len; } @@ -728,7 +730,7 @@ BadPaddingException { // calculate the total input length - int totalLen = buffered + inputLen; + int totalLen = addExact(buffered, inputLen); int paddedLen = totalLen; int paddingLen = 0; @@ -753,7 +755,7 @@ // if encrypting and padding not null, add padding if (!decrypting && padding != null) - paddedLen += paddingLen; + paddedLen = addExact(paddedLen, paddingLen); // check output buffer capacity. // if we are decrypting with padding applied, we can perform this @@ -939,4 +941,43 @@ return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm, wrappedKeyType); } + + /* Taken from java.lang.Math in OpenJDK 8 */ + + /** + * Returns the sum of its arguments, + * throwing an exception if the result overflows an {@code int}. + * + * @param x the first value + * @param y the second value + * @return the result + * @throws ArithmeticException if the result overflows an int + * @since 1.8 + */ + public static int addExact(int x, int y) { + int r = x + y; + // HD 2-12 Overflow iff both arguments have the opposite sign of the result + if (((x ^ r) & (y ^ r)) < 0) { + throw new ArithmeticException("integer overflow"); + } + return r; + } + + /** + * Returns the product of the arguments, + * throwing an exception if the result overflows an {@code int}. + * + * @param x the first value + * @param y the second value + * @return the result + * @throws ArithmeticException if the result overflows an int + * @since 1.8 + */ + public static int multiplyExact(int x, int y) { + long r = (long)x * (long)y; + if ((int)r != r) { + throw new ArithmeticException("integer overflow"); + } + return (int)r; + } }
--- a/src/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java Thu May 18 17:01:00 2017 +0100 +++ b/src/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java Thu Mar 23 15:00:29 2017 -0700 @@ -137,7 +137,7 @@ if (decrypting) { result = inputLen - 16; } else { - result = inputLen + 16; + result = CipherCore.addExact(inputLen, 16); } return (result < 0? 0:result); } @@ -453,12 +453,15 @@ } byte[] cks = getChecksum(keyVal); - byte[] out = new byte[iv.length + keyVal.length + cks.length]; + byte[] out = new byte[CipherCore.addExact(iv.length, + CipherCore.addExact(keyVal.length, cks.length))]; System.arraycopy(keyVal, 0, out, iv.length, keyVal.length); - System.arraycopy(cks, 0, out, iv.length+keyVal.length, cks.length); - cipher.encrypt(out, iv.length, keyVal.length+cks.length, - out, iv.length); + System.arraycopy(cks, 0, out, + CipherCore.addExact(iv.length, keyVal.length), cks.length); + + cipher.encrypt(out, iv.length, + CipherCore.addExact(keyVal.length, cks.length), out, iv.length); System.arraycopy(iv, 0, out, 0, iv.length); // reverse the array content
--- a/src/share/classes/com/sun/crypto/provider/ISO10126Padding.java Thu May 18 17:01:00 2017 +0100 +++ b/src/share/classes/com/sun/crypto/provider/ISO10126Padding.java Thu Mar 23 15:00:29 2017 -0700 @@ -63,15 +63,16 @@ if (in == null) return; - if ((off + len) > in.length) { + int idx = CipherCore.addExact(off, len); + if (idx > in.length) { throw new ShortBufferException("Buffer too small to hold padding"); } byte paddingOctet = (byte) (len & 0xff); - byte[] padding = new byte[len]; + byte[] padding = new byte[len -1]; SunJCE.RANDOM.nextBytes(padding); - padding[len-1] = paddingOctet; - System.arraycopy(padding, 0, in, off, len); + System.arraycopy(padding, 0, in, off, len - 1); + in[idx - 1] = paddingOctet; return; } @@ -94,14 +95,15 @@ return 0; } - byte lastByte = in[off + len - 1]; + int idx = CipherCore.addExact(off, len); + byte lastByte = in[idx - 1]; int padValue = (int)lastByte & 0x0ff; if ((padValue < 0x01) || (padValue > blockSize)) { return -1; } - int start = off + len - ((int)lastByte & 0x0ff); + int start = idx - padValue; if (start < off) { return -1; }
--- a/src/share/classes/com/sun/crypto/provider/PBECipherCore.java Thu May 18 17:01:00 2017 +0100 +++ b/src/share/classes/com/sun/crypto/provider/PBECipherCore.java Thu Mar 23 15:00:29 2017 -0700 @@ -264,7 +264,7 @@ if (algo.equals("DES")) { // P || S (password concatenated with salt) - byte[] concat = new byte[passwdBytes.length + salt.length]; + byte[] concat = new byte[CipherCore.addExact(passwdBytes.length, salt.length)]; System.arraycopy(passwdBytes, 0, concat, 0, passwdBytes.length); java.util.Arrays.fill(passwdBytes, (byte)0x00); System.arraycopy(salt, 0, concat, passwdBytes.length, salt.length);
--- a/src/share/classes/com/sun/crypto/provider/PKCS5Padding.java Thu May 18 17:01:00 2017 +0100 +++ b/src/share/classes/com/sun/crypto/provider/PKCS5Padding.java Thu Mar 23 15:00:29 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -26,6 +26,7 @@ package com.sun.crypto.provider; import javax.crypto.ShortBufferException; +import java.util.Arrays; /** * This class implements padding as specified in the PKCS#5 standard. @@ -63,14 +64,13 @@ if (in == null) return; - if ((off + len) > in.length) { + int idx = CipherCore.addExact(off, len); + if (idx > in.length) { throw new ShortBufferException("Buffer too small to hold padding"); } byte paddingOctet = (byte) (len & 0xff); - for (int i = 0; i < len; i++) { - in[i + off] = paddingOctet; - } + Arrays.fill(in, off, idx, paddingOctet); return; } @@ -92,25 +92,24 @@ (len == 0)) { // this can happen if input is really a padded buffer return 0; } - - byte lastByte = in[off + len - 1]; + int idx = CipherCore.addExact(off, len); + byte lastByte = in[idx - 1]; int padValue = (int)lastByte & 0x0ff; if ((padValue < 0x01) || (padValue > blockSize)) { return -1; } - int start = off + len - ((int)lastByte & 0x0ff); + int start = idx - padValue; if (start < off) { return -1; } - for (int i = 0; i < ((int)lastByte & 0x0ff); i++) { - if (in[start+i] != lastByte) { + for (int i = start; i < idx; i++) { + if (in[i] != lastByte) { return -1; } } - return start; }