mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8286503: Enhance security classes
Reviewed-by: rhalade, mullan, skoivu, weijun
This commit is contained in:
parent
195c9b2c48
commit
adca97b659
39 changed files with 931 additions and 149 deletions
|
@ -25,6 +25,8 @@
|
|||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.lang.ref.Reference;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.KeyRep;
|
||||
|
@ -45,7 +47,7 @@ import jdk.internal.ref.CleanerFactory;
|
|||
final class DESKey implements SecretKey {
|
||||
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 7724971015953279128L;
|
||||
private static final long serialVersionUID = 7724971015953279128L;
|
||||
|
||||
private byte[] key;
|
||||
|
||||
|
@ -143,17 +145,26 @@ final class DESKey implements SecretKey {
|
|||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of this key from
|
||||
* a stream.
|
||||
* Restores the state of this object from the stream.
|
||||
*
|
||||
* @param s the {@code ObjectInputStream} from which data is read
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||
*/
|
||||
@java.io.Serial
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException, ClassNotFoundException
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
s.defaultReadObject();
|
||||
if ((key == null) || (key.length != DESKeySpec.DES_KEY_LEN)) {
|
||||
throw new InvalidObjectException("Wrong key size");
|
||||
}
|
||||
byte[] temp = key;
|
||||
key = temp.clone();
|
||||
Arrays.fill(temp, (byte)0x00);
|
||||
|
||||
DESKeyGenerator.setParityBit(key, 0);
|
||||
|
||||
// Use the cleaner to zero the key when no longer referenced
|
||||
final byte[] k = this.key;
|
||||
CleanerFactory.cleaner().register(this,
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.lang.ref.Reference;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.KeyRep;
|
||||
|
@ -45,7 +47,7 @@ import jdk.internal.ref.CleanerFactory;
|
|||
final class DESedeKey implements SecretKey {
|
||||
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2463986565756745178L;
|
||||
private static final long serialVersionUID = 2463986565756745178L;
|
||||
|
||||
private byte[] key;
|
||||
|
||||
|
@ -144,17 +146,28 @@ final class DESedeKey implements SecretKey {
|
|||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of this key from
|
||||
* a stream.
|
||||
* Restores the state of this object from the stream.
|
||||
*
|
||||
* @param s the {@code ObjectInputStream} from which data is read
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||
*/
|
||||
@java.io.Serial
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException, ClassNotFoundException
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
s.defaultReadObject();
|
||||
if ((key == null) || (key.length != DESedeKeySpec.DES_EDE_KEY_LEN)) {
|
||||
throw new InvalidObjectException("Wrong key size");
|
||||
}
|
||||
byte[] temp = key;
|
||||
this.key = temp.clone();
|
||||
java.util.Arrays.fill(temp, (byte)0x00);
|
||||
|
||||
DESKeyGenerator.setParityBit(key, 0);
|
||||
DESKeyGenerator.setParityBit(key, 8);
|
||||
DESKeyGenerator.setParityBit(key, 16);
|
||||
|
||||
// Use the cleaner to zero the key when no longer referenced
|
||||
final byte[] k = this.key;
|
||||
CleanerFactory.cleaner().register(this,
|
||||
|
|
|
@ -40,8 +40,6 @@ import sun.security.util.*;
|
|||
* algorithm.
|
||||
*
|
||||
* @author Jan Luehe
|
||||
*
|
||||
*
|
||||
* @see DHPublicKey
|
||||
* @see javax.crypto.KeyAgreement
|
||||
*/
|
||||
|
@ -49,7 +47,7 @@ final class DHPrivateKey implements PrivateKey,
|
|||
javax.crypto.interfaces.DHPrivateKey, Serializable {
|
||||
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 7565477590005668886L;
|
||||
private static final long serialVersionUID = 7565477590005668886L;
|
||||
|
||||
// only supported version of PKCS#8 PrivateKeyInfo
|
||||
private static final BigInteger PKCS8_VERSION = BigInteger.ZERO;
|
||||
|
@ -64,10 +62,10 @@ final class DHPrivateKey implements PrivateKey,
|
|||
private byte[] encodedKey;
|
||||
|
||||
// the prime modulus
|
||||
private BigInteger p;
|
||||
private final BigInteger p;
|
||||
|
||||
// the base generator
|
||||
private BigInteger g;
|
||||
private final BigInteger g;
|
||||
|
||||
// the private-value length (optional)
|
||||
private int l;
|
||||
|
@ -321,4 +319,28 @@ final class DHPrivateKey implements PrivateKey,
|
|||
getFormat(),
|
||||
encodedKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the state of this object from the stream.
|
||||
* <p>
|
||||
* JDK 1.5+ objects use <code>KeyRep</code>s instead.
|
||||
*
|
||||
* @param stream the {@code ObjectInputStream} from which data is read
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||
*/
|
||||
@java.io.Serial
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
if ((key == null) || (key.length == 0)) {
|
||||
throw new InvalidObjectException("key not deserializable");
|
||||
}
|
||||
this.key = key.clone();
|
||||
if ((encodedKey == null) || (encodedKey.length == 0)) {
|
||||
throw new InvalidObjectException(
|
||||
"encoded key not deserializable");
|
||||
}
|
||||
this.encodedKey = encodedKey.clone();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,6 @@ import sun.security.util.*;
|
|||
* A public key in X.509 format for the Diffie-Hellman key agreement algorithm.
|
||||
*
|
||||
* @author Jan Luehe
|
||||
*
|
||||
*
|
||||
* @see DHPrivateKey
|
||||
* @see javax.crypto.KeyAgreement
|
||||
*/
|
||||
|
@ -48,7 +46,7 @@ final class DHPublicKey implements PublicKey,
|
|||
javax.crypto.interfaces.DHPublicKey, Serializable {
|
||||
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 7647557958927458271L;
|
||||
private static final long serialVersionUID = 7647557958927458271L;
|
||||
|
||||
// the public key
|
||||
private BigInteger y;
|
||||
|
@ -60,10 +58,10 @@ javax.crypto.interfaces.DHPublicKey, Serializable {
|
|||
private byte[] encodedKey;
|
||||
|
||||
// the prime modulus
|
||||
private BigInteger p;
|
||||
private final BigInteger p;
|
||||
|
||||
// the base generator
|
||||
private BigInteger g;
|
||||
private final BigInteger g;
|
||||
|
||||
// the private-value length (optional)
|
||||
private int l;
|
||||
|
@ -313,4 +311,28 @@ javax.crypto.interfaces.DHPublicKey, Serializable {
|
|||
getFormat(),
|
||||
getEncoded());
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the state of this object from the stream.
|
||||
* <p>
|
||||
* JDK 1.5+ objects use <code>KeyRep</code>s instead.
|
||||
*
|
||||
* @param stream the {@code ObjectInputStream} from which data is read
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||
*/
|
||||
@java.io.Serial
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
if ((key == null) || (key.length == 0)) {
|
||||
throw new InvalidObjectException("key not deserializable");
|
||||
}
|
||||
this.key = key.clone();
|
||||
if ((encodedKey == null) || (encodedKey.length == 0)) {
|
||||
throw new InvalidObjectException(
|
||||
"encoded key not deserializable");
|
||||
}
|
||||
this.encodedKey = encodedKey.clone();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.Cleaner.Cleanable;
|
||||
import java.security.MessageDigest;
|
||||
|
@ -46,11 +48,11 @@ import jdk.internal.ref.CleanerFactory;
|
|||
final class PBEKey implements SecretKey {
|
||||
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = -2234768909660948176L;
|
||||
private static final long serialVersionUID = -2234768909660948176L;
|
||||
|
||||
private byte[] key;
|
||||
|
||||
private String type;
|
||||
private final String type;
|
||||
|
||||
private transient Cleanable cleanable;
|
||||
|
||||
|
@ -162,17 +164,35 @@ final class PBEKey implements SecretKey {
|
|||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of this key from
|
||||
* a stream.
|
||||
* Restores the state of this object from the stream.
|
||||
*
|
||||
* @param s the {@code ObjectInputStream} from which data is read
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||
*/
|
||||
@java.io.Serial
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException, ClassNotFoundException
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
s.defaultReadObject();
|
||||
if (key == null) {
|
||||
throw new InvalidObjectException(
|
||||
"PBEKey couldn't be deserialized");
|
||||
}
|
||||
byte[] temp = key;
|
||||
key = temp.clone();
|
||||
Arrays.fill(temp, (byte)0x00);
|
||||
|
||||
// Accept "\0" to signify "zero-length password with no terminator".
|
||||
if (!(key.length == 1 && key[0] == 0)) {
|
||||
for (int i = 0; i < key.length; i++) {
|
||||
if ((key[i] < '\u0020') || (key[i] > '\u007E')) {
|
||||
throw new InvalidObjectException(
|
||||
"PBEKey had non-ASCII chars");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use cleaner to zero the key when no longer referenced
|
||||
final byte[] k = this.key;
|
||||
cleanable = CleanerFactory.cleaner().register(this,
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.*;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.Cleaner;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -58,16 +58,16 @@ import jdk.internal.ref.CleanerFactory;
|
|||
final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
|
||||
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = -2234868909660948157L;
|
||||
private static final long serialVersionUID = -2234868909660948157L;
|
||||
|
||||
private char[] passwd;
|
||||
private byte[] salt;
|
||||
private int iterCount;
|
||||
private final char[] passwd;
|
||||
private final byte[] salt;
|
||||
private final int iterCount;
|
||||
private byte[] key;
|
||||
|
||||
// The following fields are not Serializable. See writeReplace method.
|
||||
private transient Mac prf;
|
||||
private transient Cleaner.Cleanable cleaner;
|
||||
private final transient Mac prf;
|
||||
private final transient Cleaner.Cleanable cleaner;
|
||||
|
||||
private static byte[] getPasswordBytes(char[] passwd) {
|
||||
CharBuffer cb = CharBuffer.wrap(passwd);
|
||||
|
@ -141,13 +141,14 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
|
|||
int intR = keyLength - (intL - 1)*hlen; // residue
|
||||
byte[] ui = new byte[hlen];
|
||||
byte[] ti = new byte[hlen];
|
||||
String algName = prf.getAlgorithm();
|
||||
// SecretKeySpec cannot be used, since password can be empty here.
|
||||
SecretKey macKey = new SecretKey() {
|
||||
@java.io.Serial
|
||||
private static final long serialVersionUID = 7874493593505141603L;
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return prf.getAlgorithm();
|
||||
return algName;
|
||||
}
|
||||
@Override
|
||||
public String getFormat() {
|
||||
|
@ -160,18 +161,27 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
|
|||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(password) * 41 +
|
||||
prf.getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode();
|
||||
algName.toLowerCase(Locale.ENGLISH).hashCode();
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || this.getClass() != obj.getClass()) return false;
|
||||
SecretKey sk = (SecretKey)obj;
|
||||
return prf.getAlgorithm().equalsIgnoreCase(
|
||||
return algName.equalsIgnoreCase(
|
||||
sk.getAlgorithm()) &&
|
||||
MessageDigest.isEqual(password, sk.getEncoded());
|
||||
}
|
||||
// This derived key can't be deserialized.
|
||||
@java.io.Serial
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException {
|
||||
throw new InvalidObjectException(
|
||||
"PBKDF2KeyImpl SecretKeys are not " +
|
||||
"directly deserializable");
|
||||
}
|
||||
};
|
||||
|
||||
prf.init(macKey);
|
||||
|
||||
byte[] ibytes = new byte[4];
|
||||
|
@ -303,4 +313,20 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
|
|||
Reference.reachabilityFence(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the state of this object from the stream.
|
||||
* <p>
|
||||
* Deserialization of this class is not supported.
|
||||
*
|
||||
* @param stream the {@code ObjectInputStream} from which data is read
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||
*/
|
||||
@java.io.Serial
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException {
|
||||
throw new InvalidObjectException(
|
||||
"PBKDF2KeyImpl keys are not directly deserializable");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2023, 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,9 @@
|
|||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
|
@ -62,11 +65,11 @@ public final class TlsMasterSecretGenerator extends KeyGeneratorSpi {
|
|||
@SuppressWarnings("deprecation")
|
||||
protected void engineInit(AlgorithmParameterSpec params,
|
||||
SecureRandom random) throws InvalidAlgorithmParameterException {
|
||||
if (params instanceof TlsMasterSecretParameterSpec == false) {
|
||||
if (!(params instanceof TlsMasterSecretParameterSpec)) {
|
||||
throw new InvalidAlgorithmParameterException(MSG);
|
||||
}
|
||||
this.spec = (TlsMasterSecretParameterSpec)params;
|
||||
if ("RAW".equals(spec.getPremasterSecret().getFormat()) == false) {
|
||||
if (!"RAW".equals(spec.getPremasterSecret().getFormat())) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"Key format must be RAW");
|
||||
}
|
||||
|
@ -191,6 +194,22 @@ public final class TlsMasterSecretGenerator extends KeyGeneratorSpi {
|
|||
return key.clone();
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Restores the state of this object from the stream.
|
||||
*
|
||||
* @param stream the {@code ObjectInputStream} from which data is read
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||
*/
|
||||
@java.io.Serial
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
if ((key == null) || (key.length == 0)) {
|
||||
throw new InvalidObjectException("TlsMasterSecretKey is null");
|
||||
}
|
||||
key = key.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue