Mercurial > hg > icedtea8-forest > jdk
changeset 12296:b44d695f738b jdk8u112-b02
Merge
author | robm |
---|---|
date | Sat, 25 Jun 2016 20:03:28 +0100 |
parents | 74e5fc94c77b (current diff) 2ff1de5b482d (diff) |
children | 4c3025443a71 9a47402d9c0e |
files | |
diffstat | 36 files changed, 2476 insertions(+), 342 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java Tue Jun 21 10:14:40 2016 -0700 +++ b/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java Sat Jun 25 20:03:28 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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,8 @@ package com.sun.crypto.provider; import java.security.InvalidKeyException; +import java.security.ProviderException; + /** * This class represents ciphers in cipher block chaining (CBC) mode. @@ -122,31 +124,31 @@ * * <p>The input plain text <code>plain</code>, starting at * <code>plainOffset</code> and ending at - * <code>(plainOffset + len - 1)</code>, is encrypted. + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. * The result is stored in <code>cipher</code>, starting at * <code>cipherOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the embedded cipher's block size, - * as any excess bytes are ignored. - * * @param plain the buffer with the input data to be encrypted * @param plainOffset the offset in <code>plain</code> * @param plainLen the length of the input data * @param cipher the buffer for the result * @param cipherOffset the offset in <code>cipher</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size * @return the length of the encrypted data */ int encrypt(byte[] plain, int plainOffset, int plainLen, byte[] cipher, int cipherOffset) { - int i; + if ((plainLen % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } int endIndex = plainOffset + plainLen; for (; plainOffset < endIndex; plainOffset+=blockSize, cipherOffset += blockSize) { - for (i=0; i<blockSize; i++) { - k[i] = (byte)(plain[i+plainOffset] ^ r[i]); + for (int i = 0; i < blockSize; i++) { + k[i] = (byte)(plain[i + plainOffset] ^ r[i]); } embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset); System.arraycopy(cipher, cipherOffset, r, 0, blockSize); @@ -159,14 +161,10 @@ * * <p>The input cipher text <code>cipher</code>, starting at * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. + * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted. * The result is stored in <code>plain</code>, starting at * <code>plainOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * * <p>It is also the application's responsibility to make sure that * <code>init</code> has been called before this method is called. * (This check is omitted here, to avoid double checking.) @@ -176,23 +174,23 @@ * @param cipherLen the length of the input data * @param plain the buffer for the result * @param plainOffset the offset in <code>plain</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size * @return the length of the decrypted data - * - * @exception IllegalBlockSizeException if input data whose length does - * not correspond to the embedded cipher's block size is passed to the - * embedded cipher */ int decrypt(byte[] cipher, int cipherOffset, int cipherLen, byte[] plain, int plainOffset) { - int i; + if ((cipherLen % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } int endIndex = cipherOffset + cipherLen; for (; cipherOffset < endIndex; cipherOffset += blockSize, plainOffset += blockSize) { embeddedCipher.decryptBlock(cipher, cipherOffset, k, 0); - for (i = 0; i < blockSize; i++) { - plain[i+plainOffset] = (byte)(k[i] ^ r[i]); + for (int i = 0; i < blockSize; i++) { + plain[i + plainOffset] = (byte)(k[i] ^ r[i]); } System.arraycopy(cipher, cipherOffset, r, 0, blockSize); }
--- a/src/share/classes/com/sun/crypto/provider/CipherCore.java Tue Jun 21 10:14:40 2016 -0700 +++ b/src/share/classes/com/sun/crypto/provider/CipherCore.java Sat Jun 25 20:03:28 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, 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 @@ -708,7 +708,7 @@ len -= blockSize; } // do not count the trailing bytes which do not make up a unit - len = (len > 0 ? (len - (len%unitBytes)) : 0); + len = (len > 0 ? (len - (len % unitBytes)) : 0); // check output buffer capacity if ((output == null) || @@ -720,6 +720,15 @@ int outLen = 0; if (len != 0) { // there is some work to do + if ((input == output) + && (outputOffset < (inputOffset + inputLen)) + && (inputOffset < (outputOffset + buffer.length))) { + // copy 'input' out to avoid its content being + // overwritten prematurely. + input = Arrays.copyOfRange(input, inputOffset, + inputOffset + inputLen); + inputOffset = 0; + } if (len <= buffered) { // all to-be-processed data are from 'buffer' if (decrypting) { @@ -732,37 +741,40 @@ System.arraycopy(buffer, len, buffer, 0, buffered); } } else { // len > buffered - if ((input != output) && (buffered == 0)) { - // all to-be-processed data are from 'input' - // however, note that if 'input' and 'output' are the same, - // then they can't be passed directly to the underlying cipher - // engine operations as data may be overwritten before they - // are read. - if (decrypting) { - outLen = cipher.decrypt(input, inputOffset, len, output, outputOffset); - } else { - outLen = cipher.encrypt(input, inputOffset, len, output, outputOffset); + int inputConsumed = len - buffered; + int temp; + if (buffered > 0) { + int bufferCapacity = buffer.length - buffered; + if (bufferCapacity != 0) { + temp = Math.min(bufferCapacity, inputConsumed); + if (unitBytes != blockSize) { + temp -= ((buffered + temp) % unitBytes); + } + System.arraycopy(input, inputOffset, buffer, buffered, temp); + inputOffset += temp; + inputConsumed -= temp; + inputLen -= temp; + buffered += temp; } - inputOffset += len; - inputLen -= len; - } else { - // assemble the data using both 'buffer' and 'input' - byte[] in = new byte[len]; - int inConsumed = len - buffered; - if (buffered != 0) { - System.arraycopy(buffer, 0, in, 0, buffered); - buffered = 0; + // process 'buffer' + if (decrypting) { + outLen = cipher.decrypt(buffer, 0, buffered, output, outputOffset); + } else { + outLen = cipher.encrypt(buffer, 0, buffered, output, outputOffset); } - if (inConsumed != 0) { - System.arraycopy(input, inputOffset, in, len - inConsumed, inConsumed); - inputOffset += inConsumed; - inputLen -= inConsumed; + outputOffset += outLen; + buffered = 0; + } + if (inputConsumed > 0) { // still has input to process + if (decrypting) { + outLen += cipher.decrypt(input, inputOffset, inputConsumed, + output, outputOffset); + } else { + outLen += cipher.encrypt(input, inputOffset, inputConsumed, + output, outputOffset); } - if (decrypting) { - outLen = cipher.decrypt(in, 0, len, output, outputOffset); - } else { - outLen = cipher.encrypt(in, 0, len, output, outputOffset); - } + inputOffset += inputConsumed; + inputLen -= inputConsumed; } } // Let's keep track of how many bytes are needed to make @@ -925,8 +937,10 @@ byte[] finalBuf = input; int finalOffset = inputOffset; int finalBufLen = inputLen; - if ((input == output) || (buffered != 0) || - (!decrypting && padding != null)) { + if ((buffered != 0) || (!decrypting && padding != null) || + ((input == output) + && (outputOffset < (inputOffset + inputLen)) + && (inputOffset < (outputOffset + buffer.length)))) { if (decrypting || padding == null) { paddingLen = 0; }
--- a/src/share/classes/com/sun/crypto/provider/CipherFeedback.java Tue Jun 21 10:14:40 2016 -0700 +++ b/src/share/classes/com/sun/crypto/provider/CipherFeedback.java Sat Jun 25 20:03:28 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 java.security.InvalidKeyException; +import java.security.ProviderException; /** * This class represents ciphers in cipher-feedback (CFB) mode. @@ -133,66 +134,72 @@ * * <p>The input plain text <code>plain</code>, starting at * <code>plainOffset</code> and ending at - * <code>(plainOffset + len - 1)</code>, is encrypted. + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. * The result is stored in <code>cipher</code>, starting at * <code>cipherOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the stream unit size - * <code>numBytes</code>, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param plain the buffer with the input data to be encrypted * @param plainOffset the offset in <code>plain</code> * @param plainLen the length of the input data * @param cipher the buffer for the result * @param cipherOffset the offset in <code>cipher</code> + * @exception ProviderException if <code>plainLen</code> is not + * a multiple of the <code>numBytes</code> * @return the length of the encrypted data */ int encrypt(byte[] plain, int plainOffset, int plainLen, - byte[] cipher, int cipherOffset) - { - int i, len; - len = blockSize - numBytes; + byte[] cipher, int cipherOffset) { + if ((plainLen % numBytes) != 0) { + throw new ProviderException("Internal error in input buffering"); + } + + int nShift = blockSize - numBytes; int loopCount = plainLen / numBytes; - int oddBytes = plainLen % numBytes; - if (len == 0) { - for (; loopCount > 0 ; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i = 0; i < blockSize; i++) - register[i] = cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); + for (; loopCount > 0 ; + plainOffset += numBytes, cipherOffset += numBytes, + loopCount--) { + embeddedCipher.encryptBlock(register, 0, k, 0); + if (nShift != 0) { + System.arraycopy(register, numBytes, register, 0, nShift); + } + for (int i = 0; i < numBytes; i++) { + register[nShift + i] = cipher[i + cipherOffset] = + (byte)(k[i] ^ plain[i + plainOffset]); } - if (oddBytes > 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<oddBytes; i++) - register[i] = cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - } - } else { - for (; loopCount > 0 ; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - System.arraycopy(register, numBytes, register, 0, len); - for (i=0; i<numBytes; i++) - register[i+len] = cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); + } + return plainLen; + } - } - if (oddBytes != 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - System.arraycopy(register, numBytes, register, 0, len); - for (i=0; i<oddBytes; i++) { - register[i+len] = cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - } + /** + * Performs the last encryption operation. + * + * <p>The input plain text <code>plain</code>, starting at + * <code>plainOffset</code> and ending at + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. + * The result is stored in <code>cipher</code>, starting at + * <code>cipherOffset</code>. + * + * @param plain the buffer with the input data to be encrypted + * @param plainOffset the offset in <code>plain</code> + * @param plainLen the length of the input data + * @param cipher the buffer for the result + * @param cipherOffset the offset in <code>cipher</code> + * @return the number of bytes placed into <code>cipher</code> + */ + int encryptFinal(byte[] plain, int plainOffset, int plainLen, + byte[] cipher, int cipherOffset) { + + int oddBytes = plainLen % numBytes; + int len = encrypt(plain, plainOffset, (plainLen - oddBytes), + cipher, cipherOffset); + plainOffset += len; + cipherOffset += len; + if (oddBytes != 0) { + embeddedCipher.encryptBlock(register, 0, k, 0); + for (int i = 0; i < oddBytes; i++) { + cipher[i + cipherOffset] = + (byte)(k[i] ^ plain[i + plainOffset]); } } return plainLen; @@ -203,17 +210,52 @@ * * <p>The input cipher text <code>cipher</code>, starting at * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. + * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted. * The result is stored in <code>plain</code>, starting at * <code>plainOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the stream unit size - * <code>numBytes</code>, as any excess bytes are ignored. + * @param cipher the buffer with the input data to be decrypted + * @param cipherOffset the offset in <code>cipherOffset</code> + * @param cipherLen the length of the input data + * @param plain the buffer for the result + * @param plainOffset the offset in <code>plain</code> + * @exception ProviderException if <code>cipherLen</code> is not + * a multiple of the <code>numBytes</code> + * @return the length of the decrypted data + */ + int decrypt(byte[] cipher, int cipherOffset, int cipherLen, + byte[] plain, int plainOffset) { + if ((cipherLen % numBytes) != 0) { + throw new ProviderException("Internal error in input buffering"); + } + + int nShift = blockSize - numBytes; + int loopCount = cipherLen / numBytes; + + for (; loopCount > 0; + plainOffset += numBytes, cipherOffset += numBytes, + loopCount--) { + embeddedCipher.encryptBlock(register, 0, k, 0); + if (nShift != 0) { + System.arraycopy(register, numBytes, register, 0, nShift); + } + for (int i = 0; i < numBytes; i++) { + register[i + nShift] = cipher[i + cipherOffset]; + plain[i + plainOffset] + = (byte)(cipher[i + cipherOffset] ^ k[i]); + } + } + return cipherLen; + } + + /** + * Performs the last decryption operation. * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + * <p>The input cipher text <code>cipher</code>, starting at + * <code>cipherOffset</code> and ending at + * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted. + * The result is stored in <code>plain</code>, starting at + * <code>plainOffset</code>. * * @param cipher the buffer with the input data to be decrypted * @param cipherOffset the offset in <code>cipherOffset</code> @@ -222,53 +264,19 @@ * @param plainOffset the offset in <code>plain</code> * @return the length of the decrypted data */ - int decrypt(byte[] cipher, int cipherOffset, int cipherLen, - byte[] plain, int plainOffset) - { - int i, len; - len = blockSize - numBytes; - int loopCount = cipherLen / numBytes; - int oddBytes = cipherLen % numBytes; + int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen, + byte[] plain, int plainOffset) { - if (len == 0) { - for (; loopCount > 0; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i = 0; i < blockSize; i++) { - register[i] = cipher[i+cipherOffset]; - plain[i+plainOffset] - = (byte)(cipher[i+cipherOffset] ^ k[i]); - } - } - if (oddBytes > 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<oddBytes; i++) { - register[i] = cipher[i+cipherOffset]; - plain[i+plainOffset] - = (byte)(cipher[i+cipherOffset] ^ k[i]); - } - } - } else { - for (; loopCount > 0; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - System.arraycopy(register, numBytes, register, 0, len); - for (i=0; i<numBytes; i++) { - register[i+len] = cipher[i+cipherOffset]; - plain[i+plainOffset] - = (byte)(cipher[i+cipherOffset] ^ k[i]); - } - } - if (oddBytes != 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - System.arraycopy(register, numBytes, register, 0, len); - for (i=0; i<oddBytes; i++) { - register[i+len] = cipher[i+cipherOffset]; - plain[i+plainOffset] - = (byte)(cipher[i+cipherOffset] ^ k[i]); - } + int oddBytes = cipherLen % numBytes; + int len = decrypt(cipher, cipherOffset, (cipherLen - oddBytes), + plain, plainOffset); + cipherOffset += len; + plainOffset += len; + if (oddBytes != 0) { + embeddedCipher.encryptBlock(register, 0, k, 0); + for (int i = 0; i < oddBytes; i++) { + plain[i + plainOffset] + = (byte)(cipher[i + cipherOffset] ^ k[i]); } } return cipherLen;
--- a/src/share/classes/com/sun/crypto/provider/CounterMode.java Tue Jun 21 10:14:40 2016 -0700 +++ b/src/share/classes/com/sun/crypto/provider/CounterMode.java Sat Jun 25 20:03:28 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 201313, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, 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,6 +27,7 @@ import java.security.InvalidKeyException; + /** * This class represents ciphers in counter (CTR) mode. * @@ -136,14 +137,6 @@ * The result is stored in <code>cipher</code>, starting at * <code>cipherOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the embedded cipher's block size, - * as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param in the buffer with the input data to be encrypted * @param inOffset the offset in <code>plain</code> * @param len the length of the input data @@ -155,30 +148,7 @@ return crypt(in, inOff, len, out, outOff); } - /** - * Performs decryption operation. - * - * <p>The input cipher text <code>cipher</code>, starting at - * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. - * The result is stored in <code>plain</code>, starting at - * <code>plainOffset</code>. - * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * - * @param in the buffer with the input data to be decrypted - * @param inOff the offset in <code>cipherOffset</code> - * @param len the length of the input data - * @param out the buffer for the result - * @param outOff the offset in <code>plain</code> - * @return the length of the decrypted data - */ + // CTR encrypt and decrypt are identical int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { return crypt(in, inOff, len, out, outOff); }
--- a/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java Tue Jun 21 10:14:40 2016 -0700 +++ b/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java Sat Jun 25 20:03:28 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 java.security.InvalidKeyException; +import java.security.ProviderException; /** * This class represents ciphers in electronic codebook (ECB) mode. @@ -96,28 +97,24 @@ /** * Performs encryption operation. * - * <p>The input plain text <code>plain</code>, starting at - * <code>plainOffset</code> and ending at - * <code>(plainOffset + len - 1)</code>, is encrypted. - * The result is stored in <code>cipher</code>, starting at - * <code>cipherOffset</code>. - * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the embedded cipher's block size, - * as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + * <p>The input plain text <code>in</code>, starting at + * <code>inOff</code> and ending at * <code>(inOff + len - 1)</code>, + * is encrypted. The result is stored in <code>out</code>, starting at + * <code>outOff</code>. * * @param in the buffer with the input data to be encrypted - * @param inOffset the offset in <code>plain</code> + * @param inOff the offset in <code>plain</code> * @param len the length of the input data * @param out the buffer for the result * @param outOff the offset in <code>cipher</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size * @return the length of the encrypted data */ int encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { + if ((len % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } for (int i = len; i >= blockSize; i -= blockSize) { embeddedCipher.encryptBlock(in, inOff, out, outOff); inOff += blockSize; @@ -129,28 +126,24 @@ /** * Performs decryption operation. * - * <p>The input cipher text <code>cipher</code>, starting at - * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. - * The result is stored in <code>plain</code>, starting at - * <code>plainOffset</code>. - * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + * <p>The input cipher text <code>in</code>, starting at + * <code>inOff</code> and ending at * <code>(inOff + len - 1)</code>, + * is decrypted.The result is stored in <code>out</code>, starting at + * <code>outOff</code>. * * @param in the buffer with the input data to be decrypted * @param inOff the offset in <code>cipherOffset</code> * @param len the length of the input data * @param out the buffer for the result * @param outOff the offset in <code>plain</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size * @return the length of the decrypted data */ int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { + if ((len % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } for (int i = len; i >= blockSize; i -= blockSize) { embeddedCipher.decryptBlock(in, inOff, out, outOff); inOff += blockSize;
--- a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java Tue Jun 21 10:14:40 2016 -0700 +++ b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java Sat Jun 25 20:03:28 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -371,21 +371,19 @@ * and ending at <code>(inOff + len - 1)</code>, is encrypted. The result * is stored in <code>out</code>, starting at <code>outOfs</code>. * - * <p>It is the application's responsibility to make sure that - * <code>len</code> is a multiple of the embedded cipher's block size, - * otherwise, a ProviderException will be thrown. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param in the buffer with the input data to be encrypted * @param inOfs the offset in <code>in</code> * @param len the length of the input data * @param out the buffer for the result * @param outOfs the offset in <code>out</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size + * @return the number of bytes placed into the <code>out</code> buffer */ int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) { + if ((len % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } processAAD(); if (len > 0) { gctrPAndC.update(in, inOfs, len, out, outOfs); @@ -398,9 +396,6 @@ /** * Performs encryption operation for the last time. * - * <p>NOTE: <code>len</code> may not be multiple of the embedded - * cipher's block size for this call. - * * @param in the input buffer with the data to be encrypted * @param inOfs the offset in <code>in</code> * @param len the length of the input data @@ -439,21 +434,19 @@ * is decrypted. The result is stored in <code>out</code>, starting at * <code>outOfs</code>. * - * <p>It is the application's responsibility to make sure that - * <code>len</code> is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param in the buffer with the input data to be decrypted * @param inOfs the offset in <code>in</code> * @param len the length of the input data * @param out the buffer for the result * @param outOfs the offset in <code>out</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size + * @return the number of bytes placed into the <code>out</code> buffer */ int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) { + if ((len % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } processAAD(); if (len > 0) {
--- a/src/share/classes/com/sun/crypto/provider/OutputFeedback.java Tue Jun 21 10:14:40 2016 -0700 +++ b/src/share/classes/com/sun/crypto/provider/OutputFeedback.java Sat Jun 25 20:03:28 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 java.security.InvalidKeyException; +import java.security.ProviderException; /** * This class represents ciphers in output-feedback (OFB) mode. @@ -132,17 +133,52 @@ * * <p>The input plain text <code>plain</code>, starting at * <code>plainOffset</code> and ending at - * <code>(plainOffset + len - 1)</code>, is encrypted. + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. * The result is stored in <code>cipher</code>, starting at * <code>cipherOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the stream unit size - * <code>numBytes</code>, as any excess bytes are ignored. + * @param plain the buffer with the input data to be encrypted + * @param plainOffset the offset in <code>plain</code> + * @param plainLen the length of the input data + * @param cipher the buffer for the result + * @param cipherOffset the offset in <code>cipher</code> + * @exception ProviderException if <code>plainLen</code> is not + * a multiple of the <code>numBytes</code> + * @return the length of the encrypted data + */ + int encrypt(byte[] plain, int plainOffset, int plainLen, + byte[] cipher, int cipherOffset) { + + if ((plainLen % numBytes) != 0) { + throw new ProviderException("Internal error in input buffering"); + } + int nShift = blockSize - numBytes; + int loopCount = plainLen / numBytes; + + for (; loopCount > 0; + plainOffset += numBytes, cipherOffset += numBytes, + loopCount--) { + embeddedCipher.encryptBlock(register, 0, k, 0); + for (int i = 0; i < numBytes; i++) { + cipher[i + cipherOffset] = + (byte)(k[i] ^ plain[i + plainOffset]); + if (nShift != 0) { + System.arraycopy(register, numBytes, register, 0, nShift); + } + System.arraycopy(k, 0, register, nShift, numBytes); + } + } + return plainLen; + } + + /** + * Performs last encryption operation. * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + * <p>The input plain text <code>plain</code>, starting at + * <code>plainOffset</code> and ending at + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. + * The result is stored in <code>cipher</code>, starting at + * <code>cipherOffset</code>. * * @param plain the buffer with the input data to be encrypted * @param plainOffset the offset in <code>plain</code> @@ -151,82 +187,34 @@ * @param cipherOffset the offset in <code>cipher</code> * @return the length of the encrypted data */ - int encrypt(byte[] plain, int plainOffset, int plainLen, - byte[] cipher, int cipherOffset) - { - int i; - int len = blockSize - numBytes; - int loopCount = plainLen / numBytes; + int encryptFinal(byte[] plain, int plainOffset, int plainLen, + byte[] cipher, int cipherOffset) { int oddBytes = plainLen % numBytes; + int len = encrypt(plain, plainOffset, (plainLen - oddBytes), + cipher, cipherOffset); + plainOffset += len; + cipherOffset += len; - if (len == 0) { - for (; loopCount > 0; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<numBytes; i++) - cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - System.arraycopy(k, 0, register, 0, numBytes); - } - if (oddBytes > 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<oddBytes; i++) - cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - System.arraycopy(k, 0, register, 0, numBytes); - } - } else { - for (; loopCount > 0; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<numBytes; i++) - cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - System.arraycopy(register, numBytes, register, 0, len); - System.arraycopy(k, 0, register, len, numBytes); - } - if (oddBytes > 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<oddBytes; i++) - cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - System.arraycopy(register, numBytes, register, 0, len); - System.arraycopy(k, 0, register, len, numBytes); + if (oddBytes != 0) { + embeddedCipher.encryptBlock(register, 0, k, 0); + for (int i = 0; i < oddBytes; i++) { + cipher[i + cipherOffset] = + (byte)(k[i] ^ plain[ i + plainOffset]); } } return plainLen; } - /** - * Performs decryption operation. - * - * <p>The input cipher text <code>cipher</code>, starting at - * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. - * The result is stored in <code>plain</code>, starting at - * <code>plainOffset</code>. - * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the stream unit size - * <code>numBytes</code>, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * - * @param cipher the buffer with the input data to be decrypted - * @param cipherOffset the offset in <code>cipherOffset</code> - * @param cipherLen the length of the input data - * @param plain the buffer for the result - * @param plainOffset the offset in <code>plain</code> - * @return the length of the decrypted data - */ + // OFB encrypt and decrypt are identical int decrypt(byte[] cipher, int cipherOffset, int cipherLen, - byte[] plain, int plainOffset) - { - // OFB encrypt and decrypt are identical + byte[] plain, int plainOffset) { return encrypt(cipher, cipherOffset, cipherLen, plain, plainOffset); } + + // OFB encrypt and decrypt are identical + int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen, + byte[] plain, int plainOffset) { + // OFB encrypt and decrypt are identical + return encryptFinal(cipher, cipherOffset, cipherLen, plain, plainOffset); + } }
--- a/src/share/classes/com/sun/crypto/provider/PCBC.java Tue Jun 21 10:14:40 2016 -0700 +++ b/src/share/classes/com/sun/crypto/provider/PCBC.java Sat Jun 25 20:03:28 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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,8 @@ package com.sun.crypto.provider; import java.security.InvalidKeyException; +import java.security.ProviderException; + /** * This class represents ciphers in Plaintext Cipher Block Chaining (PCBC) @@ -118,38 +120,36 @@ * * <p>The input plain text <code>plain</code>, starting at * <code>plainOffset</code> and ending at - * <code>(plainOffset + len - 1)</code>, is encrypted. + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. * The result is stored in <code>cipher</code>, starting at * <code>cipherOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the embedded cipher's block size, - * as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param plain the buffer with the input data to be encrypted * @param plainOffset the offset in <code>plain</code> * @param plainLen the length of the input data * @param cipher the buffer for the result * @param cipherOffset the offset in <code>cipher</code> + * @exception ProviderException if <code>plainLen</code> is not + * a multiple of the block size + * @return the length of the encrypted data */ int encrypt(byte[] plain, int plainOffset, int plainLen, byte[] cipher, int cipherOffset) { + if ((plainLen % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } int i; int endIndex = plainOffset + plainLen; for (; plainOffset < endIndex; plainOffset += blockSize, cipherOffset += blockSize) { - for (i=0; i<blockSize; i++) { - k[i] ^= plain[i+plainOffset]; + for (i = 0; i < blockSize; i++) { + k[i] ^= plain[i + plainOffset]; } embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset); for (i = 0; i < blockSize; i++) { - k[i] = (byte)(plain[i+plainOffset] ^ cipher[i+cipherOffset]); + k[i] = (byte)(plain[i + plainOffset] ^ cipher[i + cipherOffset]); } } return plainLen; @@ -160,27 +160,25 @@ * * <p>The input cipher text <code>cipher</code>, starting at * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. + * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted. * The result is stored in <code>plain</code>, starting at * <code>plainOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param cipher the buffer with the input data to be decrypted * @param cipherOffset the offset in <code>cipherOffset</code> * @param cipherLen the length of the input data * @param plain the buffer for the result * @param plainOffset the offset in <code>plain</code> + * @exception ProviderException if <code>cipherLen</code> is not + * a multiple of the block size + * @return the length of the decrypted data */ int decrypt(byte[] cipher, int cipherOffset, int cipherLen, byte[] plain, int plainOffset) { + if ((cipherLen % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } int i; int endIndex = cipherOffset + cipherLen; @@ -189,10 +187,10 @@ embeddedCipher.decryptBlock(cipher, cipherOffset, plain, plainOffset); for (i = 0; i < blockSize; i++) { - plain[i+plainOffset] ^= k[i]; + plain[i + plainOffset] ^= k[i]; } for (i = 0; i < blockSize; i++) { - k[i] = (byte)(plain[i+plainOffset] ^ cipher[i+cipherOffset]); + k[i] = (byte)(plain[i + plainOffset] ^ cipher[i + cipherOffset]); } } return cipherLen;
--- a/src/share/classes/javax/swing/plaf/nimbus/skin.laf Tue Jun 21 10:14:40 2016 -0700 +++ b/src/share/classes/javax/swing/plaf/nimbus/skin.laf Sat Jun 25 20:03:28 2016 +0100 @@ -13407,7 +13407,7 @@ <cacheSettingsInherited>false</cacheSettingsInherited> <cacheMode>NO_CACHING</cacheMode> <uiproperties> - <uiProperty name="rendererUseListColors" type="BOOLEAN" value="true"/> + <uiProperty name="rendererUseListColors" type="BOOLEAN" value="false"/> <uiProperty name="rendererUseUIBorder" type="BOOLEAN" value="true"/> <uiProperty name="cellNoFocusBorder" type="BORDER"> <border type="empty" top="2" left="5" bottom="2" right="5"/> @@ -13513,10 +13513,10 @@ <uiproperties/> </style> <backgroundStates> - <state stateKeys="Disabled"> + <state stateKeys="Selected"> <style> <textForeground> - <matte red="142" green="143" blue="145" alpha="255" uiDefaultParentName="nimbusDisabledText" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> + <matte red="255" green="255" blue="255" alpha="255" uiDefaultParentName="nimbusLightBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> </textForeground> <textBackground/> <background> @@ -13541,6 +13541,56 @@ </layer> </canvas> </state> + <state stateKeys="Disabled+Selected"> + <style> + <textForeground/> + <textBackground/> + <background> + <matte red="57" green="105" blue="138" alpha="255" uiDefaultParentName="nimbusSelectionBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> + </background> + <inherit-background>false</inherit-background> + <uiproperties/> + </style> + <canvas> + <size width="100" height="30"/> + <nextLayerNameIndex>2</nextLayerNameIndex> + <stretchingInsets top="0" bottom="0" left="0" right="0"/> + <layer name="Layer 1"> + <opacity>1.0</opacity> + <fillOpacity>1.0</fillOpacity> + <blendingMode>NORMAL</blendingMode> + <locked>false</locked> + <visible>true</visible> + <shapes/> + <effects/> + </layer> + </canvas> + </state> + <state stateKeys="Disabled"> + <style> + <textForeground> + <matte red="142" green="143" blue="145" alpha="255" uiDefaultParentName="nimbusDisabledText" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> + </textForeground> + <textBackground/> + <background/> + <inherit-textForeground>false</inherit-textForeground> + <uiproperties/> + </style> + <canvas> + <size width="100" height="30"/> + <nextLayerNameIndex>2</nextLayerNameIndex> + <stretchingInsets top="0" bottom="0" left="0" right="0"/> + <layer name="Layer 1"> + <opacity>1.0</opacity> + <fillOpacity>1.0</fillOpacity> + <blendingMode>NORMAL</blendingMode> + <locked>false</locked> + <visible>true</visible> + <shapes/> + <effects/> + </layer> + </canvas> + </state> </backgroundStates> <foregroundStates/> <borderStates/>
--- a/src/share/classes/sun/java2d/opengl/OGLMaskFill.java Tue Jun 21 10:14:40 2016 -0700 +++ b/src/share/classes/sun/java2d/opengl/OGLMaskFill.java Sat Jun 25 20:03:28 2016 +0100 @@ -26,6 +26,7 @@ package sun.java2d.opengl; import java.awt.Composite; +import sun.java2d.InvalidPipeException; import sun.java2d.SunGraphics2D; import sun.java2d.loops.GraphicsPrimitive; import sun.java2d.loops.GraphicsPrimitiveMgr; @@ -67,7 +68,14 @@ protected void validateContext(SunGraphics2D sg2d, Composite comp, int ctxflags) { - OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData; + OGLSurfaceData dstData; + try { + dstData = (OGLSurfaceData) sg2d.surfaceData; + } catch (ClassCastException e) { + throw new InvalidPipeException("wrong surface data type: " + + sg2d.surfaceData); + } + OGLContext.validateContext(dstData, dstData, sg2d.getCompClip(), comp, null, sg2d.paint, sg2d, ctxflags);
--- a/src/windows/classes/sun/java2d/d3d/D3DMaskFill.java Tue Jun 21 10:14:40 2016 -0700 +++ b/src/windows/classes/sun/java2d/d3d/D3DMaskFill.java Sat Jun 25 20:03:28 2016 +0100 @@ -26,6 +26,7 @@ package sun.java2d.d3d; import java.awt.Composite; +import sun.java2d.InvalidPipeException; import sun.java2d.SunGraphics2D; import sun.java2d.loops.GraphicsPrimitive; import sun.java2d.loops.GraphicsPrimitiveMgr; @@ -67,7 +68,13 @@ protected void validateContext(SunGraphics2D sg2d, Composite comp, int ctxflags) { - D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData; + D3DSurfaceData dstData; + try { + dstData = (D3DSurfaceData) sg2d.surfaceData; + } catch (ClassCastException e) { + throw new InvalidPipeException("wrong surface data type: " + + sg2d.surfaceData); + } D3DContext.validateContext(dstData, dstData, sg2d.getCompClip(), comp, null, sg2d.paint, sg2d, ctxflags);
--- a/test/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java Tue Jun 21 10:14:40 2016 -0700 +++ b/test/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java Sat Jun 25 20:03:28 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8026943 + * @bug 8026943 8027575 * @summary Verify that same buffer can be used as input and output when * using Cipher objects. * @author Valerie Peng @@ -44,7 +44,7 @@ private static SecretKey KEY = new SecretKeySpec(new byte[16], "AES"); private static byte[] IV = new byte[16]; - private static int[] OFFSETS = { 1, 8, 17 }; + private static int[] OFFSETS = { 1, 8, 9, 16, 17, 32, 33 }; private static final String[] MODES = { "ECB", "CBC", "PCBC", "CTR", "CTS",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/Blowfish/TestCipherBlowfish.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,51 @@ +/* + * 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. + */ + +import java.security.NoSuchAlgorithmException; + +/* + * @test + * @bug 8048601 + * @library ../ + * @summary Test Blowfish cipher with different MODES and padding + */ + +public class TestCipherBlowfish extends TestCipher { + + TestCipherBlowfish() throws NoSuchAlgorithmException { + super("Blowfish", + new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC", + //CFBx + "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", + "CFB64", + //OFBx + "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56", + "OFB64"}, + new String[]{"NoPaDDing", "PKCS5Padding"}, + true); + } + + public static void main(String[] args) throws Exception { + new TestCipherBlowfish().runAll(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/DES/TestCipherDES.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,48 @@ +/* + * 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 8048601 + * @library ../ + * @summary Test DES/DESede cipher with different MODES and padding + */ + +public class TestCipherDES extends TestCipher { + + TestCipherDES() { + super("DES", + new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC", + //CFBx + "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", + "CFB64", + //OFBx + "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56", + "OFB64"}, + new String[]{"NoPaDDing", "PKCS5Padding"}); + } + + public static void main(String[] args) throws Exception { + new TestCipherDES().runAll(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/DES/TestCipherDESede.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,48 @@ +/* + * 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 8048601 + * @library ../ + * @summary Test DES/DESede cipher with different MODES and padding + */ + +public class TestCipherDESede extends TestCipher { + + TestCipherDESede() { + super("DESede", + new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC", + //CFBx + "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", + "CFB64", + //OFBx + "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56", + "OFB64"}, + new String[]{"NoPaDDing", "PKCS5Padding"}); + } + + public static void main(String[] args) throws Exception { + new TestCipherDESede().runAll(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBE.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,128 @@ +/* + * 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. + */ + +import static java.lang.System.out; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; + +/* + * @test + * @bug 8048601 + * @summary Tests for PBE ciphers + */ +public class TestCipherPBE { + + private static final String[] ALGORITHMS = {"PBEWithMD5AndDES", + "PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithMD5AndTripleDES", + "PBEWithMD5AndTripleDES/CBC/PKCS5Padding"}; + + private static final String KEY_ALGO = "pbeWithMD5ANDdes"; + private final byte[] SALT; + private final byte[] PLAIN_TEXT; + + public TestCipherPBE() { + SALT = generateBytes(8); + PLAIN_TEXT = generateBytes(200); + } + + public static void main(String[] args) throws Exception { + + new TestCipherPBE().runAll(); + } + + private void runAll() throws Exception { + for (String algorithm : ALGORITHMS) { + runTest(algorithm); + } + } + + private void runTest(String algorithm) + throws InvalidKeySpecException, NoSuchAlgorithmException, + InvalidAlgorithmParameterException, ShortBufferException, + NoSuchPaddingException, IllegalBlockSizeException, + BadPaddingException, InvalidKeyException { + + out.println("=> Testing: " + algorithm); + + try { + // Initialization + AlgorithmParameterSpec algoParamSpec + = new PBEParameterSpec(SALT, 6); + + SecretKey secretKey + = SecretKeyFactory.getInstance(KEY_ALGO).generateSecret( + new PBEKeySpec(("Secret Key Value").toCharArray())); + + Cipher ci = Cipher.getInstance(algorithm); + ci.init(Cipher.ENCRYPT_MODE, secretKey, algoParamSpec); + + // Encryption + byte[] cipherText = ci.doFinal(PLAIN_TEXT); + + // Decryption + ci.init(Cipher.DECRYPT_MODE, secretKey, algoParamSpec); + byte[] recoveredText = ci.doFinal(cipherText); + + if (algorithm.contains("TripleDES")) { + throw new RuntimeException( + "Expected InvalidKeyException exception uncaugh"); + } + + // Comparison + if (!Arrays.equals(PLAIN_TEXT, recoveredText)) { + throw new RuntimeException( + "Test failed: plainText is not equal to recoveredText"); + } + out.println("Test Passed."); + } catch (InvalidKeyException ex) { + if (algorithm.contains("TripleDES")) { + out.println("Expected InvalidKeyException raised"); + } else { + throw new RuntimeException(ex); + } + } + } + + public static byte[] generateBytes(int length) { + byte[] bytes = new byte[length]; + for (int i = 0; i < length; i++) { + bytes[i] = (byte) (i & 0xff); + } + return bytes; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/TestCipher.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,220 @@ +/* + * 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. + */ + +import static java.lang.System.out; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * This is a abstract class used to test various ciphers + */ +public abstract class TestCipher { + + private final String SUNJCE = "SunJCE"; + private final String ALGORITHM; + private final String[] MODES; + private final String[] PADDINGS; + + /* Used to test cipher with different key strengths + Key size tested is increment of KEYCUTTER from MINIMUM_KEY_SIZE to + maximum allowed keysize. + DES/DESede/Blowfish work with currently selected key sizes. + */ + private final int variousKeySize; + private final int KEYCUTTER = 8; + private final int MINIMUM_KEY_SIZE = 32; + + // Used to assert that Encryption/Decryption works with same buffer + // TEXT_LEN is multiple of blocks in order to work against ciphers w/ NoPadding + private final int TEXT_LEN = 800; + private final int ENC_OFFSET = 6; + private final int STORAGE_OFFSET = 3; + private final int PAD_BYTES = 16; + + private final byte[] IV; + private final byte[] INPUT_TEXT; + + TestCipher(String algo, String[] modes, String[] paddings, + boolean keyStrength) throws NoSuchAlgorithmException { + ALGORITHM = algo; + MODES = modes; + PADDINGS = paddings; + this.variousKeySize + = keyStrength ? Cipher.getMaxAllowedKeyLength(ALGORITHM) : 0; + + IV = generateBytes(8); + INPUT_TEXT = generateBytes(TEXT_LEN + PAD_BYTES + ENC_OFFSET); + } + + TestCipher(String algo, String[] modes, String[] paddings) { + ALGORITHM = algo; + MODES = modes; + PADDINGS = paddings; + variousKeySize = 0; + + IV = generateBytes(8); + INPUT_TEXT = generateBytes(TEXT_LEN + PAD_BYTES + ENC_OFFSET); + } + + private static byte[] generateBytes(int length) { + byte[] bytes = new byte[length]; + for (int i = 0; i < length; i++) { + bytes[i] = (byte) (i & 0xff); + } + return bytes; + } + + private boolean isKeyStrenthSupported() { + return (variousKeySize != 0); + } + + public void runAll() throws InvalidKeyException, + NoSuchPaddingException, InvalidAlgorithmParameterException, + ShortBufferException, IllegalBlockSizeException, + BadPaddingException, NoSuchAlgorithmException, + NoSuchProviderException { + + for (String mode : MODES) { + for (String padding : PADDINGS) { + if (!isKeyStrenthSupported()) { + runTest(mode, padding, 0); + } else { + int keySize = variousKeySize; + while (keySize >= MINIMUM_KEY_SIZE) { + out.println("With Key Strength: " + keySize); + runTest(mode, padding, keySize); + keySize -= KEYCUTTER; + } + } + } + } + } + + private void runTest(String mo, String pad, int keySize) + throws NoSuchPaddingException, BadPaddingException, + ShortBufferException, IllegalBlockSizeException, + InvalidAlgorithmParameterException, InvalidKeyException, + NoSuchAlgorithmException, NoSuchProviderException { + + String TRANSFORMATION = ALGORITHM + "/" + mo + "/" + pad; + out.println("Testing: " + TRANSFORMATION); + + // Initialization + Cipher ci = Cipher.getInstance(TRANSFORMATION, SUNJCE); + KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM, SUNJCE); + if (keySize != 0) { + kg.init(keySize); + } + SecretKey key = kg.generateKey(); + SecretKeySpec skeySpec = new SecretKeySpec(key.getEncoded(), ALGORITHM); + + AlgorithmParameterSpec aps = new IvParameterSpec(IV); + if (mo.equalsIgnoreCase("ECB")) { + ci.init(Cipher.ENCRYPT_MODE, key); + } else { + ci.init(Cipher.ENCRYPT_MODE, key, aps); + } + + // Encryption + int PAD_LEN = 0; + if (pad.equalsIgnoreCase("PKCS5Padding")) { + // Need to consider pad bytes + PAD_LEN = 8; + } + + byte[] plainText = INPUT_TEXT.clone(); + + // Generate cipher and save to separate buffer + byte[] cipherText = ci.doFinal(INPUT_TEXT, ENC_OFFSET, TEXT_LEN); + + // Generate cipher and save to same buffer + int offset = ci.update( + INPUT_TEXT, ENC_OFFSET, TEXT_LEN, INPUT_TEXT, STORAGE_OFFSET); + ci.doFinal(INPUT_TEXT, offset + STORAGE_OFFSET); + + if (!equalsBlock( + INPUT_TEXT, STORAGE_OFFSET, cipherText, 0, cipherText.length)) { + throw new RuntimeException( + "Different ciphers generated with same buffer"); + } + + // Decryption + if (mo.equalsIgnoreCase("ECB")) { + ci.init(Cipher.DECRYPT_MODE, skeySpec); + } else { + ci.init(Cipher.DECRYPT_MODE, skeySpec, aps); + } + + // Recover text from cipher and save to separate buffer + byte[] recoveredText = ci.doFinal(cipherText, 0, cipherText.length); + + if (!equalsBlock( + plainText, ENC_OFFSET, recoveredText, 0, + recoveredText.length)) { + throw new RuntimeException( + "Recovered text not same as plain text"); + } else { + out.println("Recovered and plain text are same"); + } + + // Recover text from cipher and save to same buffer + ci.update(INPUT_TEXT, STORAGE_OFFSET, TEXT_LEN + PAD_LEN, INPUT_TEXT, + ENC_OFFSET); + ci.doFinal(INPUT_TEXT, ENC_OFFSET); + + if (!equalsBlock( + plainText, ENC_OFFSET, recoveredText, 0, + recoveredText.length)) { + throw new RuntimeException( + "Recovered text not same as plain text with same buffer"); + } else { + out.println("Recovered and plain text are same with same buffer"); + } + + out.println("Test Passed."); + } + + private static boolean equalsBlock(byte[] b1, int off1, byte[] b2, int off2, + int len) { + for (int i = off1, j = off2, k = 0; k < len; i++, j++, k++) { + if (b1[i] != b2[j]) { + return false; + } + } + return true; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/TextLength/DESCipherWrapper.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,172 @@ +/* + * 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. + */ + +import static java.lang.System.out; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; + +/** + * Wrapper class to test a given DES algorithm. + */ +public class DESCipherWrapper { + + private final Cipher ci; + private final byte[] iv; + private final SecretKey key; + private final String algo; + private final String mode; + private final String pad; + private final int keyStrength; + private byte[] resultText = null; + + public DESCipherWrapper(String algo, String mode, String pad) + throws NoSuchAlgorithmException, NoSuchPaddingException { + ci = Cipher.getInstance(algo + "/" + mode + "/" + pad); + + iv = new byte[8]; + for (int i = 0; i < 8; i++) { + iv[i] = (byte) (i & 0xff); + } + + KeyGenerator kg = KeyGenerator.getInstance(algo); + key = kg.generateKey(); + keyStrength = algo.equalsIgnoreCase("DESede") ? 112 + : key.getEncoded().length * 8; + + this.algo = algo; + this.mode = mode; + this.pad = pad; + } + + public byte[] getResult() { + return resultText.clone(); + } + + public void execute(int edMode, byte[] inputText) + throws InvalidKeyException, InvalidAlgorithmParameterException, + IllegalBlockSizeException, BadPaddingException, + ShortBufferException, NoSuchAlgorithmException { + AlgorithmParameterSpec aps = null; + + try { + if (!mode.equalsIgnoreCase("ECB")) { + aps = new IvParameterSpec(iv); + } + ci.init(edMode, key, aps); + + // Generate a resultText using a single-part enc/dec + resultText = ci.doFinal(inputText); + + // Generate outputText for each multi-part en/de-cryption + /* Combination #1: + update(byte[], int, int) + doFinal(byte[], int, int) + */ + byte[] part11 = ci.update(inputText, 0, inputText.length); + byte[] part12 = ci.doFinal(); + byte[] outputText1 = new byte[part11.length + part12.length]; + System.arraycopy(part11, 0, outputText1, 0, part11.length); + System.arraycopy(part12, 0, outputText1, part11.length, + part12.length); + + List<byte[]> outputTexts = new ArrayList<>(4); + outputTexts.add(outputText1); + + /* Combination #2: + update(byte[], int, int) + doFinal(byte[], int, int, byte[], int) + */ + byte[] part21 = ci.update(inputText, 0, inputText.length - 5); + byte[] part22 = new byte[ci.getOutputSize(inputText.length)]; + int len2 = ci + .doFinal(inputText, inputText.length - 5, 5, part22, 0); + byte[] outputText2 = new byte[part21.length + len2]; + System.arraycopy(part21, 0, outputText2, 0, part21.length); + System.arraycopy(part22, 0, outputText2, part21.length, len2); + + outputTexts.add(outputText2); + + /* Combination #3: + update(byte[], int, int, byte[], int) + doFinal(byte[], int, int) + */ + byte[] part31 = new byte[ci.getOutputSize(inputText.length)]; + int len3 = ci.update(inputText, 0, inputText.length - 8, part31, 0); + byte[] part32 = ci.doFinal(inputText, inputText.length - 8, 8); + byte[] outputText3 = new byte[len3 + part32.length]; + System.arraycopy(part31, 0, outputText3, 0, len3); + System.arraycopy(part32, 0, outputText3, len3, part32.length); + + outputTexts.add(outputText3); + + /* Combination #4: + update(byte[], int, int, byte[], int) + doFinal(byte[], int, int, byte[], int) + */ + byte[] part41 = new byte[ci.getOutputSize(inputText.length)]; + int len4 = ci.update(inputText, 0, inputText.length - 8, part41, 0); + int rest4 = ci.doFinal(inputText, inputText.length - 8, 8, part41, + len4); + byte[] outputText4 = new byte[len4 + rest4]; + System.arraycopy(part41, 0, outputText4, 0, outputText4.length); + + outputTexts.add(outputText4); + + // Compare results + for (int k = 0; k < outputTexts.size(); k++) { + if (!Arrays.equals(resultText, outputTexts.get(k))) { + out.println(" Testing: " + algo + "/" + mode + "/" + pad); + throw new RuntimeException( + "Compare value of resultText and combination " + k + + " are not same. Test failed."); + } + } + if (keyStrength > Cipher.getMaxAllowedKeyLength(algo)) { + throw new RuntimeException( + "Expected exception uncaught, keyStrength " + + keyStrength); + } + } catch (InvalidKeyException ex) { + if (keyStrength <= Cipher.getMaxAllowedKeyLength(algo)) { + out.println("Unexpected exception in " + algo + "/" + mode + + "/" + pad + " , KeySize " + keyStrength); + throw ex; + } + out.println("Caught InvalidKeyException as expected"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/TextLength/PBECipherWrapper.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,258 @@ +/* + * 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. + */ + +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.InvalidParameterSpecException; +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * PBECipherWrapper is the abstract class for all concrete PBE Cipher wrappers. + */ +public abstract class PBECipherWrapper { + + public static final int ITERATION_COUNT = 1000; + private final String algorithm; + private final byte[] salt; + protected SecretKey key; + protected Cipher ci; + protected String baseAlgo; + protected byte[] resultText = null; + protected AlgorithmParameterSpec aps = null; + + public PBECipherWrapper(String algorithm, int saltSize) { + this.algorithm = algorithm; + baseAlgo = algorithm.split("/")[0].toUpperCase(); + salt = generateSalt(saltSize); + } + + protected abstract void initCipher(int mode) throws InvalidKeyException, + InvalidAlgorithmParameterException, InvalidParameterSpecException; + + public void execute(int edMode, byte[] inputText) + throws InvalidAlgorithmParameterException, + InvalidParameterSpecException, IllegalBlockSizeException, + BadPaddingException, ShortBufferException, InvalidKeyException { + // Initialize + initCipher(edMode); + + // Generate a resultText using a single-part enc/dec + resultText = ci.doFinal(inputText); + + // Generate outputText for each multi-part en/de-cryption + /* Combination #1: + update(byte[], int, int) + doFinal(byte[], int, int) + */ + byte[] part11 = ci.update(inputText, 0, inputText.length); + byte[] part12 = ci.doFinal(); + byte[] outputText1 = new byte[part11.length + part12.length]; + System.arraycopy(part11, 0, outputText1, 0, part11.length); + System.arraycopy(part12, 0, outputText1, part11.length, part12.length); + + List<byte[]> outputTexts = new ArrayList<>(4); + outputTexts.add(outputText1); + + /* Combination #2: + update(byte[], int, int) + doFinal(byte[], int, int, byte[], int) + */ + byte[] part21 = ci.update(inputText, 0, inputText.length - 5); + byte[] part22 = new byte[ci.getOutputSize(inputText.length)]; + int len2 = ci.doFinal(inputText, inputText.length - 5, 5, part22, 0); + byte[] outputText2 = new byte[part21.length + len2]; + System.arraycopy(part21, 0, outputText2, 0, part21.length); + System.arraycopy(part22, 0, outputText2, part21.length, len2); + + outputTexts.add(outputText2); + + /* Combination #3: + update(byte[], int, int, byte[], int) + doFinal(byte[], int, int) + */ + byte[] part31 = new byte[ci.getOutputSize(inputText.length)]; + int len3 = ci.update(inputText, 0, inputText.length - 8, part31, 0); + byte[] part32 = ci.doFinal(inputText, inputText.length - 8, 8); + byte[] outputText3 = new byte[len3 + part32.length]; + System.arraycopy(part31, 0, outputText3, 0, len3); + System.arraycopy(part32, 0, outputText3, len3, part32.length); + + outputTexts.add(outputText3); + + /* Combination #4: + update(byte[], int, int, byte[], int) + doFinal(byte[], int, int, byte[], int) + */ + byte[] part41 = new byte[ci.getOutputSize(inputText.length)]; + int len4 = ci.update(inputText, 0, inputText.length - 8, part41, 0); + int rest4 = ci + .doFinal(inputText, inputText.length - 8, 8, part41, len4); + byte[] outputText4 = new byte[len4 + rest4]; + System.arraycopy(part41, 0, outputText4, 0, outputText4.length); + + outputTexts.add(outputText4); + + // Compare results + for (int k = 0; k < outputTexts.size(); k++) { + if (!Arrays.equals(resultText, outputTexts.get(k))) { + throw new RuntimeException( + "Compare value of resultText and combination " + k + + " are not same. Test failed."); + } + } + + } + + public final byte[] generateSalt(int numberOfBytes) { + byte[] aSalt = new byte[numberOfBytes]; + for (int i = 0; i < numberOfBytes; i++) { + aSalt[i] = (byte) (i & 0xff); + } + return aSalt; + } + + public byte[] getResult() { + return resultText; + } + + public String getAlgorithm() { + return algorithm; + } + + public byte[] getSalt() { + return salt; + } + + /** + * Wrapper class to test a given SecretKeyFactory.PBKDF2 algorithm. + */ + public static class PBKDF2 extends PBECipherWrapper { + + private static final int PBKDF2_SALT_SIZE = 64; + private static final int CIPHER_KEY_SIZE = 128; + private static final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding"; + private static final String KEY_ALGORITHM = "AES"; + private byte[] iv = null; + + public PBKDF2(String algo, String passwd) + throws InvalidKeySpecException, NoSuchAlgorithmException, + NoSuchPaddingException { + super(algo, PBKDF2_SALT_SIZE); + + ci = Cipher.getInstance(CIPHER_TRANSFORMATION); + + PBEKeySpec pbeKeySpec = new PBEKeySpec(passwd.toCharArray(), getSalt(), + ITERATION_COUNT, CIPHER_KEY_SIZE); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algo); + key = keyFactory.generateSecret(pbeKeySpec); + } + + @Override + protected void initCipher(int mode) throws InvalidKeyException, + InvalidAlgorithmParameterException, InvalidParameterSpecException { + if (Cipher.ENCRYPT_MODE == mode) { + ci.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getEncoded(), + KEY_ALGORITHM)); + iv = ci.getParameters().getParameterSpec(IvParameterSpec.class) + .getIV(); + } else { + ci.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getEncoded(), + KEY_ALGORITHM), new IvParameterSpec(iv)); + } + } + } + + /** + * Wrapper class to test a given AES-based PBE algorithm. + */ + public static class AES extends PBECipherWrapper { + + private AlgorithmParameters pbeParams; + + public AES(String algo, String passwd) + throws NoSuchAlgorithmException, NoSuchPaddingException, + InvalidKeySpecException { + super(algo, 0); + + ci = Cipher.getInstance(algo); + + SecretKeyFactory skf = SecretKeyFactory.getInstance(algo); + key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray())); + } + + @Override + protected void initCipher(int mode) throws InvalidKeyException, + InvalidAlgorithmParameterException, InvalidParameterSpecException { + if (Cipher.ENCRYPT_MODE == mode) { + ci.init(Cipher.ENCRYPT_MODE, key); + pbeParams = ci.getParameters(); + } else { + ci.init(Cipher.DECRYPT_MODE, key, pbeParams); + } + } + } + + /** + * Wrapper class to test a given PBE algorithm. + */ + public static class Legacy extends PBECipherWrapper { + + private static final int PBE_SALT_SIZE = 8; + + public Legacy(String algo, String passwd) + throws NoSuchAlgorithmException, NoSuchPaddingException, + InvalidKeySpecException { + super(algo, PBE_SALT_SIZE); + + SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.split("/")[0]); + key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray())); + + aps = new PBEParameterSpec(getSalt(), ITERATION_COUNT); + + ci = Cipher.getInstance(algo); + } + + @Override + protected void initCipher(int mode) throws InvalidKeyException, + InvalidAlgorithmParameterException, InvalidParameterSpecException { + ci.init(mode, key, aps); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/TextLength/TestCipherTextLength.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,136 @@ +/* + * 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. + */ + +import static java.lang.System.out; + +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; + +/* + * @test + * @bug 8048601 + * @summary Performs multiple-part encryption/decryption depending on the + * specified encryption mode and check if the results obtained by + * different ways are the same. + */ +public class TestCipherTextLength { + + /* Algorithms tested by DESCipherWrapper */ + private static final String[] DES_ALGORITHMS = {"DES", "DESede", + "Blowfish"}; + private static final String[] DES_MODES = {"ECB", "CBC", "PCBC"}; + private static final String[] DES_PADDING = {"PKCS5Padding"}; + + /* Algorithms tested by PBECipherWrapper */ + private static final String[] PBE_ALGORITHMS = {"PBEWithMD5AndDES", + "PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithMD5ANDTripleDES", + "PBEWithMD5AndTripleDES/CBC/PKCS5Padding", "PBEwithSHA1AndDESede", + "PBEwithSHA1AndDESede/CBC/PKCS5Padding", "PBEwithSHA1AndRC2_40", + "PBEwithSHA1Andrc2_40/CBC/PKCS5Padding", "PBEWithSHA1AndRC2_128", + "PBEWithSHA1andRC2_128/CBC/PKCS5Padding", "PBEWithSHA1AndRC4_40", + "PBEWithsha1AndRC4_40/ECB/NoPadding", "PBEWithSHA1AndRC4_128", + "PBEWithSHA1AndRC4_128/ECB/NoPadding", "PBEWithHmacSHA1AndAES_128", + "PBEWithHmacSHA224AndAES_128", "PBEWithHmacSHA256AndAES_128", + "PBEWithHmacSHA384AndAES_128", "PBEWithHmacSHA512AndAES_128", + "PBEWithHmacSHA1AndAES_256", "PBEWithHmacSHA224AndAES_256", + "PBEWithHmacSHA256AndAES_256", "PBEWithHmacSHA384AndAES_256", + "PBEWithHmacSHA512AndAES_256", "PBKDF2WithHmacSHA1", + "PBKDF2WithHmacSHA224", "PBKDF2WithHmacSHA256", + "PBKDF2WithHmacSHA384", "PBKDF2WithHmacSHA512"}; + private static final String PBE_PASSWORD = "Hush, it's a secret!!"; + + // Algorithm tested by PBKDF2Wrappter + private static final String PBKDF2 = "PBKDF2"; + + // Algorithm tested by AESPBEWrapper + private static final String AES = "AES"; + + public static void main(String[] args) throws Exception { + byte[] plainText = new byte[64]; + for (int i = 0; i < 64; i++) { + plainText[i] = (byte) (i & 0xff); + } + + new TestCipherTextLength().runAll(plainText); + } + + public void runAll(byte[] plainText) throws Exception { + + // Testing DES/Blowfish Cipher + for (String algorithm : DES_ALGORITHMS) { + for (String desMode : DES_MODES) { + for (String padding : DES_PADDING) { + out.println("=>Testing: " + algorithm + "/" + desMode + + "/" + padding); + DESCipherWrapper desCi = new DESCipherWrapper(algorithm, + desMode, padding); + desCi.execute(Cipher.ENCRYPT_MODE, plainText); + desCi.execute(Cipher.DECRYPT_MODE, desCi.getResult()); + if (!Arrays.equals(plainText, desCi.getResult())) { + throw new RuntimeException( + "Plain and recovered texts are not same for:" + + algorithm + "/" + desMode + "/" + + padding); + } + } + } + } + + // Testing PBE Cipher + for (String algorithm : PBE_ALGORITHMS) { + int maxKeyLen = Cipher.getMaxAllowedKeyLength(algorithm); + boolean isUnlimited = maxKeyLen == Integer.MAX_VALUE; + if (!isUnlimited + && (algorithm.contains("TripleDES") || algorithm + .contains("AES_256"))) { + out.println("Test " + algorithm + " will be ignored"); + continue; + } + + out.println("=>Testing: " + algorithm); + PBECipherWrapper pbeCi = createWrapper(algorithm, PBE_PASSWORD); + pbeCi.execute(Cipher.ENCRYPT_MODE, plainText); + pbeCi.execute(Cipher.DECRYPT_MODE, pbeCi.getResult()); + if (!Arrays.equals(plainText, pbeCi.getResult())) { + throw new RuntimeException( + "Plain and recovered texts are not same for:" + + algorithm); + } + } + } + + private PBECipherWrapper createWrapper(String algo, String passwd) + throws InvalidKeySpecException, NoSuchAlgorithmException, + NoSuchPaddingException { + if (algo.contains(PBKDF2)) { + return new PBECipherWrapper.PBKDF2(algo, passwd); + } else if (algo.contains(AES)) { + return new PBECipherWrapper.AES(algo, passwd); + } else { + return new PBECipherWrapper.Legacy(algo, passwd); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloClient.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016, 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. + */ + + +import java.util.ArrayList; + +import javax.naming.InitialContext; +import javax.naming.Context; +import javax.naming.NameNotFoundException; + +import javax.rmi.PortableRemoteObject; + + + +public class HelloClient implements Runnable { + static final int MAX_RETRY = 10; + static final int ONE_SECOND = 1000; + private static boolean responseReceived; + + public static void main(String args[]) throws Exception { + executeRmiClientCall(); + } + + @Override + public void run() { + try { + executeRmiClientCall(); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + + public static boolean isResponseReceived () { + return responseReceived; + } + + public static void executeRmiClientCall() throws Exception { + Context ic; + Object objref; + HelloInterface helloSvc; + String response; + Object testResponse; + int retryCount = 0; + + ArrayList<Test> listParam = new ArrayList<Test>(); + listParam.add(null); + System.out.println("HelloClient.main: enter ..."); + while (retryCount < MAX_RETRY) { + try { + ic = new InitialContext(); + System.out.println("HelloClient.main: HelloService lookup ..."); + // STEP 1: Get the Object reference from the Name Service + // using JNDI call. + objref = ic.lookup("HelloService"); + System.out.println("HelloClient: Obtained a ref. to Hello server."); + + // STEP 2: Narrow the object reference to the concrete type and + // invoke the method. + helloSvc = (HelloInterface) PortableRemoteObject.narrow(objref, + HelloInterface.class); + + Test3 test3 = new Test3(listParam); + Test3 test3Response = helloSvc.sayHelloWithTest3(test3); + System.out.println("Server says: Test3 response == " + test3Response); + + Test3 test3WithNullList = new Test3(null); + test3Response = helloSvc.sayHelloWithTest3(test3WithNullList); + System.out.println("Server says: Test3 response == " + + test3Response); + + Test4 test4 = new Test4(listParam); + Test3 test4Response = helloSvc.sayHelloWithTest3(test4); + System.out.println("Server says: Test3 response == " + test4Response); + + responseReceived = true; + break; + } catch (NameNotFoundException nnfEx) { + System.err.println("NameNotFoundException Caught .... try again"); + retryCount++; + try { + Thread.sleep(ONE_SECOND); + } catch (InterruptedException e) { + e.printStackTrace(); + } + continue; + } catch (Exception e) { + System.err.println("Exception " + e + "Caught"); + e.printStackTrace(); + throw new RuntimeException(e); + } + } + System.err.println("HelloClient terminating "); + try { + Thread.sleep(ONE_SECOND); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloImpl.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 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. + */ + +import java.rmi.RemoteException; +import javax.rmi.PortableRemoteObject; + +public class HelloImpl extends PortableRemoteObject implements HelloInterface { + + public HelloImpl() throws java.rmi.RemoteException { + super(); // invoke rmi linking and remote object initialization + } + + @Override + public Test3 sayHelloWithTest3(Test3 test) throws RemoteException { + System.out.println("sayHelloToTest3: ENTER " ); + + return test; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloInterface.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016, 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. + */ + +import java.rmi.Remote; + +public interface HelloInterface extends Remote { + public Test3 sayHelloWithTest3( Test3 test ) throws java.rmi.RemoteException; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloServer.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, 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. + */ + +import javax.naming.InitialContext; +import javax.naming.Context; + +public class HelloServer { + + static final int MAX_RETRY = 10; + static final int ONE_SECOND = 1000; + + public static void main(String[] args) { + int retryCount = 0; + while (retryCount < MAX_RETRY) { + try { + //HelloServer.set("SETTING TEST ITL"); + // Step 1: Instantiate the Hello servant + HelloImpl helloRef = new HelloImpl(); + + // Step 2: Publish the reference in the Naming Service + // using JNDI API + Context initialNamingContext = new InitialContext(); + initialNamingContext.rebind("HelloService", helloRef); + + System.out.println("Hello Server: Ready..."); + break; + } catch (Exception e) { + System.out.println("Server initialization problem: " + e); + e.printStackTrace(); + retryCount++; + try { + Thread.sleep(ONE_SECOND); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2016, 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 8146975 + * @summary test RMI-IIOP with value object return + * @library /lib/testlibrary + * @build jdk.testlibrary.* + * @compile Test.java Test2.java Test3.java Test4.java + * HelloInterface.java HelloServer.java HelloClient.java + * HelloImpl.java _HelloImpl_Tie.java _HelloInterface_Stub.java + * RmiIiopReturnValueTest.java + * @run main/othervm -Djava.naming.provider.url=iiop://localhost:5050 + * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory + * RmiIiopReturnValueTest -port 5049 + * @run main/othervm/secure=java.lang.SecurityManager/policy=jtreg.test.policy + * -Djava.naming.provider.url=iiop://localhost:5050 + * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory + * RmiIiopReturnValueTest -port 5049 + */ + + +import java.io.DataInputStream; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.CountDownLatch; +import jdk.testlibrary.JDKToolFinder; +import jdk.testlibrary.JDKToolLauncher; + +public class RmiIiopReturnValueTest { + + static final String ORBD = JDKToolFinder.getTestJDKTool("orbd"); + static final String JAVA = JDKToolFinder.getTestJDKTool("java"); + static final JDKToolLauncher orbdLauncher = JDKToolLauncher.createUsingTestJDK("orbd"); + static final String CLASSPATH = System.getProperty("java.class.path"); + static final int FIVE_SECONDS = 5000; + + private static Throwable clientException; + private static boolean exceptionInClient; + private static Process orbdProcess; + private static Process rmiServerProcess; + + public static void main(String[] args) throws Exception { + startTestComponents(); + stopTestComponents(); + System.err.println("Test completed OK "); + } + + static void startTestComponents () throws Exception { + startOrbd(); + Thread.sleep(FIVE_SECONDS); + startRmiIiopServer(); + Thread.sleep(FIVE_SECONDS); + executeRmiIiopClient(); + } + + private static void stopTestComponents() throws Exception { + stopRmiIiopServer(); + stopOrbd(); + if (exceptionInClient) { + throw new RuntimeException(clientException); + } else if (!isResponseReceived()) { + throw new RuntimeException("Expected Response not received"); + } + } + + static void startOrbd() throws Exception { + System.out.println("\nStarting orbd with NS port 5050 and activation port 5049 "); + + //orbd -ORBInitialHost localhost -ORBInitialPort 5050 -port 5049 + orbdLauncher.addToolArg("-ORBInitialHost").addToolArg("localhost") + .addToolArg("-ORBInitialPort").addToolArg("5050") + .addToolArg("-port").addToolArg("5049"); + + System.out.println("RmiIiopReturnValueTest: Executing: " + Arrays.asList(orbdLauncher.getCommand())); + ProcessBuilder pb = new ProcessBuilder(orbdLauncher.getCommand()); + pb.redirectError(ProcessBuilder.Redirect.INHERIT); + orbdProcess = pb.start(); + } + + + static void startRmiIiopServer() throws Exception { + System.out.println("\nStarting RmiIiopServer"); + // java -cp . + // -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory + // -Djava.naming.provider.url=iiop://localhost:5050 HelloServer -port 5049 + List<String> commands = new ArrayList<>(); + commands.add(RmiIiopReturnValueTest.JAVA); + commands.add("-Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory"); + commands.add("-Djava.naming.provider.url=iiop://localhost:5050"); + commands.add("-cp"); + commands.add(RmiIiopReturnValueTest.CLASSPATH); + commands.add("HelloServer"); + commands.add("-port"); + commands.add("5049"); + + System.out.println("RmiIiopReturnValueTest: Executing: " + commands); + ProcessBuilder pb = new ProcessBuilder(commands); + pb.redirectError(ProcessBuilder.Redirect.INHERIT); + rmiServerProcess = pb.start(); + } + + static boolean isResponseReceived() { + return HelloClient.isResponseReceived(); + } + + static void stopRmiIiopServer() throws Exception { + if (rmiServerProcess != null) { + System.out.println("RmiIiopReturnValueTest.stopRmiIiopServer: destroy rmiServerProcess"); + rmiServerProcess.destroyForcibly(); + rmiServerProcess.waitFor(); + System.out.println("serverProcess exitCode:" + + rmiServerProcess.exitValue()); + } + } + + static void stopOrbd() throws Exception { + System.out.println("RmiIiopReturnValueTest.stopOrbd: destroy orbdProcess "); + orbdProcess.destroyForcibly(); + orbdProcess.waitFor(); + System.out.println("orbd exitCode:" + + orbdProcess.exitValue()); + } + + static void executeRmiIiopClient() throws Exception { + System.out.println("RmiIiopReturnValueTest.executeRmiIiopClient: HelloClient.executeRmiClientCall"); + try { + HelloClient.executeRmiClientCall(); + } catch (Throwable t) { + clientException = t; + exceptionInClient = true; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/Test.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016, 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. + */ + +import java.io.Serializable; + + +public class Test implements Serializable { + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/Test2.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, 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. + */ + +import java.io.Serializable; + + +public class Test2 implements Serializable { + + private int testValue; + private String name; + private Test aTest; + + public Test2 (String name, int value, Test test) { + this.name = name; + this.aTest = test; + this.testValue = value; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/Test3.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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. + */ + +import java.io.Serializable; +import java.util.List; + + +public class Test3 implements Serializable { + + private List<Test> list; + + public Test3(List<Test> list) { + this.list = list; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/Test4.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, 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. + */ + +import java.util.List; + + +public class Test4 extends Test3 { + + private int aNumber = 1; + + public Test4(List<Test> list) { + super(list); + } + + /** + * + */ + private static final long serialVersionUID = 1L; + + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/_HelloImpl_Tie.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016, 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. + */ + +// Tie class generated by rmic, do not edit. +// Contents subject to change without notice. + +import java.io.Serializable; +import java.rmi.Remote; +import java.rmi.RemoteException; +import javax.rmi.CORBA.Tie; +import javax.rmi.CORBA.Util; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.CORBA.portable.UnknownException; +import org.omg.CORBA_2_3.portable.ObjectImpl; + + +public class _HelloImpl_Tie extends ObjectImpl implements Tie { + + volatile private HelloImpl target = null; + + private static final String[] _type_ids = { + "RMI:HelloInterface:0000000000000000" + }; + + public void setTarget(Remote target) { + this.target = (HelloImpl) target; + } + + public Remote getTarget() { + return target; + } + + public org.omg.CORBA.Object thisObject() { + return this; + } + + public void deactivate() { + _orb().disconnect(this); + _set_delegate(null); + target = null; + } + + public ORB orb() { + return _orb(); + } + + public void orb(ORB orb) { + orb.connect(this); + } + + public String[] _ids() { + return (String[]) _type_ids.clone(); + } + + public OutputStream _invoke(String method, InputStream _in, ResponseHandler reply) throws SystemException { + try { + HelloImpl target = this.target; + if (target == null) { + throw new java.io.IOException(); + } + org.omg.CORBA_2_3.portable.InputStream in = + (org.omg.CORBA_2_3.portable.InputStream) _in; + if (method.equals("sayHelloWithTest3")) { + Test3 arg0 = (Test3) in.read_value(Test3.class); + Test3 result = target.sayHelloWithTest3(arg0); + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply(); + out.write_value(result,Test3.class); + return out; + } + throw new BAD_OPERATION(); + } catch (SystemException ex) { + throw ex; + } catch (Throwable ex) { + throw new UnknownException(ex); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/_HelloInterface_Stub.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2016, 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. + */ + +// Stub class generated by rmic, do not edit. +// Contents subject to change without notice. + +import java.io.Serializable; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.UnexpectedException; +import javax.rmi.CORBA.Stub; +import javax.rmi.CORBA.Util; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.RemarshalException; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.CORBA.portable.ServantObject; + + +public class _HelloInterface_Stub extends Stub implements HelloInterface { + + private static final String[] _type_ids = { + "RMI:HelloInterface:0000000000000000" + }; + + public String[] _ids() { + return (String[]) _type_ids.clone(); + } + + public Test3 sayHelloWithTest3(Test3 arg0) throws java.rmi.RemoteException { + if (!Util.isLocal(this)) { + try { + org.omg.CORBA_2_3.portable.InputStream in = null; + try { + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) + _request("sayHelloWithTest3", true); + out.write_value(arg0,Test3.class); + in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out); + return (Test3) in.read_value(Test3.class); + } catch (ApplicationException ex) { + in = (org.omg.CORBA_2_3.portable.InputStream) ex.getInputStream(); + String $_id = in.read_string(); + throw new UnexpectedException($_id); + } catch (RemarshalException ex) { + return sayHelloWithTest3(arg0); + } finally { + _releaseReply(in); + } + } catch (SystemException ex) { + throw Util.mapSystemException(ex); + } + } else { + ServantObject so = _servant_preinvoke("sayHelloWithTest3",HelloInterface.class); + if (so == null) { + return sayHelloWithTest3(arg0); + } + try { + Test3 arg0Copy = (Test3) Util.copyObject(arg0,_orb()); + Test3 result = ((HelloInterface)so.servant).sayHelloWithTest3(arg0Copy); + return (Test3)Util.copyObject(result,_orb()); + } catch (Throwable ex) { + Throwable exCopy = (Throwable)Util.copyObject(ex,_orb()); + throw Util.wrapException(exCopy); + } finally { + _servant_postinvoke(so); + } + } + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/jtreg.test.policy Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, 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. + */ + + +grant { + permission java.io.FilePermission "*", "read"; + permission java.io.FilePermission "./-", "read,write,execute"; + permission java.net.SocketPermission "*:*", "connect, accept, listen, resolve"; + permission java.lang.RuntimePermission "accessClassInPackage.com.sun.corba.se.*"; + permission java.lang.RuntimePermission "accessClassInPackage.sun.security.util"; + permission java.io.SerializablePermission "enableSubclassImplementation"; + permission java.util.PropertyPermission "*", "read, write"; + permission java.io.FilePermission "<<ALL FILES>>", "read,write,execute"; +};
--- a/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java Tue Jun 21 10:14:40 2016 -0700 +++ b/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java Sat Jun 25 20:03:28 2016 +0100 @@ -28,7 +28,11 @@ * @library /lib/testlibrary * @build jdk.testlibrary.* * @build Test HelloInterface HelloServer HelloClient HelloImpl _HelloImpl_Tie _HelloInterface_Stub ConcurrentHashMapTest - * @run main/othervm -Djava.naming.provider.url=iiop://localhost:1050 -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory ConcurrentHashMapTest + * @run main/othervm -Djava.naming.provider.url=iiop://localhost:1050 + * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory ConcurrentHashMapTest + * @run main/othervm/secure=java.lang.SecurityManager/policy=jtreg.test.policy + * -Djava.naming.provider.url=iiop://localhost:1050 + * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory ConcurrentHashMapTest */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/jtreg.test.policy Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, 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. + */ + + +grant { + permission java.io.FilePermission "*", "read"; + permission java.io.FilePermission "./-", "read,write,execute"; + permission java.net.SocketPermission "*:*", "connect, accept, listen, resolve"; + permission java.lang.RuntimePermission "accessClassInPackage.com.sun.corba.se.*"; + permission java.lang.RuntimePermission "accessClassInPackage.sun.security.util"; + permission java.io.SerializablePermission "enableSubclassImplementation"; + permission java.util.PropertyPermission "*", "read, write"; + permission java.io.FilePermission "<<ALL FILES>>", "read,write,execute"; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/plaf/nimbus/8057791/bug8057791.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016, 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 8057791 + @summary Selection in JList is drawn with wrong colors in Nimbus L&F + @author Anton Litvinov + @run main bug8057791 + */ + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; +import java.util.HashSet; +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.plaf.nimbus.NimbusLookAndFeel; + +public class bug8057791 { + public static void main(String[] args) { + try { + UIManager.setLookAndFeel(new NimbusLookAndFeel()); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + final int listWidth = 50; + final int listHeight = 50; + final int selCellIndex = 0; + + JList<String> list = new JList<String>(); + list.setSize(listWidth, listHeight); + DefaultListModel<String> listModel = new DefaultListModel<String>(); + listModel.add(selCellIndex, "E"); + list.setModel(listModel); + list.setSelectedIndex(selCellIndex); + + BufferedImage img = new BufferedImage(listWidth, listHeight, + BufferedImage.TYPE_INT_ARGB); + Graphics g = img.getGraphics(); + list.paint(g); + g.dispose(); + + Rectangle cellRect = list.getCellBounds(selCellIndex, selCellIndex); + HashSet<Color> cellColors = new HashSet<Color>(); + int uniqueColorIndex = 0; + for (int x = cellRect.x; x < (cellRect.x + cellRect.width); x++) { + for (int y = cellRect.y; y < (cellRect.y + cellRect.height); y++) { + Color cellColor = new Color(img.getRGB(x, y), true); + if (cellColors.add(cellColor)) { + System.err.println(String.format("Cell color #%d: %s", + uniqueColorIndex++, cellColor)); + } + } + } + + Color selForegroundColor = list.getSelectionForeground(); + Color selBackgroundColor = list.getSelectionBackground(); + if (!cellColors.contains(new Color(selForegroundColor.getRGB(), true))) { + throw new RuntimeException(String.format( + "Selected cell is drawn without selection foreground color '%s'.", + selForegroundColor)); + } + if (!cellColors.contains(new Color(selBackgroundColor.getRGB(), true))) { + throw new RuntimeException(String.format( + "Selected cell is drawn without selection background color '%s'.", + selBackgroundColor)); + } + } + }); + } catch (UnsupportedLookAndFeelException | InterruptedException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/java2d/ClassCastExceptionForInvalidSurface.java Sat Jun 25 20:03:28 2016 +0100 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2016, 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. + */ + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; + +import static java.awt.image.BufferedImage.TYPE_INT_ARGB; + +/** + * @test + * @bug 8158072 7172749 + */ +public final class ClassCastExceptionForInvalidSurface { + + static GraphicsEnvironment ge + = GraphicsEnvironment.getLocalGraphicsEnvironment(); + + static GraphicsConfiguration gc + = ge.getDefaultScreenDevice().getDefaultConfiguration(); + + static volatile VolatileImage vi = gc.createCompatibleVolatileImage(10, 10); + + static volatile Throwable failed; + + static BlockingQueue<VolatileImage> list = new ArrayBlockingQueue<>(50); + + // Will run the test no more than 15 seconds + static long endtime = System.nanoTime() + TimeUnit.SECONDS.toNanos(15); + + public static void main(final String[] args) throws InterruptedException { + + // Catch all uncaught exceptions and treat them as test failure + Thread.setDefaultUncaughtExceptionHandler((t, e) -> failed = e); + + // Data for rendering + BufferedImage bi = new BufferedImage(10, 10, TYPE_INT_ARGB); + FontRenderContext frc = new FontRenderContext(null, false, false); + Font font = new Font("Serif", Font.PLAIN, 12); + GlyphVector gv = font.createGlyphVector(frc, new char[]{'a', '1'}); + + Thread t1 = new Thread(() -> { + while (!isComplete()) { + vi = gc.createCompatibleVolatileImage(10, 10); + if (!list.offer(vi)) { + vi.flush(); + } + } + list.forEach(Image::flush); + }); + Thread t2 = new Thread(() -> { + while (!isComplete()) { + VolatileImage vi = list.poll(); + if (vi != null) { + vi.flush(); + } + } + }); + + Thread t3 = new Thread(() -> { + while (!isComplete()) { + vi.createGraphics().drawImage(bi, 1, 1, null); + } + }); + Thread t4 = new Thread(() -> { + while (!isComplete()) { + vi.createGraphics().drawGlyphVector(gv, 0, 0); + vi.createGraphics().drawOval(0, 0, 10, 10); + vi.createGraphics().drawLine(0, 0, 10, 10); + vi.createGraphics().drawString("123", 1, 1); + vi.createGraphics().draw(new Rectangle(0, 0, 10, 10)); + vi.createGraphics().fillOval(0, 0, 10, 10); + final Graphics2D graphics = vi.createGraphics(); + graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + graphics.fillPolygon(new int[] {0, 10, 10, 0}, + new int [] {0, 0, 10, 10}, 4); + } + }); + t1.start(); + t2.start(); + t3.start(); + t4.start(); + t1.join(); + t2.join(); + t3.join(); + t4.join(); + + if (failed != null) { + System.err.println("Test failed"); + failed.printStackTrace(); + } + } + + private static boolean isComplete() { + return endtime - System.nanoTime() < 0 || failed != null; + } +}