提交 da917fe7 编写于 作者: I igerasim

8189997: Enhance keystore mechanisms

8194259: keytool error: java.io.IOException: Invalid secret key format
Reviewed-by: mullan, valeriep, rriggs, ahgross
上级 bb55c829
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2018, 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
......@@ -929,8 +929,10 @@ public final class JceKeyStore extends KeyStoreSpi {
// First run a custom filter
long nestedDepth = info.depth();
if ((nestedDepth == 1 &&
info.serialClass() != SealedObjectForKeyProtector.class) ||
nestedDepth > MAX_NESTED_DEPTH) {
info.serialClass() != SealedObjectForKeyProtector.class) ||
(nestedDepth > MAX_NESTED_DEPTH &&
info.serialClass() != null &&
info.serialClass() != Object.class)) {
return Status.REJECTED;
}
......
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2018, 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,8 +26,6 @@
package com.sun.crypto.provider;
import java.io.IOException;
import java.io.Serializable;
import java.security.Security;
import java.security.Key;
import java.security.PrivateKey;
import java.security.Provider;
......@@ -35,7 +33,6 @@ import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.AlgorithmParameters;
import java.security.spec.InvalidParameterSpecException;
......@@ -44,7 +41,6 @@ import java.security.spec.PKCS8EncodedKeySpec;
import javax.crypto.Cipher;
import javax.crypto.CipherSpi;
import javax.crypto.SecretKey;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SealedObject;
import javax.crypto.spec.*;
import sun.security.x509.AlgorithmId;
......@@ -347,7 +343,7 @@ final class KeyProtector {
SunJCE.getInstance(),
"PBEWithMD5AndTripleDES");
cipher.init(Cipher.DECRYPT_MODE, skey, params);
return (Key)soForKeyProtector.getObject(cipher);
return soForKeyProtector.getKey(cipher);
} catch (NoSuchAlgorithmException ex) {
// Note: this catch needed to be here because of the
// later catch of GeneralSecurityException
......
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2018, 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 sun.misc.ObjectInputFilter;
import sun.misc.SharedSecrets;
import java.io.*;
import java.security.*;
import javax.crypto.*;
......@@ -33,6 +36,16 @@ final class SealedObjectForKeyProtector extends SealedObject {
static final long serialVersionUID = -3650226485480866989L;
/**
* The InputStreamFilter for a Key object inside this SealedObject. It can
* be either provided as a {@link Security} property or a system property
* (when provided as latter, it shadows the former). If the result of this
* filter is {@link sun.misc.ObjectInputFilter.Status.UNDECIDED}, the system
* level filter defined by jdk.serialFilter will be consulted. The value
* of this property uses the same format of jdk.serialFilter.
*/
private static final String KEY_SERIAL_FILTER = "jceks.key.serialFilter";
SealedObjectForKeyProtector(Serializable object, Cipher c)
throws IOException, IllegalBlockSizeException {
super(object, c);
......@@ -59,4 +72,88 @@ final class SealedObjectForKeyProtector extends SealedObject {
}
return params;
}
final Key getKey(Cipher c)
throws IOException, ClassNotFoundException, IllegalBlockSizeException,
BadPaddingException {
try (ObjectInputStream ois = SharedSecrets.getJavaxCryptoSealedObjectAccess()
.getExtObjectInputStream(this, c)) {
AccessController.doPrivileged(
(PrivilegedAction<Void>) () -> {
ObjectInputFilter.Config.setObjectInputFilter(ois,
DeserializationChecker.ONE_FILTER);
return null;
});
try {
@SuppressWarnings("unchecked")
Key t = (Key) ois.readObject();
return t;
} catch (InvalidClassException ice) {
String msg = ice.getMessage();
if (msg.contains("REJECTED")) {
throw new IOException("Rejected by the"
+ " jceks.key.serialFilter or jdk.serialFilter"
+ " property", ice);
} else {
throw ice;
}
}
}
}
/**
* The filter for the content of a SealedObjectForKeyProtector.
*
* First, the jceks.key.serialFilter will be consulted. If the result
* is UNDECIDED, the system level jdk.serialFilter will be consulted.
*/
private static class DeserializationChecker implements ObjectInputFilter {
private static final ObjectInputFilter ONE_FILTER;
static {
String prop = AccessController.doPrivileged(
(PrivilegedAction<String>) () -> {
String tmp = System.getProperty(KEY_SERIAL_FILTER);
if (tmp != null) {
return tmp;
} else {
return Security.getProperty(KEY_SERIAL_FILTER);
}
});
ONE_FILTER = new DeserializationChecker(prop == null ? null
: ObjectInputFilter.Config.createFilter(prop));
}
private final ObjectInputFilter base;
private DeserializationChecker(ObjectInputFilter base) {
this.base = base;
}
@Override
public ObjectInputFilter.Status checkInput(
ObjectInputFilter.FilterInfo info) {
if (info.serialClass() == Object.class) {
return Status.UNDECIDED;
}
if (base != null) {
Status result = base.checkInput(info);
if (result != Status.UNDECIDED) {
return result;
}
}
ObjectInputFilter defaultFilter =
ObjectInputFilter.Config.getSerialFilter();
if (defaultFilter != null) {
return defaultFilter.checkInput(info);
}
return Status.UNDECIDED;
}
}
}
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2018, 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 javax.crypto;
import sun.misc.SharedSecrets;
import java.io.*;
import java.security.AlgorithmParameters;
import java.security.Key;
......@@ -287,17 +289,7 @@ public class SealedObject implements Serializable {
throws IOException, ClassNotFoundException, IllegalBlockSizeException,
BadPaddingException
{
/*
* Unseal the object
*/
byte[] content = c.doFinal(this.encryptedContent);
/*
* De-serialize it
*/
// creating a stream pipe-line, from b to a
ByteArrayInputStream b = new ByteArrayInputStream(content);
ObjectInput a = new extObjectInputStream(b);
ObjectInput a = getExtObjectInputStream(c);
try {
Object obj = a.readObject();
return obj;
......@@ -417,17 +409,7 @@ public class SealedObject implements Serializable {
throw new RuntimeException(iape.getMessage());
}
/*
* Unseal the object
*/
byte[] content = c.doFinal(this.encryptedContent);
/*
* De-serialize it
*/
// creating a stream pipe-line, from b to a
ByteArrayInputStream b = new ByteArrayInputStream(content);
ObjectInput a = new extObjectInputStream(b);
ObjectInput a = getExtObjectInputStream(c);
try {
Object obj = a.readObject();
return obj;
......@@ -450,6 +432,19 @@ public class SealedObject implements Serializable {
if (encodedParams != null)
encodedParams = encodedParams.clone();
}
// This method is also called inside SealedObjectForKeyProtector.java.
private ObjectInputStream getExtObjectInputStream(Cipher c)
throws BadPaddingException, IllegalBlockSizeException, IOException {
byte[] content = c.doFinal(this.encryptedContent);
ByteArrayInputStream b = new ByteArrayInputStream(content);
return new extObjectInputStream(b);
}
static {
SharedSecrets.setJavaxCryptoSealedObjectAccess((obj,c) -> obj.getExtObjectInputStream(c));
}
}
final class extObjectInputStream extends ObjectInputStream {
......
/*
* Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 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
......@@ -22,43 +22,17 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
package com.sun.crypto.provider;
import java.io.IOException;
import java.io.Serializable;
import java.io.ObjectStreamException;
import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SealedObject;
import javax.crypto.spec.*;
/**
* This class is introduced to workaround a problem in
* the SunJCE provider shipped in JCE 1.2.1: the class
* SealedObjectForKeyProtector was obfuscated due to a mistake.
*
* In order to retrieve secret keys in a JCEKS KeyStore written
* by the SunJCE provider in JCE 1.2.1, this class will be used.
*
* @author Valerie Peng
*
*
* @see JceKeyStore
*/
final class ai extends javax.crypto.SealedObject {
static final long serialVersionUID = -7051502576727967444L;
ai(SealedObject so) {
super(so);
}
import java.io.IOException;
import java.io.ObjectInputStream;
Object readResolve() throws ObjectStreamException {
return new SealedObjectForKeyProtector(this);
}
public interface JavaxCryptoSealedObjectAccess {
ObjectInputStream getExtObjectInputStream(
SealedObject sealed, Cipher cipher)
throws BadPaddingException, IllegalBlockSizeException, IOException;
}
/*
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2018, 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,7 +25,7 @@
package sun.misc;
import java.io.ObjectInputStream;
import javax.crypto.SealedObject;
import java.util.jar.JarFile;
import java.io.Console;
import java.io.FileDescriptor;
......@@ -58,6 +58,7 @@ public class SharedSecrets {
private static JavaUtilZipFileAccess javaUtilZipFileAccess;
private static JavaAWTAccess javaAWTAccess;
private static JavaOISAccess javaOISAccess;
private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
public static JavaUtilJarAccess javaUtilJarAccess() {
if (javaUtilJarAccess == null) {
......@@ -199,4 +200,15 @@ public class SharedSecrets {
}
return javaAWTAccess;
}
public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAccess jcsoa) {
javaxCryptoSealedObjectAccess = jcsoa;
}
public static JavaxCryptoSealedObjectAccess getJavaxCryptoSealedObjectAccess() {
if (javaxCryptoSealedObjectAccess == null) {
unsafe.ensureClassInitialized(SealedObject.class);
}
return javaxCryptoSealedObjectAccess;
}
}
......@@ -860,6 +860,9 @@ jdk.xml.dsig.secureValidationPolicy=\
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
# If the system property jdk.serialFilter is also specified, it supersedes
# the security property value defined here.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
# Limits are checked before classes regardless of the order in the sequence of patterns.
......@@ -955,3 +958,20 @@ jdk.xml.dsig.secureValidationPolicy=\
# It is not guaranteed to be examined and used by other implementations.
#
#com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name
#
# JCEKS Encrypted Key Serial Filter
#
# This filter, if configured, is used by the JCEKS KeyStore during the
# deserialization of the encrypted Key object stored inside a key entry.
# If not configured or the filter result is UNDECIDED (i.e. none of the patterns
# matches), the filter configured by jdk.serialFilter will be consulted.
#
# If the system property jceks.key.serialFilter is also specified, it supersedes
# the security property value defined here.
#
# The filter pattern uses the same format as jdk.serialFilter. The default
# pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type,
# and javax.crypto.spec.SecretKeySpec and rejects all the others.
jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\
java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*
......@@ -861,6 +861,9 @@ jdk.xml.dsig.secureValidationPolicy=\
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
# If the system property jdk.serialFilter is also specified, it supersedes
# the security property value defined here.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
# Limits are checked before classes regardless of the order in the sequence of patterns.
......@@ -961,3 +964,20 @@ jdk.xml.dsig.secureValidationPolicy=\
# It is not guaranteed to be examined and used by other implementations.
#
#com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name
#
# JCEKS Encrypted Key Serial Filter
#
# This filter, if configured, is used by the JCEKS KeyStore during the
# deserialization of the encrypted Key object stored inside a key entry.
# If not configured or the filter result is UNDECIDED (i.e. none of the patterns
# matches), the filter configured by jdk.serialFilter will be consulted.
#
# If the system property jceks.key.serialFilter is also specified, it supersedes
# the security property value defined here.
#
# The filter pattern uses the same format as jdk.serialFilter. The default
# pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type,
# and javax.crypto.spec.SecretKeySpec and rejects all the others.
jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\
java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*
......@@ -864,6 +864,9 @@ jdk.xml.dsig.secureValidationPolicy=\
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
# If the system property jdk.serialFilter is also specified, it supersedes
# the security property value defined here.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
# Limits are checked before classes regardless of the order in the sequence of patterns.
......@@ -959,3 +962,20 @@ jdk.xml.dsig.secureValidationPolicy=\
# It is not guaranteed to be examined and used by other implementations.
#
#com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name
#
# JCEKS Encrypted Key Serial Filter
#
# This filter, if configured, is used by the JCEKS KeyStore during the
# deserialization of the encrypted Key object stored inside a key entry.
# If not configured or the filter result is UNDECIDED (i.e. none of the patterns
# matches), the filter configured by jdk.serialFilter will be consulted.
#
# If the system property jceks.key.serialFilter is also specified, it supersedes
# the security property value defined here.
#
# The filter pattern uses the same format as jdk.serialFilter. The default
# pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type,
# and javax.crypto.spec.SecretKeySpec and rejects all the others.
jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\
java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*
......@@ -863,6 +863,9 @@ jdk.xml.dsig.secureValidationPolicy=\
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
# If the system property jdk.serialFilter is also specified, it supersedes
# the security property value defined here.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
# Limits are checked before classes regardless of the order in the sequence of patterns.
......@@ -958,3 +961,20 @@ jdk.xml.dsig.secureValidationPolicy=\
# It is not guaranteed to be examined and used by other implementations.
#
#com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name
#
# JCEKS Encrypted Key Serial Filter
#
# This filter, if configured, is used by the JCEKS KeyStore during the
# deserialization of the encrypted Key object stored inside a key entry.
# If not configured or the filter result is UNDECIDED (i.e. none of the patterns
# matches), the filter configured by jdk.serialFilter will be consulted.
#
# If the system property jceks.key.serialFilter is also specified, it supersedes
# the security property value defined here.
#
# The filter pattern uses the same format as jdk.serialFilter. The default
# pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type,
# and javax.crypto.spec.SecretKeySpec and rejects all the others.
jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\
java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*
......@@ -864,6 +864,9 @@ jdk.xml.dsig.secureValidationPolicy=\
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
# If the system property jdk.serialFilter is also specified, it supersedes
# the security property value defined here.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
# Limits are checked before classes regardless of the order in the sequence of patterns.
......@@ -959,3 +962,20 @@ jdk.xml.dsig.secureValidationPolicy=\
# It is not guaranteed to be examined and used by other implementations.
#
#com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name
#
# JCEKS Encrypted Key Serial Filter
#
# This filter, if configured, is used by the JCEKS KeyStore during the
# deserialization of the encrypted Key object stored inside a key entry.
# If not configured or the filter result is UNDECIDED (i.e. none of the patterns
# matches), the filter configured by jdk.serialFilter will be consulted.
#
# If the system property jceks.key.serialFilter is also specified, it supersedes
# the security property value defined here.
#
# The filter pattern uses the same format as jdk.serialFilter. The default
# pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type,
# and javax.crypto.spec.SecretKeySpec and rejects all the others.
jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\
java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册