mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
8258419: RSA cipher buffer cleanup
Reviewed-by: valeriep
This commit is contained in:
parent
1f556d22ca
commit
b97fe6c410
3 changed files with 72 additions and 55 deletions
|
@ -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.
|
* 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
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
package com.sun.crypto.provider;
|
package com.sun.crypto.provider;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
|
@ -347,28 +348,40 @@ public final class RSACipher extends CipherSpi {
|
||||||
throw new IllegalBlockSizeException("Data must not be longer "
|
throw new IllegalBlockSizeException("Data must not be longer "
|
||||||
+ "than " + buffer.length + " bytes");
|
+ "than " + buffer.length + " bytes");
|
||||||
}
|
}
|
||||||
|
byte[] paddingCopy = null;
|
||||||
|
byte[] result = null;
|
||||||
try {
|
try {
|
||||||
byte[] data;
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case MODE_SIGN:
|
case MODE_SIGN:
|
||||||
data = padding.pad(buffer, 0, bufOfs);
|
paddingCopy = padding.pad(buffer, 0, bufOfs);
|
||||||
return RSACore.rsa(data, privateKey, true);
|
result = RSACore.rsa(paddingCopy, privateKey, true);
|
||||||
|
break;
|
||||||
case MODE_VERIFY:
|
case MODE_VERIFY:
|
||||||
byte[] verifyBuffer = RSACore.convert(buffer, 0, bufOfs);
|
byte[] verifyBuffer = RSACore.convert(buffer, 0, bufOfs);
|
||||||
data = RSACore.rsa(verifyBuffer, publicKey);
|
paddingCopy = RSACore.rsa(verifyBuffer, publicKey);
|
||||||
return padding.unpad(data);
|
result = padding.unpad(paddingCopy);
|
||||||
|
break;
|
||||||
case MODE_ENCRYPT:
|
case MODE_ENCRYPT:
|
||||||
data = padding.pad(buffer, 0, bufOfs);
|
paddingCopy = padding.pad(buffer, 0, bufOfs);
|
||||||
return RSACore.rsa(data, publicKey);
|
result = RSACore.rsa(paddingCopy, publicKey);
|
||||||
|
break;
|
||||||
case MODE_DECRYPT:
|
case MODE_DECRYPT:
|
||||||
byte[] decryptBuffer = RSACore.convert(buffer, 0, bufOfs);
|
byte[] decryptBuffer = RSACore.convert(buffer, 0, bufOfs);
|
||||||
data = RSACore.rsa(decryptBuffer, privateKey, false);
|
paddingCopy = RSACore.rsa(decryptBuffer, privateKey, false);
|
||||||
return padding.unpad(data);
|
result = padding.unpad(paddingCopy);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new AssertionError("Internal error");
|
throw new AssertionError("Internal error");
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
} finally {
|
} finally {
|
||||||
|
Arrays.fill(buffer, 0, bufOfs, (byte)0);
|
||||||
bufOfs = 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();
|
byte[] result = doFinal();
|
||||||
int n = result.length;
|
int n = result.length;
|
||||||
System.arraycopy(result, 0, out, outOfs, n);
|
System.arraycopy(result, 0, out, outOfs, n);
|
||||||
|
Arrays.fill(result, (byte)0);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,6 +428,7 @@ public final class RSACipher extends CipherSpi {
|
||||||
if ((encoded == null) || (encoded.length == 0)) {
|
if ((encoded == null) || (encoded.length == 0)) {
|
||||||
throw new InvalidKeyException("Could not obtain encoded key");
|
throw new InvalidKeyException("Could not obtain encoded key");
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
if (encoded.length > buffer.length) {
|
if (encoded.length > buffer.length) {
|
||||||
throw new InvalidKeyException("Key is too long for wrapping");
|
throw new InvalidKeyException("Key is too long for wrapping");
|
||||||
}
|
}
|
||||||
|
@ -424,6 +439,9 @@ public final class RSACipher extends CipherSpi {
|
||||||
// should not occur
|
// should not occur
|
||||||
throw new InvalidKeyException("Wrapping failed", e);
|
throw new InvalidKeyException("Wrapping failed", e);
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
Arrays.fill(encoded, (byte)0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// see JCE spec
|
// see JCE spec
|
||||||
|
@ -453,6 +471,7 @@ public final class RSACipher extends CipherSpi {
|
||||||
throw new InvalidKeyException("Unwrapping failed", e);
|
throw new InvalidKeyException("Unwrapping failed", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
if (isTlsRsaPremasterSecret) {
|
if (isTlsRsaPremasterSecret) {
|
||||||
if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
|
if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
|
@ -467,6 +486,11 @@ public final class RSACipher extends CipherSpi {
|
||||||
}
|
}
|
||||||
|
|
||||||
return ConstructKeys.constructKey(encoded, algorithm, type);
|
return ConstructKeys.constructKey(encoded, algorithm, type);
|
||||||
|
} finally {
|
||||||
|
if (encoded != null) {
|
||||||
|
Arrays.fill(encoded, (byte) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// see JCE spec
|
// see JCE spec
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2015, 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.
|
* 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
|
||||||
|
@ -231,12 +231,14 @@ public final class RSACore {
|
||||||
if ((n == len + 1) && (b[0] == 0)) {
|
if ((n == len + 1) && (b[0] == 0)) {
|
||||||
byte[] t = new byte[len];
|
byte[] t = new byte[len];
|
||||||
System.arraycopy(b, 1, t, 0, len);
|
System.arraycopy(b, 1, t, 0, len);
|
||||||
|
Arrays.fill(b, (byte)0);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
// must be smaller
|
// must be smaller
|
||||||
assert (n < len);
|
assert (n < len);
|
||||||
byte[] t = new byte[len];
|
byte[] t = new byte[len];
|
||||||
System.arraycopy(b, 0, t, (len - n), n);
|
System.arraycopy(b, 0, t, (len - n), n);
|
||||||
|
Arrays.fill(b, (byte)0);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
* 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
|
||||||
|
@ -238,41 +238,33 @@ public final class RSAPadding {
|
||||||
/**
|
/**
|
||||||
* Pad the data and return the padded block.
|
* Pad the data and return the padded block.
|
||||||
*/
|
*/
|
||||||
public byte[] pad(byte[] data, int ofs, int len)
|
public byte[] pad(byte[] data) throws BadPaddingException {
|
||||||
throws BadPaddingException {
|
return pad(data, 0, data.length);
|
||||||
return pad(RSACore.convert(data, ofs, len));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pad the data and return the padded block.
|
* Pad the data and return the padded block.
|
||||||
*/
|
*/
|
||||||
public byte[] pad(byte[] data) throws BadPaddingException {
|
public byte[] pad(byte[] data, int ofs, int len)
|
||||||
if (data.length > maxDataSize) {
|
throws BadPaddingException {
|
||||||
|
if (len > maxDataSize) {
|
||||||
throw new BadPaddingException("Data must be shorter than "
|
throw new BadPaddingException("Data must be shorter than "
|
||||||
+ (maxDataSize + 1) + " bytes but received "
|
+ (maxDataSize + 1) + " bytes but received "
|
||||||
+ data.length + " bytes.");
|
+ len + " bytes.");
|
||||||
}
|
}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PAD_NONE:
|
case PAD_NONE:
|
||||||
return data;
|
return RSACore.convert(data, ofs, len);
|
||||||
case PAD_BLOCKTYPE_1:
|
case PAD_BLOCKTYPE_1:
|
||||||
case PAD_BLOCKTYPE_2:
|
case PAD_BLOCKTYPE_2:
|
||||||
return padV15(data);
|
return padV15(data, ofs, len);
|
||||||
case PAD_OAEP_MGF1:
|
case PAD_OAEP_MGF1:
|
||||||
return padOAEP(data);
|
return padOAEP(data, ofs, len);
|
||||||
default:
|
default:
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Unpad the padded block and return the data.
|
|
||||||
*/
|
|
||||||
public byte[] unpad(byte[] padded, int ofs, int len)
|
|
||||||
throws BadPaddingException {
|
|
||||||
return unpad(RSACore.convert(padded, ofs, len));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unpad the padded block and return the data.
|
* Unpad the padded block and return the data.
|
||||||
*/
|
*/
|
||||||
|
@ -298,11 +290,10 @@ public final class RSAPadding {
|
||||||
/**
|
/**
|
||||||
* PKCS#1 v1.5 padding (blocktype 1 and 2).
|
* PKCS#1 v1.5 padding (blocktype 1 and 2).
|
||||||
*/
|
*/
|
||||||
private byte[] padV15(byte[] data) throws BadPaddingException {
|
private byte[] padV15(byte[] data, int ofs, int len) throws BadPaddingException {
|
||||||
byte[] padded = new byte[paddedSize];
|
byte[] padded = new byte[paddedSize];
|
||||||
System.arraycopy(data, 0, padded, paddedSize - data.length,
|
System.arraycopy(data, ofs, padded, paddedSize - len, len);
|
||||||
data.length);
|
int psSize = paddedSize - 3 - len;
|
||||||
int psSize = paddedSize - 3 - data.length;
|
|
||||||
int k = 0;
|
int k = 0;
|
||||||
padded[k++] = 0;
|
padded[k++] = 0;
|
||||||
padded[k++] = (byte)type;
|
padded[k++] = (byte)type;
|
||||||
|
@ -388,7 +379,7 @@ public final class RSAPadding {
|
||||||
* PKCS#1 v2.0 OAEP padding (MGF1).
|
* PKCS#1 v2.0 OAEP padding (MGF1).
|
||||||
* Paragraph references refer to PKCS#1 v2.1 (June 14, 2002)
|
* Paragraph references refer to PKCS#1 v2.1 (June 14, 2002)
|
||||||
*/
|
*/
|
||||||
private byte[] padOAEP(byte[] M) throws BadPaddingException {
|
private byte[] padOAEP(byte[] M, int ofs, int len) throws BadPaddingException {
|
||||||
if (random == null) {
|
if (random == null) {
|
||||||
random = JCAUtil.getSecureRandom();
|
random = JCAUtil.getSecureRandom();
|
||||||
}
|
}
|
||||||
|
@ -415,7 +406,7 @@ public final class RSAPadding {
|
||||||
int dbLen = EM.length - dbStart;
|
int dbLen = EM.length - dbStart;
|
||||||
|
|
||||||
// start of message M in EM
|
// start of message M in EM
|
||||||
int mStart = paddedSize - M.length;
|
int mStart = paddedSize - len;
|
||||||
|
|
||||||
// build DB
|
// build DB
|
||||||
// 2.b: Concatenate lHash, PS, a single octet with hexadecimal value
|
// 2.b: Concatenate lHash, PS, a single octet with hexadecimal value
|
||||||
|
@ -424,7 +415,7 @@ public final class RSAPadding {
|
||||||
// (note that PS is all zeros)
|
// (note that PS is all zeros)
|
||||||
System.arraycopy(lHash, 0, EM, dbStart, hLen);
|
System.arraycopy(lHash, 0, EM, dbStart, hLen);
|
||||||
EM[mStart - 1] = 1;
|
EM[mStart - 1] = 1;
|
||||||
System.arraycopy(M, 0, EM, mStart, M.length);
|
System.arraycopy(M, ofs, EM, mStart, len);
|
||||||
|
|
||||||
// produce maskedDB
|
// produce maskedDB
|
||||||
mgf.generateAndXor(EM, seedStart, seedLen, dbLen, EM, dbStart);
|
mgf.generateAndXor(EM, seedStart, seedLen, dbLen, EM, dbStart);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue