changeset 4130:bf2a12c1ffe3

Merge
author mduigou
date Wed, 27 Apr 2011 14:18:26 -0700
parents 5b05f8d1c0e5 7c109d060365
children 76703c84b3a2
files
diffstat 11 files changed, 473 insertions(+), 158 deletions(-) [+]
line wrap: on
line diff
--- a/make/java/nio/mapfile-linux	Tue Apr 26 14:25:42 2011 -0700
+++ b/make/java/nio/mapfile-linux	Wed Apr 27 14:18:26 2011 -0700
@@ -44,7 +44,6 @@
 		Java_sun_nio_ch_EPollArrayWrapper_interrupt;
 		Java_sun_nio_ch_EPollArrayWrapper_offsetofData;
 		Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent;
-		Java_sun_nio_ch_EPoll_init;
 		Java_sun_nio_ch_EPoll_eventSize;
 		Java_sun_nio_ch_EPoll_eventsOffset;
 		Java_sun_nio_ch_EPoll_dataOffset;
@@ -129,7 +128,6 @@
 		Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGio;
 		Java_sun_nio_fs_GnomeFileTypeDetector_initializeGnomeVfs;
 		Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGnomeVfs;
-		Java_sun_nio_fs_LinuxWatchService_init;
 		Java_sun_nio_fs_LinuxWatchService_eventSize;
 		Java_sun_nio_fs_LinuxWatchService_eventOffsets;
 		Java_sun_nio_fs_LinuxWatchService_inotifyInit;
--- a/src/solaris/classes/sun/nio/ch/EPoll.java	Tue Apr 26 14:25:42 2011 -0700
+++ b/src/solaris/classes/sun/nio/ch/EPoll.java	Wed Apr 27 14:18:26 2011 -0700
@@ -99,8 +99,6 @@
 
     // -- Native methods --
 
-    private static native void init();
-
     private static native int eventSize();
 
     private static native int eventsOffset();
@@ -116,6 +114,5 @@
 
     static {
         Util.load();
-        init();
     }
 }
--- a/src/solaris/classes/sun/nio/fs/LinuxWatchService.java	Tue Apr 26 14:25:42 2011 -0700
+++ b/src/solaris/classes/sun/nio/fs/LinuxWatchService.java	Wed Apr 27 14:18:26 2011 -0700
@@ -432,8 +432,6 @@
 
     // -- native methods --
 
-    private static native void init();
-
     // sizeof inotify_event
     private static native int eventSize();
 
@@ -461,6 +459,5 @@
                 System.loadLibrary("nio");
                 return null;
         }});
-        init();
     }
 }
--- a/src/solaris/native/sun/nio/ch/EPoll.c	Tue Apr 26 14:25:42 2011 -0700
+++ b/src/solaris/native/sun/nio/ch/EPoll.c	Wed Apr 27 14:18:26 2011 -0700
@@ -34,55 +34,7 @@
 #include <dlfcn.h>
 #include <unistd.h>
 #include <sys/types.h>
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-/* epoll_wait(2) man page */
-
-typedef union epoll_data {
-    void *ptr;
-    int fd;
-    __uint32_t u32;
-    __uint64_t u64;
-} epoll_data_t;
-
-struct epoll_event {
-    __uint32_t events;  /* Epoll events */
-    epoll_data_t data;  /* User data variable */
-} __attribute__ ((__packed__));
-
-#ifdef  __cplusplus
-}
-#endif
-
-/*
- * epoll event notification is new in 2.6 kernel. As the offical build
- * platform for the JDK is on a 2.4-based distribution then we must
- * obtain the addresses of the epoll functions dynamically.
- */
-typedef int (*epoll_create_t)(int size);
-typedef int (*epoll_ctl_t)   (int epfd, int op, int fd, struct epoll_event *event);
-typedef int (*epoll_wait_t)  (int epfd, struct epoll_event *events, int maxevents, int timeout);
-
-static epoll_create_t epoll_create_func;
-static epoll_ctl_t    epoll_ctl_func;
-static epoll_wait_t   epoll_wait_func;
-
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_EPoll_init(JNIEnv *env, jclass this)
-{
-    epoll_create_func = (epoll_create_t) dlsym(RTLD_DEFAULT, "epoll_create");
-    epoll_ctl_func    = (epoll_ctl_t)    dlsym(RTLD_DEFAULT, "epoll_ctl");
-    epoll_wait_func   = (epoll_wait_t)   dlsym(RTLD_DEFAULT, "epoll_wait");
-
-    if ((epoll_create_func == NULL) || (epoll_ctl_func == NULL) ||
-        (epoll_wait_func == NULL)) {
-        JNU_ThrowInternalError(env, "unable to get address of epoll functions, pre-2.6 kernel?");
-    }
-}
+#include <sys/epoll.h>
 
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_EPoll_eventSize(JNIEnv* env, jclass this)
@@ -108,7 +60,7 @@
      * epoll_create expects a size as a hint to the kernel about how to
      * dimension internal structures. We can't predict the size in advance.
      */
-    int epfd = (*epoll_create_func)(256);
+    int epfd = epoll_create(256);
     if (epfd < 0) {
        JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed");
     }
@@ -125,7 +77,7 @@
     event.events = events;
     event.data.fd = fd;
 
-    RESTARTABLE((*epoll_ctl_func)(epfd, (int)opcode, (int)fd, &event), res);
+    RESTARTABLE(epoll_ctl(epfd, (int)opcode, (int)fd, &event), res);
 
     return (res == 0) ? 0 : errno;
 }
@@ -137,7 +89,7 @@
     struct epoll_event *events = jlong_to_ptr(address);
     int res;
 
-    RESTARTABLE((*epoll_wait_func)(epfd, events, numfds, -1), res);
+    RESTARTABLE(epoll_wait(epfd, events, numfds, -1), res);
     if (res < 0) {
         JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed");
     }
--- a/src/solaris/native/sun/nio/fs/LinuxWatchService.c	Tue Apr 26 14:25:42 2011 -0700
+++ b/src/solaris/native/sun/nio/fs/LinuxWatchService.c	Wed Apr 27 14:18:26 2011 -0700
@@ -33,33 +33,10 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/poll.h>
+#include <sys/inotify.h>
 
 #include "sun_nio_fs_LinuxWatchService.h"
 
-/* inotify.h may not be available at build time */
-#ifdef  __cplusplus
-extern "C" {
-#endif
-struct inotify_event
-{
-  int wd;
-  uint32_t mask;
-  uint32_t cookie;
-  uint32_t len;
-  char name __flexarr;
-};
-#ifdef  __cplusplus
-}
-#endif
-
-typedef int inotify_init_func(void);
-typedef int inotify_add_watch_func(int fd, const char* path, uint32_t mask);
-typedef int inotify_rm_watch_func(int fd, uint32_t wd);
-
-inotify_init_func* my_inotify_init_func = NULL;
-inotify_add_watch_func* my_inotify_add_watch_func = NULL;
-inotify_rm_watch_func* my_inotify_rm_watch_func = NULL;
-
 static void throwUnixException(JNIEnv* env, int errnum) {
     jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
         "(I)V", errnum);
@@ -68,22 +45,6 @@
     }
 }
 
-JNIEXPORT void JNICALL
-Java_sun_nio_fs_LinuxWatchService_init(JNIEnv *env, jclass clazz)
-{
-    my_inotify_init_func = (inotify_init_func*)
-        dlsym(RTLD_DEFAULT, "inotify_init");
-    my_inotify_add_watch_func =
-        (inotify_add_watch_func*) dlsym(RTLD_DEFAULT, "inotify_add_watch");
-    my_inotify_rm_watch_func =
-        (inotify_rm_watch_func*) dlsym(RTLD_DEFAULT, "inotify_rm_watch");
-
-    if ((my_inotify_init_func == NULL) || (my_inotify_add_watch_func == NULL) ||
-        (my_inotify_rm_watch_func == NULL)) {
-        JNU_ThrowInternalError(env, "unable to get address of inotify functions");
-    }
-}
-
 JNIEXPORT jint JNICALL
 Java_sun_nio_fs_LinuxWatchService_eventSize(JNIEnv *env, jclass clazz)
 {
@@ -111,7 +72,7 @@
 Java_sun_nio_fs_LinuxWatchService_inotifyInit
     (JNIEnv* env, jclass clazz)
 {
-    int ifd = (*my_inotify_init_func)();
+    int ifd = inotify_init();
     if (ifd == -1) {
         throwUnixException(env, errno);
     }
@@ -125,7 +86,7 @@
     int wfd = -1;
     const char* path = (const char*)jlong_to_ptr(address);
 
-    wfd = (*my_inotify_add_watch_func)((int)fd, path, mask);
+    wfd = inotify_add_watch((int)fd, path, mask);
     if (wfd == -1) {
         throwUnixException(env, errno);
     }
@@ -136,7 +97,7 @@
 Java_sun_nio_fs_LinuxWatchService_inotifyRmWatch
     (JNIEnv* env, jclass clazz, jint fd, jint wd)
 {
-    int err = (*my_inotify_rm_watch_func)((int)fd, (int)wd);
+    int err = inotify_rm_watch((int)fd, (int)wd);
     if (err == -1)
         throwUnixException(env, errno);
 }
@@ -166,7 +127,6 @@
         res[1] = (jint)sp[1];
         (*env)->SetIntArrayRegion(env, sv, 0, 2, &res[0]);
     }
-
 }
 
 JNIEXPORT jint JNICALL
@@ -190,6 +150,4 @@
         }
      }
     return (jint)n;
-
-
 }
--- a/src/windows/classes/sun/security/mscapi/RSASignature.java	Tue Apr 26 14:25:42 2011 -0700
+++ b/src/windows/classes/sun/security/mscapi/RSASignature.java	Wed Apr 27 14:18:26 2011 -0700
@@ -50,6 +50,9 @@
  * following algorithm names:
  *
  *  . "SHA1withRSA"
+ *  . "SHA256withRSA"
+ *  . "SHA384withRSA"
+ *  . "SHA512withRSA"
  *  . "MD5withRSA"
  *  . "MD2withRSA"
  *
@@ -63,7 +66,10 @@
     // message digest implementation we use
     private final MessageDigest messageDigest;
 
-    // flag indicating whether the digest is reset
+    // message digest name
+    private final String messageDigestAlgorithm;
+
+    // flag indicating whether the digest has been reset
     private boolean needsReset;
 
     // the signing key
@@ -73,10 +79,15 @@
     private Key publicKey = null;
 
 
+    /**
+     * Constructs a new RSASignature. Used by subclasses.
+     */
     RSASignature(String digestName) {
 
         try {
             messageDigest = MessageDigest.getInstance(digestName);
+            // Get the digest's canonical name
+            messageDigestAlgorithm = messageDigest.getAlgorithm();
 
         } catch (NoSuchAlgorithmException e) {
            throw new ProviderException(e);
@@ -91,6 +102,24 @@
         }
     }
 
+    public static final class SHA256 extends RSASignature {
+        public SHA256() {
+            super("SHA-256");
+        }
+    }
+
+    public static final class SHA384 extends RSASignature {
+        public SHA384() {
+            super("SHA-384");
+        }
+    }
+
+    public static final class SHA512 extends RSASignature {
+        public SHA512() {
+            super("SHA-512");
+        }
+    }
+
     public static final class MD5 extends RSASignature {
         public MD5() {
             super("MD5");
@@ -103,16 +132,7 @@
         }
     }
 
-    /**
-     * Initializes this signature object with the specified
-     * public key for verification operations.
-     *
-     * @param publicKey the public key of the identity whose signature is
-     * going to be verified.
-     *
-     * @exception InvalidKeyException if the key is improperly
-     * encoded, parameters are missing, and so on.
-     */
+    // initialize for signing. See JCA doc
     protected void engineInitVerify(PublicKey key)
         throws InvalidKeyException
     {
@@ -158,24 +178,12 @@
             publicKey = (sun.security.mscapi.RSAPublicKey) key;
         }
 
-        if (needsReset) {
-            messageDigest.reset();
-            needsReset = false;
-        }
+        this.privateKey = null;
+        resetDigest();
     }
 
-    /**
-     * Initializes this signature object with the specified
-     * private key for signing operations.
-     *
-     * @param privateKey the private key of the identity whose signature
-     * will be generated.
-     *
-     * @exception InvalidKeyException if the key is improperly
-     * encoded, parameters are missing, and so on.
-     */
-    protected void engineInitSign(PrivateKey key)
-        throws InvalidKeyException
+    // initialize for signing. See JCA doc
+    protected void engineInitSign(PrivateKey key) throws InvalidKeyException
     {
         // This signature accepts only RSAPrivateKey
         if ((key instanceof sun.security.mscapi.RSAPrivateKey) == false) {
@@ -189,12 +197,25 @@
             null, RSAKeyPairGenerator.KEY_SIZE_MIN,
             RSAKeyPairGenerator.KEY_SIZE_MAX);
 
+        this.publicKey = null;
+        resetDigest();
+    }
+
+    /**
+     * Resets the message digest if needed.
+     */
+    private void resetDigest() {
         if (needsReset) {
             messageDigest.reset();
             needsReset = false;
         }
     }
 
+    private byte[] getDigestValue() {
+        needsReset = false;
+        return messageDigest.digest();
+    }
+
     /**
      * Updates the data to be signed or verified
      * using the specified byte.
@@ -254,13 +275,12 @@
      */
     protected byte[] engineSign() throws SignatureException {
 
-        byte[] hash = messageDigest.digest();
-        needsReset = false;
+        byte[] hash = getDigestValue();
 
         // Sign hash using MS Crypto APIs
 
         byte[] result = signHash(hash, hash.length,
-            messageDigest.getAlgorithm(), privateKey.getHCryptProvider(),
+            messageDigestAlgorithm, privateKey.getHCryptProvider(),
             privateKey.getHCryptKey());
 
         // Convert signature array from little endian to big endian
@@ -314,11 +334,10 @@
     protected boolean engineVerify(byte[] sigBytes)
         throws SignatureException
     {
-        byte[] hash = messageDigest.digest();
-        needsReset = false;
+        byte[] hash = getDigestValue();
 
         return verifySignedHash(hash, hash.length,
-            messageDigest.getAlgorithm(), convertEndianArray(sigBytes),
+            messageDigestAlgorithm, convertEndianArray(sigBytes),
             sigBytes.length, publicKey.getHCryptProvider(),
             publicKey.getHCryptKey());
     }
--- a/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Tue Apr 26 14:25:42 2011 -0700
+++ b/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Wed Apr 27 14:18: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
@@ -81,6 +81,12 @@
          */
         map.put("Signature.SHA1withRSA",
             "sun.security.mscapi.RSASignature$SHA1");
+        map.put("Signature.SHA256withRSA",
+            "sun.security.mscapi.RSASignature$SHA256");
+        map.put("Signature.SHA384withRSA",
+            "sun.security.mscapi.RSASignature$SHA384");
+        map.put("Signature.SHA512withRSA",
+            "sun.security.mscapi.RSASignature$SHA512");
         map.put("Signature.MD5withRSA",
             "sun.security.mscapi.RSASignature$MD5");
         map.put("Signature.MD2withRSA",
@@ -89,12 +95,16 @@
         // supported key classes
         map.put("Signature.SHA1withRSA SupportedKeyClasses",
             "sun.security.mscapi.Key");
+        map.put("Signature.SHA256withRSA SupportedKeyClasses",
+            "sun.security.mscapi.Key");
+        map.put("Signature.SHA384withRSA SupportedKeyClasses",
+            "sun.security.mscapi.Key");
+        map.put("Signature.SHA512withRSA SupportedKeyClasses",
+            "sun.security.mscapi.Key");
         map.put("Signature.MD5withRSA SupportedKeyClasses",
             "sun.security.mscapi.Key");
         map.put("Signature.MD2withRSA SupportedKeyClasses",
             "sun.security.mscapi.Key");
-        map.put("Signature.NONEwithRSA SupportedKeyClasses",
-            "sun.security.mscapi.Key");
 
         /*
          * Key Pair Generator engines
--- a/src/windows/native/sun/security/mscapi/security.cpp	Tue Apr 26 14:25:42 2011 -0700
+++ b/src/windows/native/sun/security/mscapi/security.cpp	Wed Apr 27 14:18:26 2011 -0700
@@ -483,6 +483,7 @@
     jbyte* pHashBuffer = NULL;
     jbyte* pSignedHashBuffer = NULL;
     jbyteArray jSignedHash = NULL;
+    HCRYPTPROV hCryptProvAlt = NULL;
 
     __try
     {
@@ -492,8 +493,32 @@
         // Acquire a hash object handle.
         if (::CryptCreateHash(HCRYPTPROV(hCryptProv), algId, 0, 0, &hHash) == FALSE)
         {
-            ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
-            __leave;
+            // Failover to using the PROV_RSA_AES CSP
+
+            DWORD cbData = 256;
+            BYTE pbData[256];
+            pbData[0] = '\0';
+
+            // Get name of the key container
+            ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER,
+                (BYTE *)pbData, &cbData, 0);
+
+            // Acquire an alternative CSP handle
+            if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
+                PROV_RSA_AES, 0) == FALSE)
+            {
+
+                ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
+                __leave;
+            }
+
+            // Acquire a hash object handle.
+            if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0,
+                &hHash) == FALSE)
+            {
+                ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
+                __leave;
+            }
         }
 
         // Copy hash from Java to native buffer
@@ -546,6 +571,9 @@
     }
     __finally
     {
+        if (hCryptProvAlt)
+            ::CryptReleaseContext(hCryptProvAlt, 0);
+
         if (pSignedHashBuffer)
             delete [] pSignedHashBuffer;
 
@@ -574,6 +602,7 @@
     jbyte* pSignedHashBuffer = NULL;
     DWORD dwSignedHashBufferLen = jSignedHashSize;
     jboolean result = JNI_FALSE;
+    HCRYPTPROV hCryptProvAlt = NULL;
 
     __try
     {
@@ -584,8 +613,32 @@
         if (::CryptCreateHash(HCRYPTPROV(hCryptProv), algId, 0, 0, &hHash)
             == FALSE)
         {
-            ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
-            __leave;
+            // Failover to using the PROV_RSA_AES CSP
+
+            DWORD cbData = 256;
+            BYTE pbData[256];
+            pbData[0] = '\0';
+
+            // Get name of the key container
+            ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER,
+                (BYTE *)pbData, &cbData, 0);
+
+            // Acquire an alternative CSP handle
+            if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
+                PROV_RSA_AES, 0) == FALSE)
+            {
+
+                ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
+                __leave;
+            }
+
+            // Acquire a hash object handle.
+            if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0,
+                &hHash) == FALSE)
+            {
+                ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
+                __leave;
+            }
         }
 
         // Copy hash and signedHash from Java to native buffer
@@ -616,6 +669,9 @@
 
     __finally
     {
+        if (hCryptProvAlt)
+            ::CryptReleaseContext(hCryptProvAlt, 0);
+
         if (pSignedHashBuffer)
             delete [] pSignedHashBuffer;
 
@@ -648,15 +704,27 @@
         pszKeyContainerName = env->GetStringUTFChars(keyContainerName, NULL);
 
         // Acquire a CSP context (create a new key container).
+        // Prefer a PROV_RSA_AES CSP, when available, due to its support
+        // for SHA-2-based signatures.
         if (::CryptAcquireContext(
             &hCryptProv,
             pszKeyContainerName,
             NULL,
-            PROV_RSA_FULL,
+            PROV_RSA_AES,
             CRYPT_NEWKEYSET) == FALSE)
         {
-            ThrowException(env, KEY_EXCEPTION, GetLastError());
-            __leave;
+            // Failover to using the default CSP (PROV_RSA_FULL)
+
+            if (::CryptAcquireContext(
+                &hCryptProv,
+                pszKeyContainerName,
+                NULL,
+                PROV_RSA_FULL,
+                CRYPT_NEWKEYSET) == FALSE)
+            {
+                ThrowException(env, KEY_EXCEPTION, GetLastError());
+                __leave;
+            }
         }
 
         // Generate an RSA keypair
@@ -1849,15 +1917,27 @@
         pbKeyBlob = (BYTE *) env->GetByteArrayElements(keyBlob, 0);
 
         // Acquire a CSP context (create a new key container).
+        // Prefer a PROV_RSA_AES CSP, when available, due to its support
+        // for SHA-2-based signatures.
         if (::CryptAcquireContext(
             &hCryptProv,
             NULL,
             NULL,
-            PROV_RSA_FULL,
+            PROV_RSA_AES,
             CRYPT_VERIFYCONTEXT) == FALSE)
         {
-            ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
-            __leave;
+            // Failover to using the default CSP (PROV_RSA_FULL)
+
+            if (::CryptAcquireContext(
+                &hCryptProv,
+                NULL,
+                NULL,
+                PROV_RSA_FULL,
+                CRYPT_VERIFYCONTEXT) == FALSE)
+            {
+                ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
+                __leave;
+            }
         }
 
         // Import the public key
--- a/test/sun/security/krb5/auto/BadKdc.java	Tue Apr 26 14:25:42 2011 -0700
+++ b/test/sun/security/krb5/auto/BadKdc.java	Wed Apr 27 14:18:26 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -22,8 +22,14 @@
  */
 
 import java.io.*;
+import java.net.BindException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import javax.security.auth.login.LoginException;
+import sun.security.krb5.Asn1Exception;
 import sun.security.krb5.Config;
 
 public class BadKdc {
@@ -34,8 +40,51 @@
     static final Pattern re = Pattern.compile(
             ">>> KDCCommunication: kdc=kdc.rabbit.hole UDP:(\\d)...., " +
             "timeout=(\\d)000,");
+
+    /*
+     * There are several cases this test fails:
+     *
+     * 1. The random selected port is used by another process. No good way to
+     * prevent this happening, coz krb5.conf must be written before KDC starts.
+     * There are two different outcomes:
+     *
+     *  a. Cannot start the KDC. A BindException thrown.
+     *  b. When trying to access a non-existing KDC, a response is received!
+     *     Most likely a Asn1Exception thrown
+     *
+     * 2. Even if a KDC is started, and more than 20 seconds pass by, a timeout
+     * can still happens for the first UDP request. In fact, the KDC did not
+     * received it at all. This happens on almost all platforms, especially
+     * solaris-i586 and solaris-x64.
+     *
+     * To avoid them:
+     *
+     * 1. Catch those exceptions and ignore
+     *
+     * 2. a. Make the timeout longer? useless
+     *    b. Read the output carefully, if there is a timeout, it's OK.
+     *       Just make sure the retries times and KDCs are correct.
+     *       This is tough.
+     *    c. Feed the KDC a UDP packet first. The current "solution".
+     */
     public static void go(int[]... expected)
             throws Exception {
+        try {
+            go0(expected);
+        } catch (BindException be) {
+            System.out.println("The random port is used by another process");
+        } catch (LoginException le) {
+            Throwable cause = le.getCause();
+            if (cause instanceof Asn1Exception) {
+                System.out.println("Bad packet possibly from another process");
+                return;
+            }
+            throw le;
+        }
+    }
+
+    public static void go0(int[]... expected)
+            throws Exception {
         System.setProperty("sun.security.krb5.debug", "true");
 
         // Make sure KDCs' ports starts with 1 and 2 and 3,
@@ -78,20 +127,39 @@
         KDC k = new KDC(OneKDC.REALM, OneKDC.KDCHOST, p, true);
         k.addPrincipal(OneKDC.USER, OneKDC.PASS);
         k.addPrincipalRandKey("krbtgt/" + OneKDC.REALM);
+        // Feed a packet to newly started KDC to warm it up
+        System.err.println("-------- IGNORE THIS ERROR MESSAGE --------");
+        new DatagramSocket().send(
+                new DatagramPacket("Hello".getBytes(), 5,
+                        InetAddress.getByName(OneKDC.KDCHOST), p));
         return k;
     }
 
+    private static void test(int... expected) throws Exception {
+        ByteArrayOutputStream bo = new ByteArrayOutputStream();
+        try {
+            test0(bo, expected);
+        } catch (Exception e) {
+            System.out.println("----------------- ERROR -----------------");
+            System.out.println(new String(bo.toByteArray()));
+            System.out.println("--------------- ERROR END ---------------");
+            throw e;
+        }
+    }
+
     /**
      * One round of test for max_retries and timeout.
-     * @param timeout the expected timeout
      * @param expected the expected kdc# timeout kdc# timeout...
      */
-    private static void test(int... expected) throws Exception {
-        ByteArrayOutputStream bo = new ByteArrayOutputStream();
+    private static void test0(ByteArrayOutputStream bo, int... expected)
+            throws Exception {
         PrintStream oldout = System.out;
         System.setOut(new PrintStream(bo));
-        Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
-        System.setOut(oldout);
+        try {
+            Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+        } finally {
+            System.setOut(oldout);
+        }
 
         String[] lines = new String(bo.toByteArray()).split("\n");
         System.out.println("----------------- TEST -----------------");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/mscapi/SignUsingSHA2withRSA.java	Wed Apr 27 14:18:26 2011 -0700
@@ -0,0 +1,153 @@
+/*
+ * 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 SignUsingSHA2withRSA.sh
+ */
+
+import java.security.*;
+import java.util.*;
+
+public class SignUsingSHA2withRSA {
+
+    private static final byte[] toBeSigned = new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10
+    };
+
+    private static List<byte[]> generatedSignatures = new ArrayList<>();
+
+    public static void main(String[] args) throws Exception {
+
+        Provider[] providers = Security.getProviders("Signature.SHA256withRSA");
+        if (providers == null) {
+            System.out.println("No JCE providers support the " +
+                "'Signature.SHA256withRSA' algorithm");
+            System.out.println("Skipping this test...");
+            return;
+
+        } else {
+            System.out.println("The following JCE providers support the " +
+                "'Signature.SHA256withRSA' algorithm: ");
+            for (Provider provider : providers) {
+                System.out.println("    " + provider.getName());
+            }
+        }
+        System.out.println("-------------------------------------------------");
+
+        KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
+        ks.load(null, null);
+        System.out.println("Loaded keystore: Windows-MY");
+
+        Enumeration e = ks.aliases();
+        PrivateKey privateKey = null;
+        PublicKey publicKey = null;
+
+        while (e.hasMoreElements()) {
+            String alias = (String) e.nextElement();
+            if (alias.equals("6753664")) {
+                System.out.println("Loaded entry: " + alias);
+                privateKey = (PrivateKey) ks.getKey(alias, null);
+                publicKey = (PublicKey) ks.getCertificate(alias).getPublicKey();
+            }
+        }
+        if (privateKey == null || publicKey == null) {
+            throw new Exception("Cannot load the keys need to run this test");
+        }
+        System.out.println("-------------------------------------------------");
+
+        generatedSignatures.add(signUsing("SHA256withRSA", privateKey));
+        generatedSignatures.add(signUsing("SHA384withRSA", privateKey));
+        generatedSignatures.add(signUsing("SHA512withRSA", privateKey));
+
+        System.out.println("-------------------------------------------------");
+
+        verifyUsing("SHA256withRSA", publicKey, generatedSignatures.get(0));
+        verifyUsing("SHA384withRSA", publicKey, generatedSignatures.get(1));
+        verifyUsing("SHA512withRSA", publicKey, generatedSignatures.get(2));
+
+        System.out.println("-------------------------------------------------");
+    }
+
+    private static byte[] signUsing(String signAlgorithm,
+        PrivateKey privateKey) throws Exception {
+
+        // Must explicitly specify the SunMSCAPI JCE provider
+        // (otherwise SunJCE is chosen because it appears earlier in the list)
+        Signature sig1 = Signature.getInstance(signAlgorithm, "SunMSCAPI");
+        if (sig1 == null) {
+            throw new Exception("'" + signAlgorithm + "' is not supported");
+        }
+        System.out.println("Using " + signAlgorithm + " signer from the " +
+            sig1.getProvider().getName() + " JCE provider");
+
+        System.out.println("Using key: " + privateKey);
+        sig1.initSign(privateKey);
+        sig1.update(toBeSigned);
+        byte [] sigBytes = null;
+
+        try {
+            sigBytes = sig1.sign();
+            System.out.println("Generated RSA signature over a " +
+                toBeSigned.length + "-byte data (signature length: " +
+                sigBytes.length * 8 + " bits)");
+            System.out.println(String.format("0x%0" +
+                (sigBytes.length * 2) + "x",
+                new java.math.BigInteger(1, sigBytes)));
+
+        } catch (SignatureException se) {
+                System.out.println("Error generating RSA signature: " + se);
+        }
+
+        return sigBytes;
+    }
+
+    private static void verifyUsing(String signAlgorithm, PublicKey publicKey,
+        byte[] signature) throws Exception {
+
+        // Must explicitly specify the SunMSCAPI JCE provider
+        // (otherwise SunJCE is chosen because it appears earlier in the list)
+        Signature sig1 = Signature.getInstance(signAlgorithm, "SunMSCAPI");
+        if (sig1 == null) {
+            throw new Exception("'" + signAlgorithm + "' is not supported");
+        }
+        System.out.println("Using " + signAlgorithm + " verifier from the "
+            + sig1.getProvider().getName() + " JCE provider");
+
+        System.out.println("Using key: " + publicKey);
+
+        System.out.println("\nVerifying RSA Signature over a " +
+            toBeSigned.length + "-byte data (signature length: " +
+            signature.length * 8 + " bits)");
+        System.out.println(String.format("0x%0" + (signature.length * 2) +
+            "x", new java.math.BigInteger(1, signature)));
+
+        sig1.initVerify(publicKey);
+        sig1.update(toBeSigned);
+
+        if (sig1.verify(signature)) {
+            System.out.println("Verify PASSED\n");
+        } else {
+            throw new Exception("Verify FAILED");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/mscapi/SignUsingSHA2withRSA.sh	Wed Apr 27 14:18:26 2011 -0700
@@ -0,0 +1,83 @@
+#!/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 6753664
+# @run shell SignUsingSHA2withRSA.sh
+# @summary Support SHA256 (and higher) in SunMSCAPI
+
+# 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 6753664 \
+	    -dname "cn=6753664,c=US" \
+	    -noprompt
+
+        echo
+	echo "Running the test..."
+        ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\SignUsingSHA2withRSA.java
+        ${TESTJAVA}/bin/java SignUsingSHA2withRSA
+
+        rc=$?
+
+        echo
+        echo "Removing the temporary RSA keypair from the Windows-My store..."
+        ${TESTJAVA}/bin/keytool \
+	    -delete \
+	    -storetype Windows-My \
+	    -alias 6753664
+
+	echo done.
+        exit $rc
+        ;;
+
+    * )
+        echo "This test is not intended for '$OS' - passing test"
+        exit 0
+        ;;
+esac