提交 147c71d0 编写于 作者: A asaha

Merge

...@@ -389,6 +389,7 @@ f0d5cb59b0e6a67fa102465458cc4725c6e59089 jdk8u40-b25 ...@@ -389,6 +389,7 @@ f0d5cb59b0e6a67fa102465458cc4725c6e59089 jdk8u40-b25
d4453d784fb6c52e4ed998b167588551e2fd43c5 jdk8u40-b27 d4453d784fb6c52e4ed998b167588551e2fd43c5 jdk8u40-b27
5a45234e0fc14ff943e13dc1f8966818acaeb4de jdk8u40-b31 5a45234e0fc14ff943e13dc1f8966818acaeb4de jdk8u40-b31
d8ac13c5eafe422d3425dc1aebebfcdf8ca67e2d jdk8u40-b32 d8ac13c5eafe422d3425dc1aebebfcdf8ca67e2d jdk8u40-b32
c7fbbf6133c339fb56f03241de28666774023d5d jdk8u40-b33
1ecc234bd38950a2bc047aa253a5e803f0836a4e jdk8u45-b00 1ecc234bd38950a2bc047aa253a5e803f0836a4e jdk8u45-b00
e0c7864bbca3f76cde680722f2ae58dff2bff61d jdk8u45-b01 e0c7864bbca3f76cde680722f2ae58dff2bff61d jdk8u45-b01
9505c0392cddbfb905401e9fccc23262edc3254f jdk8u45-b02 9505c0392cddbfb905401e9fccc23262edc3254f jdk8u45-b02
...@@ -534,17 +535,26 @@ d7cc3225f1050de03b236b92e12c547f21697013 jdk8u72-b11 ...@@ -534,17 +535,26 @@ d7cc3225f1050de03b236b92e12c547f21697013 jdk8u72-b11
d841d3fdae44f120883dab0a3a809a054cd0274b jdk8u72-b13 d841d3fdae44f120883dab0a3a809a054cd0274b jdk8u72-b13
f6d24d424cd2af4d2612f7737d3d9a25f58b882d jdk8u72-b14 f6d24d424cd2af4d2612f7737d3d9a25f58b882d jdk8u72-b14
f3e86cc607260bae368b52d88d7bc8883ee767e3 jdk8u72-b15 f3e86cc607260bae368b52d88d7bc8883ee767e3 jdk8u72-b15
1d4b343084874b1afa1cdd504b9b1e50bab7f121 jdk8u72-b31
892eb9ab179650b89b7bab6bc42f079391c98624 jdk8u73-b00 892eb9ab179650b89b7bab6bc42f079391c98624 jdk8u73-b00
9b77d3ca0d66a117c3cc0e0a74b8059545b22f0e jdk8u73-b01 9b77d3ca0d66a117c3cc0e0a74b8059545b22f0e jdk8u73-b01
2ab13901d6f14bab0dcf4823d5e378a421fba7e2 jdk8u73-b02 2ab13901d6f14bab0dcf4823d5e378a421fba7e2 jdk8u73-b02
9a843dc6f959f62c61014a3a71ec9aa329f1daf1 jdk8u74-b00 9a843dc6f959f62c61014a3a71ec9aa329f1daf1 jdk8u74-b00
e829ab80dfd828803aa8837411900faeaa1254a5 jdk8u74-b01 e829ab80dfd828803aa8837411900faeaa1254a5 jdk8u74-b01
32c49f4a16599e376e4e46bb33c7bcc486e52ff3 jdk8u74-b02 32c49f4a16599e376e4e46bb33c7bcc486e52ff3 jdk8u74-b02
9c828e688240362b6f1b761b619cdaa070462c4e jdk8u74-b31
6968ca30f8fdc9429fcd56187e16f46b215b474b jdk8u74-b32
02e1209648050922a5a9f2789d9d359795f6f834 jdk8u77-b00
f08584a0fde9344b0aa4766984266ca68b9a5018 jdk8u77-b01
1a3e81c05703bb36def80a57681e1692c866f621 jdk8u77-b02
c44179bce874a97e93ffd7b76a226af417e017a4 jdk8u77-b03
8c3f4e540348daed7263bae092b0e5f212478b00 jdk8u77-b31
1d4b343084874b1afa1cdd504b9b1e50bab7f121 jdk8u72-b31 1d4b343084874b1afa1cdd504b9b1e50bab7f121 jdk8u72-b31
7cfd2c51c501df909833aa0fb6e40c50c61621ed jdk8u75-b00 7cfd2c51c501df909833aa0fb6e40c50c61621ed jdk8u75-b00
9e00a43602f87930c2318b2567002871ad9c59dd jdk8u75-b01 9e00a43602f87930c2318b2567002871ad9c59dd jdk8u75-b01
9de301db625bb1b462aad3ebd8347118b94bb728 jdk8u75-b02 9de301db625bb1b462aad3ebd8347118b94bb728 jdk8u75-b02
dcacefa73649a2d821267b6bff1d70aa10a06801 jdk8u75-b03 dcacefa73649a2d821267b6bff1d70aa10a06801 jdk8u75-b03
f6cc9dbb5db5883385c91bb71ca02081220aaf3d jdk8u101-b00
de91f05824c5398cb2d2f666ff404aaa165498de jdk8u75-b04 de91f05824c5398cb2d2f666ff404aaa165498de jdk8u75-b04
4138b3f27ffea524185a604c3f4f149c7e5ba780 jdk8u75-b05 4138b3f27ffea524185a604c3f4f149c7e5ba780 jdk8u75-b05
32f64c19b5fba8beeae5236ca6e480bd8e99698a jdk8u75-b06 32f64c19b5fba8beeae5236ca6e480bd8e99698a jdk8u75-b06
...@@ -557,6 +567,7 @@ e6f4eb91a1fa895c2f4520e4cca0ae6f2ca14fbb jdk8u75-b09 ...@@ -557,6 +567,7 @@ e6f4eb91a1fa895c2f4520e4cca0ae6f2ca14fbb jdk8u75-b09
f08584a0fde9344b0aa4766984266ca68b9a5018 jdk8u77-b01 f08584a0fde9344b0aa4766984266ca68b9a5018 jdk8u77-b01
1a3e81c05703bb36def80a57681e1692c866f621 jdk8u77-b02 1a3e81c05703bb36def80a57681e1692c866f621 jdk8u77-b02
c44179bce874a97e93ffd7b76a226af417e017a4 jdk8u77-b03 c44179bce874a97e93ffd7b76a226af417e017a4 jdk8u77-b03
8c3f4e540348daed7263bae092b0e5f212478b00 jdk8u77-b31
71f59a00df6c8f3bd5c6d6631a4988a431adab56 jdk8u91-b00 71f59a00df6c8f3bd5c6d6631a4988a431adab56 jdk8u91-b00
7ade7a1ab10ff893f62cce9440b4a839aa19c250 jdk8u91-b13 7ade7a1ab10ff893f62cce9440b4a839aa19c250 jdk8u91-b13
f8725698a870b6be82fad578e78a55910b259975 jdk8u91-b14 f8725698a870b6be82fad578e78a55910b259975 jdk8u91-b14
...@@ -576,6 +587,13 @@ cbafa4c725f9d80fd369dd7979dd97682ae284e6 jdk8u76-b09 ...@@ -576,6 +587,13 @@ cbafa4c725f9d80fd369dd7979dd97682ae284e6 jdk8u76-b09
ea965fea71f612d65013192aa637d88e05915b10 jdk8u92-b00 ea965fea71f612d65013192aa637d88e05915b10 jdk8u92-b00
cc8d0d6c6f9543120836e70e0aa3fa9c9b6fe0f3 jdk8u92-b13 cc8d0d6c6f9543120836e70e0aa3fa9c9b6fe0f3 jdk8u92-b13
4f06a20cdc59ce9742e6538ff4b9040baba0778a jdk8u92-b14 4f06a20cdc59ce9742e6538ff4b9040baba0778a jdk8u92-b14
5875e297cfcf18304b4b062dc44fa9be312ad6e8 jdk8u92-b31
f6cc9dbb5db5883385c91bb71ca02081220aaf3d jdk8u81-b00
00f8f39308687cde45f23282871c46cc6c2f10b3 jdk8u101-b01
6042757c329b1b96fa6bc931e09306794f5c50c0 jdk8u101-b02
25934d0d38fe10383ff22eb3f39bf5e8b9e73ac9 jdk8u101-b03
ebc56c2e803597ef409a5296addc986b390d934d jdk8u101-b04
c387bd2fb7db40467bd9aa803c8510a04ca32bae jdk8u101-b05
39baa472e20c13c0eb1243eb5dce589e82f78143 jdk8u76-b00 39baa472e20c13c0eb1243eb5dce589e82f78143 jdk8u76-b00
6ea3aea950d19d803475b3f4d704a2942e71b302 jdk8u76-b01 6ea3aea950d19d803475b3f4d704a2942e71b302 jdk8u76-b01
4de4cffb5988cd68959ce4bbd14c6d4547078c91 jdk8u76-b02 4de4cffb5988cd68959ce4bbd14c6d4547078c91 jdk8u76-b02
......
/* /*
* Copyright (c) 2002, 2013, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -172,6 +172,11 @@ abstract class AESCipher extends CipherSpi { ...@@ -172,6 +172,11 @@ abstract class AESCipher extends CipherSpi {
*/ */
private final int fixedKeySize; // in bytes, -1 if no restriction private final int fixedKeySize; // in bytes, -1 if no restriction
/*
* needed to enforce ISE thrown when updateAAD is called after update for GCM mode.
*/
private boolean updateCalled;
/** /**
* Creates an instance of AES cipher with default ECB mode and * Creates an instance of AES cipher with default ECB mode and
* PKCS5Padding. * PKCS5Padding.
...@@ -304,6 +309,7 @@ abstract class AESCipher extends CipherSpi { ...@@ -304,6 +309,7 @@ abstract class AESCipher extends CipherSpi {
protected void engineInit(int opmode, Key key, SecureRandom random) protected void engineInit(int opmode, Key key, SecureRandom random)
throws InvalidKeyException { throws InvalidKeyException {
checkKeySize(key, fixedKeySize); checkKeySize(key, fixedKeySize);
updateCalled = false;
core.init(opmode, key, random); core.init(opmode, key, random);
} }
...@@ -336,6 +342,7 @@ abstract class AESCipher extends CipherSpi { ...@@ -336,6 +342,7 @@ abstract class AESCipher extends CipherSpi {
SecureRandom random) SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException { throws InvalidKeyException, InvalidAlgorithmParameterException {
checkKeySize(key, fixedKeySize); checkKeySize(key, fixedKeySize);
updateCalled = false;
core.init(opmode, key, params, random); core.init(opmode, key, params, random);
} }
...@@ -344,6 +351,7 @@ abstract class AESCipher extends CipherSpi { ...@@ -344,6 +351,7 @@ abstract class AESCipher extends CipherSpi {
SecureRandom random) SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException { throws InvalidKeyException, InvalidAlgorithmParameterException {
checkKeySize(key, fixedKeySize); checkKeySize(key, fixedKeySize);
updateCalled = false;
core.init(opmode, key, params, random); core.init(opmode, key, params, random);
} }
...@@ -368,6 +376,7 @@ abstract class AESCipher extends CipherSpi { ...@@ -368,6 +376,7 @@ abstract class AESCipher extends CipherSpi {
*/ */
protected byte[] engineUpdate(byte[] input, int inputOffset, protected byte[] engineUpdate(byte[] input, int inputOffset,
int inputLen) { int inputLen) {
updateCalled = true;
return core.update(input, inputOffset, inputLen); return core.update(input, inputOffset, inputLen);
} }
...@@ -397,6 +406,7 @@ abstract class AESCipher extends CipherSpi { ...@@ -397,6 +406,7 @@ abstract class AESCipher extends CipherSpi {
protected int engineUpdate(byte[] input, int inputOffset, int inputLen, protected int engineUpdate(byte[] input, int inputOffset, int inputLen,
byte[] output, int outputOffset) byte[] output, int outputOffset)
throws ShortBufferException { throws ShortBufferException {
updateCalled = true;
return core.update(input, inputOffset, inputLen, output, return core.update(input, inputOffset, inputLen, output,
outputOffset); outputOffset);
} }
...@@ -433,7 +443,9 @@ abstract class AESCipher extends CipherSpi { ...@@ -433,7 +443,9 @@ abstract class AESCipher extends CipherSpi {
*/ */
protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
throws IllegalBlockSizeException, BadPaddingException { throws IllegalBlockSizeException, BadPaddingException {
return core.doFinal(input, inputOffset, inputLen); byte[] out = core.doFinal(input, inputOffset, inputLen);
updateCalled = false;
return out;
} }
/** /**
...@@ -476,8 +488,10 @@ abstract class AESCipher extends CipherSpi { ...@@ -476,8 +488,10 @@ abstract class AESCipher extends CipherSpi {
byte[] output, int outputOffset) byte[] output, int outputOffset)
throws IllegalBlockSizeException, ShortBufferException, throws IllegalBlockSizeException, ShortBufferException,
BadPaddingException { BadPaddingException {
return core.doFinal(input, inputOffset, inputLen, output, int outLen = core.doFinal(input, inputOffset, inputLen, output,
outputOffset); outputOffset);
updateCalled = false;
return outLen;
} }
/** /**
...@@ -574,6 +588,9 @@ abstract class AESCipher extends CipherSpi { ...@@ -574,6 +588,9 @@ abstract class AESCipher extends CipherSpi {
*/ */
@Override @Override
protected void engineUpdateAAD(byte[] src, int offset, int len) { protected void engineUpdateAAD(byte[] src, int offset, int len) {
if (core.getMode() == CipherCore.GCM_MODE && updateCalled) {
throw new IllegalStateException("AAD must be supplied before encryption/decryption starts");
}
core.updateAAD(src, offset, len); core.updateAAD(src, offset, len);
} }
...@@ -606,6 +623,9 @@ abstract class AESCipher extends CipherSpi { ...@@ -606,6 +623,9 @@ abstract class AESCipher extends CipherSpi {
*/ */
@Override @Override
protected void engineUpdateAAD(ByteBuffer src) { protected void engineUpdateAAD(ByteBuffer src) {
if (core.getMode() == CipherCore.GCM_MODE && updateCalled) {
throw new IllegalStateException("AAD must be supplied before encryption/decryption starts");
}
if (src != null) { if (src != null) {
int aadLen = src.limit() - src.position(); int aadLen = src.limit() - src.position();
if (aadLen != 0) { if (aadLen != 0) {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -124,7 +124,7 @@ final class CipherCore { ...@@ -124,7 +124,7 @@ final class CipherCore {
private static final int PCBC_MODE = 4; private static final int PCBC_MODE = 4;
private static final int CTR_MODE = 5; private static final int CTR_MODE = 5;
private static final int CTS_MODE = 6; private static final int CTS_MODE = 6;
private static final int GCM_MODE = 7; static final int GCM_MODE = 7;
/* /*
* variables used for performing the GCM (key+iv) uniqueness check. * variables used for performing the GCM (key+iv) uniqueness check.
...@@ -196,7 +196,7 @@ final class CipherCore { ...@@ -196,7 +196,7 @@ final class CipherCore {
cipher = new CounterMode(rawImpl); cipher = new CounterMode(rawImpl);
unitBytes = 1; unitBytes = 1;
padding = null; padding = null;
} else if (modeUpperCase.startsWith("GCM")) { } else if (modeUpperCase.equals("GCM")) {
// can only be used for block ciphers w/ 128-bit block size // can only be used for block ciphers w/ 128-bit block size
if (blockSize != 16) { if (blockSize != 16) {
throw new NoSuchAlgorithmException throw new NoSuchAlgorithmException
...@@ -223,6 +223,15 @@ final class CipherCore { ...@@ -223,6 +223,15 @@ final class CipherCore {
} }
} }
/**
* Returns the mode of this cipher.
*
* @return the parsed cipher mode
*/
int getMode() {
return cipherMode;
}
private static int getNumOfUnit(String mode, int offset, int blockSize) private static int getNumOfUnit(String mode, int offset, int blockSize)
throws NoSuchAlgorithmException { throws NoSuchAlgorithmException {
int result = blockSize; // use blockSize as default value int result = blockSize; // use blockSize as default value
......
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -49,6 +49,16 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -49,6 +49,16 @@ final class GaloisCounterMode extends FeedbackCipher {
static int DEFAULT_TAG_LEN = AES_BLOCK_SIZE; static int DEFAULT_TAG_LEN = AES_BLOCK_SIZE;
static int DEFAULT_IV_LEN = 12; // in bytes static int DEFAULT_IV_LEN = 12; // in bytes
// In NIST SP 800-38D, GCM input size is limited to be no longer
// than (2^36 - 32) bytes. Otherwise, the counter will wrap
// around and lead to a leak of plaintext.
// However, given the current GCM spec requirement that recovered
// text can only be returned after successful tag verification,
// we are bound by limiting the data size to the size limit of
// java byte array, e.g. Integer.MAX_VALUE, since all data
// can only be returned by the doFinal(...) call.
private static final int MAX_BUF_SIZE = Integer.MAX_VALUE;
// buffer for AAD data; if null, meaning update has been called // buffer for AAD data; if null, meaning update has been called
private ByteArrayOutputStream aadBuffer = new ByteArrayOutputStream(); private ByteArrayOutputStream aadBuffer = new ByteArrayOutputStream();
private int sizeOfAAD = 0; private int sizeOfAAD = 0;
...@@ -89,9 +99,13 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -89,9 +99,13 @@ final class GaloisCounterMode extends FeedbackCipher {
} }
} }
// ivLen in bits private static byte[] getLengthBlock(int ivLenInBytes) {
private static byte[] getLengthBlock(int ivLen) { long ivLen = ((long)ivLenInBytes) << 3;
byte[] out = new byte[AES_BLOCK_SIZE]; byte[] out = new byte[AES_BLOCK_SIZE];
out[8] = (byte)(ivLen >>> 56);
out[9] = (byte)(ivLen >>> 48);
out[10] = (byte)(ivLen >>> 40);
out[11] = (byte)(ivLen >>> 32);
out[12] = (byte)(ivLen >>> 24); out[12] = (byte)(ivLen >>> 24);
out[13] = (byte)(ivLen >>> 16); out[13] = (byte)(ivLen >>> 16);
out[14] = (byte)(ivLen >>> 8); out[14] = (byte)(ivLen >>> 8);
...@@ -99,13 +113,22 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -99,13 +113,22 @@ final class GaloisCounterMode extends FeedbackCipher {
return out; return out;
} }
// aLen and cLen both in bits private static byte[] getLengthBlock(int aLenInBytes, int cLenInBytes) {
private static byte[] getLengthBlock(int aLen, int cLen) { long aLen = ((long)aLenInBytes) << 3;
long cLen = ((long)cLenInBytes) << 3;
byte[] out = new byte[AES_BLOCK_SIZE]; byte[] out = new byte[AES_BLOCK_SIZE];
out[0] = (byte)(aLen >>> 56);
out[1] = (byte)(aLen >>> 48);
out[2] = (byte)(aLen >>> 40);
out[3] = (byte)(aLen >>> 32);
out[4] = (byte)(aLen >>> 24); out[4] = (byte)(aLen >>> 24);
out[5] = (byte)(aLen >>> 16); out[5] = (byte)(aLen >>> 16);
out[6] = (byte)(aLen >>> 8); out[6] = (byte)(aLen >>> 8);
out[7] = (byte)aLen; out[7] = (byte)aLen;
out[8] = (byte)(cLen >>> 56);
out[9] = (byte)(cLen >>> 48);
out[10] = (byte)(cLen >>> 40);
out[11] = (byte)(cLen >>> 32);
out[12] = (byte)(cLen >>> 24); out[12] = (byte)(cLen >>> 24);
out[13] = (byte)(cLen >>> 16); out[13] = (byte)(cLen >>> 16);
out[14] = (byte)(cLen >>> 8); out[14] = (byte)(cLen >>> 8);
...@@ -142,13 +165,20 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -142,13 +165,20 @@ final class GaloisCounterMode extends FeedbackCipher {
} else { } else {
g.update(iv); g.update(iv);
} }
byte[] lengthBlock = getLengthBlock(iv.length*8); byte[] lengthBlock = getLengthBlock(iv.length);
g.update(lengthBlock); g.update(lengthBlock);
j0 = g.digest(); j0 = g.digest();
} }
return j0; return j0;
} }
private static void checkDataLength(int processed, int len) {
if (processed > MAX_BUF_SIZE - len) {
throw new ProviderException("SunJCE provider only supports " +
"input size up to " + MAX_BUF_SIZE + " bytes");
}
}
GaloisCounterMode(SymmetricCipher embeddedCipher) { GaloisCounterMode(SymmetricCipher embeddedCipher) {
super(embeddedCipher); super(embeddedCipher);
aadBuffer = new ByteArrayOutputStream(); aadBuffer = new ByteArrayOutputStream();
...@@ -319,20 +349,22 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -319,20 +349,22 @@ final class GaloisCounterMode extends FeedbackCipher {
// Feed the AAD data to GHASH, pad if necessary // Feed the AAD data to GHASH, pad if necessary
void processAAD() { void processAAD() {
if (aadBuffer != null && aadBuffer.size() > 0) { if (aadBuffer != null) {
byte[] aad = aadBuffer.toByteArray(); if (aadBuffer.size() > 0) {
sizeOfAAD = aad.length; byte[] aad = aadBuffer.toByteArray();
aadBuffer = null; sizeOfAAD = aad.length;
int lastLen = aad.length % AES_BLOCK_SIZE; int lastLen = aad.length % AES_BLOCK_SIZE;
if (lastLen != 0) { if (lastLen != 0) {
ghashAllToS.update(aad, 0, aad.length - lastLen); ghashAllToS.update(aad, 0, aad.length - lastLen);
byte[] padded = expandToOneBlock(aad, aad.length - lastLen, byte[] padded = expandToOneBlock(aad, aad.length - lastLen,
lastLen); lastLen);
ghashAllToS.update(padded); ghashAllToS.update(padded);
} else { } else {
ghashAllToS.update(aad); ghashAllToS.update(aad);
}
} }
aadBuffer = null;
} }
} }
...@@ -386,6 +418,8 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -386,6 +418,8 @@ final class GaloisCounterMode extends FeedbackCipher {
* @param outOfs the offset in <code>out</code> * @param outOfs the offset in <code>out</code>
*/ */
int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) { int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
checkDataLength(processed, len);
processAAD(); processAAD();
if (len > 0) { if (len > 0) {
gctrPAndC.update(in, inOfs, len, out, outOfs); gctrPAndC.update(in, inOfs, len, out, outOfs);
...@@ -410,17 +444,23 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -410,17 +444,23 @@ final class GaloisCounterMode extends FeedbackCipher {
*/ */
int encryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs) int encryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs)
throws IllegalBlockSizeException, ShortBufferException { throws IllegalBlockSizeException, ShortBufferException {
if (len > MAX_BUF_SIZE - tagLenBytes) {
throw new ShortBufferException
("Can't fit both data and tag into one buffer");
}
if (out.length - outOfs < (len + tagLenBytes)) { if (out.length - outOfs < (len + tagLenBytes)) {
throw new ShortBufferException("Output buffer too small"); throw new ShortBufferException("Output buffer too small");
} }
checkDataLength(processed, len);
processAAD(); processAAD();
if (len > 0) { if (len > 0) {
doLastBlock(in, inOfs, len, out, outOfs, true); doLastBlock(in, inOfs, len, out, outOfs, true);
} }
byte[] lengthBlock = byte[] lengthBlock =
getLengthBlock(sizeOfAAD*8, processed*8); getLengthBlock(sizeOfAAD, processed);
ghashAllToS.update(lengthBlock); ghashAllToS.update(lengthBlock);
byte[] s = ghashAllToS.digest(); byte[] s = ghashAllToS.digest();
byte[] sOut = new byte[s.length]; byte[] sOut = new byte[s.length];
...@@ -454,6 +494,8 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -454,6 +494,8 @@ final class GaloisCounterMode extends FeedbackCipher {
* @param outOfs the offset in <code>out</code> * @param outOfs the offset in <code>out</code>
*/ */
int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) { int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
checkDataLength(ibuffer.size(), len);
processAAD(); processAAD();
if (len > 0) { if (len > 0) {
...@@ -488,10 +530,21 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -488,10 +530,21 @@ final class GaloisCounterMode extends FeedbackCipher {
if (len < tagLenBytes) { if (len < tagLenBytes) {
throw new AEADBadTagException("Input too short - need tag"); throw new AEADBadTagException("Input too short - need tag");
} }
// do this check here can also catch the potential integer overflow
// scenario for the subsequent output buffer capacity check.
checkDataLength(ibuffer.size(), (len - tagLenBytes));
if (out.length - outOfs < ((ibuffer.size() + len) - tagLenBytes)) { if (out.length - outOfs < ((ibuffer.size() + len) - tagLenBytes)) {
throw new ShortBufferException("Output buffer too small"); throw new ShortBufferException("Output buffer too small");
} }
processAAD(); processAAD();
// get the trailing tag bytes from 'in'
byte[] tag = new byte[tagLenBytes];
System.arraycopy(in, inOfs + len - tagLenBytes, tag, 0, tagLenBytes);
len -= tagLenBytes;
if (len != 0) { if (len != 0) {
ibuffer.write(in, inOfs, len); ibuffer.write(in, inOfs, len);
} }
...@@ -502,17 +555,12 @@ final class GaloisCounterMode extends FeedbackCipher { ...@@ -502,17 +555,12 @@ final class GaloisCounterMode extends FeedbackCipher {
len = in.length; len = in.length;
ibuffer.reset(); ibuffer.reset();
byte[] tag = new byte[tagLenBytes];
// get the trailing tag bytes from 'in'
System.arraycopy(in, len - tagLenBytes, tag, 0, tagLenBytes);
len -= tagLenBytes;
if (len > 0) { if (len > 0) {
doLastBlock(in, inOfs, len, out, outOfs, false); doLastBlock(in, inOfs, len, out, outOfs, false);
} }
byte[] lengthBlock = byte[] lengthBlock =
getLengthBlock(sizeOfAAD*8, processed*8); getLengthBlock(sizeOfAAD, processed);
ghashAllToS.update(lengthBlock); ghashAllToS.update(lengthBlock);
byte[] s = ghashAllToS.digest(); byte[] s = ghashAllToS.digest();
......
...@@ -81,7 +81,7 @@ public class JMXSubjectDomainCombiner extends SubjectDomainCombiner { ...@@ -81,7 +81,7 @@ public class JMXSubjectDomainCombiner extends SubjectDomainCombiner {
* A ProtectionDomain with a null CodeSource and an empty permission set. * A ProtectionDomain with a null CodeSource and an empty permission set.
*/ */
private static final ProtectionDomain pdNoPerms = private static final ProtectionDomain pdNoPerms =
new ProtectionDomain(nullCodeSource, new Permissions()); new ProtectionDomain(nullCodeSource, new Permissions(), null, null);
/** /**
* Get the current AccessControlContext combined with the supplied subject. * Get the current AccessControlContext combined with the supplied subject.
......
...@@ -158,7 +158,7 @@ class DirectMethodHandle extends MethodHandle { ...@@ -158,7 +158,7 @@ class DirectMethodHandle extends MethodHandle {
private static LambdaForm preparedLambdaForm(MemberName m) { private static LambdaForm preparedLambdaForm(MemberName m) {
assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead
MethodType mtype = m.getInvocationType().basicType(); MethodType mtype = m.getInvocationType().basicType();
assert(!m.isMethodHandleInvoke() || "invokeBasic".equals(m.getName())) : m; assert(!m.isMethodHandleInvoke()) : m;
int which; int which;
switch (m.getReferenceKind()) { switch (m.getReferenceKind()) {
case REF_invokeVirtual: which = LF_INVVIRTUAL; break; case REF_invokeVirtual: which = LF_INVVIRTUAL; break;
......
...@@ -1034,7 +1034,7 @@ class LambdaForm { ...@@ -1034,7 +1034,7 @@ class LambdaForm {
this.member = member; this.member = member;
this.resolvedHandle = resolvedHandle; this.resolvedHandle = resolvedHandle;
// The following assert is almost always correct, but will fail for corner cases, such as PrivateInvokeTest. // The following assert is almost always correct, but will fail for corner cases, such as PrivateInvokeTest.
//assert(!isInvokeBasic()); //assert(!isInvokeBasic(member));
} }
NamedFunction(MethodType basicInvokerType) { NamedFunction(MethodType basicInvokerType) {
assert(basicInvokerType == basicInvokerType.basicType()) : basicInvokerType; assert(basicInvokerType == basicInvokerType.basicType()) : basicInvokerType;
...@@ -1045,13 +1045,13 @@ class LambdaForm { ...@@ -1045,13 +1045,13 @@ class LambdaForm {
// necessary to pass BigArityTest // necessary to pass BigArityTest
this.member = Invokers.invokeBasicMethod(basicInvokerType); this.member = Invokers.invokeBasicMethod(basicInvokerType);
} }
assert(isInvokeBasic()); assert(isInvokeBasic(member));
} }
private boolean isInvokeBasic() { private static boolean isInvokeBasic(MemberName member) {
return member != null && return member != null &&
member.isMethodHandleInvoke() && member.getDeclaringClass() == MethodHandle.class &&
"invokeBasic".equals(member.getName()); "invokeBasic".equals(member.getName());
} }
// The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc. // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc.
...@@ -1191,7 +1191,7 @@ class LambdaForm { ...@@ -1191,7 +1191,7 @@ class LambdaForm {
assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype)) assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype))
: Arrays.asList(mh, rtype, arity); : Arrays.asList(mh, rtype, arity);
MemberName member = mh.internalMemberName(); MemberName member = mh.internalMemberName();
if (member != null && member.getName().equals("invokeBasic") && member.isMethodHandleInvoke()) { if (isInvokeBasic(member)) {
assert(arity > 0); assert(arity > 0);
assert(a[0] instanceof MethodHandle); assert(a[0] instanceof MethodHandle);
MethodHandle mh2 = (MethodHandle) a[0]; MethodHandle mh2 = (MethodHandle) a[0];
......
...@@ -341,7 +341,6 @@ import java.util.Objects; ...@@ -341,7 +341,6 @@ import java.util.Objects;
} }
/** Utility method to query if this member is a method handle invocation (invoke or invokeExact). /** Utility method to query if this member is a method handle invocation (invoke or invokeExact).
* Also returns true for the non-public MH.invokeBasic.
*/ */
public boolean isMethodHandleInvoke() { public boolean isMethodHandleInvoke() {
final int bits = MH_INVOKE_MODS &~ Modifier.PUBLIC; final int bits = MH_INVOKE_MODS &~ Modifier.PUBLIC;
...@@ -356,7 +355,6 @@ import java.util.Objects; ...@@ -356,7 +355,6 @@ import java.util.Objects;
switch (name) { switch (name) {
case "invoke": case "invoke":
case "invokeExact": case "invokeExact":
case "invokeBasic": // internal sig-poly method
return true; return true;
default: default:
return false; return false;
......
...@@ -864,8 +864,6 @@ assertEquals("", (String) MH_newString.invokeExact()); ...@@ -864,8 +864,6 @@ assertEquals("", (String) MH_newString.invokeExact());
return invoker(type); return invoker(type);
if ("invokeExact".equals(name)) if ("invokeExact".equals(name))
return exactInvoker(type); return exactInvoker(type);
if ("invokeBasic".equals(name))
return basicInvoker(type);
assert(!MemberName.isMethodHandleInvokeName(name)); assert(!MemberName.isMethodHandleInvokeName(name));
return null; return null;
} }
......
...@@ -475,6 +475,11 @@ public class ProtectionDomain { ...@@ -475,6 +475,11 @@ public class ProtectionDomain {
} }
}; };
} }
@Override
public boolean getStaticPermissionsField(ProtectionDomain pd) {
return pd.staticPermissions;
}
}); });
} }
} }
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -37,6 +37,8 @@ import java.security.Security; ...@@ -37,6 +37,8 @@ import java.security.Security;
import java.util.Set; import java.util.Set;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import sun.misc.SharedSecrets;
import sun.misc.JavaSecurityProtectionDomainAccess;
/** /**
* A {@code SubjectDomainCombiner} updates ProtectionDomains * A {@code SubjectDomainCombiner} updates ProtectionDomains
...@@ -65,6 +67,9 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner { ...@@ -65,6 +67,9 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner {
private static final boolean allowCaching = private static final boolean allowCaching =
(useJavaxPolicy && cachePolicy()); (useJavaxPolicy && cachePolicy());
private static final JavaSecurityProtectionDomainAccess pdAccess =
SharedSecrets.getJavaSecurityProtectionDomainAccess();
/** /**
* Associate the provided {@code Subject} with this * Associate the provided {@code Subject} with this
* {@code SubjectDomainCombiner}. * {@code SubjectDomainCombiner}.
...@@ -239,10 +244,16 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner { ...@@ -239,10 +244,16 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner {
subjectPd = cachedPDs.getValue(pd); subjectPd = cachedPDs.getValue(pd);
if (subjectPd == null) { if (subjectPd == null) {
subjectPd = new ProtectionDomain(pd.getCodeSource(), if (pdAccess.getStaticPermissionsField(pd)) {
// Need to keep static ProtectionDomain objects static
subjectPd = new ProtectionDomain(pd.getCodeSource(),
pd.getPermissions());
} else {
subjectPd = new ProtectionDomain(pd.getCodeSource(),
pd.getPermissions(), pd.getPermissions(),
pd.getClassLoader(), pd.getClassLoader(),
principals); principals);
}
cachedPDs.putValue(pd, subjectPd); cachedPDs.putValue(pd, subjectPd);
} else { } else {
allNew = false; allNew = false;
...@@ -341,60 +352,63 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner { ...@@ -341,60 +352,63 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner {
ProtectionDomain subjectPd = cachedPDs.getValue(pd); ProtectionDomain subjectPd = cachedPDs.getValue(pd);
if (subjectPd == null) { if (subjectPd == null) {
if (pdAccess.getStaticPermissionsField(pd)) {
// XXX // keep static ProtectionDomain objects static
// we must first add the original permissions. subjectPd = new ProtectionDomain(pd.getCodeSource(),
// that way when we later add the new JAAS permissions, pd.getPermissions());
// any unresolved JAAS-related permissions will } else {
// automatically get resolved. // XXX
// we must first add the original permissions.
// get the original perms // that way when we later add the new JAAS permissions,
Permissions perms = new Permissions(); // any unresolved JAAS-related permissions will
PermissionCollection coll = pd.getPermissions(); // automatically get resolved.
java.util.Enumeration<Permission> e;
if (coll != null) { // get the original perms
synchronized (coll) { Permissions perms = new Permissions();
e = coll.elements(); PermissionCollection coll = pd.getPermissions();
while (e.hasMoreElements()) { java.util.Enumeration<Permission> e;
Permission newPerm = if (coll != null) {
synchronized (coll) {
e = coll.elements();
while (e.hasMoreElements()) {
Permission newPerm =
e.nextElement(); e.nextElement();
perms.add(newPerm); perms.add(newPerm);
}
} }
} }
}
// get perms from the policy // get perms from the policy
final java.security.CodeSource finalCs = pd.getCodeSource();
final java.security.CodeSource finalCs = pd.getCodeSource(); final Subject finalS = subject;
final Subject finalS = subject; PermissionCollection newPerms =
PermissionCollection newPerms = java.security.AccessController.doPrivileged
java.security.AccessController.doPrivileged (new PrivilegedAction<PermissionCollection>() {
(new PrivilegedAction<PermissionCollection>() { @SuppressWarnings("deprecation")
@SuppressWarnings("deprecation") public PermissionCollection run() {
public PermissionCollection run() { return
return javax.security.auth.Policy.getPolicy().getPermissions
javax.security.auth.Policy.getPolicy().getPermissions (finalS, finalCs);
(finalS, finalCs); }
} });
});
// add the newly granted perms,
// add the newly granted perms, // avoiding duplicates
// avoiding duplicates synchronized (newPerms) {
synchronized (newPerms) { e = newPerms.elements();
e = newPerms.elements(); while (e.hasMoreElements()) {
while (e.hasMoreElements()) { Permission newPerm = e.nextElement();
Permission newPerm = e.nextElement(); if (!perms.implies(newPerm)) {
if (!perms.implies(newPerm)) { perms.add(newPerm);
perms.add(newPerm); if (debug != null)
if (debug != null) debug.println (
debug.println ( "Adding perm " + newPerm + "\n");
"Adding perm " + newPerm + "\n"); }
} }
} }
subjectPd = new ProtectionDomain
(finalCs, perms, pd.getClassLoader(), principals);
} }
subjectPd = new ProtectionDomain
(finalCs, perms, pd.getClassLoader(), principals);
if (allowCaching) if (allowCaching)
cachedPDs.putValue(pd, subjectPd); cachedPDs.putValue(pd, subjectPd);
} }
......
...@@ -36,4 +36,9 @@ public interface JavaSecurityProtectionDomainAccess { ...@@ -36,4 +36,9 @@ public interface JavaSecurityProtectionDomainAccess {
* Returns the ProtectionDomainCache. * Returns the ProtectionDomainCache.
*/ */
ProtectionDomainCache getProtectionDomainCache(); ProtectionDomainCache getProtectionDomainCache();
/**
* Returns the staticPermissions field of the specified object
*/
boolean getStaticPermissionsField(ProtectionDomain pd);
} }
/* /*
* Copyright (c) 2002, 2013, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -37,6 +37,7 @@ import java.nio.channels.spi.*; ...@@ -37,6 +37,7 @@ import java.nio.channels.spi.*;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException; import java.security.PrivilegedActionException;
import java.security.SecureRandom;
import java.util.Random; import java.util.Random;
...@@ -47,24 +48,16 @@ import java.util.Random; ...@@ -47,24 +48,16 @@ import java.util.Random;
class PipeImpl class PipeImpl
extends Pipe extends Pipe
{ {
// Number of bytes in the secret handshake.
private static final int NUM_SECRET_BYTES = 16;
// Random object for handshake values
private static final Random RANDOM_NUMBER_GENERATOR = new SecureRandom();
// Source and sink channels // Source and sink channels
private SourceChannel source; private SourceChannel source;
private SinkChannel sink; private SinkChannel sink;
// Random object for handshake values
private static final Random rnd;
static {
byte[] someBytes = new byte[8];
boolean resultOK = IOUtil.randomBytes(someBytes);
if (resultOK) {
rnd = new Random(ByteBuffer.wrap(someBytes).getLong());
} else {
rnd = new Random();
}
}
private class Initializer private class Initializer
implements PrivilegedExceptionAction<Void> implements PrivilegedExceptionAction<Void>
{ {
...@@ -112,6 +105,10 @@ class PipeImpl ...@@ -112,6 +105,10 @@ class PipeImpl
SocketChannel sc2 = null; SocketChannel sc2 = null;
try { try {
// Create secret with a backing array.
ByteBuffer secret = ByteBuffer.allocate(NUM_SECRET_BYTES);
ByteBuffer bb = ByteBuffer.allocate(NUM_SECRET_BYTES);
// Loopback address // Loopback address
InetAddress lb = InetAddress.getByName("127.0.0.1"); InetAddress lb = InetAddress.getByName("127.0.0.1");
assert(lb.isLoopbackAddress()); assert(lb.isLoopbackAddress());
...@@ -128,18 +125,22 @@ class PipeImpl ...@@ -128,18 +125,22 @@ class PipeImpl
// Establish connection (assume connections are eagerly // Establish connection (assume connections are eagerly
// accepted) // accepted)
sc1 = SocketChannel.open(sa); sc1 = SocketChannel.open(sa);
ByteBuffer bb = ByteBuffer.allocate(8); RANDOM_NUMBER_GENERATOR.nextBytes(secret.array());
long secret = rnd.nextLong(); do {
bb.putLong(secret).flip(); sc1.write(secret);
sc1.write(bb); } while (secret.hasRemaining());
secret.rewind();
// Get a connection and verify it is legitimate // Get a connection and verify it is legitimate
sc2 = ssc.accept(); sc2 = ssc.accept();
bb.clear(); do {
sc2.read(bb); sc2.read(bb);
} while (bb.hasRemaining());
bb.rewind(); bb.rewind();
if (bb.getLong() == secret)
if (bb.equals(secret))
break; break;
sc2.close(); sc2.close();
sc1.close(); sc1.close();
} }
......
...@@ -256,7 +256,7 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale) ...@@ -256,7 +256,7 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale)
AwtFont* awtFont = NULL; AwtFont* awtFont = NULL;
jobjectArray compFont = NULL; jobjectArray compFont = NULL;
int cfnum; int cfnum = 0;
try { try {
if (env->EnsureLocalCapacity(3) < 0) if (env->EnsureLocalCapacity(3) < 0)
...@@ -264,7 +264,9 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale) ...@@ -264,7 +264,9 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale)
if (IsMultiFont(env, font)) { if (IsMultiFont(env, font)) {
compFont = GetComponentFonts(env, font); compFont = GetComponentFonts(env, font);
cfnum = env->GetArrayLength(compFont); if (compFont != NULL) {
cfnum = env->GetArrayLength(compFont);
}
} else { } else {
compFont = NULL; compFont = NULL;
cfnum = 0; cfnum = 0;
...@@ -614,7 +616,9 @@ int AwtFont::getFontDescriptorNumber(JNIEnv *env, jobject font, ...@@ -614,7 +616,9 @@ int AwtFont::getFontDescriptorNumber(JNIEnv *env, jobject font,
if (IsMultiFont(env, font)) { if (IsMultiFont(env, font)) {
array = GetComponentFonts(env, font); array = GetComponentFonts(env, font);
num = env->GetArrayLength(array); if (array != NULL) {
num = env->GetArrayLength(array);
}
} else { } else {
array = NULL; array = NULL;
num = 0; num = 0;
...@@ -672,14 +676,16 @@ SIZE AwtFont::DrawStringSize_sub(jstring str, HDC hDC, ...@@ -672,14 +676,16 @@ SIZE AwtFont::DrawStringSize_sub(jstring str, HDC hDC,
if (IsMultiFont(env, font)) { if (IsMultiFont(env, font)) {
jobject peer = env->CallObjectMethod(font, AwtFont::peerMID); jobject peer = env->CallObjectMethod(font, AwtFont::peerMID);
array = (jobjectArray)(env->CallObjectMethod( if (peer != NULL) {
peer, AwtFont::makeConvertedMultiFontStringMID, str)); array = (jobjectArray)(env->CallObjectMethod(
DASSERT(!safe_ExceptionOccurred(env)); peer, AwtFont::makeConvertedMultiFontStringMID, str));
DASSERT(!safe_ExceptionOccurred(env));
if (array != NULL) { if (array != NULL) {
arrayLength = env->GetArrayLength(array); arrayLength = env->GetArrayLength(array);
}
env->DeleteLocalRef(peer);
} }
env->DeleteLocalRef(peer);
} else { } else {
array = NULL; array = NULL;
arrayLength = 0; arrayLength = 0;
......
...@@ -230,11 +230,14 @@ public: ...@@ -230,11 +230,14 @@ public:
INLINE static jobjectArray GetComponentFonts(JNIEnv *env, INLINE static jobjectArray GetComponentFonts(JNIEnv *env,
jobject font) { jobject font) {
jobject platformFont = env->CallObjectMethod(font, AwtFont::peerMID); jobject platformFont = env->CallObjectMethod(font, AwtFont::peerMID);
jobjectArray result = if (platformFont != NULL) {
(jobjectArray)(env->GetObjectField(platformFont, jobjectArray result =
AwtFont::componentFontsID)); (jobjectArray)(env->GetObjectField(platformFont,
env->DeleteLocalRef(platformFont); AwtFont::componentFontsID));
return result; env->DeleteLocalRef(platformFont);
return result;
}
return NULL;
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册