Mercurial > hg > openjdk > bsd-port > jdk
changeset 8778:1de398ed4d75
8181370: Better keystore handling
Reviewed-by: weijun, igerasim
author | igerasim |
---|---|
date | Tue, 14 Nov 2017 23:10:05 +0000 |
parents | 88d3306d6ee8 |
children | 82c50cf87400 |
files | src/share/classes/com/sun/crypto/provider/JceKeyStore.java |
diffstat | 1 files changed, 47 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/crypto/provider/JceKeyStore.java Tue Nov 14 22:58:57 2017 +0000 +++ b/src/share/classes/com/sun/crypto/provider/JceKeyStore.java Tue Nov 14 23:10:05 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2017, 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,12 +27,14 @@ import java.io.*; import java.util.*; +import java.security.AccessController; import java.security.DigestInputStream; import java.security.DigestOutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Key; import java.security.PrivateKey; +import java.security.PrivilegedAction; import java.security.KeyStoreSpi; import java.security.KeyStoreException; import java.security.UnrecoverableKeyException; @@ -41,6 +43,8 @@ import java.security.cert.CertificateException; import javax.crypto.SealedObject; +import sun.misc.ObjectInputFilter; + /** * This class provides the keystore implementation referred to as "jceks". * This implementation strongly protects the keystore private keys using @@ -835,11 +839,23 @@ // read the sealed key try { ois = new ObjectInputStream(dis); + final ObjectInputStream ois2 = ois; + // Set a deserialization checker + AccessController.doPrivileged(new PrivilegedAction<Void>() { + @Override + public Void run() { + ObjectInputFilter.Config.setObjectInputFilter( + ois2, new DeserializationChecker()); + return null; + } + }); entry.sealedKey = (SealedObject)ois.readObject(); // NOTE: don't close ois here since we are still // using dis!!! } catch (ClassNotFoundException cnfe) { throw new IOException(cnfe.getMessage()); + } catch (InvalidClassException ice) { + throw new IOException("Invalid secret key format"); } // Add the entry to the list @@ -898,4 +914,34 @@ md.update("Mighty Aphrodite".getBytes("UTF8")); return md; } + + /* + * An ObjectInputFilter that checks the format of the secret key being + * deserialized. + */ + private static class DeserializationChecker implements ObjectInputFilter { + private static final int MAX_NESTED_DEPTH = 2; + + @Override + public ObjectInputFilter.Status + checkInput(ObjectInputFilter.FilterInfo info) { + + // First run a custom filter + long nestedDepth = info.depth(); + if ((nestedDepth == 1 && + info.serialClass() != SealedObjectForKeyProtector.class) || + nestedDepth > MAX_NESTED_DEPTH) { + return Status.REJECTED; + } + + // Next run the default filter, if available + ObjectInputFilter defaultFilter = + ObjectInputFilter.Config.getSerialFilter(); + if (defaultFilter != null) { + return defaultFilter.checkInput(info); + } + + return Status.UNDECIDED; + } + } }