mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8302111: Serialization considerations
Reviewed-by: skoivu, rhalade, weijun, wetmore
This commit is contained in:
parent
df7d6e081f
commit
369c573383
21 changed files with 747 additions and 468 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, 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
|
||||
|
@ -407,6 +407,11 @@ implements Serializable
|
|||
@SuppressWarnings("unchecked")
|
||||
Hashtable<Class<?>, PermissionCollection> perms =
|
||||
(Hashtable<Class<?>, PermissionCollection>)gfields.get("perms", null);
|
||||
|
||||
if (perms == null) {
|
||||
throw new InvalidObjectException("perms can't be null");
|
||||
}
|
||||
|
||||
permsMap = new ConcurrentHashMap<>(perms.size()*2);
|
||||
permsMap.putAll(perms);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, 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
|
||||
|
@ -152,20 +152,20 @@ public final class SignedObject implements Serializable {
|
|||
*/
|
||||
public SignedObject(Serializable object, PrivateKey signingKey,
|
||||
Signature signingEngine)
|
||||
throws IOException, InvalidKeyException, SignatureException {
|
||||
// creating a stream pipe-line, from a to b
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
ObjectOutput a = new ObjectOutputStream(b);
|
||||
throws IOException, InvalidKeyException, SignatureException {
|
||||
// creating a stream pipe-line, from a to b
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
ObjectOutput a = new ObjectOutputStream(b);
|
||||
|
||||
// write and flush the object content to byte array
|
||||
a.writeObject(object);
|
||||
a.flush();
|
||||
a.close();
|
||||
this.content = b.toByteArray();
|
||||
b.close();
|
||||
// write and flush the object content to byte array
|
||||
a.writeObject(object);
|
||||
a.flush();
|
||||
a.close();
|
||||
this.content = b.toByteArray();
|
||||
b.close();
|
||||
|
||||
// now sign the encapsulated object
|
||||
this.sign(signingKey, signingEngine);
|
||||
// now sign the encapsulated object
|
||||
this.sign(signingKey, signingEngine);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,12 +245,12 @@ public final class SignedObject implements Serializable {
|
|||
* @throws SignatureException if signing fails.
|
||||
*/
|
||||
private void sign(PrivateKey signingKey, Signature signingEngine)
|
||||
throws InvalidKeyException, SignatureException {
|
||||
// initialize the signing engine
|
||||
signingEngine.initSign(signingKey);
|
||||
signingEngine.update(this.content.clone());
|
||||
this.signature = signingEngine.sign().clone();
|
||||
this.thealgorithm = signingEngine.getAlgorithm();
|
||||
throws InvalidKeyException, SignatureException {
|
||||
// initialize the signing engine
|
||||
signingEngine.initSign(signingKey);
|
||||
signingEngine.update(this.content.clone());
|
||||
this.signature = signingEngine.sign();
|
||||
this.thealgorithm = signingEngine.getAlgorithm();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -263,10 +263,16 @@ public final class SignedObject implements Serializable {
|
|||
*/
|
||||
@Serial
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
content = ((byte[])fields.get("content", null)).clone();
|
||||
signature = ((byte[])fields.get("signature", null)).clone();
|
||||
thealgorithm = (String)fields.get("thealgorithm", null);
|
||||
throws IOException, ClassNotFoundException {
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
byte[] c = (byte[]) fields.get("content", null);
|
||||
byte[] sig = (byte[]) fields.get("signature", null);
|
||||
String a = (String) fields.get("thealgorithm", null);
|
||||
if (c == null || sig == null || a == null) {
|
||||
throw new InvalidObjectException("One or more null fields");
|
||||
}
|
||||
content = c.clone();
|
||||
signature = sig.clone();
|
||||
thealgorithm = a;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2024, 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 java.security;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.Serializable;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.cert.Certificate;
|
||||
|
@ -78,7 +79,7 @@ public final class Timestamp implements Serializable {
|
|||
* {@code null}.
|
||||
*/
|
||||
public Timestamp(Date timestamp, CertPath signerCertPath) {
|
||||
if (timestamp == null || signerCertPath == null) {
|
||||
if (isNull(timestamp, signerCertPath)) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.timestamp = new Date(timestamp.getTime()); // clone
|
||||
|
@ -166,9 +167,16 @@ public final class Timestamp implements Serializable {
|
|||
*/
|
||||
@java.io.Serial
|
||||
private void readObject(ObjectInputStream ois)
|
||||
throws IOException, ClassNotFoundException {
|
||||
throws IOException, ClassNotFoundException {
|
||||
ois.defaultReadObject();
|
||||
if (isNull(timestamp, signerCertPath)) {
|
||||
throw new InvalidObjectException("Invalid null field(s)");
|
||||
}
|
||||
myhash = -1;
|
||||
timestamp = new Date(timestamp.getTime());
|
||||
}
|
||||
|
||||
private static boolean isNull(Date d, CertPath c) {
|
||||
return (d == null || c == null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, 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.io.IOException;
|
|||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamField;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
@ -196,23 +197,32 @@ implements java.io.Serializable
|
|||
ObjectInputStream.GetField gfields = in.readFields();
|
||||
|
||||
// Get permissions
|
||||
@SuppressWarnings("unchecked")
|
||||
// writeObject writes a Hashtable<String, Vector<UnresolvedPermission>>
|
||||
// for the permissions key, so this cast is safe, unless the data is corrupt.
|
||||
Hashtable<String, Vector<UnresolvedPermission>> permissions =
|
||||
(Hashtable<String, Vector<UnresolvedPermission>>)
|
||||
gfields.get("permissions", null);
|
||||
perms = new ConcurrentHashMap<>(permissions.size()*2);
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Hashtable<String, Vector<UnresolvedPermission>> permissions =
|
||||
(Hashtable<String, Vector<UnresolvedPermission>>)
|
||||
gfields.get("permissions", null);
|
||||
|
||||
// Convert each entry (Vector) into a List
|
||||
Set<Map.Entry<String, Vector<UnresolvedPermission>>> set = permissions.entrySet();
|
||||
for (Map.Entry<String, Vector<UnresolvedPermission>> e : set) {
|
||||
// Convert Vector into ArrayList
|
||||
Vector<UnresolvedPermission> vec = e.getValue();
|
||||
List<UnresolvedPermission> list = new CopyOnWriteArrayList<>(vec);
|
||||
if (permissions == null) {
|
||||
throw new InvalidObjectException("Invalid null permissions");
|
||||
}
|
||||
|
||||
// Add to Hashtable being serialized
|
||||
perms.put(e.getKey(), list);
|
||||
perms = new ConcurrentHashMap<>(permissions.size()*2);
|
||||
|
||||
// Convert each entry (Vector) into a List
|
||||
Set<Map.Entry<String, Vector<UnresolvedPermission>>> set = permissions.entrySet();
|
||||
for (Map.Entry<String, Vector<UnresolvedPermission>> e : set) {
|
||||
// Convert Vector into ArrayList
|
||||
Vector<UnresolvedPermission> vec = e.getValue();
|
||||
List<UnresolvedPermission> list = new CopyOnWriteArrayList<>(vec);
|
||||
|
||||
// Add to Hashtable being serialized
|
||||
perms.put(e.getKey(), list);
|
||||
}
|
||||
} catch (ClassCastException cce) {
|
||||
throw new InvalidObjectException("Invalid type for permissions");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2024, 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 java.security.cert;
|
|||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
@ -70,6 +71,13 @@ public class CertificateRevokedException extends CertificateException {
|
|||
|
||||
private transient Map<String, Extension> extensions;
|
||||
|
||||
private static boolean isNull(Date revocationDate,
|
||||
CRLReason reason, X500Principal authority,
|
||||
Map<String, Extension> extensions) {
|
||||
return (revocationDate == null || reason == null || authority == null
|
||||
|| extensions == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code CertificateRevokedException} with
|
||||
* the specified revocation date, reason code, authority name, and map
|
||||
|
@ -92,8 +100,7 @@ public class CertificateRevokedException extends CertificateException {
|
|||
*/
|
||||
public CertificateRevokedException(Date revocationDate, CRLReason reason,
|
||||
X500Principal authority, Map<String, Extension> extensions) {
|
||||
if (revocationDate == null || reason == null || authority == null ||
|
||||
extensions == null) {
|
||||
if (isNull(revocationDate, reason, authority, extensions)) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.revocationDate = new Date(revocationDate.getTime());
|
||||
|
@ -234,9 +241,6 @@ public class CertificateRevokedException extends CertificateException {
|
|||
// (revocationDate, reason, authority)
|
||||
ois.defaultReadObject();
|
||||
|
||||
// Defensively copy the revocation date
|
||||
revocationDate = new Date(revocationDate.getTime());
|
||||
|
||||
// Read in the size (number of mappings) of the extensions map
|
||||
// and create the extensions map
|
||||
int size = ois.readInt();
|
||||
|
@ -247,6 +251,13 @@ public class CertificateRevokedException extends CertificateException {
|
|||
} else {
|
||||
extensions = HashMap.newHashMap(Math.min(size, 20));
|
||||
}
|
||||
// make sure all fields are set before checking
|
||||
if (isNull(revocationDate, reason, authority, extensions)) {
|
||||
throw new InvalidObjectException("Invalid null field(s)");
|
||||
}
|
||||
|
||||
// Defensively copy the revocation date
|
||||
revocationDate = new Date(revocationDate.getTime());
|
||||
|
||||
// Read in the extensions and put the mappings in the extensions map
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue