< prev index next >

src/share/classes/com/sun/crypto/provider/JceKeyStore.java

Print this page
rev 12545 : 8181370: Better keystore handling
Reviewed-by: weijun, igerasim

*** 1,7 **** /* ! * Copyright (c) 1998, 2016, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 25,48 **** --- 25,52 ---- package com.sun.crypto.provider; 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; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; 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 * triple-DES, where the triple-DES encryption/decryption key is derived from * the user's password.
*** 833,847 **** --- 837,861 ---- entry.date = new Date(dis.readLong()); // read the sealed key try { ois = new ObjectInputStream(dis); + final ObjectInputStream ois2 = ois; + // Set a deserialization checker + AccessController.doPrivileged( + (PrivilegedAction<Void>)() -> { + 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 entries.put(alias, entry);
*** 898,903 **** --- 912,947 ---- for (i=0; i<passwdBytes.length; i++) passwdBytes[i] = 0; 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; + } + } }
< prev index next >