Skip to content
This repository was archived by the owner on Sep 2, 2022. It is now read-only.

Commit 7b2e7d8

Browse files
committed
8268525: Some new memory leak after JDK-8248268 and JDK-8255557
Reviewed-by: valeriep, ascarpino
1 parent 53b6e2c commit 7b2e7d8

File tree

5 files changed

+89
-106
lines changed

5 files changed

+89
-106
lines changed

src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -435,50 +435,54 @@ void init(int opmode, Key key, AlgorithmParameterSpec params,
435435

436436
byte[] keyBytes = getKeyBytes(key);
437437
byte[] ivBytes = null;
438-
if (params != null) {
439-
if (params instanceof IvParameterSpec) {
440-
ivBytes = ((IvParameterSpec) params).getIV();
441-
if ((ivBytes == null) || (ivBytes.length != blockSize)) {
438+
try {
439+
if (params != null) {
440+
if (params instanceof IvParameterSpec) {
441+
ivBytes = ((IvParameterSpec) params).getIV();
442+
if ((ivBytes == null) || (ivBytes.length != blockSize)) {
443+
throw new InvalidAlgorithmParameterException
444+
("Wrong IV length: must be " + blockSize +
445+
" bytes long");
446+
}
447+
} else if (params instanceof RC2ParameterSpec) {
448+
ivBytes = ((RC2ParameterSpec) params).getIV();
449+
if ((ivBytes != null) && (ivBytes.length != blockSize)) {
450+
throw new InvalidAlgorithmParameterException
451+
("Wrong IV length: must be " + blockSize +
452+
" bytes long");
453+
}
454+
} else {
442455
throw new InvalidAlgorithmParameterException
443-
("Wrong IV length: must be " + blockSize +
444-
" bytes long");
456+
("Unsupported parameter: " + params);
445457
}
446-
} else if (params instanceof RC2ParameterSpec) {
447-
ivBytes = ((RC2ParameterSpec) params).getIV();
448-
if ((ivBytes != null) && (ivBytes.length != blockSize)) {
458+
}
459+
if (cipherMode == ECB_MODE) {
460+
if (ivBytes != null) {
449461
throw new InvalidAlgorithmParameterException
450-
("Wrong IV length: must be " + blockSize +
451-
" bytes long");
462+
("ECB mode cannot use IV");
463+
}
464+
} else if (ivBytes == null) {
465+
if (decrypting) {
466+
throw new InvalidAlgorithmParameterException("Parameters "
467+
+ "missing");
452468
}
453-
} else {
454-
throw new InvalidAlgorithmParameterException
455-
("Unsupported parameter: " + params);
456-
}
457-
}
458-
if (cipherMode == ECB_MODE) {
459-
if (ivBytes != null) {
460-
throw new InvalidAlgorithmParameterException
461-
("ECB mode cannot use IV");
462-
}
463-
} else if (ivBytes == null) {
464-
if (decrypting) {
465-
throw new InvalidAlgorithmParameterException("Parameters "
466-
+ "missing");
467-
}
468469

469-
if (random == null) {
470-
random = SunJCE.getRandom();
471-
}
470+
if (random == null) {
471+
random = SunJCE.getRandom();
472+
}
472473

473-
ivBytes = new byte[blockSize];
474-
random.nextBytes(ivBytes);
475-
}
474+
ivBytes = new byte[blockSize];
475+
random.nextBytes(ivBytes);
476+
}
476477

477-
buffered = 0;
478-
diffBlocksize = blockSize;
478+
buffered = 0;
479+
diffBlocksize = blockSize;
479480

480-
String algorithm = key.getAlgorithm();
481-
cipher.init(decrypting, algorithm, keyBytes, ivBytes);
481+
String algorithm = key.getAlgorithm();
482+
cipher.init(decrypting, algorithm, keyBytes, ivBytes);
483+
} finally {
484+
Arrays.fill(keyBytes, (byte)0);
485+
}
482486
}
483487

484488
void init(int opmode, Key key, AlgorithmParameters params,

src/java.base/share/classes/com/sun/crypto/provider/ConstructKeys.java

Lines changed: 25 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
package com.sun.crypto.provider;
2727

28+
import jdk.internal.access.SharedSecrets;
29+
2830
import java.security.Key;
2931
import java.security.PublicKey;
3032
import java.security.PrivateKey;
@@ -48,33 +50,25 @@
4850
*/
4951

5052
final class ConstructKeys {
51-
/**
52-
* Construct a public key from its encoding.
53-
*
54-
* @param encodedKey the encoding of a public key.
55-
*
56-
* @param encodedKeyAlgorithm the algorithm the encodedKey is for.
57-
*
58-
* @return a public key constructed from the encodedKey.
59-
*/
53+
6054
private static final PublicKey constructPublicKey(byte[] encodedKey,
61-
String encodedKeyAlgorithm)
55+
int ofs, int len, String encodedKeyAlgorithm)
6256
throws InvalidKeyException, NoSuchAlgorithmException {
6357
PublicKey key = null;
58+
byte[] keyBytes = (ofs == 0 && encodedKey.length == len)
59+
? encodedKey : Arrays.copyOfRange(encodedKey, ofs, ofs + len);
60+
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
6461
try {
6562
KeyFactory keyFactory =
6663
KeyFactory.getInstance(encodedKeyAlgorithm,
6764
SunJCE.getInstance());
68-
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
6965
key = keyFactory.generatePublic(keySpec);
7066
} catch (NoSuchAlgorithmException nsae) {
7167
// Try to see whether there is another
7268
// provider which supports this algorithm
7369
try {
7470
KeyFactory keyFactory =
7571
KeyFactory.getInstance(encodedKeyAlgorithm);
76-
X509EncodedKeySpec keySpec =
77-
new X509EncodedKeySpec(encodedKey);
7872
key = keyFactory.generatePublic(keySpec);
7973
} catch (NoSuchAlgorithmException nsae2) {
8074
throw new NoSuchAlgorithmException("No installed providers " +
@@ -97,34 +91,24 @@ private static final PublicKey constructPublicKey(byte[] encodedKey,
9791
return key;
9892
}
9993

100-
/**
101-
* Construct a private key from its encoding.
102-
*
103-
* @param encodedKey the encoding of a private key.
104-
*
105-
* @param encodedKeyAlgorithm the algorithm the wrapped key is for.
106-
*
107-
* @return a private key constructed from the encodedKey.
108-
*/
10994
private static final PrivateKey constructPrivateKey(byte[] encodedKey,
110-
String encodedKeyAlgorithm)
95+
int ofs, int len, String encodedKeyAlgorithm)
11196
throws InvalidKeyException, NoSuchAlgorithmException {
11297
PrivateKey key = null;
113-
98+
byte[] keyBytes = (ofs == 0 && encodedKey.length == len)
99+
? encodedKey : Arrays.copyOfRange(encodedKey, ofs, ofs + len);
100+
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
114101
try {
115102
KeyFactory keyFactory =
116103
KeyFactory.getInstance(encodedKeyAlgorithm,
117104
SunJCE.getInstance());
118-
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
119105
return keyFactory.generatePrivate(keySpec);
120106
} catch (NoSuchAlgorithmException nsae) {
121107
// Try to see whether there is another
122108
// provider which supports this algorithm
123109
try {
124110
KeyFactory keyFactory =
125111
KeyFactory.getInstance(encodedKeyAlgorithm);
126-
PKCS8EncodedKeySpec keySpec =
127-
new PKCS8EncodedKeySpec(encodedKey);
128112
key = keyFactory.generatePrivate(keySpec);
129113
} catch (NoSuchAlgorithmException nsae2) {
130114
throw new NoSuchAlgorithmException("No installed providers " +
@@ -142,20 +126,16 @@ private static final PrivateKey constructPrivateKey(byte[] encodedKey,
142126
new InvalidKeyException("Cannot construct private key");
143127
ike.initCause(ikse);
144128
throw ike;
129+
} finally {
130+
SharedSecrets.getJavaSecuritySpecAccess().clearEncodedKeySpec(keySpec);
131+
if (keyBytes != encodedKey) {
132+
Arrays.fill(keyBytes, (byte)0);
133+
}
145134
}
146135

147136
return key;
148137
}
149138

150-
/**
151-
* Construct a secret key from its encoding.
152-
*
153-
* @param encodedKey the encoding of a secret key.
154-
*
155-
* @param encodedKeyAlgorithm the algorithm the secret key is for.
156-
*
157-
* @return a secret key constructed from the encodedKey.
158-
*/
159139
private static final SecretKey constructSecretKey(byte[] encodedKey,
160140
int ofs, int len, String encodedKeyAlgorithm) {
161141
return (new SecretKeySpec(encodedKey, ofs, len, encodedKeyAlgorithm));
@@ -170,35 +150,14 @@ static final Key constructKey(byte[] encoding, String keyAlgorithm,
170150
static final Key constructKey(byte[] encoding, int ofs, int len,
171151
String keyAlgorithm, int keyType)
172152
throws InvalidKeyException, NoSuchAlgorithmException {
173-
switch (keyType) {
174-
case Cipher.SECRET_KEY:
175-
try {
176-
return ConstructKeys.constructSecretKey(encoding, ofs, len,
177-
keyAlgorithm);
178-
} finally {
179-
Arrays.fill(encoding, ofs, len, (byte)0);
180-
}
181-
case Cipher.PRIVATE_KEY:
182-
byte[] encoding2 = encoding;
183-
try {
184-
if (ofs != 0 || len != encoding.length) {
185-
encoding2 = Arrays.copyOfRange(encoding, ofs, ofs + len);
186-
}
187-
return ConstructKeys.constructPrivateKey(encoding2,
188-
keyAlgorithm);
189-
} finally {
190-
Arrays.fill(encoding, ofs, len, (byte)0);
191-
if (encoding2 != encoding) {
192-
Arrays.fill(encoding2, (byte)0);
193-
}
194-
}
195-
case Cipher.PUBLIC_KEY:
196-
if (ofs != 0 || len != encoding.length) {
197-
encoding = Arrays.copyOfRange(encoding, ofs, ofs + len);
198-
}
199-
return ConstructKeys.constructPublicKey(encoding, keyAlgorithm);
200-
default:
201-
throw new NoSuchAlgorithmException("Unsupported key type");
202-
}
153+
return switch (keyType) {
154+
case Cipher.SECRET_KEY -> ConstructKeys.constructSecretKey(
155+
encoding, ofs, len, keyAlgorithm);
156+
case Cipher.PRIVATE_KEY -> ConstructKeys.constructPrivateKey(
157+
encoding, ofs, len, keyAlgorithm);
158+
case Cipher.PUBLIC_KEY -> ConstructKeys.constructPublicKey(
159+
encoding, ofs, len, keyAlgorithm);
160+
default -> throw new NoSuchAlgorithmException("Unsupported key type");
161+
};
203162
}
204163
}

src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,13 @@ void init(int opmode, Key key, GCMParameterSpec spec)
163163
reInit = false;
164164

165165
// always encrypt mode for embedded cipher
166-
blockCipher.init(false, key.getAlgorithm(), keyValue);
166+
try {
167+
blockCipher.init(false, key.getAlgorithm(), keyValue);
168+
} finally {
169+
if (!encryption) {
170+
Arrays.fill(keyValue, (byte) 0);
171+
}
172+
}
167173
}
168174

169175
@Override

src/java.base/share/classes/com/sun/crypto/provider/KWUtil.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ static final int W_INV(byte[] in, int inLen, byte[] icvOut,
124124
}
125125
}
126126
System.arraycopy(buffer, 0, icvOut, 0, SEMI_BLKSIZE);
127+
Arrays.fill(buffer, (byte)0);
127128
return inLen - SEMI_BLKSIZE;
128129
}
129130
}

src/java.base/share/classes/com/sun/crypto/provider/KeyWrapCipher.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,11 @@ protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
472472
int outLen = engineDoFinal(in, inOfs, inLen, out, 0);
473473

474474
if (outLen < estOutLen) {
475-
return Arrays.copyOf(out, outLen);
475+
try {
476+
return Arrays.copyOf(out, outLen);
477+
} finally {
478+
Arrays.fill(out, (byte)0);
479+
}
476480
} else {
477481
return out;
478482
}
@@ -529,6 +533,9 @@ protected int engineDoFinal(byte[] in, int inOfs, int inLen,
529533
return outLen;
530534
}
531535
} finally {
536+
if (dataBuf != null) {
537+
Arrays.fill(dataBuf, (byte)0);
538+
}
532539
dataBuf = null;
533540
dataIdx = 0;
534541
}
@@ -559,8 +566,14 @@ private int implDoFinal(byte[] in, int inOfs, int inLen, byte[] out)
559566
len += inLen;
560567
}
561568

562-
return (opmode == Cipher.ENCRYPT_MODE?
563-
helperEncrypt(out, len) : helperDecrypt(out, len));
569+
try {
570+
return (opmode == Cipher.ENCRYPT_MODE ?
571+
helperEncrypt(out, len) : helperDecrypt(out, len));
572+
} finally {
573+
if (dataBuf != null && dataBuf != out) {
574+
Arrays.fill(dataBuf, (byte)0);
575+
}
576+
}
564577
}
565578

566579
// helper routine for in-place encryption.

0 commit comments

Comments
 (0)