Merge
authorasaha
Thu, 21 Apr 2011 08:38:26 -0700
changeset 9844 f7ee612f9c23
parent 9843 5b2c8e3a02f0 (current diff)
parent 9506 fb042badb461 (diff)
child 9847 e68bfaa6e25c
Merge
--- a/jdk/src/share/classes/java/util/concurrent/BlockingDeque.java	Wed Apr 20 21:24:26 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/BlockingDeque.java	Thu Apr 21 08:38:26 2011 -0700
@@ -400,8 +400,10 @@
      * @param o element to be removed from this deque, if present
      * @return <tt>true</tt> if an element was removed as a result of this call
      * @throws ClassCastException if the class of the specified element
-     *         is incompatible with this deque (optional)
-     * @throws NullPointerException if the specified element is null (optional)
+     *         is incompatible with this deque
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if the specified element is null
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     boolean removeFirstOccurrence(Object o);
 
@@ -416,8 +418,10 @@
      * @param o element to be removed from this deque, if present
      * @return <tt>true</tt> if an element was removed as a result of this call
      * @throws ClassCastException if the class of the specified element
-     *         is incompatible with this deque (optional)
-     * @throws NullPointerException if the specified element is null (optional)
+     *         is incompatible with this deque
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if the specified element is null
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     boolean removeLastOccurrence(Object o);
 
@@ -591,8 +595,10 @@
      * @param o element to be removed from this deque, if present
      * @return <tt>true</tt> if this deque changed as a result of the call
      * @throws ClassCastException if the class of the specified element
-     *         is incompatible with this deque (optional)
-     * @throws NullPointerException if the specified element is null (optional)
+     *         is incompatible with this deque
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if the specified element is null
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     boolean remove(Object o);
 
@@ -604,8 +610,10 @@
      * @param o object to be checked for containment in this deque
      * @return <tt>true</tt> if this deque contains the specified element
      * @throws ClassCastException if the class of the specified element
-     *         is incompatible with this deque (optional)
-     * @throws NullPointerException if the specified element is null (optional)
+     *         is incompatible with this deque
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if the specified element is null
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     public boolean contains(Object o);
 
--- a/jdk/src/share/classes/java/util/concurrent/BlockingQueue.java	Wed Apr 20 21:24:26 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/BlockingQueue.java	Thu Apr 21 08:38:26 2011 -0700
@@ -303,8 +303,10 @@
      * @param o element to be removed from this queue, if present
      * @return <tt>true</tt> if this queue changed as a result of the call
      * @throws ClassCastException if the class of the specified element
-     *         is incompatible with this queue (optional)
-     * @throws NullPointerException if the specified element is null (optional)
+     *         is incompatible with this queue
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if the specified element is null
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     boolean remove(Object o);
 
@@ -316,8 +318,10 @@
      * @param o object to be checked for containment in this queue
      * @return <tt>true</tt> if this queue contains the specified element
      * @throws ClassCastException if the class of the specified element
-     *         is incompatible with this queue (optional)
-     * @throws NullPointerException if the specified element is null (optional)
+     *         is incompatible with this queue
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if the specified element is null
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     public boolean contains(Object o);
 
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentMap.java	Wed Apr 20 21:24:26 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentMap.java	Thu Apr 21 08:38:26 2011 -0700
@@ -103,9 +103,11 @@
      * @throws UnsupportedOperationException if the <tt>remove</tt> operation
      *         is not supported by this map
      * @throws ClassCastException if the key or value is of an inappropriate
-     *         type for this map (optional)
+     *         type for this map
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified key or value is null,
-     *         and this map does not permit null keys or values (optional)
+     *         and this map does not permit null keys or values
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     boolean remove(Object key, Object value);
 
--- a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Wed Apr 20 21:24:26 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Thu Apr 21 08:38:26 2011 -0700
@@ -631,9 +631,11 @@
      * @param c collection containing elements to be removed from this list
      * @return <tt>true</tt> if this list changed as a result of the call
      * @throws ClassCastException if the class of an element of this list
-     *         is incompatible with the specified collection (optional)
+     *         is incompatible with the specified collection
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if this list contains a null element and the
-     *         specified collection does not permit null elements (optional),
+     *         specified collection does not permit null elements
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>),
      *         or if the specified collection is null
      * @see #remove(Object)
      */
@@ -671,9 +673,11 @@
      * @param c collection containing elements to be retained in this list
      * @return <tt>true</tt> if this list changed as a result of the call
      * @throws ClassCastException if the class of an element of this list
-     *         is incompatible with the specified collection (optional)
+     *         is incompatible with the specified collection
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if this list contains a null element and the
-     *         specified collection does not permit null elements (optional),
+     *         specified collection does not permit null elements
+     *         (<a href="../Collection.html#optional-restrictions">optional</a>),
      *         or if the specified collection is null
      * @see #remove(Object)
      */
--- a/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java	Wed Apr 20 21:24:26 2011 -0700
+++ b/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java	Thu Apr 21 08:38:26 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, 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
@@ -25,6 +25,7 @@
 
 package sun.security.mscapi;
 
+import java.math.BigInteger;
 import java.security.*;
 import java.security.Key;
 import java.security.interfaces.*;
@@ -33,6 +34,8 @@
 import javax.crypto.*;
 import javax.crypto.spec.*;
 
+import sun.security.rsa.RSAKeyFactory;
+
 /**
  * RSA cipher implementation using the Microsoft Crypto API.
  * Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding.
@@ -189,8 +192,38 @@
         default:
             throw new InvalidKeyException("Unknown mode: " + opmode);
         }
+
         if (!(key instanceof sun.security.mscapi.Key)) {
-            throw new InvalidKeyException("Unsupported key type: " + key);
+            if (key instanceof java.security.interfaces.RSAPublicKey) {
+                java.security.interfaces.RSAPublicKey rsaKey =
+                    (java.security.interfaces.RSAPublicKey) key;
+
+                // Convert key to MSCAPI format
+
+                BigInteger modulus = rsaKey.getModulus();
+                BigInteger exponent =  rsaKey.getPublicExponent();
+
+                // Check against the local and global values to make sure
+                // the sizes are ok.  Round up to the nearest byte.
+                RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
+                    exponent, -1, RSAKeyPairGenerator.KEY_SIZE_MAX);
+
+                byte[] modulusBytes = modulus.toByteArray();
+                byte[] exponentBytes = exponent.toByteArray();
+
+                // Adjust key length due to sign bit
+                int keyBitLength = (modulusBytes[0] == 0)
+                    ? (modulusBytes.length - 1) * 8
+                    : modulusBytes.length * 8;
+
+                byte[] keyBlob = RSASignature.generatePublicKeyBlob(
+                    keyBitLength, modulusBytes, exponentBytes);
+
+                key = RSASignature.importPublicKey(keyBlob, keyBitLength);
+
+            } else {
+                throw new InvalidKeyException("Unsupported key type: " + key);
+            }
         }
 
         if (key instanceof PublicKey) {
@@ -358,6 +391,10 @@
 
         if (key instanceof sun.security.mscapi.Key) {
             return ((sun.security.mscapi.Key) key).bitLength();
+
+        } else if (key instanceof RSAKey) {
+            return ((RSAKey) key).getModulus().bitLength();
+
         } else {
             throw new InvalidKeyException("Unsupported key type: " + key);
         }
--- a/jdk/src/windows/classes/sun/security/mscapi/RSAPublicKey.java	Wed Apr 20 21:24:26 2011 -0700
+++ b/jdk/src/windows/classes/sun/security/mscapi/RSAPublicKey.java	Thu Apr 21 08:38:26 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, 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
@@ -91,7 +91,7 @@
         if (exponent == null) {
             publicKeyBlob = getPublicKeyBlob(hCryptKey);
 
-            exponent = new BigInteger(getExponent(publicKeyBlob));
+            exponent = new BigInteger(1, getExponent(publicKeyBlob));
         }
 
         return exponent;
@@ -104,7 +104,7 @@
 
         if (modulus == null) {
             publicKeyBlob = getPublicKeyBlob(hCryptKey);
-            modulus = new BigInteger(getModulus(publicKeyBlob));
+            modulus = new BigInteger(1, getModulus(publicKeyBlob));
         }
 
         return modulus;
--- a/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java	Wed Apr 20 21:24:26 2011 -0700
+++ b/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java	Thu Apr 21 08:38:26 2011 -0700
@@ -379,11 +379,13 @@
     /**
      * Generates a public-key BLOB from a key's components.
      */
-    private native byte[] generatePublicKeyBlob(
+    // used by RSACipher
+    static native byte[] generatePublicKeyBlob(
         int keyBitLength, byte[] modulus, byte[] publicExponent);
 
     /**
      * Imports a public-key BLOB.
      */
-    private native RSAPublicKey importPublicKey(byte[] keyBlob, int keySize);
+    // used by RSACipher
+    static native RSAPublicKey importPublicKey(byte[] keyBlob, int keySize);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/mscapi/PublicKeyInterop.java	Thu Apr 21 08:38:26 2011 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+/**
+ * @see PublicKeyInterop.sh
+ */
+
+import java.security.*;
+import java.util.*;
+import javax.crypto.*;
+
+import sun.misc.HexDumpEncoder;
+
+/*
+ * Confirm interoperability of RSA public keys between SunMSCAPI and SunJCE
+ * security providers.
+ */
+public class PublicKeyInterop {
+
+    public static void main(String[] arg) throws Exception {
+        PrivateKey privKey = null;
+        Certificate cert = null;
+        KeyStore ks = KeyStore.getInstance("Windows-MY");
+        ks.load(null, null);
+        System.out.println("Loaded keystore: Windows-MY");
+
+        PublicKey myPuKey =
+            (PublicKey) ks.getCertificate("6888925").getPublicKey();
+        System.out.println("Public key is a " + myPuKey.getClass().getName());
+        PrivateKey myPrKey = (PrivateKey) ks.getKey("6888925", null);
+        System.out.println("Private key is a " + myPrKey.getClass().getName());
+        System.out.println();
+
+        byte[] plain = new byte[] {0x01, 0x02, 0x03, 0x04, 0x05};
+        HexDumpEncoder hde = new HexDumpEncoder();
+        System.out.println("Plaintext:\n" + hde.encode(plain) + "\n");
+
+        Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+        rsa.init(Cipher.ENCRYPT_MODE, myPuKey);
+        byte[] encrypted = rsa.doFinal(plain);
+        System.out.println("Encrypted plaintext using RSA Cipher from " +
+            rsa.getProvider().getName() + " JCE provider\n");
+        System.out.println(hde.encode(encrypted) + "\n");
+
+        Cipher rsa2 = Cipher.getInstance("RSA/ECB/PKCS1Padding", "SunMSCAPI");
+        rsa2.init(Cipher.ENCRYPT_MODE, myPuKey);
+        byte[] encrypted2 = rsa2.doFinal(plain);
+        System.out.println("Encrypted plaintext using RSA Cipher from " +
+            rsa2.getProvider().getName() + " JCE provider\n");
+        System.out.println(hde.encode(encrypted2) + "\n");
+
+        Cipher rsa3 = Cipher.getInstance("RSA/ECB/PKCS1Padding", "SunMSCAPI");
+        rsa3.init(Cipher.DECRYPT_MODE, myPrKey);
+        byte[] decrypted = rsa3.doFinal(encrypted);
+        System.out.println("Decrypted first ciphertext using RSA Cipher from " +
+            rsa3.getProvider().getName() + " JCE provider\n");
+        System.out.println(hde.encode(decrypted) + "\n");
+        if (! Arrays.equals(plain, decrypted)) {
+            throw new Exception("First decrypted ciphertext does not match " +
+                "original plaintext");
+        }
+
+        decrypted = rsa3.doFinal(encrypted2);
+        System.out.println("Decrypted second ciphertext using RSA Cipher from "
+            + rsa3.getProvider().getName() + " JCE provider\n");
+        System.out.println(hde.encode(decrypted) + "\n");
+        if (! Arrays.equals(plain, decrypted)) {
+            throw new Exception("Second decrypted ciphertext does not match " +
+                "original plaintext");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/mscapi/PublicKeyInterop.sh	Thu Apr 21 08:38:26 2011 -0700
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2011, 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 6888925
+# @run shell PublicKeyInterop.sh
+# @summary SunMSCAPI's Cipher can't use RSA public keys obtained from other
+#          sources.
+#
+
+# set a few environment variables so that the shell-script can run stand-alone
+# in the source directory
+if [ "${TESTSRC}" = "" ] ; then
+   TESTSRC="."
+fi
+
+if [ "${TESTCLASSES}" = "" ] ; then
+   TESTCLASSES="."
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+   echo "TESTJAVA not set.  Test cannot execute."
+   echo "FAILED!!!"
+   exit 1
+fi
+
+OS=`uname -s`
+case "$OS" in
+    Windows* | CYGWIN* )
+
+        echo "Creating a temporary RSA keypair in the Windows-My store..."
+        ${TESTJAVA}/bin/keytool \
+	    -genkeypair \
+	    -storetype Windows-My \
+	    -keyalg RSA \
+	    -alias 6888925 \
+	    -dname "cn=6888925,c=US" \
+	    -noprompt
+
+        echo
+	echo "Running the test..."
+        ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\PublicKeyInterop.java
+        ${TESTJAVA}/bin/java PublicKeyInterop
+
+        rc=$?
+
+        echo
+        echo "Removing the temporary RSA keypair from the Windows-My store..."
+        ${TESTJAVA}/bin/keytool \
+	    -delete \
+	    -storetype Windows-My \
+	    -alias 6888925
+
+	echo done.
+        exit $rc
+        ;;
+
+    * )
+        echo "This test is not intended for '$OS' - passing test"
+        exit 0
+        ;;
+esac