summaryrefslogtreecommitdiff
path: root/java/openjdk6/files/icedtea/security/7186286.patch
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2012-10-19 22:43:10 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2012-10-19 22:43:10 +0000
commit81a8a55b63815f66e325d8ba0051a10e48f90bd1 (patch)
tree583a72c17d448ec15fd905bf3467d0378376c4de /java/openjdk6/files/icedtea/security/7186286.patch
parentUpdate to 7u9. (diff)
- Add 2012/10/16 security patches from IcedTea6 1.11.5. [1]
http://icedtea.classpath.org/hg/release/icedtea6-1.11/rev/d9564350faa6 http://blog.fuseyism.com/index.php/2012/10/19/security-icedtea-1-10-10-1-11-15-2-1-3-2-2-3-2-3-3-released/ - Completely turn off parallel build by default and remove parallel build hack for HotSpot. There were several reports that it fails to build under certain environment, ports/162991 for example. Users can still do parallel build by setting FORCE_MAKE_JOBS (and MAKE_JOBS_NUMBER if desired). - Implement os::available_memory(). Now it is consistent with "vm.vmtotal" sysctl(3) MIB rather than bogus (physical memory / 4). - Prefer sysconf(_SC_NPROCESSORS_CONF) over HW_NCPU sysctl MIB to get the number of installed processors. There is no functional difference except for CURRENT, which obtains the information from ELF aux vector. - Prefer sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) over HW_USERMEM sysctl MIB to get size of physical memory. Although it looks more logical to find currently available memory, it has an inevitable side-effect, i. e., it changes dynamically depending on current wired page count. Therefore, it is unpredictable and not too useful some times. For example, launcher uses the parameter to determine initial heap size and machine class for i386. Now it is more consistent with other places (and Linux JDK/JREs, including the ones we have in ports tree). - Implement os::active_processor_count() using cpuset_getaffinity(2). For example, Runtime.getRuntime().availableProcessors() now returns number of available processors for the current process as it should. - Sync. launchers (java_md.c) for HotSpot and JDK as much as possible for maintainability. As a good side-effect, launcher for i386 can now determine machine class based on the current hardware configuration. Previously, client VM was always chosen by default. - Fix CounterGet(), which is only used for debugging launcher. - Add swap info for os::print_memory_info(). Obtained from: IcedTea project [1] Feature safe: yes
Diffstat (limited to 'java/openjdk6/files/icedtea/security/7186286.patch')
-rw-r--r--java/openjdk6/files/icedtea/security/7186286.patch552
1 files changed, 552 insertions, 0 deletions
diff --git a/java/openjdk6/files/icedtea/security/7186286.patch b/java/openjdk6/files/icedtea/security/7186286.patch
new file mode 100644
index 000000000000..cc5adc1a3cf9
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/7186286.patch
@@ -0,0 +1,552 @@
+# HG changeset patch
+# User xuelei
+# Date 1343546404 25200
+# Node ID a6294da5a21f609b67a0d4d216028dda9f56e689
+# Parent 88243aa6e67b6b84ff529ccdfd3b476410f60057
+7186286: TLS implementation to better adhere to RFC
+Summary: also reviewed by Alexander Fomin <Alexander.Fomin@Oracle.COM>, Andrew Gross<Andrew.Gross@Oracle.COM>, Sean Coffey<Sean.Coffey@Oracle.COM>
+Reviewed-by: valeriep, wetmore
+
+diff --git a/src/share/classes/sun/security/pkcs11/P11Cipher.java b/src/share/classes/sun/security/pkcs11/P11Cipher.java
+--- jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java
++++ jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2012, 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
+@@ -650,7 +650,7 @@
+ // see JCE spec
+ protected int engineGetKeySize(Key key) throws InvalidKeyException {
+ int n = P11SecretKeyFactory.convertKey
+- (token, key, keyAlgorithm).keyLength();
++ (token, key, keyAlgorithm).length();
+ return n;
+ }
+ }
+diff --git a/src/share/classes/sun/security/pkcs11/P11Key.java b/src/share/classes/sun/security/pkcs11/P11Key.java
+--- jdk/src/share/classes/sun/security/pkcs11/P11Key.java
++++ jdk/src/share/classes/sun/security/pkcs11/P11Key.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2012, 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
+@@ -46,6 +46,7 @@
+ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+ import sun.security.util.DerValue;
++import sun.security.util.Length;
+
+ /**
+ * Key implementation classes.
+@@ -61,7 +62,7 @@
+ * @author Andreas Sterbenz
+ * @since 1.5
+ */
+-abstract class P11Key implements Key {
++abstract class P11Key implements Key, Length {
+
+ private final static String PUBLIC = "public";
+ private final static String PRIVATE = "private";
+@@ -212,7 +213,11 @@
+ return s1;
+ }
+
+- int keyLength() {
++ /**
++ * Return bit length of the key.
++ */
++ @Override
++ public int length() {
+ return keyLength;
+ }
+
+diff --git a/src/share/classes/sun/security/pkcs11/P11RSACipher.java b/src/share/classes/sun/security/pkcs11/P11RSACipher.java
+--- jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java
++++ jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2012, 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
+@@ -201,7 +201,7 @@
+ } else {
+ throw new InvalidKeyException("Unknown key type: " + p11Key);
+ }
+- int n = (p11Key.keyLength() + 7) >> 3;
++ int n = (p11Key.length() + 7) >> 3;
+ outputSize = n;
+ buffer = new byte[n];
+ maxInputSize = encrypt ? (n - PKCS1_MIN_PADDING_LENGTH) : n;
+@@ -458,7 +458,7 @@
+
+ // see JCE spec
+ protected int engineGetKeySize(Key key) throws InvalidKeyException {
+- int n = P11KeyFactory.convertKey(token, key, algorithm).keyLength();
++ int n = P11KeyFactory.convertKey(token, key, algorithm).length();
+ return n;
+ }
+ }
+diff --git a/src/share/classes/sun/security/pkcs11/P11Signature.java b/src/share/classes/sun/security/pkcs11/P11Signature.java
+--- jdk/src/share/classes/sun/security/pkcs11/P11Signature.java
++++ jdk/src/share/classes/sun/security/pkcs11/P11Signature.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2012, 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
+@@ -274,7 +274,7 @@
+ if (keyAlgorithm.equals("DSA")) {
+ signature = new byte[40];
+ } else {
+- signature = new byte[(p11Key.keyLength() + 7) >> 3];
++ signature = new byte[(p11Key.length() + 7) >> 3];
+ }
+ if (type == T_UPDATE) {
+ token.p11.C_VerifyFinal(session.id(), signature);
+@@ -359,7 +359,7 @@
+ if (keyAlgorithm.equals("RSA") && publicKey != p11Key) {
+ int keyLen;
+ if (publicKey instanceof P11Key) {
+- keyLen = ((P11Key) publicKey).keyLength();
++ keyLen = ((P11Key) publicKey).length();
+ } else {
+ keyLen = ((RSAKey) publicKey).getModulus().bitLength();
+ }
+@@ -620,7 +620,7 @@
+
+ private byte[] pkcs1Pad(byte[] data) {
+ try {
+- int len = (p11Key.keyLength() + 7) >> 3;
++ int len = (p11Key.length() + 7) >> 3;
+ RSAPadding padding = RSAPadding.getInstance
+ (RSAPadding.PAD_BLOCKTYPE_1, len);
+ byte[] padded = padding.pad(data);
+diff --git a/src/share/classes/sun/security/ssl/HandshakeInStream.java b/src/share/classes/sun/security/ssl/HandshakeInStream.java
+--- jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java
++++ jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2012, 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
+@@ -190,6 +190,7 @@
+
+ byte[] getBytes8() throws IOException {
+ int len = getInt8();
++ verifyLength(len);
+ byte b[] = new byte[len];
+
+ read(b, 0, len);
+@@ -198,6 +199,7 @@
+
+ byte[] getBytes16() throws IOException {
+ int len = getInt16();
++ verifyLength(len);
+ byte b[] = new byte[len];
+
+ read(b, 0, len);
+@@ -206,10 +208,19 @@
+
+ byte[] getBytes24() throws IOException {
+ int len = getInt24();
++ verifyLength(len);
+ byte b[] = new byte[len];
+
+ read(b, 0, len);
+ return b;
+ }
+
++ // Is a length greater than available bytes in the record?
++ private void verifyLength(int len) throws SSLException {
++ if (len > available()) {
++ throw new SSLException(
++ "Not enough data to fill declared vector size");
++ }
++ }
++
+ }
+diff --git a/src/share/classes/sun/security/ssl/Handshaker.java b/src/share/classes/sun/security/ssl/Handshaker.java
+--- jdk/src/share/classes/sun/security/ssl/Handshaker.java
++++ jdk/src/share/classes/sun/security/ssl/Handshaker.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2012, 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
+@@ -776,9 +776,9 @@
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println("RSA master secret generation error:");
+ e.printStackTrace(System.out);
+- System.out.println("Generating new random premaster secret");
+ }
+- preMasterSecret = RSAClientKeyExchange.generateDummySecret(protocolVersion);
++ preMasterSecret =
++ RSAClientKeyExchange.generateDummySecret(protocolVersion);
+ // recursive call with new premaster secret
+ return calculateMasterSecret(preMasterSecret, null);
+ }
+@@ -821,9 +821,9 @@
+ System.out.println("RSA PreMasterSecret version error: expected"
+ + protocolVersion + " or " + requestedVersion + ", decrypted: "
+ + premasterVersion);
+- System.out.println("Generating new random premaster secret");
+ }
+- preMasterSecret = RSAClientKeyExchange.generateDummySecret(protocolVersion);
++ preMasterSecret =
++ RSAClientKeyExchange.generateDummySecret(protocolVersion);
+ // recursive call with new premaster secret
+ return calculateMasterSecret(preMasterSecret, null);
+ }
+diff --git a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java
+--- jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java
++++ jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2012, 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
+@@ -36,6 +36,7 @@
+ import javax.net.ssl.*;
+
+ import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
++import sun.security.util.KeyLength;
+
+ /**
+ * This is the client key exchange message (CLIENT --> SERVER) used with
+@@ -85,7 +86,8 @@
+ * it, using its RSA private key. Result is the same size as the
+ * server's public key, and uses PKCS #1 block format 02.
+ */
+- RSAClientKeyExchange(ProtocolVersion protocolVersion, ProtocolVersion maxVersion,
++ RSAClientKeyExchange(ProtocolVersion protocolVersion,
++ ProtocolVersion maxVersion,
+ SecureRandom generator, PublicKey publicKey) throws IOException {
+ if (publicKey.getAlgorithm().equals("RSA") == false) {
+ throw new SSLKeyException("Public key not of type RSA");
+@@ -120,7 +122,8 @@
+ * Server gets the PKCS #1 (block format 02) data, decrypts
+ * it with its private key.
+ */
+- RSAClientKeyExchange(ProtocolVersion currentVersion, HandshakeInStream input,
++ RSAClientKeyExchange(ProtocolVersion currentVersion,
++ ProtocolVersion maxVersion, HandshakeInStream input,
+ int messageSize, PrivateKey privateKey) throws IOException {
+
+ if (privateKey.getAlgorithm().equals("RSA") == false) {
+@@ -143,28 +146,119 @@
+ cipher.init(Cipher.UNWRAP_MODE, privateKey);
+ preMaster = (SecretKey)cipher.unwrap(encrypted,
+ "TlsRsaPremasterSecret", Cipher.SECRET_KEY);
++
++ // polish the premaster secret
++ preMaster = polishPreMasterSecretKey(
++ currentVersion, maxVersion, preMaster, null);
+ } catch (Exception e) {
+- /*
+- * Bogus decrypted ClientKeyExchange? If so, conjure a
+- * a random preMaster secret that will fail later during
+- * Finished message processing. This is a countermeasure against
+- * the "interactive RSA PKCS#1 encryption envelop attack" reported
+- * in June 1998. Preserving the executation path will
+- * mitigate timing attacks and force consistent error handling
+- * that will prevent an attacking client from differentiating
+- * different kinds of decrypted ClientKeyExchange bogosities.
+- */
+- if (debug != null && Debug.isOn("handshake")) {
+- System.out.println("Error decrypting premaster secret:");
+- e.printStackTrace(System.out);
+- System.out.println("Generating random secret");
++ // polish the premaster secret
++ preMaster = polishPreMasterSecretKey(
++ currentVersion, maxVersion, preMaster, e);
++ }
++ }
++
++ /**
++ * To avoid vulnerabilities described by section 7.4.7.1, RFC 5246,
++ * treating incorrectly formatted message blocks and/or mismatched
++ * version numbers in a manner indistinguishable from correctly
++ * formatted RSA blocks.
++ *
++ * RFC 5246 describes the approach as :
++ *
++ * 1. Generate a string R of 46 random bytes
++ *
++ * 2. Decrypt the message to recover the plaintext M
++ *
++ * 3. If the PKCS#1 padding is not correct, or the length of message
++ * M is not exactly 48 bytes:
++ * pre_master_secret = ClientHello.client_version || R
++ * else If ClientHello.client_version <= TLS 1.0, and version
++ * number check is explicitly disabled:
++ * pre_master_secret = M
++ * else:
++ * pre_master_secret = ClientHello.client_version || M[2..47]
++ *
++ * Note that although TLS 1.2 is not supported in this release, we still
++ * want to make use of the above approach to provide better protection.
++ */
++ private SecretKey polishPreMasterSecretKey(
++ ProtocolVersion currentVersion, ProtocolVersion clientHelloVersion,
++ SecretKey secretKey, Exception failoverException) {
++
++ if (failoverException == null && secretKey != null) {
++ // check the length
++ byte[] encoded = secretKey.getEncoded();
++ if (encoded == null) { // unable to get the encoded key
++ if (debug != null && Debug.isOn("handshake")) {
++ System.out.println(
++ "unable to get the plaintext of the premaster secret");
++ }
++
++ int keySize = KeyLength.getKeySize(secretKey);
++ if (keySize > 0 && keySize != 384) { // 384 = 48 * 8
++ if (debug != null && Debug.isOn("handshake")) {
++ System.out.println(
++ "incorrect length of premaster secret: " +
++ (keySize/8));
++ }
++
++ return generateDummySecret(currentVersion);
++ }
++
++ // The key size is exactly 48 bytes or not accessible.
++ //
++ // Conservatively, pass the checking to master secret
++ // calculation.
++ return secretKey;
++ } else if (encoded.length == 48) {
++ // check the version
++ if (clientHelloVersion.major == encoded[0] &&
++ clientHelloVersion.minor == encoded[1]) {
++
++ return secretKey;
++ } else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v &&
++ currentVersion.major == encoded[0] &&
++ currentVersion.minor == encoded[1]) {
++ /*
++ * For compatibility, we maintain the behavior that the
++ * version in pre_master_secret can be the negotiated
++ * version for TLS v1.0 and SSL v3.0.
++ */
++ return secretKey;
++ }
++
++ if (debug != null && Debug.isOn("handshake")) {
++ System.out.println("Mismatching Protocol Versions, " +
++ "ClientHello.client_version is " + clientHelloVersion +
++ ", while PreMasterSecret.client_version is " +
++ ProtocolVersion.valueOf(encoded[0], encoded[1]));
++ }
++ return generateDummySecret(currentVersion);
++ } else {
++ if (debug != null && Debug.isOn("handshake")) {
++ System.out.println(
++ "incorrect length of premaster secret: " +
++ encoded.length);
++ }
++ return generateDummySecret(currentVersion);
+ }
+- preMaster = generateDummySecret(currentVersion);
+ }
++
++ if (debug != null && Debug.isOn("handshake") &&
++ failoverException != null) {
++ System.out.println("Error decrypting premaster secret:");
++ failoverException.printStackTrace(System.out);
++ }
++
++ return generateDummySecret(currentVersion);
+ }
+
+ // generate a premaster secret with the specified version number
+ static SecretKey generateDummySecret(ProtocolVersion version) {
++ if (debug != null && Debug.isOn("handshake")) {
++ System.out.println("Generating a random fake premaster secret");
++ }
++
+ try {
+ KeyGenerator kg =
+ JsseJce.getKeyGenerator("SunTlsRsaPremasterSecret");
+diff --git a/src/share/classes/sun/security/ssl/ServerHandshaker.java b/src/share/classes/sun/security/ssl/ServerHandshaker.java
+--- jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java
++++ jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2012, 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
+@@ -190,8 +190,9 @@
+ * temporary one used for non-export or signing-only
+ * certificates/keys.
+ */
+- RSAClientKeyExchange pms = new RSAClientKeyExchange
+- (protocolVersion, input, message_len, privateKey);
++ RSAClientKeyExchange pms = new RSAClientKeyExchange(
++ protocolVersion, clientRequestedVersion,
++ input, message_len, privateKey);
+ preMasterSecret = this.clientKeyExchange(pms);
+ break;
+ case K_KRB5:
+diff --git a/src/share/classes/sun/security/util/KeyLength.java b/src/share/classes/sun/security/util/KeyLength.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/security/util/KeyLength.java
+@@ -0,0 +1,91 @@
++/*
++ * Copyright (c) 2012, 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
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * 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.
++ */
++
++package sun.security.util;
++
++import java.security.Key;
++import java.security.PrivilegedAction;
++import java.security.AccessController;
++import java.security.interfaces.ECKey;
++import java.security.interfaces.RSAKey;
++import java.security.interfaces.DSAKey;
++import javax.crypto.SecretKey;
++import javax.crypto.interfaces.DHKey;
++
++/**
++ * A utility class to get key length
++ */
++public final class KeyLength {
++
++ /**
++ * Returns the key size of the given key object in bits.
++ *
++ * @param key the key object, cannot be null
++ * @return the key size of the given key object in bits, or -1 if the
++ * key size is not accessible
++ */
++ final public static int getKeySize(Key key) {
++ int size = -1;
++
++ if (key instanceof Length) {
++ try {
++ Length ruler = (Length)key;
++ size = ruler.length();
++ } catch (UnsupportedOperationException usoe) {
++ // ignore the exception
++ }
++
++ if (size >= 0) {
++ return size;
++ }
++ }
++
++ // try to parse the length from key specification
++ if (key instanceof SecretKey) {
++ SecretKey sk = (SecretKey)key;
++ String format = sk.getFormat();
++ if ("RAW".equals(format) && sk.getEncoded() != null) {
++ size = (sk.getEncoded().length * 8);
++ } // Otherwise, it may be a unextractable key of PKCS#11, or
++ // a key we are not able to handle.
++ } else if (key instanceof RSAKey) {
++ RSAKey pubk = (RSAKey)key;
++ size = pubk.getModulus().bitLength();
++ } else if (key instanceof ECKey) {
++ ECKey pubk = (ECKey)key;
++ size = pubk.getParams().getOrder().bitLength();
++ } else if (key instanceof DSAKey) {
++ DSAKey pubk = (DSAKey)key;
++ size = pubk.getParams().getP().bitLength();
++ } else if (key instanceof DHKey) {
++ DHKey pubk = (DHKey)key;
++ size = pubk.getParams().getP().bitLength();
++ } // Otherwise, it may be a unextractable key of PKCS#11, or
++ // a key we are not able to handle.
++
++ return size;
++ }
++}
++
+diff --git a/src/share/classes/sun/security/util/Length.java b/src/share/classes/sun/security/util/Length.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/security/util/Length.java
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (c) 2012, 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
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * 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.
++ */
++
++package sun.security.util;
++
++/**
++ * The Length interface defines the length of an object
++ */
++public interface Length {
++
++ /**
++ * Gets the length of this object
++ * <p>
++ * Note that if a class of java.security.Key implements this interfaces,
++ * the length should be measured in bits.
++ *
++ * @return the length of this object
++ * @throws UnsupportedOperationException if the operation is not supported
++ */
++ public int length();
++}