8062264: KeychainStore requires non-null password to be supplied when retrieving a private key
Reviewed-by: mullan
This commit is contained in:
parent
7abf72a2dc
commit
9299e8a8a6
@ -140,7 +140,8 @@ public final class KeychainStore extends KeyStoreSpi {
|
||||
* password to recover it.
|
||||
*
|
||||
* @param alias the alias name
|
||||
* @param password the password for recovering the key
|
||||
* @param password the password for recovering the key. This password is
|
||||
* used internally as the key is exported in a PKCS12 format.
|
||||
*
|
||||
* @return the requested key, or null if the given alias does not exist
|
||||
* or does not identify a <i>key entry</i>.
|
||||
@ -155,6 +156,20 @@ public final class KeychainStore extends KeyStoreSpi {
|
||||
{
|
||||
permissionCheck();
|
||||
|
||||
// An empty password is rejected by MacOS API, no private key data
|
||||
// is exported. If no password is passed (as is the case when
|
||||
// this implementation is used as browser keystore in various
|
||||
// deployment scenarios like Webstart, JFX and applets), create
|
||||
// a dummy password so MacOS API is happy.
|
||||
if (password == null || password.length == 0) {
|
||||
// Must not be a char array with only a 0, as this is an empty
|
||||
// string.
|
||||
if (random == null) {
|
||||
random = new SecureRandom();
|
||||
}
|
||||
password = Long.toString(random.nextLong()).toCharArray();
|
||||
}
|
||||
|
||||
Object entry = entries.get(alias.toLowerCase());
|
||||
|
||||
if (entry == null || !(entry instanceof KeyEntry)) {
|
||||
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.security.*;
|
||||
|
||||
/*
|
||||
* Export a private key from the named keychain entry without supplying a
|
||||
* password. See JDK-8062264.
|
||||
*
|
||||
* NOTE: Keychain access controls must already have been lowered to permit
|
||||
* the target entry to be accessed.
|
||||
*/
|
||||
public class ExportPrivateKeyNoPwd {
|
||||
|
||||
public static final void main(String[] args) throws Exception {
|
||||
|
||||
if (args.length != 1) {
|
||||
throw new Exception(
|
||||
"ExportPrivateKeyNoPwd: must supply name of a keystore entry");
|
||||
}
|
||||
String alias = args[0];
|
||||
|
||||
KeyStore ks = KeyStore.getInstance("KeychainStore");
|
||||
System.out.println("ExportPrivateKeyNoPwd: loading keychains...");
|
||||
ks.load(null, null);
|
||||
|
||||
System.out.println("ExportPrivateKeyNoPwd: exporting key...");
|
||||
Key key = ks.getKey(alias, null);
|
||||
if (key instanceof PrivateKey) {
|
||||
System.out.println("ExportPrivateKeyNoPwd: exported " +
|
||||
key.getAlgorithm() + " private key from '" + alias + "'");
|
||||
} else {
|
||||
throw new Exception("Error exporting private key from keychain");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
#
|
||||
|
||||
# @test
|
||||
# @bug 7133495 8041740
|
||||
# @bug 7133495 8041740 8062264
|
||||
# @summary [macosx] KeyChain KeyStore implementation retrieves only one private key entry
|
||||
|
||||
if [ "${TESTJAVA}" = "" ] ; then
|
||||
@ -30,6 +30,9 @@ if [ "${TESTJAVA}" = "" ] ; then
|
||||
TESTJAVA=`dirname $JAVAC_CMD`/..
|
||||
fi
|
||||
|
||||
if [ "${TESTSRC}" = "" ] ; then
|
||||
TESTSRC="."
|
||||
fi
|
||||
if [ "${TESTCLASSES}" = "" ] ; then
|
||||
TESTCLASSES=`pwd`
|
||||
fi
|
||||
@ -59,10 +62,6 @@ CLEANUP_LIST="rm -f $TEMPORARY_LIST"
|
||||
COUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l`
|
||||
echo "Found $COUNT private key entries in the Keychain keystores"
|
||||
|
||||
if [ $COUNT -gt 1 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create a temporary PKCS12 keystore containing 3 public/private keypairs
|
||||
|
||||
RESULT=`$CLEANUP_P12`
|
||||
@ -107,8 +106,9 @@ fi
|
||||
echo "Unlocked the temporary keychain"
|
||||
|
||||
# Import the keypairs from the PKCS12 keystore into the keychain
|
||||
# (The '-A' option is used to lower the temporary keychain's access controls)
|
||||
|
||||
security import $TEMPORARY_P12 -k $TEMPORARY_KC -f pkcs12 -P $PWD
|
||||
security import $TEMPORARY_P12 -k $TEMPORARY_KC -f pkcs12 -P $PWD -A
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: cannot import keypairs from PKCS12 keystore into the keychain"
|
||||
RESULT=`$CLEANUP_P12`
|
||||
@ -128,26 +128,39 @@ security list-keychains
|
||||
|
||||
# Recount the number of private key entries in the Keychain keystores
|
||||
|
||||
COUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l`
|
||||
echo "Found $COUNT private key entries in the Keychain keystore"
|
||||
if [ $COUNT -lt 3 ]; then
|
||||
echo "Error: expected >2 private key entries in the Keychain keystores"
|
||||
RECOUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l`
|
||||
echo "Found $RECOUNT private key entries in the Keychain keystore"
|
||||
if [ $RECOUNT -lt `expr $COUNT + 3` ]; then
|
||||
echo "Error: expected >$COUNT private key entries in the Keychain keystores"
|
||||
RESULT=`$CLEANUP_P12`
|
||||
RESULT=`$CLEANUP_KC`
|
||||
exit 5
|
||||
fi
|
||||
|
||||
# Export a private key from the keychain (without supplying a password)
|
||||
# Access controls have already been lowered (see 'security import ... -A' above)
|
||||
|
||||
${TESTJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . ${TESTSRC}/ExportPrivateKeyNoPwd.java || exit 6
|
||||
echo | ${TESTJAVA}/bin/java ${TESTVMOPTS} ExportPrivateKeyNoPwd x
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error exporting private key from the temporary keychain"
|
||||
RESULT=`$CLEANUP_P12`
|
||||
RESULT=`$CLEANUP_KC`
|
||||
exit 6
|
||||
fi
|
||||
echo "Exported a private key from the temporary keychain"
|
||||
|
||||
RESULT=`$CLEANUP_P12`
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: cannot remove the temporary PKCS12 keystore"
|
||||
exit 6
|
||||
exit 7
|
||||
fi
|
||||
echo "Removed the temporary PKCS12 keystore"
|
||||
|
||||
RESULT=`$CLEANUP_KC`
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: cannot remove the temporary keychain"
|
||||
exit 7
|
||||
exit 8
|
||||
fi
|
||||
echo "Removed the temporary keychain"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user