8258419: RSA cipher buffer cleanup

Reviewed-by: valeriep
This commit is contained in:
Weijun Wang 2020-12-15 22:49:35 +00:00
parent 1f556d22ca
commit b97fe6c410
3 changed files with 72 additions and 55 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@
package com.sun.crypto.provider;
import java.util.Arrays;
import java.util.Locale;
import java.security.*;
@ -347,28 +348,40 @@ public final class RSACipher extends CipherSpi {
throw new IllegalBlockSizeException("Data must not be longer "
+ "than " + buffer.length + " bytes");
}
byte[] paddingCopy = null;
byte[] result = null;
try {
byte[] data;
switch (mode) {
case MODE_SIGN:
data = padding.pad(buffer, 0, bufOfs);
return RSACore.rsa(data, privateKey, true);
paddingCopy = padding.pad(buffer, 0, bufOfs);
result = RSACore.rsa(paddingCopy, privateKey, true);
break;
case MODE_VERIFY:
byte[] verifyBuffer = RSACore.convert(buffer, 0, bufOfs);
data = RSACore.rsa(verifyBuffer, publicKey);
return padding.unpad(data);
paddingCopy = RSACore.rsa(verifyBuffer, publicKey);
result = padding.unpad(paddingCopy);
break;
case MODE_ENCRYPT:
data = padding.pad(buffer, 0, bufOfs);
return RSACore.rsa(data, publicKey);
paddingCopy = padding.pad(buffer, 0, bufOfs);
result = RSACore.rsa(paddingCopy, publicKey);
break;
case MODE_DECRYPT:
byte[] decryptBuffer = RSACore.convert(buffer, 0, bufOfs);
data = RSACore.rsa(decryptBuffer, privateKey, false);
return padding.unpad(data);
paddingCopy = RSACore.rsa(decryptBuffer, privateKey, false);
result = padding.unpad(paddingCopy);
break;
default:
throw new AssertionError("Internal error");
}
return result;
} finally {
Arrays.fill(buffer, 0, bufOfs, (byte)0);
bufOfs = 0;
if (paddingCopy != null // will not happen
&& paddingCopy != buffer // already cleaned
&& paddingCopy != result) { // DO NOT CLEAN, THIS IS RESULT!
Arrays.fill(paddingCopy, (byte)0);
}
}
}
@ -404,6 +417,7 @@ public final class RSACipher extends CipherSpi {
byte[] result = doFinal();
int n = result.length;
System.arraycopy(result, 0, out, outOfs, n);
Arrays.fill(result, (byte)0);
return n;
}
@ -414,15 +428,19 @@ public final class RSACipher extends CipherSpi {
if ((encoded == null) || (encoded.length == 0)) {
throw new InvalidKeyException("Could not obtain encoded key");
}
if (encoded.length > buffer.length) {
throw new InvalidKeyException("Key is too long for wrapping");
}
update(encoded, 0, encoded.length);
try {
return doFinal();
} catch (BadPaddingException e) {
// should not occur
throw new InvalidKeyException("Wrapping failed", e);
if (encoded.length > buffer.length) {
throw new InvalidKeyException("Key is too long for wrapping");
}
update(encoded, 0, encoded.length);
try {
return doFinal();
} catch (BadPaddingException e) {
// should not occur
throw new InvalidKeyException("Wrapping failed", e);
}
} finally {
Arrays.fill(encoded, (byte)0);
}
}
@ -453,20 +471,26 @@ public final class RSACipher extends CipherSpi {
throw new InvalidKeyException("Unwrapping failed", e);
}
if (isTlsRsaPremasterSecret) {
if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
throw new IllegalStateException(
"No TlsRsaPremasterSecretParameterSpec specified");
try {
if (isTlsRsaPremasterSecret) {
if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
throw new IllegalStateException(
"No TlsRsaPremasterSecretParameterSpec specified");
}
// polish the TLS premaster secret
encoded = KeyUtil.checkTlsPreMasterSecretKey(
((TlsRsaPremasterSecretParameterSpec) spec).getClientVersion(),
((TlsRsaPremasterSecretParameterSpec) spec).getServerVersion(),
random, encoded, (failover != null));
}
// polish the TLS premaster secret
encoded = KeyUtil.checkTlsPreMasterSecretKey(
((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(),
((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(),
random, encoded, (failover != null));
return ConstructKeys.constructKey(encoded, algorithm, type);
} finally {
if (encoded != null) {
Arrays.fill(encoded, (byte) 0);
}
}
return ConstructKeys.constructKey(encoded, algorithm, type);
}
// see JCE spec