# HG changeset patch # User valeriep # Date 1385409413 28800 # Node ID 3902d25a64b170e361519bb46a08ebf69db81e48 # Parent 8d279ff7e53e39413947b8e90ea2ab002f29e98f 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init() Summary: Add key length checks to P11Signature class Reviewed-by: mullan diff -r 8d279ff7e53e -r 3902d25a64b1 jdk/src/share/classes/sun/security/pkcs11/P11Signature.java --- a/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java Mon Nov 25 09:40:25 2013 -0800 +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java Mon Nov 25 11:56:53 2013 -0800 @@ -326,6 +326,48 @@ } } + private void checkKeySize(String keyAlgo, Key key) + throws InvalidKeyException { + CK_MECHANISM_INFO mechInfo = null; + try { + mechInfo = token.getMechanismInfo(mechanism); + } catch (PKCS11Exception e) { + // should not happen, ignore for now. + } + if (mechInfo == null) { + // skip the check if no native info available + return; + } + int minKeySize = (int) mechInfo.ulMinKeySize; + int maxKeySize = (int) mechInfo.ulMaxKeySize; + + int keySize = 0; + if (key instanceof P11Key) { + keySize = ((P11Key) key).length(); + } else { + if (keyAlgo.equals("RSA")) { + keySize = ((RSAKey) key).getModulus().bitLength(); + } else if (keyAlgo.equals("DSA")) { + keySize = ((DSAKey) key).getParams().getP().bitLength(); + } else if (keyAlgo.equals("EC")) { + keySize = ((ECKey) key).getParams().getCurve().getField().getFieldSize(); + } else { + throw new ProviderException("Error: unsupported algo " + keyAlgo); + } + } + if ((minKeySize != -1) && (keySize < minKeySize)) { + throw new InvalidKeyException(keyAlgo + + " key must be at least " + minKeySize + " bits"); + } + if ((maxKeySize != -1) && (keySize > maxKeySize)) { + throw new InvalidKeyException(keyAlgo + + " key must be at most " + maxKeySize + " bits"); + } + if (keyAlgo.equals("RSA")) { + checkRSAKeyLength(keySize); + } + } + private void checkRSAKeyLength(int len) throws InvalidKeyException { RSAPadding padding; try { @@ -364,15 +406,9 @@ if (publicKey == null) { throw new InvalidKeyException("Key must not be null"); } - // Need to check RSA key length whenever a new key is set - if (keyAlgorithm.equals("RSA") && publicKey != p11Key) { - int keyLen; - if (publicKey instanceof P11Key) { - keyLen = ((P11Key) publicKey).length(); - } else { - keyLen = ((RSAKey) publicKey).getModulus().bitLength(); - } - checkRSAKeyLength(keyLen); + // Need to check key length whenever a new key is set + if (publicKey != p11Key) { + checkKeySize(keyAlgorithm, publicKey); } cancelOperation(); mode = M_VERIFY; @@ -387,14 +423,8 @@ throw new InvalidKeyException("Key must not be null"); } // Need to check RSA key length whenever a new key is set - if (keyAlgorithm.equals("RSA") && privateKey != p11Key) { - int keyLen; - if (privateKey instanceof P11Key) { - keyLen = ((P11Key) privateKey).keyLength; - } else { - keyLen = ((RSAKey) privateKey).getModulus().bitLength(); - } - checkRSAKeyLength(keyLen); + if (privateKey != p11Key) { + checkKeySize(keyAlgorithm, privateKey); } cancelOperation(); mode = M_SIGN; diff -r 8d279ff7e53e -r 3902d25a64b1 jdk/src/share/classes/sun/security/pkcs11/Token.java --- a/jdk/src/share/classes/sun/security/pkcs11/Token.java Mon Nov 25 09:40:25 2013 -0800 +++ b/jdk/src/share/classes/sun/security/pkcs11/Token.java Mon Nov 25 11:56:53 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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,6 +26,7 @@ package sun.security.pkcs11; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.io.*; import java.lang.ref.*; @@ -151,8 +152,8 @@ privateCache = new KeyCache(); templateManager = config.getTemplateManager(); explicitCancel = config.getExplicitCancel(); - mechInfoMap = Collections.synchronizedMap - (new HashMap(10)); + mechInfoMap = + new ConcurrentHashMap(10); } boolean isWriteProtected() { diff -r 8d279ff7e53e -r 3902d25a64b1 jdk/test/sun/security/pkcs11/Signature/TestDSAKeyLength.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/pkcs11/Signature/TestDSAKeyLength.java Mon Nov 25 11:56:53 2013 -0800 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013, 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. + */ +/* + * @test + * @bug 7200306 + * @run main/othervm/timeout=250 TestDSAKeyLength + * @summary verify that P11Signature impl will error out when initialized + * with unsupported key sizes + */ + + +import java.security.*; +import java.security.spec.*; +import java.security.interfaces.*; + +public class TestDSAKeyLength extends PKCS11Test { + + public static void main(String[] args) throws Exception { + main(new TestDSAKeyLength()); + } + + public void main(Provider provider) throws Exception { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", "SUN"); + kpg.initialize(2048, new SecureRandom()); + KeyPair pair = kpg.generateKeyPair(); + + boolean status = true; + Signature sig = Signature.getInstance("SHA1withDSA", provider); + try { + sig.initSign(pair.getPrivate()); + status = false; + } catch (InvalidKeyException ike) { + System.out.println("Expected IKE thrown for initSign()"); + } + try { + sig.initVerify(pair.getPublic()); + status = false; + } catch (InvalidKeyException ike) { + System.out.println("Expected IKE thrown for initVerify()"); + } + if (status) { + System.out.println("Test Passed"); + } else { + throw new Exception("Test Failed - expected IKE not thrown"); + } + } +}