mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8258915: Temporary buffer cleanup
Reviewed-by: valeriep
This commit is contained in:
parent
31d8a19e47
commit
f834557ae0
79 changed files with 1517 additions and 1039 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2021, 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
|
||||
|
@ -40,6 +40,7 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.security.ProviderException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class implements the AES algorithm in its various modes
|
||||
|
@ -163,9 +164,12 @@ abstract class AESCipher extends CipherSpi {
|
|||
byte[] value = key.getEncoded();
|
||||
if (value == null) {
|
||||
throw new InvalidKeyException("Key encoding must not be null");
|
||||
} else if (value.length != fixedKeySize) {
|
||||
throw new InvalidKeyException("The key must be " +
|
||||
fixedKeySize + " bytes");
|
||||
} else {
|
||||
Arrays.fill(value, (byte)0);
|
||||
if (value.length != fixedKeySize) {
|
||||
throw new InvalidKeyException("The key must be " +
|
||||
fixedKeySize + " bytes");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -515,6 +519,7 @@ abstract class AESCipher extends CipherSpi {
|
|||
*/
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
byte[] encoded = key.getEncoded();
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
if (!AESCrypt.isKeySizeValid(encoded.length)) {
|
||||
throw new InvalidKeyException("Invalid AES key length: " +
|
||||
encoded.length + " bytes");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2021, 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
|
||||
|
@ -94,6 +94,9 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
|
|||
if (!MessageDigest.isEqual(key, lastKey)) {
|
||||
// re-generate session key 'sessionK' when cipher key changes
|
||||
makeSessionKey(key);
|
||||
if (lastKey != null) {
|
||||
Arrays.fill(lastKey, (byte)0);
|
||||
}
|
||||
lastKey = key.clone(); // save cipher key
|
||||
}
|
||||
|
||||
|
@ -673,12 +676,23 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
|
|||
// and expand them into arrays of ints.
|
||||
int[] expandedKe = expandToSubKey(Ke, false); // decrypting==false
|
||||
int[] expandedKd = expandToSubKey(Kd, true); // decrypting==true
|
||||
|
||||
Arrays.fill(tk, 0);
|
||||
for (int[] ia: Ke) {
|
||||
Arrays.fill(ia, 0);
|
||||
}
|
||||
for (int[] ia: Kd) {
|
||||
Arrays.fill(ia, 0);
|
||||
}
|
||||
ROUNDS_12 = (ROUNDS>=12);
|
||||
ROUNDS_14 = (ROUNDS==14);
|
||||
limit = ROUNDS*4;
|
||||
|
||||
// store the expanded sub keys into 'sessionK'
|
||||
if (sessionK != null) {
|
||||
// erase the previous values in sessionK
|
||||
Arrays.fill(sessionK[0], 0);
|
||||
Arrays.fill(sessionK[1], 0);
|
||||
}
|
||||
sessionK = new int[][] { expandedKe, expandedKd };
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2021, 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
|
||||
|
@ -30,6 +30,7 @@ import java.security.InvalidParameterException;
|
|||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.KeyGeneratorSpi;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
@ -112,6 +113,7 @@ public final class AESKeyGenerator extends KeyGeneratorSpi {
|
|||
byte[] keyBytes = new byte[keySize];
|
||||
this.random.nextBytes(keyBytes);
|
||||
aesKey = new SecretKeySpec(keyBytes, "AES");
|
||||
Arrays.fill(keyBytes, (byte)0);
|
||||
return aesKey;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2021, 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
|
||||
|
@ -198,7 +198,12 @@ abstract class AESWrapCipher extends CipherSpi {
|
|||
"only be used for key wrapping and unwrapping");
|
||||
}
|
||||
AESCipher.checkKeySize(key, fixedKeySize);
|
||||
cipher.init(decrypting, key.getAlgorithm(), key.getEncoded());
|
||||
byte[] encoded = key.getEncoded();
|
||||
try {
|
||||
cipher.init(decrypting, key.getAlgorithm(), encoded);
|
||||
} finally {
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -374,6 +379,7 @@ abstract class AESWrapCipher extends CipherSpi {
|
|||
*/
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
byte[] encoded = key.getEncoded();
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
if (!AESCrypt.isKeySizeValid(encoded.length)) {
|
||||
throw new InvalidKeyException("Invalid key length: " +
|
||||
encoded.length + " bytes");
|
||||
|
@ -404,38 +410,42 @@ abstract class AESWrapCipher extends CipherSpi {
|
|||
throw new InvalidKeyException("Cannot get an encoding of " +
|
||||
"the key to be wrapped");
|
||||
}
|
||||
byte[] out = new byte[Math.addExact(keyVal.length, 8)];
|
||||
try {
|
||||
byte[] out = new byte[Math.addExact(keyVal.length, 8)];
|
||||
|
||||
if (keyVal.length == 8) {
|
||||
System.arraycopy(IV, 0, out, 0, IV.length);
|
||||
System.arraycopy(keyVal, 0, out, IV.length, 8);
|
||||
cipher.encryptBlock(out, 0, out, 0);
|
||||
} else {
|
||||
if (keyVal.length % 8 != 0) {
|
||||
throw new IllegalBlockSizeException("length of the " +
|
||||
"to be wrapped key should be multiples of 8 bytes");
|
||||
}
|
||||
System.arraycopy(IV, 0, out, 0, IV.length);
|
||||
System.arraycopy(keyVal, 0, out, IV.length, keyVal.length);
|
||||
int N = keyVal.length/8;
|
||||
byte[] buffer = new byte[blksize];
|
||||
for (int j = 0; j < 6; j++) {
|
||||
for (int i = 1; i <= N; i++) {
|
||||
int T = i + j*N;
|
||||
System.arraycopy(out, 0, buffer, 0, IV.length);
|
||||
System.arraycopy(out, i*8, buffer, IV.length, 8);
|
||||
cipher.encryptBlock(buffer, 0, buffer, 0);
|
||||
for (int k = 1; T != 0; k++) {
|
||||
byte v = (byte) T;
|
||||
buffer[IV.length - k] ^= v;
|
||||
T >>>= 8;
|
||||
if (keyVal.length == 8) {
|
||||
System.arraycopy(IV, 0, out, 0, IV.length);
|
||||
System.arraycopy(keyVal, 0, out, IV.length, 8);
|
||||
cipher.encryptBlock(out, 0, out, 0);
|
||||
} else {
|
||||
if (keyVal.length % 8 != 0) {
|
||||
throw new IllegalBlockSizeException("length of the " +
|
||||
"to be wrapped key should be multiples of 8 bytes");
|
||||
}
|
||||
System.arraycopy(IV, 0, out, 0, IV.length);
|
||||
System.arraycopy(keyVal, 0, out, IV.length, keyVal.length);
|
||||
int N = keyVal.length / 8;
|
||||
byte[] buffer = new byte[blksize];
|
||||
for (int j = 0; j < 6; j++) {
|
||||
for (int i = 1; i <= N; i++) {
|
||||
int T = i + j * N;
|
||||
System.arraycopy(out, 0, buffer, 0, IV.length);
|
||||
System.arraycopy(out, i * 8, buffer, IV.length, 8);
|
||||
cipher.encryptBlock(buffer, 0, buffer, 0);
|
||||
for (int k = 1; T != 0; k++) {
|
||||
byte v = (byte) T;
|
||||
buffer[IV.length - k] ^= v;
|
||||
T >>>= 8;
|
||||
}
|
||||
System.arraycopy(buffer, 0, out, 0, IV.length);
|
||||
System.arraycopy(buffer, 8, out, 8 * i, 8);
|
||||
}
|
||||
System.arraycopy(buffer, 0, out, 0, IV.length);
|
||||
System.arraycopy(buffer, 8, out, 8*i, 8);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
} finally {
|
||||
Arrays.fill(keyVal, (byte)0);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -474,38 +484,43 @@ abstract class AESWrapCipher extends CipherSpi {
|
|||
}
|
||||
byte[] out = new byte[wrappedKeyLen - 8];
|
||||
byte[] buffer = new byte[blksize];
|
||||
if (wrappedKeyLen == 16) {
|
||||
cipher.decryptBlock(wrappedKey, 0, buffer, 0);
|
||||
for (int i = 0; i < IV.length; i++) {
|
||||
if (IV[i] != buffer[i]) {
|
||||
throw new InvalidKeyException("Integrity check failed");
|
||||
}
|
||||
}
|
||||
System.arraycopy(buffer, IV.length, out, 0, out.length);
|
||||
} else {
|
||||
System.arraycopy(wrappedKey, 0, buffer, 0, IV.length);
|
||||
System.arraycopy(wrappedKey, IV.length, out, 0, out.length);
|
||||
int N = out.length/8;
|
||||
for (int j = 5; j >= 0; j--) {
|
||||
for (int i = N; i > 0; i--) {
|
||||
int T = i + j*N;
|
||||
System.arraycopy(out, 8*(i-1), buffer, IV.length, 8);
|
||||
for (int k = 1; T != 0; k++) {
|
||||
byte v = (byte) T;
|
||||
buffer[IV.length - k] ^= v;
|
||||
T >>>= 8;
|
||||
try {
|
||||
if (wrappedKeyLen == 16) {
|
||||
cipher.decryptBlock(wrappedKey, 0, buffer, 0);
|
||||
for (int i = 0; i < IV.length; i++) {
|
||||
if (IV[i] != buffer[i]) {
|
||||
throw new InvalidKeyException("Integrity check failed");
|
||||
}
|
||||
}
|
||||
System.arraycopy(buffer, IV.length, out, 0, out.length);
|
||||
} else {
|
||||
System.arraycopy(wrappedKey, 0, buffer, 0, IV.length);
|
||||
System.arraycopy(wrappedKey, IV.length, out, 0, out.length);
|
||||
int N = out.length / 8;
|
||||
for (int j = 5; j >= 0; j--) {
|
||||
for (int i = N; i > 0; i--) {
|
||||
int T = i + j * N;
|
||||
System.arraycopy(out, 8 * (i - 1), buffer, IV.length, 8);
|
||||
for (int k = 1; T != 0; k++) {
|
||||
byte v = (byte) T;
|
||||
buffer[IV.length - k] ^= v;
|
||||
T >>>= 8;
|
||||
}
|
||||
cipher.decryptBlock(buffer, 0, buffer, 0);
|
||||
System.arraycopy(buffer, IV.length, out, 8 * (i - 1), 8);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < IV.length; i++) {
|
||||
if (IV[i] != buffer[i]) {
|
||||
throw new InvalidKeyException("Integrity check failed");
|
||||
}
|
||||
cipher.decryptBlock(buffer, 0, buffer, 0);
|
||||
System.arraycopy(buffer, IV.length, out, 8*(i-1), 8);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < IV.length; i++) {
|
||||
if (IV[i] != buffer[i]) {
|
||||
throw new InvalidKeyException("Integrity check failed");
|
||||
}
|
||||
}
|
||||
return ConstructKeys.constructKey(out, wrappedKeyAlgorithm,
|
||||
wrappedKeyType);
|
||||
} finally {
|
||||
Arrays.fill(out, (byte)0);
|
||||
Arrays.fill(buffer, (byte)0);
|
||||
}
|
||||
return ConstructKeys.constructKey(out, wrappedKeyAlgorithm,
|
||||
wrappedKeyType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, 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 @@ package com.sun.crypto.provider;
|
|||
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.*;
|
||||
|
||||
|
@ -180,6 +181,9 @@ public final class ARCFOURCipher extends CipherSpi {
|
|||
|
||||
// init method. Check opmode and key, then call init(byte[]).
|
||||
private void init(int opmode, Key key) throws InvalidKeyException {
|
||||
if (lastKey != null) {
|
||||
Arrays.fill(lastKey, (byte)0);
|
||||
}
|
||||
if ((opmode < Cipher.ENCRYPT_MODE) || (opmode > Cipher.UNWRAP_MODE)) {
|
||||
throw new InvalidKeyException("Unknown opmode: " + opmode);
|
||||
}
|
||||
|
@ -199,6 +203,7 @@ public final class ARCFOURCipher extends CipherSpi {
|
|||
}
|
||||
byte[] encodedKey = key.getEncoded();
|
||||
if ((encodedKey.length < 5) || (encodedKey.length > 128)) {
|
||||
Arrays.fill(encodedKey, (byte)0);
|
||||
throw new InvalidKeyException
|
||||
("Key length must be between 40 and 1024 bit");
|
||||
}
|
||||
|
@ -244,19 +249,31 @@ public final class ARCFOURCipher extends CipherSpi {
|
|||
if ((encoded == null) || (encoded.length == 0)) {
|
||||
throw new InvalidKeyException("Could not obtain encoded key");
|
||||
}
|
||||
return engineDoFinal(encoded, 0, encoded.length);
|
||||
try {
|
||||
return engineDoFinal(encoded, 0, encoded.length);
|
||||
} finally {
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
protected Key engineUnwrap(byte[] wrappedKey, String algorithm,
|
||||
int type) throws InvalidKeyException, NoSuchAlgorithmException {
|
||||
byte[] encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
|
||||
return ConstructKeys.constructKey(encoded, algorithm, type);
|
||||
byte[] encoded = null;
|
||||
try {
|
||||
encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
|
||||
return ConstructKeys.constructKey(encoded, algorithm, type);
|
||||
} finally {
|
||||
if (encoded != null) {
|
||||
Arrays.fill(encoded, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// see JCE spec
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
byte[] encodedKey = getEncodedKey(key);
|
||||
Arrays.fill(encodedKey, (byte)0);
|
||||
return Math.multiplyExact(encodedKey.length, 8);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2021, 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,8 @@ package com.sun.crypto.provider;
|
|||
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
import sun.security.util.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
@ -373,7 +375,9 @@ public final class BlowfishCipher extends CipherSpi {
|
|||
* @exception InvalidKeyException if <code>key</code> is invalid.
|
||||
*/
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
return Math.multiplyExact(key.getEncoded().length, 8);
|
||||
byte[] encodedKey = key.getEncoded();
|
||||
Arrays.fill(encodedKey, (byte)0);
|
||||
return Math.multiplyExact(encodedKey.length, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2021, 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
|
||||
|
@ -29,6 +29,7 @@ import java.security.SecureRandom;
|
|||
import java.security.InvalidParameterException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.KeyGeneratorSpi;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
@ -110,6 +111,10 @@ public final class BlowfishKeyGenerator extends KeyGeneratorSpi {
|
|||
byte[] keyBytes = new byte[this.keysize];
|
||||
this.random.nextBytes(keyBytes);
|
||||
|
||||
return new SecretKeySpec(keyBytes, "Blowfish");
|
||||
try {
|
||||
return new SecretKeySpec(keyBytes, "Blowfish");
|
||||
} finally {
|
||||
Arrays.fill(keyBytes, (byte)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2021, 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
|
||||
|
@ -33,6 +33,7 @@ import java.nio.ByteBuffer;
|
|||
import java.nio.ByteOrder;
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.ChaCha20ParameterSpec;
|
||||
|
@ -546,6 +547,9 @@ abstract class ChaCha20Cipher extends CipherSpi {
|
|||
// assigning them to the object.
|
||||
byte[] newKeyBytes = getEncodedKey(key);
|
||||
checkKeyAndNonce(newKeyBytes, newNonce);
|
||||
if (this.keyBytes != null) {
|
||||
Arrays.fill(this.keyBytes, (byte)0);
|
||||
}
|
||||
this.keyBytes = newKeyBytes;
|
||||
nonce = newNonce;
|
||||
|
||||
|
@ -612,6 +616,9 @@ abstract class ChaCha20Cipher extends CipherSpi {
|
|||
}
|
||||
byte[] encodedKey = key.getEncoded();
|
||||
if (encodedKey == null || encodedKey.length != 32) {
|
||||
if (encodedKey != null) {
|
||||
Arrays.fill(encodedKey, (byte)0);
|
||||
}
|
||||
throw new InvalidKeyException("Key length must be 256 bits");
|
||||
}
|
||||
return encodedKey;
|
||||
|
@ -790,6 +797,7 @@ abstract class ChaCha20Cipher extends CipherSpi {
|
|||
@Override
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
byte[] encodedKey = getEncodedKey(key);
|
||||
Arrays.fill(encodedKey, (byte)0);
|
||||
return encodedKey.length << 3;
|
||||
}
|
||||
|
||||
|
|
|
@ -504,97 +504,106 @@ final class CipherCore {
|
|||
|| (opmode == Cipher.UNWRAP_MODE);
|
||||
|
||||
byte[] keyBytes = getKeyBytes(key);
|
||||
int tagLen = -1;
|
||||
byte[] ivBytes = null;
|
||||
if (params != null) {
|
||||
if (cipherMode == GCM_MODE) {
|
||||
if (params instanceof GCMParameterSpec) {
|
||||
tagLen = ((GCMParameterSpec)params).getTLen();
|
||||
if (tagLen < 96 || tagLen > 128 || ((tagLen & 0x07) != 0)) {
|
||||
try {
|
||||
int tagLen = -1;
|
||||
byte[] ivBytes = null;
|
||||
if (params != null) {
|
||||
if (cipherMode == GCM_MODE) {
|
||||
if (params instanceof GCMParameterSpec) {
|
||||
tagLen = ((GCMParameterSpec) params).getTLen();
|
||||
if (tagLen < 96 || tagLen > 128 || ((tagLen & 0x07) != 0)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported TLen value; must be one of " +
|
||||
"{128, 120, 112, 104, 96}");
|
||||
}
|
||||
tagLen = tagLen >> 3;
|
||||
ivBytes = ((GCMParameterSpec) params).getIV();
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported TLen value; must be one of " +
|
||||
"{128, 120, 112, 104, 96}");
|
||||
}
|
||||
tagLen = tagLen >> 3;
|
||||
ivBytes = ((GCMParameterSpec)params).getIV();
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported parameter: " + params);
|
||||
}
|
||||
} else {
|
||||
if (params instanceof IvParameterSpec) {
|
||||
ivBytes = ((IvParameterSpec)params).getIV();
|
||||
if ((ivBytes == null) || (ivBytes.length != blockSize)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Wrong IV length: must be " + blockSize +
|
||||
" bytes long");
|
||||
}
|
||||
} else if (params instanceof RC2ParameterSpec) {
|
||||
ivBytes = ((RC2ParameterSpec)params).getIV();
|
||||
if ((ivBytes != null) && (ivBytes.length != blockSize)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Wrong IV length: must be " + blockSize +
|
||||
" bytes long");
|
||||
("Unsupported parameter: " + params);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported parameter: " + params);
|
||||
if (params instanceof IvParameterSpec) {
|
||||
ivBytes = ((IvParameterSpec) params).getIV();
|
||||
if ((ivBytes == null) || (ivBytes.length != blockSize)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Wrong IV length: must be " + blockSize +
|
||||
" bytes long");
|
||||
}
|
||||
} else if (params instanceof RC2ParameterSpec) {
|
||||
ivBytes = ((RC2ParameterSpec) params).getIV();
|
||||
if ((ivBytes != null) && (ivBytes.length != blockSize)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Wrong IV length: must be " + blockSize +
|
||||
" bytes long");
|
||||
}
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported parameter: " + params);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cipherMode == ECB_MODE) {
|
||||
if (ivBytes != null) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("ECB mode cannot use IV");
|
||||
}
|
||||
} else if (ivBytes == null) {
|
||||
if (decrypting) {
|
||||
throw new InvalidAlgorithmParameterException("Parameters "
|
||||
+ "missing");
|
||||
if (cipherMode == ECB_MODE) {
|
||||
if (ivBytes != null) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("ECB mode cannot use IV");
|
||||
}
|
||||
} else if (ivBytes == null) {
|
||||
if (decrypting) {
|
||||
throw new InvalidAlgorithmParameterException("Parameters "
|
||||
+ "missing");
|
||||
}
|
||||
|
||||
if (random == null) {
|
||||
random = SunJCE.getRandom();
|
||||
}
|
||||
if (cipherMode == GCM_MODE) {
|
||||
ivBytes = new byte[GaloisCounterMode.DEFAULT_IV_LEN];
|
||||
} else {
|
||||
ivBytes = new byte[blockSize];
|
||||
}
|
||||
random.nextBytes(ivBytes);
|
||||
}
|
||||
|
||||
if (random == null) {
|
||||
random = SunJCE.getRandom();
|
||||
}
|
||||
buffered = 0;
|
||||
diffBlocksize = blockSize;
|
||||
|
||||
String algorithm = key.getAlgorithm();
|
||||
|
||||
// GCM mode needs additional handling
|
||||
if (cipherMode == GCM_MODE) {
|
||||
ivBytes = new byte[GaloisCounterMode.DEFAULT_IV_LEN];
|
||||
} else {
|
||||
ivBytes = new byte[blockSize];
|
||||
}
|
||||
random.nextBytes(ivBytes);
|
||||
}
|
||||
|
||||
buffered = 0;
|
||||
diffBlocksize = blockSize;
|
||||
|
||||
String algorithm = key.getAlgorithm();
|
||||
|
||||
// GCM mode needs additional handling
|
||||
if (cipherMode == GCM_MODE) {
|
||||
if(tagLen == -1) {
|
||||
tagLen = GaloisCounterMode.DEFAULT_TAG_LEN;
|
||||
}
|
||||
if (decrypting) {
|
||||
minBytes = tagLen;
|
||||
} else {
|
||||
// check key+iv for encryption in GCM mode
|
||||
requireReinit =
|
||||
Arrays.equals(ivBytes, lastEncIv) &&
|
||||
MessageDigest.isEqual(keyBytes, lastEncKey);
|
||||
if (requireReinit) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Cannot reuse iv for GCM encryption");
|
||||
if (tagLen == -1) {
|
||||
tagLen = GaloisCounterMode.DEFAULT_TAG_LEN;
|
||||
}
|
||||
lastEncIv = ivBytes;
|
||||
lastEncKey = keyBytes;
|
||||
if (decrypting) {
|
||||
minBytes = tagLen;
|
||||
} else {
|
||||
// check key+iv for encryption in GCM mode
|
||||
requireReinit =
|
||||
Arrays.equals(ivBytes, lastEncIv) &&
|
||||
MessageDigest.isEqual(keyBytes, lastEncKey);
|
||||
if (requireReinit) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Cannot reuse iv for GCM encryption");
|
||||
}
|
||||
lastEncIv = ivBytes;
|
||||
if (lastEncKey != null) {
|
||||
Arrays.fill(lastEncKey, (byte) 0);
|
||||
}
|
||||
lastEncKey = keyBytes;
|
||||
}
|
||||
((GaloisCounterMode) cipher).init
|
||||
(decrypting, algorithm, keyBytes, ivBytes, tagLen);
|
||||
} else {
|
||||
cipher.init(decrypting, algorithm, keyBytes, ivBytes);
|
||||
}
|
||||
// skip checking key+iv from now on until after doFinal()
|
||||
requireReinit = false;
|
||||
} finally {
|
||||
if (lastEncKey != keyBytes) {
|
||||
Arrays.fill(keyBytes, (byte) 0);
|
||||
}
|
||||
((GaloisCounterMode) cipher).init
|
||||
(decrypting, algorithm, keyBytes, ivBytes, tagLen);
|
||||
} else {
|
||||
cipher.init(decrypting, algorithm, keyBytes, ivBytes);
|
||||
}
|
||||
// skip checking key+iv from now on until after doFinal()
|
||||
requireReinit = false;
|
||||
}
|
||||
|
||||
void init(int opmode, Key key, AlgorithmParameters params,
|
||||
|
@ -1156,7 +1165,11 @@ final class CipherCore {
|
|||
throw new InvalidKeyException("Cannot get an encoding of " +
|
||||
"the key to be wrapped");
|
||||
}
|
||||
result = doFinal(encodedKey, 0, encodedKey.length);
|
||||
try {
|
||||
result = doFinal(encodedKey, 0, encodedKey.length);
|
||||
} finally {
|
||||
Arrays.fill(encodedKey, (byte)0);
|
||||
}
|
||||
} catch (BadPaddingException e) {
|
||||
// Should never happen
|
||||
}
|
||||
|
@ -1197,8 +1210,12 @@ final class CipherCore {
|
|||
throw new InvalidKeyException("The wrapped key does not have " +
|
||||
"the correct length");
|
||||
}
|
||||
return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
|
||||
wrappedKeyType);
|
||||
try {
|
||||
return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
|
||||
wrappedKeyType);
|
||||
} finally {
|
||||
Arrays.fill(encodedKey, (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,259 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.security.Key;
|
||||
import java.security.PublicKey;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherSpi;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* This class entends the javax.crypto.CipherSpi class with a concrete
|
||||
* implementation of the methods for wrapping and unwrapping
|
||||
* keys.
|
||||
*
|
||||
* @author Sharon Liu
|
||||
*
|
||||
*
|
||||
* @see javax.crypto.CipherSpi
|
||||
* @see BlowfishCipher
|
||||
* @see DESCipher
|
||||
* @see PBEWithMD5AndDESCipher
|
||||
*/
|
||||
|
||||
public abstract class CipherWithWrappingSpi extends CipherSpi {
|
||||
|
||||
/**
|
||||
* Wrap a key.
|
||||
*
|
||||
* @param key the key to be wrapped.
|
||||
*
|
||||
* @return the wrapped key.
|
||||
*
|
||||
* @exception IllegalBlockSizeException if this cipher is a block
|
||||
* cipher, no padding has been requested, and the length of the
|
||||
* encoding of the key to be wrapped is not a
|
||||
* multiple of the block size.
|
||||
*
|
||||
* @exception InvalidKeyException if it is impossible or unsafe to
|
||||
* wrap the key with this cipher (e.g., a hardware protected key is
|
||||
* being passed to a software only cipher).
|
||||
*/
|
||||
protected final byte[] engineWrap(Key key)
|
||||
throws IllegalBlockSizeException, InvalidKeyException
|
||||
{
|
||||
byte[] result = null;
|
||||
|
||||
try {
|
||||
byte[] encodedKey = key.getEncoded();
|
||||
if ((encodedKey == null) || (encodedKey.length == 0)) {
|
||||
throw new InvalidKeyException("Cannot get an encoding of " +
|
||||
"the key to be wrapped");
|
||||
}
|
||||
|
||||
result = engineDoFinal(encodedKey, 0, encodedKey.length);
|
||||
} catch (BadPaddingException e) {
|
||||
// Should never happen
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap a previously wrapped key.
|
||||
*
|
||||
* @param wrappedKey the key to be unwrapped.
|
||||
*
|
||||
* @param wrappedKeyAlgorithm the algorithm the wrapped key is for.
|
||||
*
|
||||
* @param wrappedKeyType the type of the wrapped key.
|
||||
* This is one of <code>Cipher.SECRET_KEY</code>,
|
||||
* <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.
|
||||
*
|
||||
* @return the unwrapped key.
|
||||
*
|
||||
* @exception InvalidKeyException if <code>wrappedKey</code> does not
|
||||
* represent a wrapped key, or if the algorithm associated with the
|
||||
* wrapped key is different from <code>wrappedKeyAlgorithm</code>
|
||||
* and/or its key type is different from <code>wrappedKeyType</code>.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if no installed providers
|
||||
* can create keys for the <code>wrappedKeyAlgorithm</code>.
|
||||
*/
|
||||
protected final Key engineUnwrap(byte[] wrappedKey,
|
||||
String wrappedKeyAlgorithm,
|
||||
int wrappedKeyType)
|
||||
throws InvalidKeyException, NoSuchAlgorithmException
|
||||
{
|
||||
byte[] encodedKey;
|
||||
Key result = null;
|
||||
|
||||
try {
|
||||
encodedKey = engineDoFinal(wrappedKey, 0,
|
||||
wrappedKey.length);
|
||||
} catch (BadPaddingException ePadding) {
|
||||
throw new InvalidKeyException();
|
||||
} catch (IllegalBlockSizeException eBlockSize) {
|
||||
throw new InvalidKeyException();
|
||||
}
|
||||
|
||||
switch (wrappedKeyType) {
|
||||
case Cipher.SECRET_KEY:
|
||||
result = constructSecretKey(encodedKey,
|
||||
wrappedKeyAlgorithm);
|
||||
break;
|
||||
case Cipher.PRIVATE_KEY:
|
||||
result = constructPrivateKey(encodedKey,
|
||||
wrappedKeyAlgorithm);
|
||||
break;
|
||||
case Cipher.PUBLIC_KEY:
|
||||
result = constructPublicKey(encodedKey,
|
||||
wrappedKeyAlgorithm);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a public key from its encoding.
|
||||
*
|
||||
* @param encodedKey the encoding of a public key.
|
||||
*
|
||||
* @param encodedKeyAlgorithm the algorithm the encodedKey is for.
|
||||
*
|
||||
* @return a public key constructed from the encodedKey.
|
||||
*/
|
||||
private final PublicKey constructPublicKey(byte[] encodedKey,
|
||||
String encodedKeyAlgorithm)
|
||||
throws InvalidKeyException, NoSuchAlgorithmException
|
||||
{
|
||||
PublicKey key = null;
|
||||
|
||||
try {
|
||||
KeyFactory keyFactory =
|
||||
KeyFactory.getInstance(encodedKeyAlgorithm,
|
||||
SunJCE.getInstance());
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
|
||||
key = keyFactory.generatePublic(keySpec);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
// Try to see whether there is another
|
||||
// provider which supports this algorithm
|
||||
try {
|
||||
KeyFactory keyFactory =
|
||||
KeyFactory.getInstance(encodedKeyAlgorithm);
|
||||
X509EncodedKeySpec keySpec =
|
||||
new X509EncodedKeySpec(encodedKey);
|
||||
key = keyFactory.generatePublic(keySpec);
|
||||
} catch (NoSuchAlgorithmException nsae2) {
|
||||
throw new NoSuchAlgorithmException("No installed providers " +
|
||||
"can create keys for the " +
|
||||
encodedKeyAlgorithm +
|
||||
"algorithm");
|
||||
} catch (InvalidKeySpecException ikse2) {
|
||||
// Should never happen.
|
||||
}
|
||||
} catch (InvalidKeySpecException ikse) {
|
||||
// Should never happen.
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a private key from its encoding.
|
||||
*
|
||||
* @param encodedKey the encoding of a private key.
|
||||
*
|
||||
* @param encodedKeyAlgorithm the algorithm the wrapped key is for.
|
||||
*
|
||||
* @return a private key constructed from the encodedKey.
|
||||
*/
|
||||
private final PrivateKey constructPrivateKey(byte[] encodedKey,
|
||||
String encodedKeyAlgorithm)
|
||||
throws InvalidKeyException, NoSuchAlgorithmException
|
||||
{
|
||||
PrivateKey key = null;
|
||||
|
||||
try {
|
||||
KeyFactory keyFactory =
|
||||
KeyFactory.getInstance(encodedKeyAlgorithm,
|
||||
SunJCE.getInstance());
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
|
||||
return keyFactory.generatePrivate(keySpec);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
// Try to see whether there is another
|
||||
// provider which supports this algorithm
|
||||
try {
|
||||
KeyFactory keyFactory =
|
||||
KeyFactory.getInstance(encodedKeyAlgorithm);
|
||||
PKCS8EncodedKeySpec keySpec =
|
||||
new PKCS8EncodedKeySpec(encodedKey);
|
||||
key = keyFactory.generatePrivate(keySpec);
|
||||
} catch (NoSuchAlgorithmException nsae2) {
|
||||
throw new NoSuchAlgorithmException("No installed providers " +
|
||||
"can create keys for the " +
|
||||
encodedKeyAlgorithm +
|
||||
"algorithm");
|
||||
} catch (InvalidKeySpecException ikse2) {
|
||||
// Should never happen.
|
||||
}
|
||||
} catch (InvalidKeySpecException ikse) {
|
||||
// Should never happen.
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a secret key from its encoding.
|
||||
*
|
||||
* @param encodedKey the encoding of a secret key.
|
||||
*
|
||||
* @param encodedKeyAlgorithm the algorithm the secret key is for.
|
||||
*
|
||||
* @return a secret key constructed from the encodedKey.
|
||||
*/
|
||||
private final SecretKey constructSecretKey(byte[] encodedKey,
|
||||
String encodedKeyAlgorithm)
|
||||
{
|
||||
return (new SecretKeySpec(encodedKey, encodedKeyAlgorithm));
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2021, 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,8 @@
|
|||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
|
||||
import java.security.Key;
|
||||
import java.security.PublicKey;
|
||||
import java.security.PrivateKey;
|
||||
|
@ -113,12 +115,11 @@ final class ConstructKeys {
|
|||
throws InvalidKeyException, NoSuchAlgorithmException
|
||||
{
|
||||
PrivateKey key = null;
|
||||
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
|
||||
try {
|
||||
KeyFactory keyFactory =
|
||||
KeyFactory.getInstance(encodedKeyAlgorithm,
|
||||
SunJCE.getInstance());
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
|
||||
return keyFactory.generatePrivate(keySpec);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
// Try to see whether there is another
|
||||
|
@ -126,8 +127,6 @@ final class ConstructKeys {
|
|||
try {
|
||||
KeyFactory keyFactory =
|
||||
KeyFactory.getInstance(encodedKeyAlgorithm);
|
||||
PKCS8EncodedKeySpec keySpec =
|
||||
new PKCS8EncodedKeySpec(encodedKey);
|
||||
key = keyFactory.generatePrivate(keySpec);
|
||||
} catch (NoSuchAlgorithmException nsae2) {
|
||||
throw new NoSuchAlgorithmException("No installed providers " +
|
||||
|
@ -145,6 +144,8 @@ final class ConstructKeys {
|
|||
new InvalidKeyException("Cannot construct private key");
|
||||
ike.initCause(ikse);
|
||||
throw ike;
|
||||
} finally {
|
||||
SharedSecrets.getJavaSecuritySpecAccess().clearEncodedKeySpec(keySpec);
|
||||
}
|
||||
|
||||
return key;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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 @@ package com.sun.crypto.provider;
|
|||
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import javax.crypto.BadPaddingException;
|
||||
|
@ -369,6 +370,7 @@ public final class DESCipher extends CipherSpi {
|
|||
*/
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
byte[] encoded = key.getEncoded();
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
if (encoded.length != 8) {
|
||||
throw new InvalidKeyException("Invalid key length: " +
|
||||
encoded.length + " bytes");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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
|
||||
|
@ -158,6 +158,6 @@ final class DESKey implements SecretKey {
|
|||
return new KeyRep(KeyRep.Type.SECRET,
|
||||
getAlgorithm(),
|
||||
getFormat(),
|
||||
getEncoded());
|
||||
key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import javax.crypto.spec.DESKeySpec;
|
|||
import java.security.InvalidKeyException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
|
@ -63,17 +64,20 @@ public final class DESKeyFactory extends SecretKeyFactorySpi {
|
|||
throws InvalidKeySpecException {
|
||||
|
||||
try {
|
||||
byte[] encoded;
|
||||
if (keySpec instanceof DESKeySpec) {
|
||||
return new DESKey(((DESKeySpec)keySpec).getKey());
|
||||
encoded = ((DESKeySpec)keySpec).getKey();
|
||||
} else if (keySpec instanceof SecretKeySpec) {
|
||||
encoded = ((SecretKeySpec)keySpec).getEncoded();
|
||||
} else {
|
||||
throw new InvalidKeySpecException(
|
||||
"Inappropriate key specification");
|
||||
}
|
||||
|
||||
if (keySpec instanceof SecretKeySpec) {
|
||||
return new DESKey(((SecretKeySpec)keySpec).getEncoded());
|
||||
try {
|
||||
return new DESKey(encoded);
|
||||
} finally {
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
}
|
||||
|
||||
throw new InvalidKeySpecException(
|
||||
"Inappropriate key specification");
|
||||
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new InvalidKeySpecException(e.getMessage());
|
||||
}
|
||||
|
@ -106,9 +110,15 @@ public final class DESKeyFactory extends SecretKeyFactorySpi {
|
|||
|
||||
// Check if requested key spec is amongst the valid ones
|
||||
if ((keySpec != null) &&
|
||||
keySpec.isAssignableFrom(DESKeySpec.class)) {
|
||||
return new DESKeySpec(key.getEncoded());
|
||||
|
||||
keySpec.isAssignableFrom(DESKeySpec.class)) {
|
||||
byte[] encoded = key.getEncoded();
|
||||
try {
|
||||
return new DESKeySpec(encoded);
|
||||
} finally {
|
||||
if (encoded != null) {
|
||||
Arrays.fill(encoded, (byte) 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new InvalidKeySpecException
|
||||
("Inappropriate key specification");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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
|
||||
|
@ -30,6 +30,7 @@ import java.security.InvalidParameterException;
|
|||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.KeyGeneratorSpi;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
|
@ -112,6 +113,7 @@ public final class DESKeyGenerator extends KeyGeneratorSpi {
|
|||
setParityBit(key, 0);
|
||||
} while (DESKeySpec.isWeak(key, 0));
|
||||
desKey = new DESKey(key);
|
||||
Arrays.fill(key, (byte)0);
|
||||
} catch (InvalidKeyException e) {
|
||||
// this is never thrown
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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 @@ package com.sun.crypto.provider;
|
|||
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
|
@ -366,6 +367,7 @@ public final class DESedeCipher extends CipherSpi {
|
|||
*/
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
byte[] encoded = key.getEncoded();
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
if (encoded.length != 24) {
|
||||
throw new InvalidKeyException("Invalid key length: " +
|
||||
encoded.length + " bytes");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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
|
||||
|
@ -156,8 +156,8 @@ final class DESedeKey implements SecretKey {
|
|||
@java.io.Serial
|
||||
private Object writeReplace() throws java.io.ObjectStreamException {
|
||||
return new KeyRep(KeyRep.Type.SECRET,
|
||||
getAlgorithm(),
|
||||
getFormat(),
|
||||
getEncoded());
|
||||
getAlgorithm(),
|
||||
getFormat(),
|
||||
key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import javax.crypto.spec.DESedeKeySpec;
|
|||
import java.security.InvalidKeyException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
|
@ -63,15 +64,20 @@ public final class DESedeKeyFactory extends SecretKeyFactorySpi {
|
|||
throws InvalidKeySpecException {
|
||||
|
||||
try {
|
||||
byte[] encoded;
|
||||
if (keySpec instanceof DESedeKeySpec) {
|
||||
return new DESedeKey(((DESedeKeySpec)keySpec).getKey());
|
||||
encoded = ((DESedeKeySpec)keySpec).getKey();
|
||||
} else if (keySpec instanceof SecretKeySpec) {
|
||||
encoded = ((SecretKeySpec)keySpec).getEncoded();
|
||||
} else {
|
||||
throw new InvalidKeySpecException
|
||||
("Inappropriate key specification");
|
||||
}
|
||||
if (keySpec instanceof SecretKeySpec) {
|
||||
return new DESedeKey(((SecretKeySpec)keySpec).getEncoded());
|
||||
|
||||
try {
|
||||
return new DESedeKey(encoded);
|
||||
} finally {
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
}
|
||||
throw new InvalidKeySpecException
|
||||
("Inappropriate key specification");
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new InvalidKeySpecException(e.getMessage());
|
||||
}
|
||||
|
@ -103,8 +109,14 @@ public final class DESedeKeyFactory extends SecretKeyFactorySpi {
|
|||
|
||||
// Check if requested key spec is amongst the valid ones
|
||||
if (keySpec.isAssignableFrom(DESedeKeySpec.class)) {
|
||||
return new DESedeKeySpec(key.getEncoded());
|
||||
|
||||
byte[] encoded = key.getEncoded();
|
||||
try {
|
||||
return new DESedeKeySpec(encoded);
|
||||
} finally {
|
||||
if (encoded != null) {
|
||||
Arrays.fill(encoded, (byte) 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new InvalidKeySpecException
|
||||
("Inappropriate key specification");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2021, 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 @@ package com.sun.crypto.provider;
|
|||
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
|
@ -241,8 +242,14 @@ public final class DESedeWrapCipher extends CipherSpi {
|
|||
throw new UnsupportedOperationException("This cipher can " +
|
||||
"only be used for key wrapping and unwrapping");
|
||||
}
|
||||
cipher.init(decrypting, key.getAlgorithm(), key.getEncoded(),
|
||||
currIv);
|
||||
byte[] encoded = key.getEncoded();
|
||||
try {
|
||||
cipher.init(decrypting, key.getAlgorithm(), encoded, currIv);
|
||||
} finally {
|
||||
if (encoded != null) {
|
||||
Arrays.fill(encoded, (byte) 0);
|
||||
}
|
||||
}
|
||||
cipherKey = key;
|
||||
}
|
||||
|
||||
|
@ -416,6 +423,7 @@ public final class DESedeWrapCipher extends CipherSpi {
|
|||
*/
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
byte[] encoded = key.getEncoded();
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
if (encoded.length != 24) {
|
||||
throw new InvalidKeyException("Invalid key length: " +
|
||||
encoded.length + " bytes");
|
||||
|
@ -448,47 +456,57 @@ public final class DESedeWrapCipher extends CipherSpi {
|
|||
"the key to be wrapped");
|
||||
}
|
||||
|
||||
byte[] cks = getChecksum(keyVal);
|
||||
byte[] in = new byte[Math.addExact(keyVal.length, CHECKSUM_LEN)];
|
||||
System.arraycopy(keyVal, 0, in, 0, keyVal.length);
|
||||
System.arraycopy(cks, 0, in, keyVal.length, CHECKSUM_LEN);
|
||||
|
||||
byte[] cipherKeyEncoded = cipherKey.getEncoded();
|
||||
byte[] out = new byte[Math.addExact(iv.length, in.length)];
|
||||
System.arraycopy(iv, 0, out, 0, iv.length);
|
||||
|
||||
cipher.encrypt(in, 0, in.length, out, iv.length);
|
||||
|
||||
// reverse the array content
|
||||
for (int i = 0; i < out.length/2; i++) {
|
||||
byte temp = out[i];
|
||||
out[i] = out[out.length-1-i];
|
||||
out[out.length-1-i] = temp;
|
||||
}
|
||||
try {
|
||||
cipher.init(false, cipherKey.getAlgorithm(),
|
||||
cipherKey.getEncoded(), IV2);
|
||||
} catch (InvalidKeyException ike) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Internal cipher key is corrupted");
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Internal cipher IV is invalid");
|
||||
}
|
||||
byte[] out2 = new byte[out.length];
|
||||
cipher.encrypt(out, 0, out.length, out2, 0);
|
||||
byte[] cks = getChecksum(keyVal);
|
||||
System.arraycopy(keyVal, 0, in, 0, keyVal.length);
|
||||
System.arraycopy(cks, 0, in, keyVal.length, CHECKSUM_LEN);
|
||||
|
||||
// restore cipher state to prior to this call
|
||||
try {
|
||||
cipher.init(decrypting, cipherKey.getAlgorithm(),
|
||||
cipherKey.getEncoded(), iv);
|
||||
} catch (InvalidKeyException ike) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Internal cipher key is corrupted");
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Internal cipher IV is invalid");
|
||||
System.arraycopy(iv, 0, out, 0, iv.length);
|
||||
|
||||
cipher.encrypt(in, 0, in.length, out, iv.length);
|
||||
|
||||
// reverse the array content
|
||||
for (int i = 0; i < out.length / 2; i++) {
|
||||
byte temp = out[i];
|
||||
out[i] = out[out.length - 1 - i];
|
||||
out[out.length - 1 - i] = temp;
|
||||
}
|
||||
try {
|
||||
cipher.init(false, cipherKey.getAlgorithm(),
|
||||
cipherKeyEncoded, IV2);
|
||||
} catch (InvalidKeyException ike) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Internal cipher key is corrupted");
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Internal cipher IV is invalid");
|
||||
}
|
||||
byte[] out2 = new byte[out.length];
|
||||
cipher.encrypt(out, 0, out.length, out2, 0);
|
||||
|
||||
// restore cipher state to prior to this call
|
||||
try {
|
||||
cipher.init(decrypting, cipherKey.getAlgorithm(),
|
||||
cipherKeyEncoded, iv);
|
||||
} catch (InvalidKeyException ike) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Internal cipher key is corrupted");
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Internal cipher IV is invalid");
|
||||
}
|
||||
return out2;
|
||||
} finally {
|
||||
Arrays.fill(keyVal, (byte)0);
|
||||
Arrays.fill(in, (byte)0);
|
||||
Arrays.fill(out, (byte)0);
|
||||
if (cipherKeyEncoded != null) {
|
||||
Arrays.fill(cipherKeyEncoded, (byte) 0);
|
||||
}
|
||||
}
|
||||
return out2;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -530,34 +548,46 @@ public final class DESedeWrapCipher extends CipherSpi {
|
|||
}
|
||||
iv = new byte[IV_LEN];
|
||||
System.arraycopy(buffer, 0, iv, 0, iv.length);
|
||||
try {
|
||||
cipher.init(true, cipherKey.getAlgorithm(), cipherKey.getEncoded(),
|
||||
iv);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new InvalidKeyException("IV in wrapped key is invalid");
|
||||
}
|
||||
byte[] cipherKeyEncoded = cipherKey.getEncoded();
|
||||
byte[] out = null;
|
||||
byte[] buffer2 = new byte[buffer.length - iv.length];
|
||||
cipher.decrypt(buffer, iv.length, buffer2.length,
|
||||
buffer2, 0);
|
||||
int keyValLen = buffer2.length - CHECKSUM_LEN;
|
||||
byte[] cks = getChecksum(buffer2, 0, keyValLen);
|
||||
int offset = keyValLen;
|
||||
for (int i = 0; i < CHECKSUM_LEN; i++) {
|
||||
if (buffer2[offset + i] != cks[i]) {
|
||||
throw new InvalidKeyException("Checksum comparison failed");
|
||||
}
|
||||
}
|
||||
// restore cipher state to prior to this call
|
||||
try {
|
||||
cipher.init(decrypting, cipherKey.getAlgorithm(),
|
||||
cipherKey.getEncoded(), IV2);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new InvalidKeyException("IV in wrapped key is invalid");
|
||||
try {
|
||||
cipher.init(true, cipherKey.getAlgorithm(), cipherKeyEncoded,
|
||||
iv);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new InvalidKeyException("IV in wrapped key is invalid");
|
||||
}
|
||||
cipher.decrypt(buffer, iv.length, buffer2.length,
|
||||
buffer2, 0);
|
||||
int keyValLen = buffer2.length - CHECKSUM_LEN;
|
||||
byte[] cks = getChecksum(buffer2, 0, keyValLen);
|
||||
int offset = keyValLen;
|
||||
for (int i = 0; i < CHECKSUM_LEN; i++) {
|
||||
if (buffer2[offset + i] != cks[i]) {
|
||||
throw new InvalidKeyException("Checksum comparison failed");
|
||||
}
|
||||
}
|
||||
// restore cipher state to prior to this call
|
||||
try {
|
||||
cipher.init(decrypting, cipherKey.getAlgorithm(),
|
||||
cipherKeyEncoded, IV2);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new InvalidKeyException("IV in wrapped key is invalid");
|
||||
}
|
||||
out = new byte[keyValLen];
|
||||
System.arraycopy(buffer2, 0, out, 0, keyValLen);
|
||||
return ConstructKeys.constructKey(out, wrappedKeyAlgorithm,
|
||||
wrappedKeyType);
|
||||
} finally {
|
||||
if (out != null) {
|
||||
Arrays.fill(out, (byte)0);
|
||||
}
|
||||
if (cipherKeyEncoded != null) {
|
||||
Arrays.fill(cipherKeyEncoded, (byte) 0);
|
||||
}
|
||||
Arrays.fill(buffer2, (byte)0);
|
||||
}
|
||||
byte[] out = new byte[keyValLen];
|
||||
System.arraycopy(buffer2, 0, out, 0, keyValLen);
|
||||
return ConstructKeys.constructKey(out, wrappedKeyAlgorithm,
|
||||
wrappedKeyType);
|
||||
}
|
||||
|
||||
private static final byte[] getChecksum(byte[] in) {
|
||||
|
@ -573,6 +603,7 @@ public final class DESedeWrapCipher extends CipherSpi {
|
|||
md.update(in, offset, len);
|
||||
byte[] cks = new byte[CHECKSUM_LEN];
|
||||
System.arraycopy(md.digest(), 0, cks, 0, cks.length);
|
||||
md.reset();
|
||||
return cks;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.security.spec.KeySpec;
|
|||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.spec.DHPublicKeySpec;
|
||||
import javax.crypto.spec.DHPrivateKeySpec;
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
|
@ -99,8 +100,7 @@ public final class DHKeyFactory extends KeyFactorySpi {
|
|||
* is inappropriate for this key factory to produce a private key.
|
||||
*/
|
||||
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
|
||||
throws InvalidKeySpecException
|
||||
{
|
||||
throws InvalidKeySpecException {
|
||||
try {
|
||||
if (keySpec instanceof DHPrivateKeySpec) {
|
||||
DHPrivateKeySpec dhPrivKeySpec = (DHPrivateKeySpec)keySpec;
|
||||
|
@ -109,9 +109,12 @@ public final class DHKeyFactory extends KeyFactorySpi {
|
|||
dhPrivKeySpec.getG());
|
||||
|
||||
} else if (keySpec instanceof PKCS8EncodedKeySpec) {
|
||||
return new DHPrivateKey
|
||||
(((PKCS8EncodedKeySpec)keySpec).getEncoded());
|
||||
|
||||
byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
|
||||
try {
|
||||
return new DHPrivateKey(encoded);
|
||||
} finally {
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidKeySpecException
|
||||
("Inappropriate key specification");
|
||||
|
@ -172,8 +175,12 @@ public final class DHKeyFactory extends KeyFactorySpi {
|
|||
params.getG()));
|
||||
|
||||
} else if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class)) {
|
||||
return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded()));
|
||||
|
||||
byte[] encoded = key.getEncoded();
|
||||
try {
|
||||
return keySpec.cast(new PKCS8EncodedKeySpec(encoded));
|
||||
} finally {
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidKeySpecException
|
||||
("Inappropriate key specification");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyRep;
|
||||
|
@ -46,7 +47,7 @@ import sun.security.util.*;
|
|||
* @see java.security.KeyAgreement
|
||||
*/
|
||||
final class DHPrivateKey implements PrivateKey,
|
||||
javax.crypto.interfaces.DHPrivateKey, Serializable {
|
||||
javax.crypto.interfaces.DHPrivateKey, Serializable {
|
||||
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 7565477590005668886L;
|
||||
|
@ -105,9 +106,12 @@ javax.crypto.interfaces.DHPrivateKey, Serializable {
|
|||
this.g = g;
|
||||
this.l = l;
|
||||
try {
|
||||
this.key = new DerValue(DerValue.tag_Integer,
|
||||
this.x.toByteArray()).toByteArray();
|
||||
this.encodedKey = getEncoded();
|
||||
byte[] xbytes = x.toByteArray();
|
||||
DerValue val = new DerValue(DerValue.tag_Integer, xbytes);
|
||||
this.key = val.toByteArray();
|
||||
val.clear();
|
||||
Arrays.fill(xbytes, (byte)0);
|
||||
encode();
|
||||
} catch (IOException e) {
|
||||
throw new ProviderException("Cannot produce ASN.1 encoding", e);
|
||||
}
|
||||
|
@ -122,9 +126,9 @@ javax.crypto.interfaces.DHPrivateKey, Serializable {
|
|||
* a Diffie-Hellman private key
|
||||
*/
|
||||
DHPrivateKey(byte[] encodedKey) throws InvalidKeyException {
|
||||
InputStream inStream = new ByteArrayInputStream(encodedKey);
|
||||
DerValue val = null;
|
||||
try {
|
||||
DerValue val = new DerValue(inStream);
|
||||
val = new DerValue(encodedKey);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new InvalidKeyException ("Key not a SEQUENCE");
|
||||
}
|
||||
|
@ -182,6 +186,10 @@ javax.crypto.interfaces.DHPrivateKey, Serializable {
|
|||
this.encodedKey = encodedKey.clone();
|
||||
} catch (IOException | NumberFormatException e) {
|
||||
throw new InvalidKeyException("Error parsing key encoding", e);
|
||||
} finally {
|
||||
if (val != null) {
|
||||
val.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,6 +211,15 @@ javax.crypto.interfaces.DHPrivateKey, Serializable {
|
|||
* Get the encoding of the key.
|
||||
*/
|
||||
public synchronized byte[] getEncoded() {
|
||||
encode();
|
||||
return encodedKey.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the encodedKey field if it has not been calculated.
|
||||
* Could generate null.
|
||||
*/
|
||||
private void encode() {
|
||||
if (this.encodedKey == null) {
|
||||
try {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
@ -238,14 +255,13 @@ javax.crypto.interfaces.DHPrivateKey, Serializable {
|
|||
tmp.putOctetString(this.key);
|
||||
|
||||
// make it a SEQUENCE
|
||||
DerOutputStream derKey = new DerOutputStream();
|
||||
derKey.write(DerValue.tag_Sequence, tmp);
|
||||
this.encodedKey = derKey.toByteArray();
|
||||
DerValue val = DerValue.wrap(DerValue.tag_Sequence, tmp);
|
||||
this.encodedKey = val.toByteArray();
|
||||
val.clear();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
return this.encodedKey.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -314,9 +330,10 @@ javax.crypto.interfaces.DHPrivateKey, Serializable {
|
|||
*/
|
||||
@java.io.Serial
|
||||
private Object writeReplace() throws java.io.ObjectStreamException {
|
||||
encode();
|
||||
return new KeyRep(KeyRep.Type.PRIVATE,
|
||||
getAlgorithm(),
|
||||
getFormat(),
|
||||
getEncoded());
|
||||
getAlgorithm(),
|
||||
getFormat(),
|
||||
encodedKey);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2021, 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
|
||||
|
@ -29,6 +29,7 @@ import java.security.SecureRandom;
|
|||
import java.security.InvalidParameterException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.KeyGeneratorSpi;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
@ -104,6 +105,10 @@ public final class HmacMD5KeyGenerator extends KeyGeneratorSpi {
|
|||
byte[] keyBytes = new byte[this.keysize];
|
||||
this.random.nextBytes(keyBytes);
|
||||
|
||||
return new SecretKeySpec(keyBytes, "HmacMD5");
|
||||
try {
|
||||
return new SecretKeySpec(keyBytes, "HmacMD5");
|
||||
} finally {
|
||||
Arrays.fill(keyBytes, (byte)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2021, 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
|
||||
|
@ -29,6 +29,7 @@ import java.security.SecureRandom;
|
|||
import java.security.InvalidParameterException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.KeyGeneratorSpi;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
@ -103,7 +104,10 @@ public final class HmacSHA1KeyGenerator extends KeyGeneratorSpi {
|
|||
|
||||
byte[] keyBytes = new byte[this.keysize];
|
||||
this.random.nextBytes(keyBytes);
|
||||
|
||||
return new SecretKeySpec(keyBytes, "HmacSHA1");
|
||||
try {
|
||||
return new SecretKeySpec(keyBytes, "HmacSHA1");
|
||||
} finally {
|
||||
Arrays.fill(keyBytes, (byte)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, 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 @@ package com.sun.crypto.provider;
|
|||
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
@ -102,7 +103,11 @@ final class KeyGeneratorCore {
|
|||
}
|
||||
byte[] b = new byte[(keySize + 7) >> 3];
|
||||
random.nextBytes(b);
|
||||
return new SecretKeySpec(b, name);
|
||||
try {
|
||||
return new SecretKeySpec(b, name);
|
||||
} finally {
|
||||
Arrays.fill(b, (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
// nested static classes for the Hmac key generator
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2021, 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
|
||||
|
@ -46,6 +46,7 @@ import javax.crypto.SealedObject;
|
|||
import javax.crypto.spec.*;
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.security.x509.AlgorithmId;
|
||||
import sun.security.util.ObjectIdentifier;
|
||||
import sun.security.util.KnownOIDs;
|
||||
|
@ -201,10 +202,17 @@ final class KeyProtector {
|
|||
|
||||
// determine the private-key algorithm, and parse private key
|
||||
// using the appropriate key factory
|
||||
PrivateKeyInfo privateKeyInfo = new PrivateKeyInfo(plain);
|
||||
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(plain);
|
||||
String oidName = new AlgorithmId
|
||||
(new PrivateKeyInfo(plain).getAlgorithm().getOID()).getName();
|
||||
KeyFactory kFac = KeyFactory.getInstance(oidName);
|
||||
return kFac.generatePrivate(new PKCS8EncodedKeySpec(plain));
|
||||
(privateKeyInfo.getAlgorithm().getOID()).getName();
|
||||
try {
|
||||
KeyFactory kFac = KeyFactory.getInstance(oidName);
|
||||
return kFac.generatePrivate(spec);
|
||||
} finally {
|
||||
privateKeyInfo.clear();
|
||||
SharedSecrets.getJavaSecuritySpecAccess().clearEncodedKeySpec(spec);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
// Note: this catch needed to be here because of the
|
||||
// later catch of GeneralSecurityException
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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
|
||||
|
@ -167,8 +167,8 @@ final class PBEKey implements SecretKey {
|
|||
@java.io.Serial
|
||||
private Object writeReplace() throws java.io.ObjectStreamException {
|
||||
return new KeyRep(KeyRep.Type.SECRET,
|
||||
getAlgorithm(),
|
||||
getFormat(),
|
||||
getEncoded());
|
||||
getAlgorithm(),
|
||||
getFormat(),
|
||||
key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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
|
||||
|
@ -292,8 +292,12 @@ abstract class PBEKeyFactory extends SecretKeyFactorySpi {
|
|||
PBEKeySpec pbeKeySpec = (PBEKeySpec)engineGetKeySpec
|
||||
(key, PBEKeySpec.class);
|
||||
|
||||
// Create key from spec, and return it
|
||||
return engineGenerateSecret(pbeKeySpec);
|
||||
try {
|
||||
// Create key from spec, and return it
|
||||
return engineGenerateSecret(pbeKeySpec);
|
||||
} finally {
|
||||
pbeKeySpec.clearPassword();
|
||||
}
|
||||
} else {
|
||||
throw new InvalidKeyException("Invalid key format/algorithm");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2021, 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
|
||||
|
@ -537,9 +537,14 @@ final class PBES1Core {
|
|||
String wrappedKeyAlgorithm,
|
||||
int wrappedKeyType)
|
||||
throws InvalidKeyException, NoSuchAlgorithmException {
|
||||
byte[] encodedKey;
|
||||
try {
|
||||
encodedKey = doFinal(wrappedKey, 0, wrappedKey.length);
|
||||
byte[] encodedKey = doFinal(wrappedKey, 0, wrappedKey.length);
|
||||
try {
|
||||
return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
|
||||
wrappedKeyType);
|
||||
} finally {
|
||||
Arrays.fill(encodedKey, (byte)0);
|
||||
}
|
||||
} catch (BadPaddingException ePadding) {
|
||||
throw new InvalidKeyException("The wrapped key is not padded " +
|
||||
"correctly");
|
||||
|
@ -547,7 +552,5 @@ final class PBES1Core {
|
|||
throw new InvalidKeyException("The wrapped key does not have " +
|
||||
"the correct length");
|
||||
}
|
||||
return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
|
||||
wrappedKeyType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2021, 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
|
||||
|
@ -274,18 +274,20 @@ abstract class PBES2Core extends CipherSpi {
|
|||
if (passwdBytes != null) Arrays.fill(passwdBytes, (byte)0x00);
|
||||
}
|
||||
|
||||
SecretKey s = null;
|
||||
PBKDF2KeyImpl s;
|
||||
|
||||
try {
|
||||
s = kdf.engineGenerateSecret(pbeSpec);
|
||||
|
||||
s = (PBKDF2KeyImpl)kdf.engineGenerateSecret(pbeSpec);
|
||||
} catch (InvalidKeySpecException ikse) {
|
||||
InvalidKeyException ike =
|
||||
new InvalidKeyException("Cannot construct PBE key");
|
||||
ike.initCause(ikse);
|
||||
throw ike;
|
||||
} finally {
|
||||
pbeSpec.clearPassword();
|
||||
}
|
||||
byte[] derivedKey = s.getEncoded();
|
||||
s.clearPassword();
|
||||
SecretKeySpec cipherKey = new SecretKeySpec(derivedKey, cipherAlgo);
|
||||
|
||||
// initialize the underlying cipher
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, 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
|
||||
|
@ -28,6 +28,7 @@ package com.sun.crypto.provider;
|
|||
import java.security.InvalidKeyException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactorySpi;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
|
@ -94,9 +95,17 @@ abstract class PBKDF2Core extends SecretKeyFactorySpi {
|
|||
&& PBEKeySpec.class.isAssignableFrom(keySpecCl)) {
|
||||
javax.crypto.interfaces.PBEKey pKey =
|
||||
(javax.crypto.interfaces.PBEKey) key;
|
||||
return new PBEKeySpec
|
||||
(pKey.getPassword(), pKey.getSalt(),
|
||||
pKey.getIterationCount(), pKey.getEncoded().length*8);
|
||||
char[] passwd = pKey.getPassword();
|
||||
byte[] encoded = pKey.getEncoded();
|
||||
try {
|
||||
return new PBEKeySpec(passwd, pKey.getSalt(),
|
||||
pKey.getIterationCount(), encoded.length * 8);
|
||||
} finally {
|
||||
if (passwd != null) {
|
||||
Arrays.fill(passwd, (char) 0);
|
||||
}
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidKeySpecException("Invalid key spec");
|
||||
}
|
||||
|
@ -132,18 +141,26 @@ abstract class PBKDF2Core extends SecretKeyFactorySpi {
|
|||
if (key instanceof javax.crypto.interfaces.PBEKey) {
|
||||
javax.crypto.interfaces.PBEKey pKey =
|
||||
(javax.crypto.interfaces.PBEKey) key;
|
||||
char[] password = pKey.getPassword();
|
||||
byte[] encoding = pKey.getEncoded();
|
||||
PBEKeySpec spec =
|
||||
new PBEKeySpec(password,
|
||||
pKey.getSalt(),
|
||||
pKey.getIterationCount(),
|
||||
encoding.length*8);
|
||||
try {
|
||||
PBEKeySpec spec =
|
||||
new PBEKeySpec(pKey.getPassword(),
|
||||
pKey.getSalt(),
|
||||
pKey.getIterationCount(),
|
||||
pKey.getEncoded().length*8);
|
||||
return new PBKDF2KeyImpl(spec, prfAlgo);
|
||||
} catch (InvalidKeySpecException re) {
|
||||
InvalidKeyException ike = new InvalidKeyException
|
||||
("Invalid key component(s)");
|
||||
ike.initCause(re);
|
||||
throw ike;
|
||||
} finally {
|
||||
if (password != null) {
|
||||
Arrays.fill(password, (char) 0);
|
||||
spec.clearPassword();
|
||||
}
|
||||
Arrays.fill(encoding, (byte)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, 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
|
||||
|
@ -28,6 +28,7 @@ package com.sun.crypto.provider;
|
|||
import java.security.InvalidKeyException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactorySpi;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
|
@ -94,9 +95,17 @@ public final class PBKDF2HmacSHA1Factory extends SecretKeyFactorySpi {
|
|||
&& PBEKeySpec.class.isAssignableFrom(keySpecCl)) {
|
||||
javax.crypto.interfaces.PBEKey pKey =
|
||||
(javax.crypto.interfaces.PBEKey) key;
|
||||
return new PBEKeySpec
|
||||
(pKey.getPassword(), pKey.getSalt(),
|
||||
pKey.getIterationCount(), pKey.getEncoded().length*8);
|
||||
char[] passwd = pKey.getPassword();
|
||||
byte[] encoded = pKey.getEncoded();
|
||||
try {
|
||||
return new PBEKeySpec(passwd, pKey.getSalt(),
|
||||
pKey.getIterationCount(), encoded.length * 8);
|
||||
} finally {
|
||||
if (passwd != null) {
|
||||
Arrays.fill(passwd, (char) 0);
|
||||
}
|
||||
Arrays.fill(encoded, (byte)0);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidKeySpecException("Invalid key spec");
|
||||
}
|
||||
|
@ -132,18 +141,26 @@ public final class PBKDF2HmacSHA1Factory extends SecretKeyFactorySpi {
|
|||
if (key instanceof javax.crypto.interfaces.PBEKey) {
|
||||
javax.crypto.interfaces.PBEKey pKey =
|
||||
(javax.crypto.interfaces.PBEKey) key;
|
||||
char[] password = pKey.getPassword();
|
||||
byte[] encoding = pKey.getEncoded();
|
||||
PBEKeySpec spec =
|
||||
new PBEKeySpec(password,
|
||||
pKey.getSalt(),
|
||||
pKey.getIterationCount(),
|
||||
encoding.length*8);
|
||||
try {
|
||||
PBEKeySpec spec =
|
||||
new PBEKeySpec(pKey.getPassword(),
|
||||
pKey.getSalt(),
|
||||
pKey.getIterationCount(),
|
||||
pKey.getEncoded().length*8);
|
||||
return new PBKDF2KeyImpl(spec, "HmacSHA1");
|
||||
} catch (InvalidKeySpecException re) {
|
||||
InvalidKeyException ike = new InvalidKeyException
|
||||
("Invalid key component(s)");
|
||||
ike.initCause(re);
|
||||
throw ike;
|
||||
} finally {
|
||||
if (password != null) {
|
||||
Arrays.fill(password, (char) 0);
|
||||
spec.clearPassword();
|
||||
}
|
||||
Arrays.fill(encoding, (byte)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, 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
|
||||
|
@ -73,6 +73,7 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
|
|||
int len = bb.limit();
|
||||
byte[] passwdBytes = new byte[len];
|
||||
bb.get(passwdBytes, 0, len);
|
||||
bb.clear().put(new byte[len]);
|
||||
|
||||
return passwdBytes;
|
||||
}
|
||||
|
@ -159,7 +160,7 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
|
|||
}
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return password;
|
||||
return password.clone();
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
@ -225,6 +226,10 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
|
|||
return iterCount;
|
||||
}
|
||||
|
||||
public void clearPassword() {
|
||||
Arrays.fill(passwd, (char)0);
|
||||
}
|
||||
|
||||
public char[] getPassword() {
|
||||
// The password is zeroized by finalize()
|
||||
// The reachability fence ensures finalize() isn't called early
|
||||
|
@ -282,7 +287,7 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
|
|||
*/
|
||||
@java.io.Serial
|
||||
private Object writeReplace() throws ObjectStreamException {
|
||||
return new KeyRep(KeyRep.Type.SECRET, getAlgorithm(),
|
||||
getFormat(), getEncoded());
|
||||
return new KeyRep(KeyRep.Type.SECRET, getAlgorithm(),
|
||||
getFormat(), key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, 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
|
||||
|
@ -174,18 +174,25 @@ abstract class PBMAC1Core extends HmacCore {
|
|||
Arrays.fill(passwdChars, '\0');
|
||||
}
|
||||
|
||||
SecretKey s;
|
||||
PBKDF2KeyImpl s = null;
|
||||
PBKDF2Core kdf = getKDFImpl(kdfAlgo);
|
||||
byte[] derivedKey;
|
||||
try {
|
||||
s = kdf.engineGenerateSecret(pbeSpec);
|
||||
s = (PBKDF2KeyImpl)kdf.engineGenerateSecret(pbeSpec);
|
||||
derivedKey = s.getEncoded();
|
||||
} catch (InvalidKeySpecException ikse) {
|
||||
InvalidKeyException ike =
|
||||
new InvalidKeyException("Cannot construct PBE key");
|
||||
ike.initCause(ikse);
|
||||
throw ike;
|
||||
} finally {
|
||||
pbeSpec.clearPassword();
|
||||
if (s != null) {
|
||||
s.clearPassword();
|
||||
}
|
||||
}
|
||||
byte[] derivedKey = s.getEncoded();
|
||||
SecretKey cipherKey = new SecretKeySpec(derivedKey, kdfAlgo);
|
||||
Arrays.fill(derivedKey, (byte)0);
|
||||
|
||||
super.engineInit(cipherKey, null);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, 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,12 +25,12 @@
|
|||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
|
||||
/**
|
||||
* This class implements password-base encryption algorithm with
|
||||
|
@ -108,7 +108,6 @@ final class PKCS12PBECipherCore {
|
|||
|
||||
byte[] Ai;
|
||||
byte[] B = new byte[v];
|
||||
byte[] tmp = new byte[v];
|
||||
|
||||
int i = 0;
|
||||
for (; ; i++, n -= u) {
|
||||
|
@ -118,37 +117,45 @@ final class PKCS12PBECipherCore {
|
|||
for (int r = 1; r < ic; r++)
|
||||
Ai = sha.digest(Ai);
|
||||
System.arraycopy(Ai, 0, key, u * i, Math.min(n, u));
|
||||
if (i + 1 == c)
|
||||
if (i + 1 == c) {
|
||||
break;
|
||||
concat(Ai, B, 0, B.length);
|
||||
BigInteger B1;
|
||||
B1 = new BigInteger(1, B).add(BigInteger.ONE);
|
||||
}
|
||||
concat(Ai, B, 0, v);
|
||||
addOne(v, B); // add 1 into B
|
||||
|
||||
for (int j = 0; j < I.length; j += v) {
|
||||
BigInteger Ij;
|
||||
int trunc;
|
||||
|
||||
if (tmp.length != v)
|
||||
tmp = new byte[v];
|
||||
System.arraycopy(I, j, tmp, 0, v);
|
||||
Ij = new BigInteger(1, tmp);
|
||||
Ij = Ij.add(B1);
|
||||
tmp = Ij.toByteArray();
|
||||
trunc = tmp.length - v;
|
||||
if (trunc >= 0) {
|
||||
System.arraycopy(tmp, trunc, I, j, v);
|
||||
} else if (trunc < 0) {
|
||||
Arrays.fill(I, j, j + (-trunc), (byte)0);
|
||||
System.arraycopy(tmp, 0, I, j + (-trunc), tmp.length);
|
||||
}
|
||||
addTwo(v, B, I, j); // add B into I from j
|
||||
}
|
||||
}
|
||||
Arrays.fill(I, (byte)0);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("internal error: " + e);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
// Add 1 to b (as integer)
|
||||
private static void addOne(int len, byte[] b) {
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
if ((b[i] & 0xff) != 255) {
|
||||
b[i]++;
|
||||
break;
|
||||
} else {
|
||||
b[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add src (as integer) to dst from offset (as integer)
|
||||
private static void addTwo(int len, byte[] src, byte[] dst, int offset) {
|
||||
int carry = 0;
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
int sum = (src[i] & 0xff) + (dst[i + offset] & 0xff) + carry;
|
||||
carry = sum >> 8;
|
||||
dst[i + offset] = (byte)sum;
|
||||
}
|
||||
}
|
||||
|
||||
private static int roundup(int x, int y) {
|
||||
return ((x + (y - 1)) / y) * y;
|
||||
}
|
||||
|
@ -341,17 +348,26 @@ final class PKCS12PBECipherCore {
|
|||
byte[] derivedKey = derive(passwdChars, salt, iCount,
|
||||
keySize, CIPHER_KEY);
|
||||
SecretKey cipherKey = new SecretKeySpec(derivedKey, algo);
|
||||
Arrays.fill(derivedKey, (byte)0);
|
||||
|
||||
if (cipherImpl != null && cipherImpl instanceof ARCFOURCipher) {
|
||||
((ARCFOURCipher)cipherImpl).engineInit(opmode, cipherKey, random);
|
||||
try {
|
||||
if (cipherImpl != null && cipherImpl instanceof ARCFOURCipher) {
|
||||
((ARCFOURCipher) cipherImpl).engineInit(opmode, cipherKey, random);
|
||||
|
||||
} else {
|
||||
byte[] derivedIv = derive(passwdChars, salt, iCount, 8,
|
||||
CIPHER_IV);
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(derivedIv, 0, 8);
|
||||
} else {
|
||||
byte[] derivedIv = derive(passwdChars, salt, iCount, 8,
|
||||
CIPHER_IV);
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(derivedIv, 0, 8);
|
||||
|
||||
// initialize the underlying cipher
|
||||
cipher.init(opmode, cipherKey, ivSpec, random);
|
||||
// initialize the underlying cipher
|
||||
cipher.init(opmode, cipherKey, ivSpec, random);
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
cipherKey.destroy();
|
||||
} catch (DestroyFailedException e) {
|
||||
// Ignore the failure
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Arrays.fill(passwdChars, '\0');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2021, 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,8 @@ package com.sun.crypto.provider;
|
|||
|
||||
import java.math.*;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
import sun.security.x509.AlgorithmId;
|
||||
import sun.security.util.*;
|
||||
|
||||
|
@ -62,23 +64,27 @@ final class PrivateKeyInfo {
|
|||
PrivateKeyInfo(byte[] encoded) throws IOException {
|
||||
DerValue val = new DerValue(encoded);
|
||||
|
||||
if (val.tag != DerValue.tag_Sequence)
|
||||
throw new IOException("private key parse error: not a sequence");
|
||||
try {
|
||||
if (val.tag != DerValue.tag_Sequence)
|
||||
throw new IOException("private key parse error: not a sequence");
|
||||
|
||||
// version
|
||||
BigInteger parsedVersion = val.data.getBigInteger();
|
||||
if (!parsedVersion.equals(VERSION)) {
|
||||
throw new IOException("version mismatch: (supported: " +
|
||||
VERSION + ", parsed: " + parsedVersion);
|
||||
// version
|
||||
BigInteger parsedVersion = val.data.getBigInteger();
|
||||
if (!parsedVersion.equals(VERSION)) {
|
||||
throw new IOException("version mismatch: (supported: " +
|
||||
VERSION + ", parsed: " + parsedVersion);
|
||||
}
|
||||
|
||||
// privateKeyAlgorithm
|
||||
this.algid = AlgorithmId.parse(val.data.getDerValue());
|
||||
|
||||
// privateKey
|
||||
this.privkey = val.data.getOctetString();
|
||||
|
||||
// OPTIONAL attributes not supported yet
|
||||
} finally {
|
||||
val.clear();
|
||||
}
|
||||
|
||||
// privateKeyAlgorithm
|
||||
this.algid = AlgorithmId.parse(val.data.getDerValue());
|
||||
|
||||
// privateKey
|
||||
this.privkey = val.data.getOctetString();
|
||||
|
||||
// OPTIONAL attributes not supported yet
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,4 +93,8 @@ final class PrivateKeyInfo {
|
|||
AlgorithmId getAlgorithm() {
|
||||
return this.algid;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
Arrays.fill(privkey, (byte)0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, 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 @@ package com.sun.crypto.provider;
|
|||
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.RC2ParameterSpec;
|
||||
|
@ -133,6 +134,7 @@ public final class RC2Cipher extends CipherSpi {
|
|||
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
byte[] keyBytes = CipherCore.getKeyBytes(key);
|
||||
Arrays.fill(keyBytes, (byte)0);
|
||||
RC2Crypt.checkKey(key.getAlgorithm(), keyBytes.length);
|
||||
return keyBytes.length << 3;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, 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 @@ package com.sun.crypto.provider;
|
|||
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
@ -86,16 +87,18 @@ public final class TlsKeyMaterialGenerator extends KeyGeneratorSpi {
|
|||
throw new IllegalStateException(
|
||||
"TlsKeyMaterialGenerator must be initialized");
|
||||
}
|
||||
byte[] masterSecret = spec.getMasterSecret().getEncoded();
|
||||
try {
|
||||
return engineGenerateKey0();
|
||||
return engineGenerateKey0(masterSecret);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new ProviderException(e);
|
||||
} finally {
|
||||
Arrays.fill(masterSecret, (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private SecretKey engineGenerateKey0() throws GeneralSecurityException {
|
||||
byte[] masterSecret = spec.getMasterSecret().getEncoded();
|
||||
private SecretKey engineGenerateKey0(byte[] masterSecret) throws GeneralSecurityException {
|
||||
|
||||
byte[] clientRandom = spec.getClientRandom();
|
||||
byte[] serverRandom = spec.getServerRandom();
|
||||
|
@ -116,7 +119,7 @@ public final class TlsKeyMaterialGenerator extends KeyGeneratorSpi {
|
|||
int keyBlockLen = macLength + keyLength
|
||||
+ (isExportable ? 0 : ivLength);
|
||||
keyBlockLen <<= 1;
|
||||
byte[] keyBlock = new byte[keyBlockLen];
|
||||
byte[] keyBlock;
|
||||
|
||||
// These may be used again later for exportable suite calculations.
|
||||
MessageDigest md5 = null;
|
||||
|
@ -169,16 +172,11 @@ public final class TlsKeyMaterialGenerator extends KeyGeneratorSpi {
|
|||
|
||||
int ofs = 0;
|
||||
if (macLength != 0) {
|
||||
byte[] tmp = new byte[macLength];
|
||||
|
||||
// mac keys
|
||||
System.arraycopy(keyBlock, ofs, tmp, 0, macLength);
|
||||
clientMacKey = new SecretKeySpec(keyBlock, ofs, macLength, "Mac");
|
||||
ofs += macLength;
|
||||
clientMacKey = new SecretKeySpec(tmp, "Mac");
|
||||
|
||||
System.arraycopy(keyBlock, ofs, tmp, 0, macLength);
|
||||
serverMacKey = new SecretKeySpec(keyBlock, ofs, macLength, "Mac");
|
||||
ofs += macLength;
|
||||
serverMacKey = new SecretKeySpec(tmp, "Mac");
|
||||
}
|
||||
|
||||
if (keyLength == 0) { // SSL_RSA_WITH_NULL_* ciphersuites
|
||||
|
@ -196,82 +194,89 @@ public final class TlsKeyMaterialGenerator extends KeyGeneratorSpi {
|
|||
System.arraycopy(keyBlock, ofs, serverKeyBytes, 0, keyLength);
|
||||
ofs += keyLength;
|
||||
|
||||
if (isExportable == false) {
|
||||
// cipher keys
|
||||
clientCipherKey = new SecretKeySpec(clientKeyBytes, alg);
|
||||
serverCipherKey = new SecretKeySpec(serverKeyBytes, alg);
|
||||
|
||||
// IV keys if needed.
|
||||
if (ivLength != 0) {
|
||||
byte[] tmp = new byte[ivLength];
|
||||
|
||||
System.arraycopy(keyBlock, ofs, tmp, 0, ivLength);
|
||||
ofs += ivLength;
|
||||
clientIv = new IvParameterSpec(tmp);
|
||||
|
||||
System.arraycopy(keyBlock, ofs, tmp, 0, ivLength);
|
||||
ofs += ivLength;
|
||||
serverIv = new IvParameterSpec(tmp);
|
||||
}
|
||||
} else {
|
||||
// if exportable suites, calculate the alternate
|
||||
// cipher key expansion and IV generation
|
||||
if (protocolVersion >= 0x0302) {
|
||||
// TLS 1.1+
|
||||
throw new RuntimeException(
|
||||
"Internal Error: TLS 1.1+ should not be negotiating" +
|
||||
"exportable ciphersuites");
|
||||
} else if (protocolVersion == 0x0301) {
|
||||
// TLS 1.0
|
||||
byte[] seed = concat(clientRandom, serverRandom);
|
||||
|
||||
byte[] tmp = doTLS10PRF(clientKeyBytes,
|
||||
LABEL_CLIENT_WRITE_KEY, seed, expandedKeyLength, md5, sha);
|
||||
clientCipherKey = new SecretKeySpec(tmp, alg);
|
||||
|
||||
tmp = doTLS10PRF(serverKeyBytes, LABEL_SERVER_WRITE_KEY, seed,
|
||||
expandedKeyLength, md5, sha);
|
||||
serverCipherKey = new SecretKeySpec(tmp, alg);
|
||||
try {
|
||||
if (isExportable == false) {
|
||||
// cipher keys
|
||||
clientCipherKey = new SecretKeySpec(clientKeyBytes, alg);
|
||||
serverCipherKey = new SecretKeySpec(serverKeyBytes, alg);
|
||||
|
||||
// IV keys if needed.
|
||||
if (ivLength != 0) {
|
||||
tmp = new byte[ivLength];
|
||||
byte[] block = doTLS10PRF(null, LABEL_IV_BLOCK, seed,
|
||||
ivLength << 1, md5, sha);
|
||||
System.arraycopy(block, 0, tmp, 0, ivLength);
|
||||
clientIv = new IvParameterSpec(tmp);
|
||||
System.arraycopy(block, ivLength, tmp, 0, ivLength);
|
||||
serverIv = new IvParameterSpec(tmp);
|
||||
clientIv = new IvParameterSpec(keyBlock, ofs, ivLength);
|
||||
ofs += ivLength;
|
||||
serverIv = new IvParameterSpec(keyBlock, ofs, ivLength);
|
||||
ofs += ivLength;
|
||||
}
|
||||
} else {
|
||||
// SSLv3
|
||||
byte[] tmp = new byte[expandedKeyLength];
|
||||
// if exportable suites, calculate the alternate
|
||||
// cipher key expansion and IV generation
|
||||
if (protocolVersion >= 0x0302) {
|
||||
// TLS 1.1+
|
||||
throw new RuntimeException(
|
||||
"Internal Error: TLS 1.1+ should not be negotiating" +
|
||||
"exportable ciphersuites");
|
||||
} else if (protocolVersion == 0x0301) {
|
||||
// TLS 1.0
|
||||
byte[] seed = concat(clientRandom, serverRandom);
|
||||
|
||||
md5.update(clientKeyBytes);
|
||||
md5.update(clientRandom);
|
||||
md5.update(serverRandom);
|
||||
System.arraycopy(md5.digest(), 0, tmp, 0, expandedKeyLength);
|
||||
clientCipherKey = new SecretKeySpec(tmp, alg);
|
||||
byte[] tmp = doTLS10PRF(clientKeyBytes,
|
||||
LABEL_CLIENT_WRITE_KEY, seed, expandedKeyLength, md5, sha);
|
||||
clientCipherKey = new SecretKeySpec(tmp, alg);
|
||||
Arrays.fill(tmp, (byte) 0);
|
||||
|
||||
md5.update(serverKeyBytes);
|
||||
md5.update(serverRandom);
|
||||
md5.update(clientRandom);
|
||||
System.arraycopy(md5.digest(), 0, tmp, 0, expandedKeyLength);
|
||||
serverCipherKey = new SecretKeySpec(tmp, alg);
|
||||
tmp = doTLS10PRF(serverKeyBytes, LABEL_SERVER_WRITE_KEY, seed,
|
||||
expandedKeyLength, md5, sha);
|
||||
serverCipherKey = new SecretKeySpec(tmp, alg);
|
||||
Arrays.fill(tmp, (byte) 0);
|
||||
|
||||
if (ivLength != 0) {
|
||||
tmp = new byte[ivLength];
|
||||
if (ivLength != 0) {
|
||||
byte[] block = doTLS10PRF(null, LABEL_IV_BLOCK, seed,
|
||||
ivLength << 1, md5, sha);
|
||||
clientIv = new IvParameterSpec(block, 0, ivLength);
|
||||
serverIv = new IvParameterSpec(block, ivLength, ivLength);
|
||||
}
|
||||
} else {
|
||||
// SSLv3
|
||||
byte[] tmp = new byte[expandedKeyLength];
|
||||
byte[] digest;
|
||||
|
||||
md5.update(clientKeyBytes);
|
||||
md5.update(clientRandom);
|
||||
md5.update(serverRandom);
|
||||
System.arraycopy(md5.digest(), 0, tmp, 0, ivLength);
|
||||
clientIv = new IvParameterSpec(tmp);
|
||||
digest = md5.digest();
|
||||
System.arraycopy(digest, 0, tmp, 0, expandedKeyLength);
|
||||
clientCipherKey = new SecretKeySpec(tmp, alg);
|
||||
Arrays.fill(digest, (byte) 0);
|
||||
|
||||
md5.update(serverKeyBytes);
|
||||
md5.update(serverRandom);
|
||||
md5.update(clientRandom);
|
||||
System.arraycopy(md5.digest(), 0, tmp, 0, ivLength);
|
||||
serverIv = new IvParameterSpec(tmp);
|
||||
digest = md5.digest();
|
||||
System.arraycopy(digest, 0, tmp, 0, expandedKeyLength);
|
||||
serverCipherKey = new SecretKeySpec(tmp, alg);
|
||||
Arrays.fill(digest, (byte) 0);
|
||||
|
||||
Arrays.fill(tmp, (byte) 0);
|
||||
|
||||
if (ivLength != 0) {
|
||||
tmp = new byte[ivLength];
|
||||
|
||||
md5.update(clientRandom);
|
||||
md5.update(serverRandom);
|
||||
System.arraycopy(md5.digest(), 0, tmp, 0, ivLength);
|
||||
clientIv = new IvParameterSpec(tmp);
|
||||
|
||||
md5.update(serverRandom);
|
||||
md5.update(clientRandom);
|
||||
System.arraycopy(md5.digest(), 0, tmp, 0, ivLength);
|
||||
serverIv = new IvParameterSpec(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Arrays.fill(serverKeyBytes, (byte) 0);
|
||||
Arrays.fill(clientKeyBytes, (byte) 0);
|
||||
Arrays.fill(keyBlock, (byte) 0);
|
||||
}
|
||||
|
||||
return new TlsKeyMaterialSpec(clientMacKey, serverMacKey,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, 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 @@ package com.sun.crypto.provider;
|
|||
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.*;
|
||||
|
||||
|
@ -135,20 +136,26 @@ public final class TlsMasterSecretGenerator extends KeyGeneratorSpi {
|
|||
sha.update(clientRandom);
|
||||
sha.update(serverRandom);
|
||||
sha.digest(tmp, 0, 20);
|
||||
sha.reset();
|
||||
|
||||
md5.update(premaster);
|
||||
md5.update(tmp);
|
||||
md5.digest(master, i << 4, 16);
|
||||
md5.reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// master is referenced inside the TlsMasterSecretKey.
|
||||
// Do not touch it anymore.
|
||||
return new TlsMasterSecretKey(master, premasterMajor,
|
||||
premasterMinor);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new ProviderException(e);
|
||||
} catch (DigestException e) {
|
||||
throw new ProviderException(e);
|
||||
} finally {
|
||||
if (premaster != null) {
|
||||
Arrays.fill(premaster, (byte)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, 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
|
||||
|
@ -162,9 +162,17 @@ abstract class TlsPrfGenerator extends KeyGeneratorSpi {
|
|||
spec.getPRFHashAlg(), spec.getPRFHashLength(),
|
||||
spec.getPRFBlockSize()) :
|
||||
doTLS10PRF(secret, labelBytes, spec.getSeed(), n));
|
||||
return new SecretKeySpec(prfBytes, "TlsPrf");
|
||||
try {
|
||||
return new SecretKeySpec(prfBytes, "TlsPrf");
|
||||
} finally {
|
||||
Arrays.fill(prfBytes, (byte)0);
|
||||
}
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new ProviderException("Could not generate PRF", e);
|
||||
} finally {
|
||||
if (secret != null) {
|
||||
Arrays.fill(secret, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,6 +265,7 @@ abstract class TlsPrfGenerator extends KeyGeneratorSpi {
|
|||
if (seclen > 64) { // 64: block size of HMAC-MD5
|
||||
md5.update(secret, 0, seclen);
|
||||
secKey = md5.digest();
|
||||
md5.reset();
|
||||
keyLen = secKey.length;
|
||||
}
|
||||
expand(md5, 16, secKey, 0, keyLen, labelBytes, seed, output,
|
||||
|
@ -267,6 +276,7 @@ abstract class TlsPrfGenerator extends KeyGeneratorSpi {
|
|||
if (seclen > 64) { // 64: block size of HMAC-SHA1
|
||||
sha.update(secret, off, seclen);
|
||||
secKey = sha.digest();
|
||||
sha.reset();
|
||||
keyLen = secKey.length;
|
||||
off = 0;
|
||||
}
|
||||
|
@ -351,12 +361,15 @@ abstract class TlsPrfGenerator extends KeyGeneratorSpi {
|
|||
digest.update(tmp);
|
||||
digest.digest(tmp, 0, hmacSize);
|
||||
|
||||
digest.reset();
|
||||
|
||||
int k = Math.min(hmacSize, remaining);
|
||||
for (int i = 0; i < k; i++) {
|
||||
output[ofs++] ^= tmp[i];
|
||||
}
|
||||
remaining -= k;
|
||||
}
|
||||
Arrays.fill(tmp, (byte)0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, 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 @@ package com.sun.crypto.provider;
|
|||
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
@ -87,7 +88,11 @@ public final class TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
|
|||
b[0] = (byte)spec.getMajorVersion();
|
||||
b[1] = (byte)spec.getMinorVersion();
|
||||
|
||||
return new SecretKeySpec(b, "TlsRsaPremasterSecret");
|
||||
try {
|
||||
return new SecretKeySpec(b, "TlsRsaPremasterSecret");
|
||||
} finally {
|
||||
Arrays.fill(b, (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue