8286503: Enhance security classes

Reviewed-by: rhalade, mullan, skoivu, weijun
This commit is contained in:
Bradford Wetmore 2023-05-19 00:58:30 +00:00 committed by Henry Jen
parent 195c9b2c48
commit adca97b659
39 changed files with 931 additions and 149 deletions

View file

@ -28,6 +28,9 @@ package javax.crypto.spec;
import jdk.internal.access.SharedSecrets;
import javax.crypto.SecretKey;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.security.MessageDigest;
import java.security.spec.KeySpec;
import java.util.Arrays;
@ -60,7 +63,7 @@ public class SecretKeySpec implements KeySpec, SecretKey {
*
* @serial
*/
private final byte[] key;
private byte[] key;
/**
* The name of the algorithm associated with this key.
@ -251,4 +254,26 @@ public class SecretKeySpec implements KeySpec, SecretKey {
void clear() {
Arrays.fill(key, (byte)0);
}
/**
* 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 || algorithm == null) {
throw new InvalidObjectException("Missing argument");
}
this.key = key.clone();
if (key.length == 0) {
throw new InvalidObjectException("Invalid key length");
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 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,10 @@
package javax.security.auth.callback;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
/**
* <p> Underlying security services instantiate and pass a
* {@code ChoiceCallback} to the {@code handle}
@ -48,7 +52,7 @@ public class ChoiceCallback implements Callback, java.io.Serializable {
* @serial the list of choices
* @since 1.4
*/
private final String[] choices;
private String[] choices;
/**
* @serial the choice to be used as the default choice
* @since 1.4
@ -72,7 +76,6 @@ public class ChoiceCallback implements Callback, java.io.Serializable {
* a list of choices, a default choice, and a boolean specifying
* whether multiple selections from the list of choices are allowed.
*
*
* @param prompt the prompt used to describe the list of choices.
*
* @param choices the list of choices. The array is cloned to protect
@ -104,15 +107,15 @@ public class ChoiceCallback implements Callback, java.io.Serializable {
defaultChoice < 0 || defaultChoice >= choices.length)
throw new IllegalArgumentException();
this.prompt = prompt;
this.defaultChoice = defaultChoice;
this.multipleSelectionsAllowed = multipleSelectionsAllowed;
this.choices = choices.clone();
for (int i = 0; i < choices.length; i++) {
if (choices[i] == null || choices[i].isEmpty())
throw new IllegalArgumentException();
}
this.prompt = prompt;
this.choices = choices.clone();
this.defaultChoice = defaultChoice;
this.multipleSelectionsAllowed = multipleSelectionsAllowed;
}
/**
@ -196,4 +199,38 @@ public class ChoiceCallback implements Callback, java.io.Serializable {
public int[] getSelectedIndexes() {
return selections == null ? null : selections.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 ((prompt == null) || prompt.isEmpty() ||
(choices == null) || (choices.length == 0) ||
(defaultChoice < 0) || (defaultChoice >= choices.length)) {
throw new InvalidObjectException(
"Missing/invalid prompt/choices");
}
choices = choices.clone();
for (int i = 0; i < choices.length; i++) {
if ((choices[i] == null) || choices[i].isEmpty())
throw new InvalidObjectException("Null/empty choices");
}
if (selections != null) {
selections = selections.clone();
if (!multipleSelectionsAllowed && (selections.length != 1)) {
throw new InvalidObjectException(
"Multiple selections not allowed");
}
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 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 javax.security.auth.callback;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* <p> Underlying security services instantiate and pass a
* {@code ConfirmationCallback} to the {@code handle}
@ -147,7 +150,7 @@ public class ConfirmationCallback implements Callback, java.io.Serializable {
* @serial
* @since 1.4
*/
private final String[] options;
private String[] options;
/**
* @serial
* @since 1.4
@ -252,16 +255,16 @@ public class ConfirmationCallback implements Callback, java.io.Serializable {
defaultOption < 0 || defaultOption >= options.length)
throw new IllegalArgumentException();
this.prompt = null;
this.messageType = messageType;
this.optionType = UNSPECIFIED_OPTION;
this.defaultOption = defaultOption;
this.options = options.clone();
for (int i = 0; i < options.length; i++) {
if (options[i] == null || options[i].isEmpty())
throw new IllegalArgumentException();
}
this.prompt = null;
this.messageType = messageType;
this.optionType = UNSPECIFIED_OPTION;
this.options = options.clone();
this.defaultOption = defaultOption;
}
/**
@ -372,16 +375,16 @@ public class ConfirmationCallback implements Callback, java.io.Serializable {
defaultOption < 0 || defaultOption >= options.length)
throw new IllegalArgumentException();
this.prompt = prompt;
this.messageType = messageType;
this.optionType = UNSPECIFIED_OPTION;
this.defaultOption = defaultOption;
this.options = options.clone();
for (int i = 0; i < options.length; i++) {
if (options[i] == null || options[i].isEmpty())
throw new IllegalArgumentException();
}
this.prompt = prompt;
this.messageType = messageType;
this.optionType = UNSPECIFIED_OPTION;
this.options = options.clone();
this.defaultOption = defaultOption;
}
/**
@ -487,4 +490,20 @@ public class ConfirmationCallback implements Callback, java.io.Serializable {
public int getSelectedIndex() {
return selection;
}
/**
* 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 (options != null) {
options = options.clone();
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 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 javax.security.auth.callback;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.lang.ref.Cleaner;
import java.util.Arrays;
@ -157,4 +160,27 @@ public class PasswordCallback implements Callback, java.io.Serializable {
private static Runnable cleanerFor(char[] password) {
return () -> Arrays.fill(password, ' ');
}
/**
* 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 (prompt == null || prompt.isEmpty()) {
throw new InvalidObjectException("Missing prompt");
}
if (inputPassword != null) {
inputPassword = inputPassword.clone();
cleanable = CleanerFactory.cleaner().register(
this, cleanerFor(inputPassword));
}
}
}