changeset 3168:42669b895e22

Improve cryptography support. S4963723: Implement SHA-224 S6578658: Request for raw RSA (NONEwithRSA) Signature support in SunMSCAPI S6753664: Support SHA256 (and higher) in SunMSCAPI S7033170: Cipher.getMaxAllowedKeyLength(String) throws NoSuchAlgorithmException S7044060: Need to support NSA Suite B Cryptography algorithms S7106773: 512 bits RSA key cannot work with SHA384 and SHA512 S7180907: Jarsigner -verify fails if rsa file used sha-256 with authenticated attributes S8006935: Need to take care of long secret keys in HMAC/PRF compuation S8049480: Current versions of Java can't verify jars signed and timestamped with Java 9 2014-10-08 Andrew John Hughes <gnu.andrew@redhat.com> * Makefile.am: (ICEDTEA_PATCHES): Add new patches. * NEWS: Updated. * patches/openjdk/4963723-implement_sha-224.patch, * patches/openjdk/6578658-sunmscapi_nonewithrsa.patch, * patches/openjdk/6753664-sunmscapi_sha-256.patch, * patches/openjdk/7033170-getmaxallowedkeylength_throws_exception.patch, * patches/openjdk/7044060-support_nsa_suite_b.patch, * patches/openjdk/7106773-512_bits_rsa.patch, * patches/openjdk/7180907-jarsigner_sha-256.patch, * patches/openjdk/8006935-long_keys_in_hmac_prf.patch, * patches/openjdk/8049480-jarsigner_openjdk_9.patch: Backports to improve cryptography support.
author Andrew John Hughes <gnu.andrew@redhat.com>
date Thu, 09 Oct 2014 02:25:23 +0100
parents 34ab3ceed7cb
children 47eca861f17f
files ChangeLog Makefile.am NEWS patches/openjdk/4963723-implement_sha-224.patch patches/openjdk/6578658-sunmscapi_nonewithrsa.patch patches/openjdk/6753664-sunmscapi_sha-256.patch patches/openjdk/7033170-getmaxallowedkeylength_throws_exception.patch patches/openjdk/7044060-support_nsa_suite_b.patch patches/openjdk/7106773-512_bits_rsa.patch patches/openjdk/7180907-jarsigner_sha-256.patch patches/openjdk/8006935-long_keys_in_hmac_prf.patch patches/openjdk/8049480-jarsigner_openjdk_9.patch
diffstat 12 files changed, 8766 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Oct 08 19:38:54 2014 +0100
+++ b/ChangeLog	Thu Oct 09 02:25:23 2014 +0100
@@ -1,3 +1,19 @@
+2014-10-08  Andrew John Hughes  <gnu.andrew@redhat.com>
+
+	* Makefile.am:
+	(ICEDTEA_PATCHES): Add new patches.
+	* NEWS: Updated.
+	* patches/openjdk/4963723-implement_sha-224.patch,
+	* patches/openjdk/6578658-sunmscapi_nonewithrsa.patch,
+	* patches/openjdk/6753664-sunmscapi_sha-256.patch,
+	* patches/openjdk/7033170-getmaxallowedkeylength_throws_exception.patch,
+	* patches/openjdk/7044060-support_nsa_suite_b.patch,
+	* patches/openjdk/7106773-512_bits_rsa.patch,
+	* patches/openjdk/7180907-jarsigner_sha-256.patch,
+	* patches/openjdk/8006935-long_keys_in_hmac_prf.patch,
+	* patches/openjdk/8049480-jarsigner_openjdk_9.patch:
+	Backports to improve cryptography support.
+
 2014-10-08  Andrew John Hughes  <gnu.andrew@redhat.com>
 
 	* patches/openjdk/7027300-unsync_hashmap_causes_endless_loop.patch,
--- a/Makefile.am	Wed Oct 08 19:38:54 2014 +0100
+++ b/Makefile.am	Thu Oct 09 02:25:23 2014 +0100
@@ -606,7 +606,16 @@
 	patches/windows-jdk-sizecalc.patch \
 	patches/shark_fixes_from_8003868.patch \
 	patches/8003992_support_6.patch \
-	patches/shark-drop_compile_method_arg_following_7083786.patch
+	patches/shark-drop_compile_method_arg_following_7083786.patch \
+	patches/openjdk/4963723-implement_sha-224.patch \
+	patches/openjdk/7180907-jarsigner_sha-256.patch \
+	patches/openjdk/8049480-jarsigner_openjdk_9.patch \
+	patches/openjdk/6753664-sunmscapi_sha-256.patch \
+	patches/openjdk/6578658-sunmscapi_nonewithrsa.patch \
+	patches/openjdk/7033170-getmaxallowedkeylength_throws_exception.patch \
+	patches/openjdk/7044060-support_nsa_suite_b.patch \
+	patches/openjdk/8006935-long_keys_in_hmac_prf.patch \
+	patches/openjdk/7106773-512_bits_rsa.patch
 
 if WITH_RHINO
 ICEDTEA_PATCHES += \
--- a/NEWS	Wed Oct 08 19:38:54 2014 +0100
+++ b/NEWS	Thu Oct 09 02:25:23 2014 +0100
@@ -54,6 +54,16 @@
   - S8042850: Extra unused entries in ICU ScriptCodes enum
   - S8052162: REGRESSION: sun/java2d/cmm/ColorConvertOp tests fail since 7u71 b01
   - S8053963: (dc) Use DatagramChannel.receive() instead of read() in connect()
+ * Backports
+  - S4963723: Implement SHA-224
+  - S6578658: Request for raw RSA (NONEwithRSA) Signature support in SunMSCAPI
+  - S6753664: Support SHA256 (and higher) in SunMSCAPI
+  - S7033170: Cipher.getMaxAllowedKeyLength(String) throws NoSuchAlgorithmException
+  - S7044060: Need to support NSA Suite B Cryptography algorithms
+  - S7106773: 512 bits RSA key cannot work with SHA384 and SHA512
+  - S7180907: Jarsigner -verify fails if rsa file used sha-256 with authenticated attributes
+  - S8006935: Need to take care of long secret keys in HMAC/PRF compuation
+  - S8049480: Current versions of Java can't verify jars signed and timestamped with Java 9
 
 New in release 1.13.4 (2014-07-15):
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/4963723-implement_sha-224.patch	Thu Oct 09 02:25:23 2014 +0100
@@ -0,0 +1,2334 @@
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java	2014-10-08 23:26:07.127607311 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2002, 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
+@@ -38,16 +38,16 @@
+  * This class constitutes the core of HMAC-<MD> algorithms, where
+  * <MD> can be SHA1 or MD5, etc.
+  *
+- * It also contains the implementation classes for the SHA-256,
++ * It also contains the implementation classes for SHA-224, SHA-256,
+  * SHA-384, and SHA-512 HMACs.
+  *
+  * @author Jan Luehe
+  */
+-final class HmacCore implements Cloneable {
++abstract class HmacCore extends MacSpi implements Cloneable {
+ 
+-    private final MessageDigest md;
+-    private final byte[] k_ipad; // inner padding - key XORd with ipad
+-    private final byte[] k_opad; // outer padding - key XORd with opad
++    private MessageDigest md;
++    private byte[] k_ipad; // inner padding - key XORd with ipad
++    private byte[] k_opad; // outer padding - key XORd with opad
+     private boolean first;       // Is this the first data to be processed?
+ 
+     private final int blockLen;
+@@ -73,22 +73,11 @@
+     }
+ 
+     /**
+-     * Constructor used for cloning.
+-     */
+-    private HmacCore(HmacCore other) throws CloneNotSupportedException {
+-        this.md = (MessageDigest)other.md.clone();
+-        this.blockLen = other.blockLen;
+-        this.k_ipad = (byte[])other.k_ipad.clone();
+-        this.k_opad = (byte[])other.k_opad.clone();
+-        this.first = other.first;
+-    }
+-
+-    /**
+      * Returns the length of the HMAC in bytes.
+      *
+      * @return the HMAC length in bytes.
+      */
+-    int getDigestLength() {
++    protected int engineGetMacLength() {
+         return this.md.getDigestLength();
+     }
+ 
+@@ -103,9 +92,8 @@
+      * @exception InvalidAlgorithmParameterException if the given algorithm
+      * parameters are inappropriate for this MAC.
+      */
+-    void init(Key key, AlgorithmParameterSpec params)
++    protected void engineInit(Key key, AlgorithmParameterSpec params)
+             throws InvalidKeyException, InvalidAlgorithmParameterException {
+-
+         if (params != null) {
+             throw new InvalidAlgorithmParameterException
+                 ("HMAC does not use parameters");
+@@ -140,7 +128,7 @@
+         Arrays.fill(secret, (byte)0);
+         secret = null;
+ 
+-        reset();
++        engineReset();
+     }
+ 
+     /**
+@@ -148,7 +136,7 @@
+      *
+      * @param input the input byte to be processed.
+      */
+-    void update(byte input) {
++    protected void engineUpdate(byte input) {
+         if (first == true) {
+             // compute digest for 1st pass; start with inner pad
+             md.update(k_ipad);
+@@ -167,7 +155,7 @@
+      * @param offset the offset in <code>input</code> where the input starts.
+      * @param len the number of bytes to process.
+      */
+-    void update(byte input[], int offset, int len) {
++    protected void engineUpdate(byte input[], int offset, int len) {
+         if (first == true) {
+             // compute digest for 1st pass; start with inner pad
+             md.update(k_ipad);
+@@ -178,7 +166,13 @@
+         md.update(input, offset, len);
+     }
+ 
+-    void update(ByteBuffer input) {
++    /**
++     * Processes the <code>input.remaining()</code> bytes in the ByteBuffer
++     * <code>input</code>.
++     *
++     * @param input the input byte buffer.
++     */
++    protected void engineUpdate(ByteBuffer input) {
+         if (first == true) {
+             // compute digest for 1st pass; start with inner pad
+             md.update(k_ipad);
+@@ -194,7 +188,7 @@
+      *
+      * @return the HMAC result.
+      */
+-    byte[] doFinal() {
++    protected byte[] engineDoFinal() {
+         if (first == true) {
+             // compute digest for 1st pass; start with inner pad
+             md.update(k_ipad);
+@@ -223,7 +217,7 @@
+      * Resets the HMAC for further use, maintaining the secret key that the
+      * HMAC was initialized with.
+      */
+-    void reset() {
++    protected void engineReset() {
+         if (first == false) {
+             md.reset();
+             first = true;
+@@ -234,118 +228,38 @@
+      * Clones this object.
+      */
+     public Object clone() throws CloneNotSupportedException {
+-        return new HmacCore(this);
++        HmacCore copy = (HmacCore) super.clone();
++        copy.md = (MessageDigest) md.clone();
++        copy.k_ipad = k_ipad.clone();
++        copy.k_opad = k_opad.clone();
++        return copy;
++    }
++
++    // nested static class for the HmacSHA224 implementation
++    public static final class HmacSHA224 extends HmacCore {
++        public HmacSHA224() throws NoSuchAlgorithmException {
++            super("SHA-224", 64);
++        }
+     }
+ 
+     // nested static class for the HmacSHA256 implementation
+-    public static final class HmacSHA256 extends MacSpi implements Cloneable {
+-        private final HmacCore core;
++    public static final class HmacSHA256 extends HmacCore {
+         public HmacSHA256() throws NoSuchAlgorithmException {
+-            SunJCE.ensureIntegrity(getClass());
+-            core = new HmacCore("SHA-256", 64);
+-        }
+-        private HmacSHA256(HmacSHA256 base) throws CloneNotSupportedException {
+-            core = (HmacCore)base.core.clone();
+-        }
+-        protected int engineGetMacLength() {
+-            return core.getDigestLength();
+-        }
+-        protected void engineInit(Key key, AlgorithmParameterSpec params)
+-                throws InvalidKeyException, InvalidAlgorithmParameterException {
+-            core.init(key, params);
+-        }
+-        protected void engineUpdate(byte input) {
+-            core.update(input);
+-        }
+-        protected void engineUpdate(byte input[], int offset, int len) {
+-            core.update(input, offset, len);
+-        }
+-        protected void engineUpdate(ByteBuffer input) {
+-            core.update(input);
+-        }
+-        protected byte[] engineDoFinal() {
+-            return core.doFinal();
+-        }
+-        protected void engineReset() {
+-            core.reset();
+-        }
+-        public Object clone() throws CloneNotSupportedException {
+-            return new HmacSHA256(this);
++            super("SHA-256", 64);
+         }
+     }
+ 
+     // nested static class for the HmacSHA384 implementation
+-    public static final class HmacSHA384 extends MacSpi implements Cloneable {
+-        private final HmacCore core;
++    public static final class HmacSHA384 extends HmacCore {
+         public HmacSHA384() throws NoSuchAlgorithmException {
+-            SunJCE.ensureIntegrity(getClass());
+-            core = new HmacCore("SHA-384", 128);
+-        }
+-        private HmacSHA384(HmacSHA384 base) throws CloneNotSupportedException {
+-            core = (HmacCore)base.core.clone();
+-        }
+-        protected int engineGetMacLength() {
+-            return core.getDigestLength();
+-        }
+-        protected void engineInit(Key key, AlgorithmParameterSpec params)
+-                throws InvalidKeyException, InvalidAlgorithmParameterException {
+-            core.init(key, params);
+-        }
+-        protected void engineUpdate(byte input) {
+-            core.update(input);
+-        }
+-        protected void engineUpdate(byte input[], int offset, int len) {
+-            core.update(input, offset, len);
+-        }
+-        protected void engineUpdate(ByteBuffer input) {
+-            core.update(input);
+-        }
+-        protected byte[] engineDoFinal() {
+-            return core.doFinal();
+-        }
+-        protected void engineReset() {
+-            core.reset();
+-        }
+-        public Object clone() throws CloneNotSupportedException {
+-            return new HmacSHA384(this);
++            super("SHA-384", 128);
+         }
+     }
+ 
+     // nested static class for the HmacSHA512 implementation
+-    public static final class HmacSHA512 extends MacSpi implements Cloneable {
+-        private final HmacCore core;
++    public static final class HmacSHA512 extends HmacCore {
+         public HmacSHA512() throws NoSuchAlgorithmException {
+-            SunJCE.ensureIntegrity(getClass());
+-            core = new HmacCore("SHA-512", 128);
+-        }
+-        private HmacSHA512(HmacSHA512 base) throws CloneNotSupportedException {
+-            core = (HmacCore)base.core.clone();
+-        }
+-        protected int engineGetMacLength() {
+-            return core.getDigestLength();
+-        }
+-        protected void engineInit(Key key, AlgorithmParameterSpec params)
+-                throws InvalidKeyException, InvalidAlgorithmParameterException {
+-            core.init(key, params);
+-        }
+-        protected void engineUpdate(byte input) {
+-            core.update(input);
+-        }
+-        protected void engineUpdate(byte input[], int offset, int len) {
+-            core.update(input, offset, len);
+-        }
+-        protected void engineUpdate(ByteBuffer input) {
+-            core.update(input);
+-        }
+-        protected byte[] engineDoFinal() {
+-            return core.doFinal();
+-        }
+-        protected void engineReset() {
+-            core.reset();
+-        }
+-        public Object clone() throws CloneNotSupportedException {
+-            return new HmacSHA512(this);
++            super("SHA-512", 128);
+         }
+     }
+-
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5.java	2014-10-08 23:26:07.127607311 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 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
+@@ -37,11 +37,7 @@
+  *
+  * @author Jan Luehe
+  */
+-public final class HmacMD5 extends MacSpi implements Cloneable {
+-
+-    private HmacCore hmac;
+-    private static final int MD5_BLOCK_LENGTH = 64;
+-
++public final class HmacMD5 extends HmacCore {
+     /**
+      * Standard constructor, creates a new HmacMD5 instance.
+      * Verify the SunJCE provider in the constructor.
+@@ -50,92 +46,6 @@
+      * its own integrity
+      */
+     public HmacMD5() throws NoSuchAlgorithmException {
+-        if (!SunJCE.verifySelfIntegrity(this.getClass())) {
+-            throw new SecurityException("The SunJCE provider may have " +
+-                                        "been tampered.");
+-        }
+-        hmac = new HmacCore(MessageDigest.getInstance("MD5"),
+-                            MD5_BLOCK_LENGTH);
+-    }
+-
+-    /**
+-     * Returns the length of the HMAC in bytes.
+-     *
+-     * @return the HMAC length in bytes.
+-     */
+-    protected int engineGetMacLength() {
+-        return hmac.getDigestLength();
+-    }
+-
+-    /**
+-     * Initializes the HMAC with the given secret key and algorithm parameters.
+-     *
+-     * @param key the secret key.
+-     * @param params the algorithm parameters.
+-     *
+-     * @exception InvalidKeyException if the given key is inappropriate for
+-     * initializing this MAC.
+-     * @exception InvalidAlgorithmParameterException if the given algorithm
+-     * parameters are inappropriate for this MAC.
+-     */
+-    protected void engineInit(Key key, AlgorithmParameterSpec params)
+-        throws InvalidKeyException, InvalidAlgorithmParameterException {
+-        hmac.init(key, params);
+-    }
+-
+-    /**
+-     * Processes the given byte.
+-     *
+-     * @param input the input byte to be processed.
+-     */
+-    protected void engineUpdate(byte input) {
+-        hmac.update(input);
+-    }
+-
+-    /**
+-     * Processes the first <code>len</code> bytes in <code>input</code>,
+-     * starting at <code>offset</code>.
+-     *
+-     * @param input the input buffer.
+-     * @param offset the offset in <code>input</code> where the input starts.
+-     * @param len the number of bytes to process.
+-     */
+-    protected void engineUpdate(byte input[], int offset, int len) {
+-        hmac.update(input, offset, len);
+-    }
+-
+-    protected void engineUpdate(ByteBuffer input) {
+-        hmac.update(input);
+-    }
+-
+-    /**
+-     * Completes the HMAC computation and resets the HMAC for further use,
+-     * maintaining the secret key that the HMAC was initialized with.
+-     *
+-     * @return the HMAC result.
+-     */
+-    protected byte[] engineDoFinal() {
+-        return hmac.doFinal();
+-    }
+-
+-    /**
+-     * Resets the HMAC for further use, maintaining the secret key that the
+-     * HMAC was initialized with.
+-     */
+-    protected void engineReset() {
+-        hmac.reset();
+-    }
+-
+-    /*
+-     * Clones this object.
+-     */
+-    public Object clone() {
+-        HmacMD5 that = null;
+-        try {
+-            that = (HmacMD5) super.clone();
+-            that.hmac = (HmacCore) this.hmac.clone();
+-        } catch (CloneNotSupportedException e) {
+-        }
+-        return that;
++        super("MD5", 64);
+     }
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java	2014-10-08 23:26:07.127607311 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, 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
+@@ -41,10 +41,7 @@
+  *
+  * @author Valerie Peng
+  */
+-public final class HmacPKCS12PBESHA1 extends MacSpi implements Cloneable {
+-
+-    private HmacCore hmac = null;
+-    private static final int SHA1_BLOCK_LENGTH = 64;
++public final class HmacPKCS12PBESHA1 extends HmacCore {
+ 
+     /**
+      * Standard constructor, creates a new HmacSHA1 instance.
+@@ -54,18 +51,7 @@
+      * its own integrity
+      */
+     public HmacPKCS12PBESHA1() throws NoSuchAlgorithmException {
+-        SunJCE.ensureIntegrity(this.getClass());
+-        this.hmac = new HmacCore(MessageDigest.getInstance("SHA1"),
+-                                 SHA1_BLOCK_LENGTH);
+-    }
+-
+-    /**
+-     * Returns the length of the HMAC in bytes.
+-     *
+-     * @return the HMAC length in bytes.
+-     */
+-    protected int engineGetMacLength() {
+-        return hmac.getDigestLength();
++        super("SHA1", 64);
+     }
+ 
+     /**
+@@ -76,7 +62,7 @@
+      *
+      * @exception InvalidKeyException if the given key is inappropriate for
+      * initializing this MAC.
+-     u* @exception InvalidAlgorithmParameterException if the given algorithm
++     * @exception InvalidAlgorithmParameterException if the given algorithm
+      * parameters are inappropriate for this MAC.
+      */
+     protected void engineInit(Key key, AlgorithmParameterSpec params)
+@@ -145,64 +131,8 @@
+                 ("IterationCount must be a positive number");
+         }
+         byte[] derivedKey = PKCS12PBECipherCore.derive(passwdChars, salt,
+-            iCount, hmac.getDigestLength(), PKCS12PBECipherCore.MAC_KEY);
++            iCount, engineGetMacLength(), PKCS12PBECipherCore.MAC_KEY);
+         SecretKey cipherKey = new SecretKeySpec(derivedKey, "HmacSHA1");
+-        hmac.init(cipherKey, null);
+-    }
+-
+-    /**
+-     * Processes the given byte.
+-     *
+-     * @param input the input byte to be processed.
+-     */
+-    protected void engineUpdate(byte input) {
+-        hmac.update(input);
+-    }
+-
+-    /**
+-     * Processes the first <code>len</code> bytes in <code>input</code>,
+-     * starting at <code>offset</code>.
+-     *
+-     * @param input the input buffer.
+-     * @param offset the offset in <code>input</code> where the input starts.
+-     * @param len the number of bytes to process.
+-     */
+-    protected void engineUpdate(byte input[], int offset, int len) {
+-        hmac.update(input, offset, len);
+-    }
+-
+-    protected void engineUpdate(ByteBuffer input) {
+-        hmac.update(input);
+-    }
+-
+-    /**
+-     * Completes the HMAC computation and resets the HMAC for further use,
+-     * maintaining the secret key that the HMAC was initialized with.
+-     *
+-     * @return the HMAC result.
+-     */
+-    protected byte[] engineDoFinal() {
+-        return hmac.doFinal();
+-    }
+-
+-    /**
+-     * Resets the HMAC for further use, maintaining the secret key that the
+-     * HMAC was initialized with.
+-     */
+-    protected void engineReset() {
+-        hmac.reset();
+-    }
+-
+-    /*
+-     * Clones this object.
+-     */
+-    public Object clone() {
+-        HmacPKCS12PBESHA1 that = null;
+-        try {
+-            that = (HmacPKCS12PBESHA1)super.clone();
+-            that.hmac = (HmacCore)this.hmac.clone();
+-        } catch (CloneNotSupportedException e) {
+-        }
+-        return that;
++        super.engineInit(cipherKey, null);
+     }
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1.java	2014-10-08 23:26:07.127607311 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 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
+@@ -37,11 +37,7 @@
+  *
+  * @author Jan Luehe
+  */
+-public final class HmacSHA1 extends MacSpi implements Cloneable {
+-
+-    private HmacCore hmac = null;
+-    private static final int SHA1_BLOCK_LENGTH = 64;
+-
++public final class HmacSHA1 extends HmacCore {
+     /**
+      * Standard constructor, creates a new HmacSHA1 instance.
+      * Verify the SunJCE provider in the constructor.
+@@ -50,92 +46,6 @@
+      * its own integrity
+      */
+     public HmacSHA1() throws NoSuchAlgorithmException {
+-        if (!SunJCE.verifySelfIntegrity(this.getClass())) {
+-            throw new SecurityException("The SunJCE provider may have " +
+-                                        "been tampered.");
+-        }
+-        this.hmac = new HmacCore(MessageDigest.getInstance("SHA1"),
+-                                 SHA1_BLOCK_LENGTH);
+-    }
+-
+-    /**
+-     * Returns the length of the HMAC in bytes.
+-     *
+-     * @return the HMAC length in bytes.
+-     */
+-    protected int engineGetMacLength() {
+-        return hmac.getDigestLength();
+-    }
+-
+-    /**
+-     * Initializes the HMAC with the given secret key and algorithm parameters.
+-     *
+-     * @param key the secret key.
+-     * @param params the algorithm parameters.
+-     *
+-     * @exception InvalidKeyException if the given key is inappropriate for
+-     * initializing this MAC.
+-     * @exception InvalidAlgorithmParameterException if the given algorithm
+-     * parameters are inappropriate for this MAC.
+-     */
+-    protected void engineInit(Key key, AlgorithmParameterSpec params)
+-        throws InvalidKeyException, InvalidAlgorithmParameterException {
+-        hmac.init(key, params);
+-    }
+-
+-    /**
+-     * Processes the given byte.
+-     *
+-     * @param input the input byte to be processed.
+-     */
+-    protected void engineUpdate(byte input) {
+-        hmac.update(input);
+-    }
+-
+-    /**
+-     * Processes the first <code>len</code> bytes in <code>input</code>,
+-     * starting at <code>offset</code>.
+-     *
+-     * @param input the input buffer.
+-     * @param offset the offset in <code>input</code> where the input starts.
+-     * @param len the number of bytes to process.
+-     */
+-    protected void engineUpdate(byte input[], int offset, int len) {
+-        hmac.update(input, offset, len);
+-    }
+-
+-    protected void engineUpdate(ByteBuffer input) {
+-        hmac.update(input);
+-    }
+-
+-    /**
+-     * Completes the HMAC computation and resets the HMAC for further use,
+-     * maintaining the secret key that the HMAC was initialized with.
+-     *
+-     * @return the HMAC result.
+-     */
+-    protected byte[] engineDoFinal() {
+-        return hmac.doFinal();
+-    }
+-
+-    /**
+-     * Resets the HMAC for further use, maintaining the secret key that the
+-     * HMAC was initialized with.
+-     */
+-    protected void engineReset() {
+-        hmac.reset();
+-    }
+-
+-    /*
+-     * Clones this object.
+-     */
+-    public Object clone() {
+-        HmacSHA1 that = null;
+-        try {
+-            that = (HmacSHA1)super.clone();
+-            that.hmac = (HmacCore)this.hmac.clone();
+-        } catch (CloneNotSupportedException e) {
+-        }
+-        return that;
++        super("SHA1", 64);
+     }
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/KeyGeneratorCore.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/KeyGeneratorCore.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/KeyGeneratorCore.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/KeyGeneratorCore.java	2014-10-08 23:26:07.127607311 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, 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
+@@ -105,12 +105,12 @@
+         return new SecretKeySpec(b, name);
+     }
+ 
+-    // nested static class for the HmacSHA256 key generator
+-    public static final class HmacSHA256KG extends KeyGeneratorSpi {
++    // nested static classes for the HmacSHA-2 family of key generator
++    abstract static class HmacSHA2KG extends KeyGeneratorSpi {
+         private final KeyGeneratorCore core;
+-        public HmacSHA256KG() {
++        protected HmacSHA2KG(String algoName, int len) {
+             SunJCE.ensureIntegrity(getClass());
+-            core = new KeyGeneratorCore("HmacSHA256", 256);
++            core = new KeyGeneratorCore(algoName, len);
+         }
+         protected void engineInit(SecureRandom random) {
+             core.implInit(random);
+@@ -125,49 +125,25 @@
+         protected SecretKey engineGenerateKey() {
+             return core.implGenerateKey();
+         }
+-    }
+-
+-    // nested static class for the HmacSHA384 key generator
+-    public static final class HmacSHA384KG extends KeyGeneratorSpi {
+-        private final KeyGeneratorCore core;
+-        public HmacSHA384KG() {
+-            SunJCE.ensureIntegrity(getClass());
+-            core = new KeyGeneratorCore("HmacSHA384", 384);
+-        }
+-        protected void engineInit(SecureRandom random) {
+-            core.implInit(random);
+-        }
+-        protected void engineInit(AlgorithmParameterSpec params,
+-                SecureRandom random) throws InvalidAlgorithmParameterException {
+-            core.implInit(params, random);
+-        }
+-        protected void engineInit(int keySize, SecureRandom random) {
+-            core.implInit(keySize, random);
+-        }
+-        protected SecretKey engineGenerateKey() {
+-            return core.implGenerateKey();
+-        }
+-    }
+-
+-    // nested static class for the HmacSHA384 key generator
+-    public static final class HmacSHA512KG extends KeyGeneratorSpi {
+-        private final KeyGeneratorCore core;
+-        public HmacSHA512KG() {
+-            SunJCE.ensureIntegrity(getClass());
+-            core = new KeyGeneratorCore("HmacSHA512", 512);
+-        }
+-        protected void engineInit(SecureRandom random) {
+-            core.implInit(random);
+-        }
+-        protected void engineInit(AlgorithmParameterSpec params,
+-                SecureRandom random) throws InvalidAlgorithmParameterException {
+-            core.implInit(params, random);
+-        }
+-        protected void engineInit(int keySize, SecureRandom random) {
+-            core.implInit(keySize, random);
+-        }
+-        protected SecretKey engineGenerateKey() {
+-            return core.implGenerateKey();
++        public static final class SHA224 extends HmacSHA2KG {
++            public SHA224() {
++                super("HmacSHA224", 224);
++            }
++        }
++        public static final class SHA256 extends HmacSHA2KG {
++            public SHA256() {
++                super("HmacSHA256", 256);
++            }
++        }
++        public static final class SHA384 extends HmacSHA2KG {
++            public SHA384() {
++                super("HmacSHA384", 384);
++            }
++        }
++        public static final class SHA512 extends HmacSHA2KG {
++            public SHA512() {
++                super("HmacSHA512", 512);
++            }
+         }
+     }
+ 
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java	2014-10-08 23:26:07.127607311 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, 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
+@@ -143,6 +143,8 @@
+                 String mgfDigestName = convertToStandardName(params.getName());
+                 if (mgfDigestName.equals("SHA-1")) {
+                     mgfSpec = MGF1ParameterSpec.SHA1;
++                } else if (mgfDigestName.equals("SHA-224")) {
++                    mgfSpec = new MGF1ParameterSpec("SHA-224");
+                 } else if (mgfDigestName.equals("SHA-256")) {
+                     mgfSpec = MGF1ParameterSpec.SHA256;
+                 } else if (mgfDigestName.equals("SHA-384")) {
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java	2014-10-08 23:26:07.127607311 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 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
+@@ -70,7 +70,7 @@
+  *
+  * - Diffie-Hellman Key Agreement
+  *
+- * - HMAC-MD5, HMAC-SHA1, HMAC-SHA-256, HMAC-SHA-384, HMAC-SHA-512
++ * - HMAC-MD5, HMAC-SHA1, HMAC-SHA-224, HMAC-SHA-256, HMAC-SHA-384, HMAC-SHA-512
+  *
+  */
+ 
+@@ -121,6 +121,7 @@
+                         "NOPADDING|PKCS1PADDING|OAEPWITHMD5ANDMGF1PADDING"
+                         + "|OAEPWITHSHA1ANDMGF1PADDING"
+                         + "|OAEPWITHSHA-1ANDMGF1PADDING"
++                        + "|OAEPWITHSHA-224ANDMGF1PADDING"
+                         + "|OAEPWITHSHA-256ANDMGF1PADDING"
+                         + "|OAEPWITHSHA-384ANDMGF1PADDING"
+                         + "|OAEPWITHSHA-512ANDMGF1PADDING");
+@@ -229,12 +230,25 @@
+                 put("KeyGenerator.HmacSHA1",
+                     "com.sun.crypto.provider.HmacSHA1KeyGenerator");
+ 
++                put("KeyGenerator.HmacSHA224",
++                    "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA224");
++                put("Alg.Alias.KeyGenerator.OID.1.2.840.113549.2.8", "HmacSHA224");
++                put("Alg.Alias.KeyGenerator.1.2.840.113549.2.8", "HmacSHA224");
++
+                 put("KeyGenerator.HmacSHA256",
+-                    "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA256KG");
++                    "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA256");
++                put("Alg.Alias.KeyGenerator.OID.1.2.840.113549.2.9", "HmacSHA256");
++                put("Alg.Alias.KeyGenerator.1.2.840.113549.2.9", "HmacSHA256");
++
+                 put("KeyGenerator.HmacSHA384",
+-                    "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA384KG");
++                    "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA384");
++                put("Alg.Alias.KeyGenerator.OID.1.2.840.113549.2.10", "HmacSHA384");
++                put("Alg.Alias.KeyGenerator.1.2.840.113549.2.10", "HmacSHA384");
++
+                 put("KeyGenerator.HmacSHA512",
+-                    "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA512KG");
++                    "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA512");
++                put("Alg.Alias.KeyGenerator.OID.1.2.840.113549.2.11", "HmacSHA512");
++                put("Alg.Alias.KeyGenerator.1.2.840.113549.2.11", "HmacSHA512");
+ 
+                 put("KeyPairGenerator.DiffieHellman",
+                     "com.sun.crypto.provider.DHKeyPairGenerator");
+@@ -397,12 +411,23 @@
+                  */
+                 put("Mac.HmacMD5", "com.sun.crypto.provider.HmacMD5");
+                 put("Mac.HmacSHA1", "com.sun.crypto.provider.HmacSHA1");
++                put("Mac.HmacSHA224",
++                    "com.sun.crypto.provider.HmacCore$HmacSHA224");
++                put("Alg.Alias.Mac.OID.1.2.840.113549.2.8", "HmacSHA224");
++                put("Alg.Alias.Mac.1.2.840.113549.2.8", "HmacSHA224");
+                 put("Mac.HmacSHA256",
+                     "com.sun.crypto.provider.HmacCore$HmacSHA256");
++                put("Alg.Alias.Mac.OID.1.2.840.113549.2.9", "HmacSHA256");
++                put("Alg.Alias.Mac.1.2.840.113549.2.9", "HmacSHA256");
+                 put("Mac.HmacSHA384",
+                     "com.sun.crypto.provider.HmacCore$HmacSHA384");
++                put("Alg.Alias.Mac.OID.1.2.840.113549.2.10", "HmacSHA384");
++                put("Alg.Alias.Mac.1.2.840.113549.2.10", "HmacSHA384");
+                 put("Mac.HmacSHA512",
+                     "com.sun.crypto.provider.HmacCore$HmacSHA512");
++                put("Alg.Alias.Mac.OID.1.2.840.113549.2.11", "HmacSHA512");
++                put("Alg.Alias.Mac.1.2.840.113549.2.11", "HmacSHA512");
++
+                 put("Mac.HmacPBESHA1",
+                     "com.sun.crypto.provider.HmacPKCS12PBESHA1");
+ 
+@@ -413,6 +438,7 @@
+ 
+                 put("Mac.HmacMD5 SupportedKeyFormats", "RAW");
+                 put("Mac.HmacSHA1 SupportedKeyFormats", "RAW");
++                put("Mac.HmacSHA224 SupportedKeyFormats", "RAW");
+                 put("Mac.HmacSHA256 SupportedKeyFormats", "RAW");
+                 put("Mac.HmacSHA384 SupportedKeyFormats", "RAW");
+                 put("Mac.HmacSHA512 SupportedKeyFormats", "RAW");
+diff -Nru openjdk.orig/jdk/src/share/classes/java/security/spec/MGF1ParameterSpec.java openjdk/jdk/src/share/classes/java/security/spec/MGF1ParameterSpec.java
+--- openjdk.orig/jdk/src/share/classes/java/security/spec/MGF1ParameterSpec.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/java/security/spec/MGF1ParameterSpec.java	2014-10-08 23:26:07.131607366 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2006, 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
+@@ -42,6 +42,7 @@
+  * <pre>
+  * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+  *   { OID id-sha1 PARAMETERS NULL   }|
++ *   { OID id-sha224 PARAMETERS NULL   }|
+  *   { OID id-sha256 PARAMETERS NULL }|
+  *   { OID id-sha384 PARAMETERS NULL }|
+  *   { OID id-sha512 PARAMETERS NULL },
+diff -Nru openjdk.orig/jdk/src/share/classes/java/security/spec/PSSParameterSpec.java openjdk/jdk/src/share/classes/java/security/spec/PSSParameterSpec.java
+--- openjdk.orig/jdk/src/share/classes/java/security/spec/PSSParameterSpec.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/java/security/spec/PSSParameterSpec.java	2014-10-08 23:26:07.131607366 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 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
+@@ -47,6 +47,7 @@
+  * <pre>
+  * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+  *   { OID id-sha1 PARAMETERS NULL   }|
++ *   { OID id-sha224 PARAMETERS NULL   }|
+  *   { OID id-sha256 PARAMETERS NULL }|
+  *   { OID id-sha384 PARAMETERS NULL }|
+  *   { OID id-sha512 PARAMETERS NULL },
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11Digest.java openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Digest.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11Digest.java	2014-10-08 23:21:44.807972437 +0100
++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Digest.java	2014-10-08 23:26:07.131607366 +0100
+@@ -39,7 +39,7 @@
+ 
+ /**
+  * MessageDigest implementation class. This class currently supports
+- * MD2, MD5, SHA-1, SHA-256, SHA-384, and SHA-512.
++ * MD2, MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512.
+  *
+  * Note that many digest operations are on fairly small amounts of data
+  * (less than 100 bytes total). For example, the 2nd hashing in HMAC or
+@@ -99,6 +99,9 @@
+         case (int)CKM_SHA_1:
+             digestLength = 20;
+             break;
++        case (int)CKM_SHA224:
++            digestLength = 28;
++            break;
+         case (int)CKM_SHA256:
+             digestLength = 32;
+             break;
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11Mac.java openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Mac.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11Mac.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Mac.java	2014-10-08 23:26:07.131607366 +0100
+@@ -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
+@@ -40,8 +40,8 @@
+ 
+ /**
+  * MAC implementation class. This class currently supports HMAC using
+- * MD5, SHA-1, SHA-256, SHA-384, and SHA-512 and the SSL3 MAC using MD5
+- * and SHA-1.
++ * MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 and the SSL3 MAC
++ * using MD5 and SHA-1.
+  *
+  * Note that unlike other classes (e.g. Signature), this does not
+  * composite various operations if the token only supports part of the
+@@ -107,6 +107,9 @@
+         case (int)CKM_SHA_1_HMAC:
+             macLength = 20;
+             break;
++        case (int)CKM_SHA224_HMAC:
++            macLength = 28;
++            break;
+         case (int)CKM_SHA256_HMAC:
+             macLength = 32;
+             break;
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java	2014-10-08 23:26:07.131607366 +0100
+@@ -54,12 +54,14 @@
+  *   . MD2withRSA
+  *   . MD5withRSA
+  *   . SHA1withRSA
++ *   . SHA224withRSA
+  *   . SHA256withRSA
+  *   . SHA384withRSA
+  *   . SHA512withRSA
+  * . ECDSA
+  *   . NONEwithECDSA
+  *   . SHA1withECDSA
++ *   . SHA224withECDSA
+  *   . SHA256withECDSA
+  *   . SHA384withECDSA
+  *   . SHA512withECDSA
+@@ -144,6 +146,7 @@
+         case (int)CKM_MD2_RSA_PKCS:
+         case (int)CKM_MD5_RSA_PKCS:
+         case (int)CKM_SHA1_RSA_PKCS:
++        case (int)CKM_SHA224_RSA_PKCS:
+         case (int)CKM_SHA256_RSA_PKCS:
+         case (int)CKM_SHA384_RSA_PKCS:
+         case (int)CKM_SHA512_RSA_PKCS:
+@@ -182,6 +185,8 @@
+                 String digestAlg;
+                 if (algorithm.equals("SHA1withECDSA")) {
+                     digestAlg = "SHA-1";
++                } else if (algorithm.equals("SHA224withECDSA")) {
++                    digestAlg = "SHA-224";
+                 } else if (algorithm.equals("SHA256withECDSA")) {
+                     digestAlg = "SHA-256";
+                 } else if (algorithm.equals("SHA384withECDSA")) {
+@@ -209,6 +214,9 @@
+             } else if (algorithm.equals("MD2withRSA")) {
+                 md = MessageDigest.getInstance("MD2");
+                 digestOID = AlgorithmId.MD2_oid;
++            } else if (algorithm.equals("SHA224withRSA")) {
++                md = MessageDigest.getInstance("SHA-224");
++                digestOID = AlgorithmId.SHA224_oid;
+             } else if (algorithm.equals("SHA256withRSA")) {
+                 md = MessageDigest.getInstance("SHA-256");
+                 digestOID = AlgorithmId.SHA256_oid;
+@@ -334,6 +342,8 @@
+             encodedLength = 34;
+         } else if (algorithm.equals("SHA1withRSA")) {
+             encodedLength = 35;
++        } else if (algorithm.equals("SHA224withRSA")) {
++            encodedLength = 47;
+         } else if (algorithm.equals("SHA256withRSA")) {
+             encodedLength = 51;
+         } else if (algorithm.equals("SHA384withRSA")) {
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java openjdk/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java	2014-10-08 23:21:44.783972104 +0100
++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java	2014-10-08 23:26:07.131607366 +0100
+@@ -328,6 +328,7 @@
+                 System.out.println("Library info:");
+                 System.out.println(p11Info);
+             }
++
+             if ((slotID < 0) || showInfo) {
+                 long[] slots = p11.C_GetSlotList(false);
+                 if (showInfo) {
+@@ -522,24 +523,37 @@
+                 m(CKM_MD2));
+         d(MD, "MD5",            P11Digest,
+                 m(CKM_MD5));
+-        d(MD, "SHA1",           P11Digest,              s("SHA", "SHA-1"),
++        d(MD, "SHA1",           P11Digest, s("SHA", "SHA-1"),
+                 m(CKM_SHA_1));
++
++        d(MD, "SHA-224",        P11Digest,
++                s("2.16.840.1.101.3.4.2.4", "OID.2.16.840.1.101.3.4.2.4"),
++                m(CKM_SHA224));
+         d(MD, "SHA-256",        P11Digest,
++                s("2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1"),
+                 m(CKM_SHA256));
+         d(MD, "SHA-384",        P11Digest,
++                s("2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2"),
+                 m(CKM_SHA384));
+         d(MD, "SHA-512",        P11Digest,
++                s("2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3"),
+                 m(CKM_SHA512));
+ 
+         d(MAC, "HmacMD5",       P11MAC,
+                 m(CKM_MD5_HMAC));
+         d(MAC, "HmacSHA1",      P11MAC,
+                 m(CKM_SHA_1_HMAC));
++        d(MAC, "HmacSHA224",    P11MAC,
++                s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"),
++                m(CKM_SHA224_HMAC));
+         d(MAC, "HmacSHA256",    P11MAC,
++                s("1.2.840.113549.2.9", "OID.1.2.840.113549.2.9"),
+                 m(CKM_SHA256_HMAC));
+         d(MAC, "HmacSHA384",    P11MAC,
++                s("1.2.840.113549.2.10", "OID.1.2.840.113549.2.10"),
+                 m(CKM_SHA384_HMAC));
+         d(MAC, "HmacSHA512",    P11MAC,
++                s("1.2.840.113549.2.11", "OID.1.2.840.113549.2.11"),
+                 m(CKM_SHA512_HMAC));
+         d(MAC, "SslMacMD5",     P11MAC,
+                 m(CKM_SSL3_MD5_MAC));
+@@ -637,11 +651,17 @@
+                 m(CKM_ECDSA));
+         d(SIG, "SHA1withECDSA", P11Signature,           s("ECDSA"),
+                 m(CKM_ECDSA_SHA1, CKM_ECDSA));
++        d(SIG, "SHA224withECDSA",       P11Signature,
++                s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"),
++                m(CKM_ECDSA));
+         d(SIG, "SHA256withECDSA",       P11Signature,
++                s("1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"),
+                 m(CKM_ECDSA));
+         d(SIG, "SHA384withECDSA",       P11Signature,
++                s("1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3"),
+                 m(CKM_ECDSA));
+         d(SIG, "SHA512withECDSA",       P11Signature,
++                s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"),
+                 m(CKM_ECDSA));
+         d(SIG, "MD2withRSA",    P11Signature,
+                 m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+@@ -649,11 +669,17 @@
+                 m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+         d(SIG, "SHA1withRSA",   P11Signature,
+                 m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
++        d(SIG, "SHA224withRSA", P11Signature,
++                s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"),
++                m(CKM_SHA224_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+         d(SIG, "SHA256withRSA", P11Signature,
++                s("1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11"),
+                 m(CKM_SHA256_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+         d(SIG, "SHA384withRSA", P11Signature,
++                s("1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12"),
+                 m(CKM_SHA384_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+         d(SIG, "SHA512withRSA", P11Signature,
++                s("1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13"),
+                 m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+ 
+         d(KG, "SunTlsRsaPremasterSecret", "sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator",
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/wrapper/Functions.java openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/Functions.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/wrapper/Functions.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/Functions.java	2014-10-08 23:26:07.131607366 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+  */
+ 
+ /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+@@ -630,6 +630,7 @@
+         addMech(CKM_X9_42_DH_DERIVE,            "CKM_X9_42_DH_DERIVE");
+         addMech(CKM_X9_42_DH_HYBRID_DERIVE,     "CKM_X9_42_DH_HYBRID_DERIVE");
+         addMech(CKM_X9_42_MQV_DERIVE,           "CKM_X9_42_MQV_DERIVE");
++        addMech(CKM_SHA224_RSA_PKCS,            "CKM_SHA224_RSA_PKCS");
+         addMech(CKM_SHA256_RSA_PKCS,            "CKM_SHA256_RSA_PKCS");
+         addMech(CKM_SHA384_RSA_PKCS,            "CKM_SHA384_RSA_PKCS");
+         addMech(CKM_SHA512_RSA_PKCS,            "CKM_SHA512_RSA_PKCS");
+@@ -675,6 +676,9 @@
+         addMech(CKM_RIPEMD160,                  "CKM_RIPEMD160");
+         addMech(CKM_RIPEMD160_HMAC,             "CKM_RIPEMD160_HMAC");
+         addMech(CKM_RIPEMD160_HMAC_GENERAL,     "CKM_RIPEMD160_HMAC_GENERAL");
++        addMech(CKM_SHA224,                     "CKM_SHA224");
++        addMech(CKM_SHA224_HMAC,                "CKM_SHA224_HMAC");
++        addMech(CKM_SHA224_HMAC_GENERAL,        "CKM_SHA224_HMAC_GENERAL");
+         addMech(CKM_SHA256,                     "CKM_SHA256");
+         addMech(CKM_SHA256_HMAC,                "CKM_SHA256_HMAC");
+         addMech(CKM_SHA256_HMAC_GENERAL,        "CKM_SHA256_HMAC_GENERAL");
+@@ -734,6 +738,7 @@
+         addMech(CKM_MD5_KEY_DERIVATION,         "CKM_MD5_KEY_DERIVATION");
+         addMech(CKM_MD2_KEY_DERIVATION,         "CKM_MD2_KEY_DERIVATION");
+         addMech(CKM_SHA1_KEY_DERIVATION,        "CKM_SHA1_KEY_DERIVATION");
++        addMech(CKM_SHA224_KEY_DERIVATION,      "CKM_SHA224_KEY_DERIVATION");
+         addMech(CKM_SHA256_KEY_DERIVATION,      "CKM_SHA256_KEY_DERIVATION");
+         addMech(CKM_SHA384_KEY_DERIVATION,      "CKM_SHA384_KEY_DERIVATION");
+         addMech(CKM_SHA512_KEY_DERIVATION,      "CKM_SHA512_KEY_DERIVATION");
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/DigestBase.java openjdk/jdk/src/share/classes/sun/security/provider/DigestBase.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/DigestBase.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/DigestBase.java	2014-10-08 23:26:07.131607366 +0100
+@@ -39,7 +39,6 @@
+  *  . abstract void implCompress(byte[] b, int ofs);
+  *  . abstract void implDigest(byte[] out, int ofs);
+  *  . abstract void implReset();
+- *  . public abstract Object clone();
+  *
+  * See the inline documentation for details.
+  *
+@@ -61,7 +60,7 @@
+     // buffer to store partial blocks, blockSize bytes large
+     // Subclasses should not access this array directly except possibly in their
+     // implDigest() method. See MD5.java as an example.
+-    final byte[] buffer;
++    byte[] buffer;
+     // offset into buffer
+     private int bufOfs;
+ 
+@@ -83,18 +82,6 @@
+         buffer = new byte[blockSize];
+     }
+ 
+-    /**
+-     * Constructor for cloning. Replicates common data.
+-     */
+-    DigestBase(DigestBase base) {
+-        this.algorithm = base.algorithm;
+-        this.digestLength = base.digestLength;
+-        this.blockSize = base.blockSize;
+-        this.buffer = base.buffer.clone();
+-        this.bufOfs = base.bufOfs;
+-        this.bytesProcessed = base.bytesProcessed;
+-    }
+-
+     // return digest length. See JCA doc.
+     protected final int engineGetDigestLength() {
+         return digestLength;
+@@ -206,12 +193,11 @@
+      */
+     abstract void implReset();
+ 
+-    /**
+-     * Clone this digest. Should be implemented as "return new MyDigest(this)".
+-     * That constructor should first call "super(baseDigest)" and then copy
+-     * subclass specific data.
+-     */
+-    public abstract Object clone();
++    public Object clone() throws CloneNotSupportedException {
++        DigestBase copy = (DigestBase) super.clone();
++        copy.buffer = copy.buffer.clone();
++        return copy;
++    }
+ 
+     // padding used for the MD5, and SHA-* message digests
+     static final byte[] padding;
+@@ -223,5 +209,4 @@
+         padding = new byte[136];
+         padding[0] = (byte)0x80;
+     }
+-
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/MD2.java openjdk/jdk/src/share/classes/sun/security/provider/MD2.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/MD2.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/MD2.java	2014-10-08 23:26:07.131607366 +0100
+@@ -39,14 +39,14 @@
+ public final class MD2 extends DigestBase {
+ 
+     // state, 48 ints
+-    private final int[] X;
++    private int[] X;
+ 
+     // checksum, 16 ints. they are really bytes, but byte arithmetic in
+     // the JVM is much slower that int arithmetic.
+-    private final int[] C;
++    private int[] C;
+ 
+     // temporary store for checksum C during final digest
+-    private final byte[] cBytes;
++    private byte[] cBytes;
+ 
+     /**
+      * Create a new MD2 digest. Called by the JCA framework
+@@ -58,15 +58,12 @@
+         cBytes = new byte[16];
+     }
+ 
+-    private MD2(MD2 base) {
+-        super(base);
+-        this.X = base.X.clone();
+-        this.C = base.C.clone();
+-        cBytes = new byte[16];
+-    }
+-
+-    public Object clone() {
+-        return new MD2(this);
++    public Object clone() throws CloneNotSupportedException {
++        MD2 copy = (MD2) super.clone();
++        copy.X = copy.X.clone();
++        copy.C = copy.C.clone();
++        copy.cBytes = new byte[16];
++        return copy;
+     }
+ 
+     // reset state and checksum
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/MD4.java openjdk/jdk/src/share/classes/sun/security/provider/MD4.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/MD4.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/MD4.java	2014-10-08 23:26:07.131607366 +0100
+@@ -44,9 +44,9 @@
+ public final class MD4 extends DigestBase {
+ 
+     // state of this object
+-    private final int[] state;
++    private int[] state;
+     // temporary buffer, used by implCompress()
+-    private final int[] x;
++    private int[] x;
+ 
+     // rotation constants
+     private static final int S11 = 3;
+@@ -91,16 +91,12 @@
+         implReset();
+     }
+ 
+-    // Cloning constructor
+-    private MD4(MD4 base) {
+-        super(base);
+-        this.state = base.state.clone();
+-        this.x = new int[16];
+-    }
+-
+     // clone this object
+-    public Object clone() {
+-        return new MD4(this);
++    public Object clone() throws CloneNotSupportedException {
++        MD4 copy = (MD4) super.clone();
++        copy.state = copy.state.clone();
++        copy.x = new int[16];
++        return copy;
+     }
+ 
+     /**
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/MD5.java openjdk/jdk/src/share/classes/sun/security/provider/MD5.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/MD5.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/MD5.java	2014-10-08 23:26:07.131607366 +0100
+@@ -39,9 +39,9 @@
+ public final class MD5 extends DigestBase {
+ 
+     // state of this object
+-    private final int[] state;
++    private int[] state;
+     // temporary buffer, used by implCompress()
+-    private final int[] x;
++    private int[] x;
+ 
+     // rotation constants
+     private static final int S11 = 7;
+@@ -69,16 +69,12 @@
+         implReset();
+     }
+ 
+-    // Cloning constructor
+-    private MD5(MD5 base) {
+-        super(base);
+-        this.state = base.state.clone();
+-        this.x = new int[16];
+-    }
+-
+     // clone this object
+-    public Object clone() {
+-        return new MD5(this);
++    public Object clone() throws CloneNotSupportedException {
++        MD5 copy = (MD5) super.clone();
++        copy.state = copy.state.clone();
++        copy.x = new int[16];
++        return copy;
+     }
+ 
+     /**
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/SHA2.java openjdk/jdk/src/share/classes/sun/security/provider/SHA2.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/SHA2.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/SHA2.java	2014-10-08 23:26:07.131607366 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2002, 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
+@@ -40,7 +40,7 @@
+  * @author      Valerie Peng
+  * @author      Andreas Sterbenz
+  */
+-public final class SHA2 extends DigestBase {
++abstract class SHA2 extends DigestBase {
+ 
+     private static final int ITERATION = 64;
+     // Constants for each round
+@@ -64,46 +64,30 @@
+     };
+ 
+     // buffer used by implCompress()
+-    private final int[] W;
++    private int[] W;
+ 
+     // state of this object
+-    private final int[] state;
++    private int[] state;
++
++    // initial state value. different between SHA-224 and SHA-256
++    private final int[] initialHashes;
+ 
+     /**
+      * Creates a new SHA object.
+      */
+-    public SHA2() {
+-        super("SHA-256", 32, 64);
++    SHA2(String name, int digestLength, int[] initialHashes) {
++        super(name, digestLength, 64);
++        this.initialHashes = initialHashes;
+         state = new int[8];
+         W = new int[64];
+         implReset();
+     }
+ 
+     /**
+-     * Creates a SHA2 object.with state (for cloning)
+-     */
+-    private SHA2(SHA2 base) {
+-        super(base);
+-        this.state = base.state.clone();
+-        this.W = new int[64];
+-    }
+-
+-    public Object clone() {
+-        return new SHA2(this);
+-    }
+-
+-    /**
+      * Resets the buffers and hash value to start a new hash.
+      */
+     void implReset() {
+-        state[0] = 0x6a09e667;
+-        state[1] = 0xbb67ae85;
+-        state[2] = 0x3c6ef372;
+-        state[3] = 0xa54ff53a;
+-        state[4] = 0x510e527f;
+-        state[5] = 0x9b05688c;
+-        state[6] = 0x1f83d9ab;
+-        state[7] = 0x5be0cd19;
++        System.arraycopy(initialHashes, 0, state, 0, state.length);
+     }
+ 
+     void implDigest(byte[] out, int ofs) {
+@@ -242,4 +226,38 @@
+         state[7] += h;
+     }
+ 
++    public Object clone() throws CloneNotSupportedException {
++        SHA2 copy = (SHA2) super.clone();
++        copy.state = copy.state.clone();
++        copy.W = new int[64];
++        return copy;
++    }
++
++    /**
++     * SHA-224 implementation class.
++     */
++    public static final class SHA224 extends SHA2 {
++        private static final int[] INITIAL_HASHES = {
++            0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
++            0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
++        };
++
++        public SHA224() {
++            super("SHA-224", 28, INITIAL_HASHES);
++        }
++    }
++
++    /**
++     * SHA-256 implementation class.
++     */
++    public static final class SHA256 extends SHA2 {
++        private static final int[] INITIAL_HASHES = {
++            0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
++            0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
++        };
++
++        public SHA256() {
++            super("SHA-256", 32, INITIAL_HASHES);
++        }
++    }
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/SHA5.java openjdk/jdk/src/share/classes/sun/security/provider/SHA5.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/SHA5.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/SHA5.java	2014-10-08 23:26:07.131607366 +0100
+@@ -82,10 +82,10 @@
+     };
+ 
+     // buffer used by implCompress()
+-    private final long[] W;
++    private long[] W;
+ 
+     // state of this object
+-    private final long[] state;
++    private long[] state;
+ 
+     // initial state value. different between SHA-384 and SHA-512
+     private final long[] initialHashes;
+@@ -101,16 +101,6 @@
+         implReset();
+     }
+ 
+-    /**
+-     * Creates a SHA object with state (for cloning)
+-     */
+-    SHA5(SHA5 base) {
+-        super(base);
+-        this.initialHashes = base.initialHashes;
+-        this.state = base.state.clone();
+-        this.W = new long[80];
+-    }
+-
+     final void implReset() {
+         System.arraycopy(initialHashes, 0, state, 0, state.length);
+     }
+@@ -255,6 +245,13 @@
+         state[7] += h;
+     }
+ 
++    public Object clone() throws CloneNotSupportedException {
++        SHA5 copy = (SHA5) super.clone();
++        copy.state = copy.state.clone();
++        copy.W = new long[80];
++        return copy;
++    }
++
+     /**
+      * SHA-512 implementation class.
+      */
+@@ -270,14 +267,6 @@
+         public SHA512() {
+             super("SHA-512", 64, INITIAL_HASHES);
+         }
+-
+-        private SHA512(SHA512 base) {
+-            super(base);
+-        }
+-
+-        public Object clone() {
+-            return new SHA512(this);
+-        }
+     }
+ 
+     /**
+@@ -295,14 +284,5 @@
+         public SHA384() {
+             super("SHA-384", 48, INITIAL_HASHES);
+         }
+-
+-        private SHA384(SHA384 base) {
+-            super(base);
+-        }
+-
+-        public Object clone() {
+-            return new SHA384(this);
+-        }
+     }
+-
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/SHA.java openjdk/jdk/src/share/classes/sun/security/provider/SHA.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/SHA.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/SHA.java	2014-10-08 23:26:07.131607366 +0100
+@@ -47,10 +47,10 @@
+     // 64 bytes are included in each hash block so the low order
+     // bits of count are used to know how to pack the bytes into ints
+     // and to know when to compute the block and start the next one.
+-    private final int[] W;
++    private int[] W;
+ 
+     // state of this
+-    private final int[] state;
++    private int[] state;
+ 
+     /**
+      * Creates a new SHA object.
+@@ -62,19 +62,14 @@
+         implReset();
+     }
+ 
+-    /**
+-     * Creates a SHA object.with state (for cloning) */
+-    private SHA(SHA base) {
+-        super(base);
+-        this.state = base.state.clone();
+-        this.W = new int[80];
+-    }
+-
+     /*
+      * Clones this object.
+      */
+-    public Object clone() {
+-        return new SHA(this);
++    public Object clone() throws CloneNotSupportedException {
++        SHA copy = (SHA) super.clone();
++        copy.state = copy.state.clone();
++        copy.W = new int[80];
++        return copy;
+     }
+ 
+     /**
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/SunEntries.java openjdk/jdk/src/share/classes/sun/security/provider/SunEntries.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/SunEntries.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/SunEntries.java	2014-10-08 23:26:07.131607366 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2006, 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
+@@ -43,6 +43,10 @@
+  *   identifier strings "OID.1.3.14.3.2.13", "OID.1.3.14.3.2.27" and
+  *   "OID.1.2.840.10040.4.3".
+  *
++ * - SHA-2 is a set of message digest schemes described in FIPS 180-2.
++ *   SHA-2 family of hash functions includes SHA-224, SHA-256, SHA-384,
++ *   and SHA-512.
++ *
+  * - DSA is the key generation scheme as described in FIPS 186.
+  *   Aliases for DSA include the OID strings "OID.1.3.14.3.2.12"
+  *   and "OID.1.2.840.10040.4.1".
+@@ -140,9 +144,19 @@
+         map.put("Alg.Alias.MessageDigest.SHA-1", "SHA");
+         map.put("Alg.Alias.MessageDigest.SHA1", "SHA");
+ 
+-        map.put("MessageDigest.SHA-256", "sun.security.provider.SHA2");
++        map.put("MessageDigest.SHA-224", "sun.security.provider.SHA2$SHA224");
++        map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.4", "SHA-224");
++        map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.4", "SHA-224");
++
++        map.put("MessageDigest.SHA-256", "sun.security.provider.SHA2$SHA256");
++        map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.1", "SHA-256");
++        map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.1", "SHA-256");
+         map.put("MessageDigest.SHA-384", "sun.security.provider.SHA5$SHA384");
++        map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.2", "SHA-384");
++        map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.2", "SHA-384");
+         map.put("MessageDigest.SHA-512", "sun.security.provider.SHA5$SHA512");
++        map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.3", "SHA-512");
++        map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.3", "SHA-512");
+ 
+         /*
+          * Algorithm Parameter Generator engines
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/rsa/RSASignature.java openjdk/jdk/src/share/classes/sun/security/rsa/RSASignature.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/rsa/RSASignature.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/rsa/RSASignature.java	2014-10-08 23:26:07.131607366 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2006, 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
+@@ -40,8 +40,8 @@
+  * PKCS#1 RSA signatures with the various message digest algorithms.
+  * This file contains an abstract base class with all the logic plus
+  * a nested static class for each of the message digest algorithms
+- * (see end of the file). We support MD2, MD5, SHA-1, SHA-256, SHA-384,
+- * and SHA-512.
++ * (see end of the file). We support MD2, MD5, SHA-1, SHA-224, SHA-256,
++ * SHA-384, and SHA-512.
+  *
+  * @since   1.5
+  * @author  Andreas Sterbenz
+@@ -271,6 +271,13 @@
+         }
+     }
+ 
++    // Nested class for SHA224withRSA signatures
++    public static final class SHA224withRSA extends RSASignature {
++        public SHA224withRSA() {
++            super("SHA-224", AlgorithmId.SHA224_oid, 11);
++        }
++    }
++
+     // Nested class for SHA256withRSA signatures
+     public static final class SHA256withRSA extends RSASignature {
+         public SHA256withRSA() {
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/rsa/SunRsaSignEntries.java openjdk/jdk/src/share/classes/sun/security/rsa/SunRsaSignEntries.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/rsa/SunRsaSignEntries.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/rsa/SunRsaSignEntries.java	2014-10-08 23:26:07.131607366 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2006, 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
+@@ -52,6 +52,8 @@
+                 "sun.security.rsa.RSASignature$MD5withRSA");
+         map.put("Signature.SHA1withRSA",
+                 "sun.security.rsa.RSASignature$SHA1withRSA");
++        map.put("Signature.SHA224withRSA",
++                "sun.security.rsa.RSASignature$SHA224withRSA");
+         map.put("Signature.SHA256withRSA",
+                 "sun.security.rsa.RSASignature$SHA256withRSA");
+         map.put("Signature.SHA384withRSA",
+@@ -66,6 +68,7 @@
+         map.put("Signature.MD2withRSA SupportedKeyClasses", rsaKeyClasses);
+         map.put("Signature.MD5withRSA SupportedKeyClasses", rsaKeyClasses);
+         map.put("Signature.SHA1withRSA SupportedKeyClasses", rsaKeyClasses);
++        map.put("Signature.SHA224withRSA SupportedKeyClasses", rsaKeyClasses);
+         map.put("Signature.SHA256withRSA SupportedKeyClasses", rsaKeyClasses);
+         map.put("Signature.SHA384withRSA SupportedKeyClasses", rsaKeyClasses);
+         map.put("Signature.SHA512withRSA SupportedKeyClasses", rsaKeyClasses);
+@@ -88,6 +91,9 @@
+         map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA1withRSA");
+         map.put("Alg.Alias.Signature.1.3.14.3.2.29",            "SHA1withRSA");
+ 
++        map.put("Alg.Alias.Signature.1.2.840.113549.1.1.14",     "SHA224withRSA");
++        map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.14", "SHA224withRSA");
++
+         map.put("Alg.Alias.Signature.1.2.840.113549.1.1.11",     "SHA256withRSA");
+         map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.11", "SHA256withRSA");
+ 
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/x509/AlgorithmId.java openjdk/jdk/src/share/classes/sun/security/x509/AlgorithmId.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/x509/AlgorithmId.java	2014-10-08 23:21:44.739971495 +0100
++++ openjdk/jdk/src/share/classes/sun/security/x509/AlgorithmId.java	2014-10-08 23:26:20.231788929 +0100
+@@ -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
+@@ -175,9 +175,9 @@
+             // it's NULL. They are ---
+             // rfc3370 2.1: Implementations SHOULD generate SHA-1
+             // AlgorithmIdentifiers with absent parameters.
+-            // rfc3447 C1: When id-sha1, id-sha256, id-sha384 and id-sha512
+-            // are used in an AlgorithmIdentifier the parameters (which are
+-            // optional) SHOULD be omitted.
++            // rfc3447 C1: When id-sha1, id-sha224, id-sha256, id-sha384 and
++            // id-sha512 are used in an AlgorithmIdentifier the parameters
++            // (which are optional) SHOULD be omitted.
+             // rfc3279 2.3.2: The id-dsa algorithm syntax includes optional
+             // domain parameters... When omitted, the parameters component
+             // MUST be omitted entirely
+@@ -185,6 +185,7 @@
+             // is used, the AlgorithmIdentifier parameters field MUST be absent.
+             /*if (
+                 algid.equals((Object)SHA_oid) ||
++                algid.equals((Object)SHA224_oid) ||
+                 algid.equals((Object)SHA256_oid) ||
+                 algid.equals((Object)SHA384_oid) ||
+                 algid.equals((Object)SHA512_oid) ||
+@@ -488,7 +489,10 @@
+             name.equalsIgnoreCase("SHA512")) {
+             return AlgorithmId.SHA512_oid;
+         }
+-
++        if (name.equalsIgnoreCase("SHA-224") ||
++            name.equalsIgnoreCase("SHA224")) {
++            return AlgorithmId.SHA224_oid;
++        }
+ 
+         // Various public key algorithms
+         if (name.equalsIgnoreCase("RSA")) {
+@@ -613,6 +617,9 @@
+     public static final ObjectIdentifier SHA_oid =
+     ObjectIdentifier.newInternal(new int[] {1, 3, 14, 3, 2, 26});
+ 
++    public static final ObjectIdentifier SHA224_oid =
++    ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 4});
++
+     public static final ObjectIdentifier SHA256_oid =
+     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 1});
+ 
+@@ -652,6 +659,8 @@
+                                        { 1, 2, 840, 113549, 1, 1, 5 };
+     private static final int sha1WithRSAEncryption_OIW_data[] =
+                                        { 1, 3, 14, 3, 2, 29 };
++    private static final int sha224WithRSAEncryption_data[] =
++                                       { 1, 2, 840, 113549, 1, 1, 14 };
+     private static final int sha256WithRSAEncryption_data[] =
+                                        { 1, 2, 840, 113549, 1, 1, 11 };
+     private static final int sha384WithRSAEncryption_data[] =
+@@ -669,6 +678,7 @@
+     public static final ObjectIdentifier md5WithRSAEncryption_oid;
+     public static final ObjectIdentifier sha1WithRSAEncryption_oid;
+     public static final ObjectIdentifier sha1WithRSAEncryption_OIW_oid;
++    public static final ObjectIdentifier sha224WithRSAEncryption_oid;
+     public static final ObjectIdentifier sha256WithRSAEncryption_oid;
+     public static final ObjectIdentifier sha384WithRSAEncryption_oid;
+     public static final ObjectIdentifier sha512WithRSAEncryption_oid;
+@@ -798,6 +808,14 @@
+             ObjectIdentifier.newInternal(sha1WithRSAEncryption_OIW_data);
+ 
+     /**
++     * Identifies a signing algorithm where a SHA224 digest is
++     * encrypted using an RSA private key; defined by PKCS #1.
++     * OID = 1.2.840.113549.1.1.14
++     */
++        sha224WithRSAEncryption_oid =
++            ObjectIdentifier.newInternal(sha224WithRSAEncryption_data);
++
++    /**
+      * Identifies a signing algorithm where a SHA256 digest is
+      * encrypted using an RSA private key; defined by PKCS #1.
+      * OID = 1.2.840.113549.1.1.11
+@@ -847,6 +865,7 @@
+         nameTable.put(MD5_oid, "MD5");
+         nameTable.put(MD2_oid, "MD2");
+         nameTable.put(SHA_oid, "SHA");
++        nameTable.put(SHA224_oid, "SHA224");
+         nameTable.put(SHA256_oid, "SHA256");
+         nameTable.put(SHA384_oid, "SHA384");
+         nameTable.put(SHA512_oid, "SHA512");
+@@ -869,6 +888,7 @@
+         nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA");
+         nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA");
+         nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA");
++        nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA");
+         nameTable.put(sha256WithRSAEncryption_oid, "SHA256withRSA");
+         nameTable.put(sha384WithRSAEncryption_oid, "SHA384withRSA");
+         nameTable.put(sha512WithRSAEncryption_oid, "SHA512withRSA");
+diff -Nru openjdk.orig/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java openjdk/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java
+--- openjdk.orig/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java	2014-10-08 23:26:07.131607366 +0100
+@@ -49,6 +49,7 @@
+  * following algorithm names:
+  *
+  *  . "SHA1withRSA"
++ *  . "SHA224withRSA"
+  *  . "MD5withRSA"
+  *  . "MD2withRSA"
+  *
+@@ -90,6 +91,12 @@
+         }
+     }
+ 
++    public static final class SHA224 extends RSASignature {
++        public SHA224() {
++            super("SHA-224");
++        }
++    }
++
+     public static final class MD5 extends RSASignature {
+         public MD5() {
+             super("MD5");
+diff -Nru openjdk.orig/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java openjdk/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java
+--- openjdk.orig/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	2014-10-08 23:26:07.131607366 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 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
+@@ -81,6 +81,10 @@
+          */
+         map.put("Signature.SHA1withRSA",
+             "sun.security.mscapi.RSASignature$SHA1");
++        map.put("Signature.SHA224withRSA",
++            "sun.security.mscapi.RSASignature$SHA224");
++        map.put("Alg.Alias.Signature.1.2.840.113549.1.1.14",     "SHA224withRSA");
++        map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.14", "SHA224withRSA");
+         map.put("Signature.MD5withRSA",
+             "sun.security.mscapi.RSASignature$MD5");
+         map.put("Signature.MD2withRSA",
+@@ -89,6 +93,8 @@
+         // supported key classes
+         map.put("Signature.SHA1withRSA SupportedKeyClasses",
+             "sun.security.mscapi.Key");
++        map.put("Signature.SHA224withRSA SupportedKeyClasses",
++            "sun.security.mscapi.Key");
+         map.put("Signature.MD5withRSA SupportedKeyClasses",
+             "sun.security.mscapi.Key");
+         map.put("Signature.MD2withRSA SupportedKeyClasses",
+diff -Nru openjdk.orig/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP.java openjdk/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP.java
+--- openjdk.orig/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, 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
+@@ -58,6 +58,7 @@
+         Cipher.getInstance("RSA/ECB/OAEPwithMD5andMGF1Padding");
+         Cipher.getInstance("RSA/ECB/OAEPwithSHA1andMGF1Padding");
+         Cipher.getInstance("RSA/ECB/OAEPwithSHA-1andMGF1Padding");
++        Cipher.getInstance("RSA/ECB/OAEPwithSHA-224andMGF1Padding");
+         Cipher.getInstance("RSA/ECB/OAEPwithSHA-256andMGF1Padding");
+         Cipher.getInstance("RSA/ECB/OAEPwithSHA-384andMGF1Padding");
+         Cipher.getInstance("RSA/ECB/OAEPwithSHA-512andMGF1Padding");
+@@ -88,6 +89,18 @@
+         // tests alias works
+         testEncryptDecrypt("SHA-1", 16);
+ 
++        // basic test using SHA-224
++        testEncryptDecrypt("SHA-224", 0);
++        testEncryptDecrypt("SHA-224", 16);
++        testEncryptDecrypt("SHA-224", 38);
++        try {
++            testEncryptDecrypt("SHA-224", 39);
++            throw new Exception("Unexpectedly completed call");
++        } catch (IllegalBlockSizeException e) {
++            // ok
++            System.out.println(e);
++        }
++
+         // basic test using SHA-256
+         testEncryptDecrypt("SHA-256", 0);
+         testEncryptDecrypt("SHA-256", 16);
+@@ -195,6 +208,7 @@
+         System.out.println("Done (" + (stop - start) + " ms).");
+     }
+ 
++    // NOTE: OAEP can process up to (modLen - 2*digestLen - 2) bytes of data
+     private static void testEncryptDecrypt(String hashAlg, int dataLength) throws Exception {
+         System.out.println("Testing OAEP with hash " + hashAlg + ", " + dataLength + " bytes");
+         Cipher c = Cipher.getInstance("RSA/ECB/OAEPwith" + hashAlg + "andMGF1Padding", cp);
+diff -Nru openjdk.orig/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPParameterSpec.java openjdk/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPParameterSpec.java
+--- openjdk.orig/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPParameterSpec.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPParameterSpec.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, 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
+@@ -121,6 +121,7 @@
+     public static void main(String[] argv) throws Exception {
+         boolean status = true;
+         byte[] p = { (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04 };
++        status &= runTest("SHA-224", MGF1ParameterSpec.SHA224, p);
+         status &= runTest("SHA-256", MGF1ParameterSpec.SHA256, p);
+         status &= runTest("SHA-384", MGF1ParameterSpec.SHA384, p);
+         status &= runTest("SHA-512", MGF1ParameterSpec.SHA512, p);
+diff -Nru openjdk.orig/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPWithParams.java openjdk/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPWithParams.java
+--- openjdk.orig/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPWithParams.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPWithParams.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, 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
+@@ -47,10 +47,10 @@
+     private static Random random = new Random();
+ 
+     private static String MD[] = {
+-        "MD5", "SHA1", "SHA-256"
++        "MD5", "SHA1", "SHA-224", "SHA-256"
+     };
+     private static int DATA_LENGTH[] = {
+-        62, 54, 30
++        62, 54, 34, 30
+     };
+     public static void main(String[] args) throws Exception {
+         long start = System.currentTimeMillis();
+diff -Nru openjdk.orig/jdk/test/com/sun/crypto/provider/KeyGenerator/Test4628062.java openjdk/jdk/test/com/sun/crypto/provider/KeyGenerator/Test4628062.java
+--- openjdk.orig/jdk/test/com/sun/crypto/provider/KeyGenerator/Test4628062.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/com/sun/crypto/provider/KeyGenerator/Test4628062.java	2014-10-08 23:26:07.135607422 +0100
+@@ -23,7 +23,7 @@
+ 
+ /*
+  * @test
+- * @bug 4628062
++ * @bug 4628062 4963723
+  * @summary Verify that AES KeyGenerator supports default initialization
+  *      when init is not called
+  * @author Valerie Peng
+@@ -34,39 +34,45 @@
+ 
+ public class Test4628062 {
+ 
+-    private static final String ALGO = "AES";
+-    private static final int[] KEYSIZES =
+-        { 16, 24, 32 }; // in bytes
++    private static final int[] AES_SIZES = { 16, 24, 32 }; // in bytes
++    private static final int[] HMACSHA224_SIZES = { 28 };
++    private static final int[] HMACSHA256_SIZES = { 32 };
++    private static final int[] HMACSHA384_SIZES = { 48 };
++    private static final int[] HMACSHA512_SIZES = { 64 };
+ 
+-    public boolean execute() throws Exception {
+-        KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
++    public boolean execute(String algo, int[] keySizes) throws Exception {
++        KeyGenerator kg = KeyGenerator.getInstance(algo, "SunJCE");
+ 
+         // TEST FIX 4628062
+         Key keyWithDefaultSize = kg.generateKey();
+         byte[] encoding = keyWithDefaultSize.getEncoded();
+-        if (encoding.length == 0) {
++        int defKeyLen = encoding.length ;
++        if (defKeyLen == 0) {
+             throw new Exception("default key length is 0!");
++        } else if (defKeyLen != keySizes[0]) {
++            throw new Exception("default key length mismatch!");
+         }
+ 
+         // BONUS TESTS
+-        // 1. call init(int keysize) with various valid key sizes
+-        // and see if the generated key is the right size.
+-        for (int i=0; i<KEYSIZES.length; i++) {
+-            kg.init(KEYSIZES[i]*8); // in bits
+-            Key key = kg.generateKey();
+-            if (key.getEncoded().length != KEYSIZES[i]) {
+-                throw new Exception("key is generated with the wrong length!");
++        if (keySizes.length > 1) {
++            // 1. call init(int keysize) with various valid key sizes
++            // and see if the generated key is the right size.
++            for (int i=0; i<keySizes.length; i++) {
++                kg.init(keySizes[i]*8); // in bits
++                Key key = kg.generateKey();
++                if (key.getEncoded().length != keySizes[i]) {
++                    throw new Exception("key is generated with the wrong length!");
++                }
++            }
++            // 2. call init(int keysize) with invalid key size and see
++            // if the expected InvalidParameterException is thrown.
++            try {
++                kg.init(keySizes[0]*8+1);
++            } catch (InvalidParameterException ex) {
++            } catch (Exception ex) {
++                throw new Exception("wrong exception is thrown for invalid key size!");
+             }
+         }
+-        // 2. call init(int keysize) with invalid key size and see
+-        // if the expected InvalidParameterException is thrown.
+-        try {
+-            kg.init(KEYSIZES[0]*8+1);
+-        } catch (InvalidParameterException ex) {
+-        } catch (Exception ex) {
+-            throw new Exception("wrong exception is thrown for invalid key size!");
+-        }
+-
+         // passed all tests...hooray!
+         return true;
+     }
+@@ -76,8 +82,20 @@
+ 
+         Test4628062 test = new Test4628062();
+         String testName = test.getClass().getName();
+-        if (test.execute()) {
+-            System.out.println(testName + ": Passed!");
++        if (test.execute("AES", AES_SIZES)) {
++            System.out.println(testName + ": AES Passed!");
++        }
++        if (test.execute("HmacSHA224", HMACSHA224_SIZES)) {
++            System.out.println(testName + ": HmacSHA224 Passed!");
++        }
++        if (test.execute("HmacSHA256", HMACSHA256_SIZES)) {
++            System.out.println(testName + ": HmacSHA256 Passed!");
++        }
++        if (test.execute("HmacSHA384", HMACSHA384_SIZES)) {
++            System.out.println(testName + ": HmacSHA384 Passed!");
++        }
++        if (test.execute("HmacSHA512", HMACSHA512_SIZES)) {
++            System.out.println(testName + ": HmacSHA512 Passed!");
+         }
+     }
+ }
+diff -Nru openjdk.orig/jdk/test/com/sun/crypto/provider/Mac/MacClone.java openjdk/jdk/test/com/sun/crypto/provider/Mac/MacClone.java
+--- openjdk.orig/jdk/test/com/sun/crypto/provider/Mac/MacClone.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/com/sun/crypto/provider/Mac/MacClone.java	2014-10-08 23:26:07.135607422 +0100
+@@ -28,15 +28,33 @@
+  * @author Jan Luehe
+  */
+ import javax.crypto.*;
++import javax.crypto.spec.SecretKeySpec;
+ 
+ public class MacClone {
+ 
+     public static void main(String[] args) throws Exception {
+ 
++        String[] algos = { "HmacMD5", "HmacSHA1", "HmacSHA224", "HmacSHA256",
++                           "HmacSHA384", "HmacSHA512" };
++        KeyGenerator kgen = KeyGenerator.getInstance("DES");
++        SecretKey skey = kgen.generateKey();
++        for (String algo : algos) {
++            doTest(algo, skey);
++        }
++
++        String[] algos2 = { "HmacPBESHA1" };
++        skey = new SecretKeySpec("whatever".getBytes(), "PBE");
++        for (String algo : algos2) {
++            doTest(algo, skey);
++        }
++        System.out.println("Test Passed");
++    }
++
++    private static void doTest(String algo, SecretKey skey) throws Exception {
+         //
+-        // Clone uninitialized Mac object
++        // Clone an uninitialized Mac object
+         //
+-        Mac mac = Mac.getInstance("HmacSHA1", "SunJCE");
++        Mac mac = Mac.getInstance(algo, "SunJCE");
+         Mac macClone = (Mac)mac.clone();
+         System.out.println(macClone.getProvider().toString());
+         System.out.println(macClone.getAlgorithm());
+@@ -51,12 +69,9 @@
+         }
+ 
+         //
+-        // Clone initialized Mac object
++        // Clone an initialized Mac object
+         //
+-        KeyGenerator kgen = KeyGenerator.getInstance("DES");
+-        SecretKey skey = kgen.generateKey();
+-
+-        mac = Mac.getInstance("HmacSHA1");
++        mac = Mac.getInstance(algo, "SunJCE");
+         mac.init(skey);
+         macClone = (Mac)mac.clone();
+         System.out.println(macClone.getProvider().toString());
+@@ -66,7 +81,20 @@
+         byte[] macFinal = mac.doFinal();
+         byte[] macCloneFinal = macClone.doFinal();
+         if (!java.util.Arrays.equals(macFinal, macCloneFinal)) {
+-            throw new Exception("MAC results are different");
+-        }
++            throw new Exception("ERROR: MAC result of init clone is different");
++        } else System.out.println("MAC check#1 passed");
++
++        //
++        // Clone an updated Mac object
++        //
++        mac.update((byte)0x12);
++        macClone = (Mac)mac.clone();
++        mac.update((byte)0x34);
++        macClone.update((byte)0x34);
++        macFinal = mac.doFinal();
++        macCloneFinal = macClone.doFinal();
++        if (!java.util.Arrays.equals(macFinal, macCloneFinal)) {
++            throw new Exception("ERROR: MAC result of updated clone is different");
++        } else System.out.println("MAC check#2 passed");
+     }
+ }
+diff -Nru openjdk.orig/jdk/test/com/sun/crypto/provider/Mac/MacKAT.java openjdk/jdk/test/com/sun/crypto/provider/Mac/MacKAT.java
+--- openjdk.orig/jdk/test/com/sun/crypto/provider/Mac/MacKAT.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/com/sun/crypto/provider/Mac/MacKAT.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, 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
+@@ -23,7 +23,7 @@
+ 
+ /**
+  * @test
+- * @bug 4846410 6313661
++ * @bug 4846410 6313661 4963723
+  * @summary Basic known-answer-test for Hmac and SslMac algorithms
+  * @author Andreas Sterbenz
+  */
+@@ -147,7 +147,9 @@
+     private static Test t(String alg, String input, String macvalue, String key) {
+         return new MacTest(alg, b(input), b(macvalue), b(key));
+     }
+-
++    private static Test t(String alg, String input, String macvalue, byte[] key) {
++        return new MacTest(alg, b(input), b(macvalue), key);
++    }
+     private static Test t(String alg, byte[] input, String macvalue, String key) {
+         return new MacTest(alg, input, b(macvalue), b(key));
+     }
+@@ -155,8 +157,8 @@
+     private static Test t(String alg, byte[] input, String macvalue, byte[] key) {
+         return new MacTest(alg, input, b(macvalue), key);
+     }
+-
+     private final static byte[] ALONG, BLONG, BKEY;
++    private final static byte[] BKEY_20, DDDATA_50, AAKEY_20, CDDATA_50, AAKEY_131;
+ 
+     static {
+         ALONG = new byte[1024 * 128];
+@@ -166,6 +168,16 @@
+         random.nextBytes(BLONG);
+         BKEY = new byte[128];
+         random.nextBytes(BKEY);
++        BKEY_20 = new byte[20];
++        Arrays.fill(BKEY_20, (byte) 0x0b);
++        DDDATA_50 = new byte[50];
++        Arrays.fill(DDDATA_50, (byte) 0xdd);
++        AAKEY_20 = new byte[20];
++        Arrays.fill(AAKEY_20, (byte) 0xaa);
++        CDDATA_50 = new byte[50];
++        Arrays.fill(CDDATA_50, (byte) 0xcd);
++        AAKEY_131 = new byte[131];
++        Arrays.fill(AAKEY_131, (byte) 0xaa);
+     }
+ 
+     private final static Test[] tests = {
+@@ -203,15 +215,24 @@
+                 "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"),
+         t("HmacSHA512", BLONG, "fb:cf:4b:c6:d5:49:5a:5b:0b:d9:2a:32:f5:fa:68:d2:68:a4:0f:ae:53:fc:49:12:e6:1d:53:cf:b2:cb:c5:c5:f2:2d:86:bd:14:61:30:c3:a6:6f:44:1f:77:9b:aa:a1:22:48:a9:dd:d0:45:86:d1:a1:82:53:13:c4:03:06:a3",
+                 BKEY),
++        // Test vectors From RFC4231
++        t("HmacSHA224", s("Hi There"), "89:6f:b1:12:8a:bb:df:19:68:32:10:7c:d4:9d:f3:3f:47:b4:b1:16:99:12:ba:4f:53:68:4b:22", BKEY_20),
++        t("HmacSHA224", s("what do ya want for nothing?"), "a3:0e:01:09:8b:c6:db:bf:45:69:0f:3a:7e:9e:6d:0f:8b:be:a2:a3:9e:61:48:00:8f:d0:5e:44", s("Jefe")),
++        t("HmacSHA224", DDDATA_50, "7f:b3:cb:35:88:c6:c1:f6:ff:a9:69:4d:7d:6a:d2:64:93:65:b0:c1:f6:5d:69:d1:ec:83:33:ea", AAKEY_20),
++        t("HmacSHA224", CDDATA_50, "6c:11:50:68:74:01:3c:ac:6a:2a:bc:1b:b3:82:62:7c:ec:6a:90:d8:6e:fc:01:2d:e7:af:ec:5a", "01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:15:16:17:18:19"),
++        t("HmacSHA224", s("Test Using Larger Than Block-Size Key - Hash Key First"), "95:e9:a0:db:96:20:95:ad:ae:be:9b:2d:6f:0d:bc:e2:d4:99:f1:12:f2:d2:b7:27:3f:a6:87:0e", AAKEY_131),
++        t("HmacSHA224", s("This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."), "3a:85:41:66:ac:5d:9f:02:3f:54:d5:17:d0:b3:9d:bd:94:67:70:db:9c:2b:95:c9:f6:f5:65:d1", AAKEY_131),
+     };
+ 
+     static void runTests(Test[] tests) throws Exception {
+         long start = System.currentTimeMillis();
+         Provider p = Security.getProvider("SunJCE");
+         System.out.println("Testing provider " + p.getName() + "...");
++        Mac.getInstance("HmacSHA224", p);
+         Mac.getInstance("HmacSHA256", p);
+         Mac.getInstance("HmacSHA384", p);
+         Mac.getInstance("HmacSHA512", p);
++        KeyGenerator.getInstance("HmacSHA224", p);
+         KeyGenerator.getInstance("HmacSHA256", p);
+         KeyGenerator.getInstance("HmacSHA384", p);
+         KeyGenerator.getInstance("HmacSHA512", p);
+diff -Nru openjdk.orig/jdk/test/sun/security/pkcs11/ec/TestCurves.java openjdk/jdk/test/sun/security/pkcs11/ec/TestCurves.java
+--- openjdk.orig/jdk/test/sun/security/pkcs11/ec/TestCurves.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/pkcs11/ec/TestCurves.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2006, 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
+@@ -68,6 +68,7 @@
+             kp2 = kpg.generateKeyPair();
+ 
+             testSigning(p, "SHA1withECDSA", data, kp1, kp2);
++            testSigning(p, "SHA224withECDSA", data, kp1, kp2);
+             testSigning(p, "SHA256withECDSA", data, kp1, kp2);
+             testSigning(p, "SHA384withECDSA", data, kp1, kp2);
+             testSigning(p, "SHA512withECDSA", data, kp1, kp2);
+diff -Nru openjdk.orig/jdk/test/sun/security/pkcs11/MessageDigest/DigestKAT.java openjdk/jdk/test/sun/security/pkcs11/MessageDigest/DigestKAT.java
+--- openjdk.orig/jdk/test/sun/security/pkcs11/MessageDigest/DigestKAT.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/pkcs11/MessageDigest/DigestKAT.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 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
+@@ -174,6 +174,12 @@
+         t("SHA1", s("12345678901234567890123456789012345678901234567890123456789012345678901234567890"), "50:ab:f5:70:6a:15:09:90:a0:8b:2c:5e:a4:0f:a0:e5:85:55:47:32"),
+         t("SHA1", ALONG, "ce:56:53:59:08:04:ba:a9:36:9f:72:d4:83:ed:9e:ba:72:f0:4d:29"),
+ 
++        t("SHA-224", s(""), "d1:4a:02:8c:2a:3a:2b:c9:47:61:02:bb:28:82:34:c4:15:a2:b0:1f:82:8e:a6:2a:c5:b3:e4:2f"),
++        t("SHA-224", s("abc"), "23:09:7d:22:34:05:d8:22:86:42:a4:77:bd:a2:55:b3:2a:ad:bc:e4:bd:a0:b3:f7:e3:6c:9d:a7"),
++        t("SHA-224", s("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"), "75:38:8b:16:51:27:76:cc:5d:ba:5d:a1:fd:89:01:50:b0:c6:45:5c:b4:f5:8b:19:52:52:25:25"),
++        t("SHA-224", s("The quick brown fox jumps over the lazy dog"), "73:0e:10:9b:d7:a8:a3:2b:1c:b9:d9:a0:9a:a2:32:5d:24:30:58:7d:db:c0:c3:8b:ad:91:15:25"),
++        t("SHA-224", s("The quick brown fox jumps over the lazy dog."), "61:9c:ba:8e:8e:05:82:6e:9b:8c:51:9c:0a:5c:68:f4:fb:65:3e:8a:3d:8a:a0:4b:b2:c8:cd:4c"),
++
+         t("SHA-256", s(""), "e3:b0:c4:42:98:fc:1c:14:9a:fb:f4:c8:99:6f:b9:24:27:ae:41:e4:64:9b:93:4c:a4:95:99:1b:78:52:b8:55"),
+         t("SHA-256", s("a"), "ca:97:81:12:ca:1b:bd:ca:fa:c2:31:b3:9a:23:dc:4d:a7:86:ef:f8:14:7c:4e:72:b9:80:77:85:af:ee:48:bb"),
+         t("SHA-256", s("abc"), "ba:78:16:bf:8f:01:cf:ea:41:41:40:de:5d:ae:22:23:b0:03:61:a3:96:17:7a:9c:b4:10:ff:61:f2:00:15:ad"),
+diff -Nru openjdk.orig/jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java openjdk/jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java
+--- openjdk.orig/jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 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
+@@ -61,6 +61,7 @@
+         testSignature("MD2withRSA", privateKey, publicKey);
+         testSignature("MD5withRSA", privateKey, publicKey);
+         testSignature("SHA1withRSA", privateKey, publicKey);
++        testSignature("SHA224withRSA", privateKey, publicKey);
+         testSignature("SHA256withRSA", privateKey, publicKey);
+         RSAPublicKey rsaKey = (RSAPublicKey)publicKey;
+         if (rsaKey.getModulus().bitLength() > 512) {
+diff -Nru openjdk.orig/jdk/test/sun/security/pkcs11/rsa/TestSignatures.java openjdk/jdk/test/sun/security/pkcs11/rsa/TestSignatures.java
+--- openjdk.orig/jdk/test/sun/security/pkcs11/rsa/TestSignatures.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/pkcs11/rsa/TestSignatures.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 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
+@@ -81,6 +81,7 @@
+         testSignature("MD2withRSA", privateKey, publicKey);
+         testSignature("MD5withRSA", privateKey, publicKey);
+         testSignature("SHA1withRSA", privateKey, publicKey);
++        testSignature("SHA224withRSA", privateKey, publicKey);
+         testSignature("SHA256withRSA", privateKey, publicKey);
+         RSAPublicKey rsaKey = (RSAPublicKey)publicKey;
+         if (rsaKey.getModulus().bitLength() > 512) {
+diff -Nru openjdk.orig/jdk/test/sun/security/pkcs11/Signature/TestRSAKeyLength.java openjdk/jdk/test/sun/security/pkcs11/Signature/TestRSAKeyLength.java
+--- openjdk.orig/jdk/test/sun/security/pkcs11/Signature/TestRSAKeyLength.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/pkcs11/Signature/TestRSAKeyLength.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2010, 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
+@@ -37,7 +37,7 @@
+     }
+     public void main(Provider p) throws Exception {
+         boolean isValidKeyLength[] = { true, true, false, false };  
+-        String algos[] = { "SHA1withRSA", "SHA256withRSA", 
++        String algos[] = { "SHA1withRSA", "SHA224withRSA", "SHA256withRSA",
+                            "SHA384withRSA", "SHA512withRSA" };
+         KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", p);
+         kpg.initialize(512);
+diff -Nru openjdk.orig/jdk/test/sun/security/provider/MessageDigest/DigestKAT.java openjdk/jdk/test/sun/security/provider/MessageDigest/DigestKAT.java
+--- openjdk.orig/jdk/test/sun/security/provider/MessageDigest/DigestKAT.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/provider/MessageDigest/DigestKAT.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2005, 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
+@@ -23,7 +23,7 @@
+ 
+ /**
+  * @test
+- * @bug 4819771 4834179 5008306
++ * @bug 4819771 4834179 5008306 4963723
+  * @summary Basic known-answer-test for all our MessageDigest algorithms
+  * @author Andreas Sterbenz
+  */
+@@ -190,6 +190,12 @@
+         t("SHA1", ALONG, "ce:56:53:59:08:04:ba:a9:36:9f:72:d4:83:ed:9e:ba:72:f0:4d:29"),
+         t("SHA1", BLONG, "1d:a8:1a:de:8d:1e:d0:82:ba:12:13:e2:56:26:30:fc:05:b8:8d:a6"),
+ 
++        t("SHA-224", s(""), "d1:4a:02:8c:2a:3a:2b:c9:47:61:02:bb:28:82:34:c4:15:a2:b0:1f:82:8e:a6:2a:c5:b3:e4:2f"),
++        t("SHA-224", s("abc"), "23:09:7d:22:34:05:d8:22:86:42:a4:77:bd:a2:55:b3:2a:ad:bc:e4:bd:a0:b3:f7:e3:6c:9d:a7"),
++        t("SHA-224", s("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"), "75:38:8b:16:51:27:76:cc:5d:ba:5d:a1:fd:89:01:50:b0:c6:45:5c:b4:f5:8b:19:52:52:25:25"),
++        t("SHA-224", s("The quick brown fox jumps over the lazy dog"), "73:0e:10:9b:d7:a8:a3:2b:1c:b9:d9:a0:9a:a2:32:5d:24:30:58:7d:db:c0:c3:8b:ad:91:15:25"),
++        t("SHA-224", s("The quick brown fox jumps over the lazy dog."), "61:9c:ba:8e:8e:05:82:6e:9b:8c:51:9c:0a:5c:68:f4:fb:65:3e:8a:3d:8a:a0:4b:b2:c8:cd:4c"),
++
+         t("SHA-256", s(""), "e3:b0:c4:42:98:fc:1c:14:9a:fb:f4:c8:99:6f:b9:24:27:ae:41:e4:64:9b:93:4c:a4:95:99:1b:78:52:b8:55"),
+         t("SHA-256", s("a"), "ca:97:81:12:ca:1b:bd:ca:fa:c2:31:b3:9a:23:dc:4d:a7:86:ef:f8:14:7c:4e:72:b9:80:77:85:af:ee:48:bb"),
+         t("SHA-256", s("abc"), "ba:78:16:bf:8f:01:cf:ea:41:41:40:de:5d:ae:22:23:b0:03:61:a3:96:17:7a:9c:b4:10:ff:61:f2:00:15:ad"),
+diff -Nru openjdk.orig/jdk/test/sun/security/provider/MessageDigest/Offsets.java openjdk/jdk/test/sun/security/provider/MessageDigest/Offsets.java
+--- openjdk.orig/jdk/test/sun/security/provider/MessageDigest/Offsets.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/provider/MessageDigest/Offsets.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2006, 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
+@@ -80,6 +80,7 @@
+         test("MD2", 0, 64, 0, 128);
+         test("MD5", 0, 64, 0, 128);
+         test("SHA1", 0, 64, 0, 128);
++        test("SHA-224", 0, 64, 0, 128);
+         test("SHA-256", 0, 64, 0, 128);
+         test("SHA-384", 0, 128, 0, 256);
+         test("SHA-512", 0, 128, 0, 256);
+diff -Nru openjdk.orig/jdk/test/sun/security/provider/MessageDigest/TestSHAClone.java openjdk/jdk/test/sun/security/provider/MessageDigest/TestSHAClone.java
+--- openjdk.orig/jdk/test/sun/security/provider/MessageDigest/TestSHAClone.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/provider/MessageDigest/TestSHAClone.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2002, 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
+@@ -24,7 +24,7 @@
+ /**
+  * @test
+  * @bug 4775971
+- * @summary test the clone implementation of SHA, SHA-256,
++ * @summary test the clone implementation of SHA, SHA-224, SHA-256,
+  *          SHA-384, SHA-512 MessageDigest implementation.
+  */
+ import java.security.*;
+@@ -33,7 +33,7 @@
+ public class TestSHAClone {
+ 
+     private static final String[] ALGOS = {
+-        "SHA", "SHA-256", "SHA-512", "SHA-384"
++        "SHA", "SHA-224", "SHA-256", "SHA-512", "SHA-384"
+     };
+ 
+     private static byte[] input1 = {
+diff -Nru openjdk.orig/jdk/test/sun/security/rsa/TestKeyPairGenerator.java openjdk/jdk/test/sun/security/rsa/TestKeyPairGenerator.java
+--- openjdk.orig/jdk/test/sun/security/rsa/TestKeyPairGenerator.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/rsa/TestKeyPairGenerator.java	2014-10-08 23:26:07.135607422 +0100
+@@ -23,7 +23,7 @@
+ 
+ /**
+  * @test
+- * @bug 4853305 4865198 4888410
++ * @bug 4853305 4865198 4888410 4963723
+  * @summary Verify that the RSA KeyPairGenerator works
+  * @author Andreas Sterbenz
+  */
+@@ -60,6 +60,7 @@
+         testSignature("MD2withRSA", privateKey, publicKey);
+         testSignature("MD5withRSA", privateKey, publicKey);
+         testSignature("SHA1withRSA", privateKey, publicKey);
++        testSignature("SHA224withRSA", privateKey, publicKey);
+         testSignature("SHA256withRSA", privateKey, publicKey);
+         RSAPublicKey rsaKey = (RSAPublicKey)publicKey;
+         if (rsaKey.getModulus().bitLength() > 512) {
+diff -Nru openjdk.orig/jdk/test/sun/security/rsa/TestSignatures.java openjdk/jdk/test/sun/security/rsa/TestSignatures.java
+--- openjdk.orig/jdk/test/sun/security/rsa/TestSignatures.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/rsa/TestSignatures.java	2014-10-08 23:26:07.135607422 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 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
+@@ -23,7 +23,7 @@
+ 
+ /**
+  * @test
+- * @bug 4853305
++ * @bug 4853305 4963723
+  * @summary Test signing/verifying using all the signature algorithms
+  * @author Andreas Sterbenz
+  */
+@@ -80,6 +80,7 @@
+         testSignature("MD2withRSA", privateKey, publicKey);
+         testSignature("MD5withRSA", privateKey, publicKey);
+         testSignature("SHA1withRSA", privateKey, publicKey);
++        testSignature("SHA224withRSA", privateKey, publicKey);
+         testSignature("SHA256withRSA", privateKey, publicKey);
+         RSAPublicKey rsaKey = (RSAPublicKey)publicKey;
+         if (rsaKey.getModulus().bitLength() > 512) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/6578658-sunmscapi_nonewithrsa.patch	Thu Oct 09 02:25:23 2014 +0100
@@ -0,0 +1,602 @@
+# HG changeset patch
+# User vinnie
+# Date 1412805665 -3600
+#      Wed Oct 08 23:01:05 2014 +0100
+# Node ID 29dda8a543712fa28e76a963b6310e6a6a1b66d6
+# Parent  c4a0ef23f3c4f3f7ab264e518fe8c6b4fa4f6683
+6578658: Request for raw RSA (NONEwithRSA) Signature support in SunMSCAPI
+Reviewed-by: wetmore
+
+diff -r c4a0ef23f3c4 -r 29dda8a54371 src/windows/classes/sun/security/mscapi/RSASignature.java
+--- openjdk/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java	Wed Oct 08 22:54:43 2014 +0100
++++ openjdk/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java	Wed Oct 08 23:01:05 2014 +0100
+@@ -48,6 +48,7 @@
+  * Objects should be instantiated by calling Signature.getInstance() using the
+  * following algorithm names:
+  *
++ *  . "NONEwithRSA"
+  *  . "SHA1withRSA"
+  *  . "SHA224withRSA"
+  *  . "SHA256withRSA"
+@@ -56,7 +57,12 @@
+  *  . "MD5withRSA"
+  *  . "MD2withRSA"
+  *
+- * Note: RSA keys must be at least 512 bits long
++ * NOTE: RSA keys must be at least 512 bits long.
++ *
++ * NOTE: NONEwithRSA must be supplied with a pre-computed message digest.
++ *       Only the following digest algorithms are supported: MD5, SHA-1,
++ *       SHA-224, SHA-256, SHA-384, SHA-512 and a special-purpose digest
++ *       algorithm which is a concatenation of SHA-1 and MD5 digests.
+  *
+  * @since   1.6
+  * @author  Stanley Man-Kit Ho
+@@ -67,7 +73,7 @@
+     private final MessageDigest messageDigest;
+ 
+     // message digest name
+-    private final String messageDigestAlgorithm;
++    private String messageDigestAlgorithm;
+ 
+     // flag indicating whether the digest has been reset
+     private boolean needsReset;
+@@ -78,6 +84,13 @@
+     // the verification key
+     private Key publicKey = null;
+ 
++    /**
++     * Constructs a new RSASignature. Used by Raw subclass.
++     */
++    RSASignature() {
++        messageDigest = null;
++        messageDigestAlgorithm = null;
++    }
+ 
+     /**
+      * Constructs a new RSASignature. Used by subclasses.
+@@ -96,6 +109,96 @@
+         needsReset = false;
+     }
+ 
++    // Nested class for NONEwithRSA signatures
++    public static final class Raw extends RSASignature {
++
++        // the longest supported digest is 512 bits (SHA-512)
++        private static final int RAW_RSA_MAX = 64;
++
++        private final byte[] precomputedDigest;
++        private int offset = 0;
++
++        public Raw() {
++            precomputedDigest = new byte[RAW_RSA_MAX];
++        }
++
++        // Stores the precomputed message digest value.
++        @Override
++        protected void engineUpdate(byte b) throws SignatureException {
++            if (offset >= precomputedDigest.length) {
++                offset = RAW_RSA_MAX + 1;
++                return;
++            }
++            precomputedDigest[offset++] = b;
++        }
++
++        // Stores the precomputed message digest value.
++        @Override
++        protected void engineUpdate(byte[] b, int off, int len)
++                throws SignatureException {
++            if (offset + len > precomputedDigest.length) {
++                offset = RAW_RSA_MAX + 1;
++                return;
++            }
++            System.arraycopy(b, off, precomputedDigest, offset, len);
++            offset += len;
++        }
++
++        // Stores the precomputed message digest value.
++        @Override
++        protected void engineUpdate(ByteBuffer byteBuffer) {
++            int len = byteBuffer.remaining();
++            if (len <= 0) {
++                return;
++            }
++            if (offset + len > precomputedDigest.length) {
++                offset = RAW_RSA_MAX + 1;
++                return;
++            }
++            byteBuffer.get(precomputedDigest, offset, len);
++            offset += len;
++        }
++
++        @Override
++        protected void resetDigest(){
++            offset = 0;
++        }
++
++        // Returns the precomputed message digest value.
++        @Override
++        protected byte[] getDigestValue() throws SignatureException {
++            if (offset > RAW_RSA_MAX) {
++                throw new SignatureException("Message digest is too long");
++            }
++
++            // Determine the digest algorithm from the digest length
++            if (offset == 20) {
++                setDigestName("SHA1");
++            } else if (offset == 36) {
++                setDigestName("SHA1+MD5");
++            } else if (offset == 32) {
++                setDigestName("SHA-256");
++            } else if (offset == 48) {
++                setDigestName("SHA-384");
++            } else if (offset == 64) {
++                setDigestName("SHA-512");
++            } else if (offset == 16) {
++                setDigestName("MD5");
++            } else if (offset == 28) {
++                setDigestName("SHA-224");
++            } else {
++                throw new SignatureException(
++                    "Message digest length is not supported");
++            }
++
++            byte[] result = new byte[offset];
++            System.arraycopy(precomputedDigest, 0, result, 0, offset);
++            offset = 0;
++
++            return result;
++        }
++    }
++
+     public static final class SHA1 extends RSASignature {
+         public SHA1() {
+             super("SHA1");
+@@ -205,18 +308,22 @@
+     /**
+      * Resets the message digest if needed.
+      */
+-    private void resetDigest() {
++    protected void resetDigest() {
+         if (needsReset) {
+             messageDigest.reset();
+             needsReset = false;
+         }
+     }
+ 
+-    private byte[] getDigestValue() {
++    protected byte[] getDigestValue() throws SignatureException {
+         needsReset = false;
+         return messageDigest.digest();
+     }
+ 
++    protected void setDigestName(String name) {
++        messageDigestAlgorithm = name;
++    }
++
+     /**
+      * Updates the data to be signed or verified
+      * using the specified byte.
+@@ -278,9 +385,12 @@
+ 
+         byte[] hash = getDigestValue();
+ 
++        // Omit the hash OID when generating a Raw signature
++        boolean noHashOID = this instanceof Raw;
++
+         // Sign hash using MS Crypto APIs
+ 
+-        byte[] result = signHash(hash, hash.length,
++        byte[] result = signHash(noHashOID, hash, hash.length,
+             messageDigestAlgorithm, privateKey.getHCryptProvider(),
+             privateKey.getHCryptKey());
+ 
+@@ -309,8 +419,8 @@
+      * Sign hash using Microsoft Crypto API with HCRYPTKEY.
+      * The returned data is in little-endian.
+      */
+-    private native static byte[] signHash(byte[] hash, int hashSize,
+-        String hashAlgorithm, long hCryptProv, long hCryptKey)
++    private native static byte[] signHash(boolean noHashOID, byte[] hash,
++        int hashSize, String hashAlgorithm, long hCryptProv, long hCryptKey)
+             throws SignatureException;
+ 
+     /**
+diff -r c4a0ef23f3c4 -r 29dda8a54371 src/windows/classes/sun/security/mscapi/SunMSCAPI.java
+--- openjdk/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Wed Oct 08 22:54:43 2014 +0100
++++ openjdk/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Wed Oct 08 23:01:05 2014 +0100
+@@ -79,6 +79,12 @@
+         /*
+          * Signature engines
+          */
++        // NONEwithRSA must be supplied with a pre-computed message digest.
++        // Only the following digest algorithms are supported: MD5, SHA-1,
++        // SHA-224, SHA-256, SHA-384, SHA-512 and a special-purpose digest
++        // algorithm which is a concatenation of SHA-1 and MD5 digests.
++        map.put("Signature.NONEwithRSA",
++            "sun.security.mscapi.RSASignature$Raw");
+         map.put("Signature.SHA1withRSA",
+             "sun.security.mscapi.RSASignature$SHA1");
+         map.put("Signature.SHA224withRSA",
+@@ -105,6 +111,8 @@
+             "sun.security.mscapi.RSASignature$MD2");
+ 
+         // supported key classes
++        map.put("Signature.NONEwithRSA SupportedKeyClasses",
++            "sun.security.mscapi.Key");
+         map.put("Signature.SHA1withRSA SupportedKeyClasses",
+             "sun.security.mscapi.Key");
+         map.put("Signature.SHA224withRSA SupportedKeyClasses",
+diff -r c4a0ef23f3c4 -r 29dda8a54371 src/windows/native/sun/security/mscapi/security.cpp
+--- openjdk/jdk/src/windows/native/sun/security/mscapi/security.cpp	Wed Oct 08 22:54:43 2014 +0100
++++ openjdk/jdk/src/windows/native/sun/security/mscapi/security.cpp	Wed Oct 08 23:01:05 2014 +0100
+@@ -79,6 +79,8 @@
+         (strcmp("SHA-1", pszHashAlgorithm) == 0)) {
+ 
+         algId = CALG_SHA1;
++    } else if (strcmp("SHA1+MD5", pszHashAlgorithm) == 0) {
++        algId = CALG_SSL3_SHAMD5; // a 36-byte concatenation of SHA-1 and MD5
+     } else if (strcmp("SHA-256", pszHashAlgorithm) == 0) {
+         algId = CALG_SHA_256;
+     } else if (strcmp("SHA-384", pszHashAlgorithm) == 0) {
+@@ -471,11 +473,12 @@
+ /*
+  * Class:     sun_security_mscapi_RSASignature
+  * Method:    signHash
+- * Signature: ([BILjava/lang/String;JJ)[B
++ * Signature: (Z[BILjava/lang/String;JJ)[B
+  */
+ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
+-  (JNIEnv *env, jclass clazz, jbyteArray jHash, jint jHashSize,
+-        jstring jHashAlgorithm, jlong hCryptProv, jlong hCryptKey)
++  (JNIEnv *env, jclass clazz, jboolean noHashOID, jbyteArray jHash,
++        jint jHashSize, jstring jHashAlgorithm, jlong hCryptProv,
++        jlong hCryptKey)
+ {
+     HCRYPTHASH hHash = NULL;
+     jbyte* pHashBuffer = NULL;
+@@ -546,14 +549,20 @@
+ 
+         // Determine size of buffer
+         DWORD dwBufLen = 0;
+-        if (::CryptSignHash(hHash, dwKeySpec, NULL, NULL, NULL, &dwBufLen) == FALSE)
++        DWORD dwFlags = 0;
++
++        if (noHashOID == JNI_TRUE) {
++            dwFlags = CRYPT_NOHASHOID; // omit hash OID in NONEwithRSA signature
++        }
++
++        if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, NULL, &dwBufLen) == FALSE)
+         {
+             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
+             __leave;
+         }
+ 
+         pSignedHashBuffer = new jbyte[dwBufLen];
+-        if (::CryptSignHash(hHash, dwKeySpec, NULL, NULL, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE)
++        if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE)
+         {
+             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
+             __leave;
+diff -r c4a0ef23f3c4 -r 29dda8a54371 test/sun/security/mscapi/SignUsingNONEwithRSA.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/test/sun/security/mscapi/SignUsingNONEwithRSA.java	Wed Oct 08 23:01:05 2014 +0100
+@@ -0,0 +1,231 @@
++/*
++ * Copyright (c) 2011, 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.
++ *
++ * 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 SignUsingNONEwithRSA.sh
++ */
++
++import java.security.*;
++import java.util.*;
++
++public class SignUsingNONEwithRSA {
++
++    private static final List<byte[]> precomputedHashes = Arrays.asList(
++        // A MD5 hash
++        new byte[] {
++            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
++            0x11, 0x12, 0x13, 0x14, 0x15, 0x16
++        },
++        // A SHA-1 hash
++        new byte[] {
++            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
++            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20
++        },
++        // A concatenation of SHA-1 and MD5 hashes (used during SSL handshake)
++        new byte[] {
++            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
++            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
++            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
++            0x31, 0x32, 0x33, 0x34, 0x35, 0x36
++        },
++        // A SHA-224 hash
++        new byte[] {
++            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
++            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
++            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28
++        },
++        // A SHA-256 hash
++        new byte[] {
++            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
++            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
++            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
++            0x31, 0x32
++        },
++        // A SHA-384 hash
++        new byte[] {
++            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
++            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
++            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
++            0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40,
++            0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48
++        },
++        // A SHA-512 hash
++        new byte[] {
++            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
++            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
++            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
++            0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40,
++            0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x50,
++            0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x60,
++            0x61, 0x62, 0x63, 0x64
++        });
++
++    private static List<byte[]> generatedSignatures = new ArrayList<>();
++
++    public static void main(String[] args) throws Exception {
++
++        Provider[] providers = Security.getProviders("Signature.NONEwithRSA");
++        if (providers == null) {
++            System.out.println("No JCE providers support the " +
++                "'Signature.NONEwithRSA' algorithm");
++            System.out.println("Skipping this test...");
++            return;
++
++        } else {
++            System.out.println("The following JCE providers support the " +
++                "'Signature.NONEwithRSA' algorithm: ");
++            for (Provider provider : providers) {
++                System.out.println("    " + provider.getName());
++            }
++        }
++        System.out.println("-------------------------------------------------");
++
++        KeyPair keys = getKeysFromKeyStore();
++        signAllUsing("SunMSCAPI", keys.getPrivate());
++        System.out.println("-------------------------------------------------");
++
++        verifyAllUsing("SunMSCAPI", keys.getPublic());
++        System.out.println("-------------------------------------------------");
++
++        verifyAllUsing("SunJCE", keys.getPublic());
++        System.out.println("-------------------------------------------------");
++
++        keys = generateKeys();
++        signAllUsing("SunJCE", keys.getPrivate());
++        System.out.println("-------------------------------------------------");
++
++        verifyAllUsing("SunMSCAPI", keys.getPublic());
++        System.out.println("-------------------------------------------------");
++
++    }
++
++    private static KeyPair getKeysFromKeyStore() throws Exception {
++        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("6578658")) {
++                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");
++        }
++
++        return new KeyPair(publicKey, privateKey);
++    }
++
++
++    private static KeyPair generateKeys() throws Exception {
++        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
++        keyGen.initialize(1024, null);
++        KeyPair pair = keyGen.generateKeyPair();
++        PrivateKey privateKey = pair.getPrivate();
++        PublicKey publicKey = pair.getPublic();
++
++        if (privateKey == null || publicKey == null) {
++            throw new Exception("Cannot load the keys need to run this test");
++        }
++
++        return new KeyPair(publicKey, privateKey);
++    }
++
++    private static void signAllUsing(String providerName, PrivateKey privateKey)
++            throws Exception {
++        Signature sig1 = Signature.getInstance("NONEwithRSA", providerName);
++        if (sig1 == null) {
++            throw new Exception("'NONEwithRSA' is not supported");
++        }
++        if (sig1.getProvider() != null) {
++            System.out.println("Using NONEwithRSA signer from the " +
++                sig1.getProvider().getName() + " JCE provider");
++        } else {
++            System.out.println(
++                "Using NONEwithRSA signer from the internal JCE provider");
++        }
++
++        System.out.println("Using key: " + privateKey);
++        generatedSignatures.clear();
++        for (byte[] hash : precomputedHashes) {
++            sig1.initSign(privateKey);
++            sig1.update(hash);
++
++            try {
++
++                byte [] sigBytes = sig1.sign();
++                System.out.println("\nGenerated RSA signature over a " +
++                    hash.length + "-byte hash (signature length: " +
++                    sigBytes.length * 8 + " bits)");
++                System.out.println(String.format("0x%0" +
++                    (sigBytes.length * 2) + "x",
++                    new java.math.BigInteger(1, sigBytes)));
++                generatedSignatures.add(sigBytes);
++
++            } catch (SignatureException se) {
++                System.out.println("Error generating RSA signature: " + se);
++            }
++        }
++    }
++
++    private static void verifyAllUsing(String providerName, PublicKey publicKey)
++            throws Exception {
++        Signature sig1 = Signature.getInstance("NONEwithRSA", providerName);
++        if (sig1.getProvider() != null) {
++            System.out.println("\nUsing NONEwithRSA verifier from the " +
++                sig1.getProvider().getName() + " JCE provider");
++        } else {
++            System.out.println(
++                "\nUsing NONEwithRSA verifier from the internal JCE provider");
++        }
++
++        System.out.println("Using key: " + publicKey);
++
++        int i = 0;
++        for (byte[] hash : precomputedHashes) {
++
++            byte[] sigBytes = generatedSignatures.get(i++);
++            System.out.println("\nVerifying RSA Signature over a " +
++                hash.length + "-byte hash (signature length: " +
++                sigBytes.length * 8 + " bits)");
++            System.out.println(String.format("0x%0" +
++                (sigBytes.length * 2) + "x",
++                new java.math.BigInteger(1, sigBytes)));
++
++            sig1.initVerify(publicKey);
++            sig1.update(hash);
++            if (sig1.verify(sigBytes)) {
++                System.out.println("Verify PASSED");
++            } else {
++                throw new Exception("Verify FAILED");
++            }
++        }
++    }
++}
+diff -r c4a0ef23f3c4 -r 29dda8a54371 test/sun/security/mscapi/SignUsingNONEwithRSA.sh
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/test/sun/security/mscapi/SignUsingNONEwithRSA.sh	Wed Oct 08 23:01:05 2014 +0100
+@@ -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 6578658
++# @run shell SignUsingNONEwithRSA.sh
++# @summary Sign using the NONEwithRSA signature algorithm from 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 6578658 \
++	    -dname "cn=6578658,c=US" \
++	    -noprompt
++
++        echo
++	echo "Running the test..."
++        ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\SignUsingNONEwithRSA.java
++        ${TESTJAVA}/bin/java SignUsingNONEwithRSA
++
++        rc=$?
++
++        echo
++        echo "Removing the temporary RSA keypair from the Windows-My store..."
++        ${TESTJAVA}/bin/keytool \
++	    -delete \
++	    -storetype Windows-My \
++	    -alias 6578658
++
++	echo done.
++        exit $rc
++        ;;
++
++    * )
++        echo "This test is not intended for '$OS' - passing test"
++        exit 0
++        ;;
++esac
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/6753664-sunmscapi_sha-256.patch	Thu Oct 09 02:25:23 2014 +0100
@@ -0,0 +1,640 @@
+# HG changeset patch
+# User vinnie
+# Date 1412805283 -3600
+#      Wed Oct 08 22:54:43 2014 +0100
+# Node ID c4a0ef23f3c4f3f7ab264e518fe8c6b4fa4f6683
+# Parent  2adb6892881f4e3b359026854562b2ac70c63bef
+6753664: Support SHA256 (and higher) in SunMSCAPI
+Reviewed-by: mullan
+
+diff -r 2adb6892881f -r c4a0ef23f3c4 src/windows/classes/sun/security/mscapi/RSASignature.java
+--- openjdk/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java	Wed Oct 08 22:42:49 2014 +0100
++++ openjdk/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java	Wed Oct 08 22:54:43 2014 +0100
+@@ -50,6 +50,9 @@
+  *
+  *  . "SHA1withRSA"
+  *  . "SHA224withRSA"
++ *  . "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);
+@@ -97,6 +108,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");
+@@ -109,16 +138,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
+     {
+@@ -159,24 +179,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) {
+@@ -190,12 +198,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.
+@@ -255,13 +276,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
+@@ -315,11 +335,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());
+     }
+diff -r 2adb6892881f -r c4a0ef23f3c4 src/windows/classes/sun/security/mscapi/SunMSCAPI.java
+--- openjdk/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Wed Oct 08 22:42:49 2014 +0100
++++ openjdk/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Wed Oct 08 22:54:43 2014 +0100
+@@ -85,6 +85,20 @@
+             "sun.security.mscapi.RSASignature$SHA224");
+         map.put("Alg.Alias.Signature.1.2.840.113549.1.1.14",     "SHA224withRSA");
+         map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.14", "SHA224withRSA");
++        map.put("Signature.SHA256withRSA",
++            "sun.security.mscapi.RSASignature$SHA256");
++        map.put("Alg.Alias.Signature.1.2.840.113549.1.1.11",     "SHA256withRSA");
++        map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.11", "SHA256withRSA");
++        map.put("Signature.SHA384withRSA",
++            "sun.security.mscapi.RSASignature$SHA384");
++        map.put("Alg.Alias.Signature.1.2.840.113549.1.1.12",     "SHA384withRSA");
++        map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.12", "SHA384withRSA");
++
++        map.put("Signature.SHA512withRSA",
++            "sun.security.mscapi.RSASignature$SHA512");
++        map.put("Alg.Alias.Signature.1.2.840.113549.1.1.13",     "SHA512withRSA");
++        map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA");
++
+         map.put("Signature.MD5withRSA",
+             "sun.security.mscapi.RSASignature$MD5");
+         map.put("Signature.MD2withRSA",
+@@ -95,12 +109,16 @@
+             "sun.security.mscapi.Key");
+         map.put("Signature.SHA224withRSA 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
+diff -r 2adb6892881f -r c4a0ef23f3c4 src/windows/native/sun/security/mscapi/security.cpp
+--- openjdk/jdk/src/windows/native/sun/security/mscapi/security.cpp	Wed Oct 08 22:42:49 2014 +0100
++++ openjdk/jdk/src/windows/native/sun/security/mscapi/security.cpp	Wed Oct 08 22:54:43 2014 +0100
+@@ -481,6 +481,7 @@
+     jbyte* pHashBuffer = NULL;
+     jbyte* pSignedHashBuffer = NULL;
+     jbyteArray jSignedHash = NULL;
++    HCRYPTPROV hCryptProvAlt = NULL;
+ 
+     __try
+     {
+@@ -490,8 +491,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
+@@ -544,6 +569,9 @@
+     }
+     __finally
+     {
++        if (hCryptProvAlt)
++            ::CryptReleaseContext(hCryptProvAlt, 0);
++
+         if (pSignedHashBuffer)
+             delete [] pSignedHashBuffer;
+ 
+@@ -572,6 +600,7 @@
+     jbyte* pSignedHashBuffer = NULL;
+     DWORD dwSignedHashBufferLen = jSignedHashSize;
+     jboolean result = JNI_FALSE;
++    HCRYPTPROV hCryptProvAlt = NULL;
+ 
+     __try
+     {
+@@ -582,8 +611,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
+@@ -614,6 +667,9 @@
+ 
+     __finally
+     {
++        if (hCryptProvAlt)
++            ::CryptReleaseContext(hCryptProvAlt, 0);
++
+         if (pSignedHashBuffer)
+             delete [] pSignedHashBuffer;
+ 
+@@ -646,15 +702,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
+@@ -1847,15 +1915,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
+diff -r 2adb6892881f -r c4a0ef23f3c4 test/sun/security/mscapi/SignUsingSHA2withRSA.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/test/sun/security/mscapi/SignUsingSHA2withRSA.java	Wed Oct 08 22:54:43 2014 +0100
+@@ -0,0 +1,157 @@
++/*
++ * Copyright (c) 2011, 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.
++ *
++ * 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<byte[]>();
++
++    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));
++        generatedSignatures.add(signUsing("SHA224withRSA", privateKey));
++
++
++        System.out.println("-------------------------------------------------");
++
++        verifyUsing("SHA256withRSA", publicKey, generatedSignatures.get(0));
++        verifyUsing("SHA384withRSA", publicKey, generatedSignatures.get(1));
++        verifyUsing("SHA512withRSA", publicKey, generatedSignatures.get(2));
++        verifyUsing("SHA224withRSA", publicKey, generatedSignatures.get(3));
++
++
++        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");
++        }
++    }
++}
+diff -r 2adb6892881f -r c4a0ef23f3c4 test/sun/security/mscapi/SignUsingSHA2withRSA.sh
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/test/sun/security/mscapi/SignUsingSHA2withRSA.sh	Wed Oct 08 22:54:43 2014 +0100
+@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/7033170-getmaxallowedkeylength_throws_exception.patch	Thu Oct 09 02:25:23 2014 +0100
@@ -0,0 +1,117 @@
+# HG changeset patch
+# User valeriep
+# Date 1326944130 28800
+#      Wed Jan 18 19:35:30 2012 -0800
+# Node ID b2488252ba0c238d37b24069808b0ac8c2da1c76
+# Parent  9ec80e94c5cda0fb59fbfe217e3505f597ccbe90
+7033170: Cipher.getMaxAllowedKeyLength(String) throws NoSuchAlgorithmException
+Summary: Changed to always use full transformation as provider properties.
+Reviewed-by: mullan
+
+diff -r 9ec80e94c5cd -r b2488252ba0c src/share/classes/sun/security/pkcs11/SunPKCS11.java
+--- openjdk/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java	Wed Jan 18 19:33:50 2012 -0800
++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java	Wed Jan 18 19:35:30 2012 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2011, 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
+@@ -606,24 +606,31 @@
+                 m(CKM_DES_CBC));
+         d(CIP, "DES/CBC/PKCS5Padding",          P11Cipher,
+                 m(CKM_DES_CBC_PAD, CKM_DES_CBC));
+-        d(CIP, "DES/ECB",                       P11Cipher,      s("DES"),
++        d(CIP, "DES/ECB/NoPadding",             P11Cipher,
+                 m(CKM_DES_ECB));
+-
++        d(CIP, "DES/ECB/PKCS5Padding",          P11Cipher,      s("DES"),
++                m(CKM_DES_ECB));
+         d(CIP, "DESede/CBC/NoPadding",          P11Cipher,
+                 m(CKM_DES3_CBC));
+         d(CIP, "DESede/CBC/PKCS5Padding",       P11Cipher,
+                 m(CKM_DES3_CBC_PAD, CKM_DES3_CBC));
+-        d(CIP, "DESede/ECB",                    P11Cipher,      s("DESede"),
++        d(CIP, "DESede/ECB/NoPadding",          P11Cipher,
++                m(CKM_DES3_ECB));
++        d(CIP, "DESede/ECB/PKCS5Padding",       P11Cipher,      s("DESede"),
+                 m(CKM_DES3_ECB));
+         d(CIP, "AES/CBC/NoPadding",             P11Cipher,
+                 m(CKM_AES_CBC));
+         d(CIP, "AES/CBC/PKCS5Padding",          P11Cipher,
+                 m(CKM_AES_CBC_PAD, CKM_AES_CBC));
+-        d(CIP, "AES/ECB",                       P11Cipher,      s("AES"),
++        d(CIP, "AES/ECB/NoPadding",             P11Cipher,
++                m(CKM_AES_ECB));
++        d(CIP, "AES/ECB/PKCS5Padding",          P11Cipher,      s("AES"),
+                 m(CKM_AES_ECB));
+         d(CIP, "AES/CTR/NoPadding",             P11Cipher,
+                 m(CKM_AES_CTR));
+-        d(CIP, "Blowfish/CBC",                  P11Cipher,
++        d(CIP, "Blowfish/CBC/NoPadding",        P11Cipher,
++                m(CKM_BLOWFISH_CBC));
++        d(CIP, "Blowfish/CBC/PKCS5Padding",     P11Cipher,
+                 m(CKM_BLOWFISH_CBC));
+ 
+         // XXX RSA_X_509, RSA_OAEP not yet supported
+diff -r 9ec80e94c5cd -r b2488252ba0c test/javax/crypto/Cipher/GetMaxAllowed.java
+--- openjdk/jdk/test/javax/crypto/Cipher/GetMaxAllowed.java	Wed Jan 18 19:33:50 2012 -0800
++++ openjdk/jdk/test/javax/crypto/Cipher/GetMaxAllowed.java	Wed Jan 18 19:35:30 2012 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, 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
+@@ -23,7 +23,7 @@
+ 
+ /**
+  * @test
+- * @bug 4807942
++ * @bug 4807942 7033170
+  * @summary Test the Cipher.getMaxAllowedKeyLength(String) and
+  * getMaxAllowedParameterSpec(String) methods
+  * @author Valerie Peng
+@@ -40,7 +40,7 @@
+ 
+ public class GetMaxAllowed {
+ 
+-    private static void runTest(boolean isUnlimited) throws Exception {
++    private static void runTest1(boolean isUnlimited) throws Exception {
+         System.out.println("Testing " + (isUnlimited? "un":"") +
+                            "limited policy...");
+ 
+@@ -78,6 +78,20 @@
+         System.out.println("All tests passed");
+     }
+ 
++    private static void runTest2() throws Exception {
++        System.out.println("Testing against Security.getAlgorithms()");
++
++        Set<String> algorithms = Security.getAlgorithms("Cipher");
++
++        for (String algorithm: algorithms) {
++            int keylength = -1;
++
++            // if 7033170 is not fixed, NoSuchAlgorithmException is thrown
++            keylength = Cipher.getMaxAllowedKeyLength(algorithm);
++
++        }
++    }
++
+     public static void main(String[] args) throws Exception {
+         // decide if the installed jurisdiction policy file is the
+         // unlimited version
+@@ -88,6 +102,9 @@
+         } catch (InvalidKeyException ike) {
+             isUnlimited = false;
+         }
+-        runTest(isUnlimited);
++        runTest1(isUnlimited);
++
++        // test using the set of algorithms returned by Security.getAlgorithms()
++        runTest2();
+     }
+ }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/7044060-support_nsa_suite_b.patch	Thu Oct 09 02:25:23 2014 +0100
@@ -0,0 +1,3223 @@
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java	2014-10-08 23:42:37.517304235 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2002, 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
+@@ -47,12 +47,115 @@
+  * @see OutputFeedback
+  */
+ 
+-public final class AESCipher extends CipherSpi {
++abstract class AESCipher extends CipherSpi {
++    public static final class General extends AESCipher {
++        public General() {
++            super(-1);
++        }
++    }
++    abstract static class OidImpl extends AESCipher {
++        protected OidImpl(int keySize, String mode, String padding) {
++            super(keySize);
++            try {
++                engineSetMode(mode);
++                engineSetPadding(padding);
++            } catch (GeneralSecurityException gse) {
++                // internal error; re-throw as provider exception
++                ProviderException pe =new ProviderException("Internal Error");
++                pe.initCause(gse);
++                throw pe;
++            }
++        }
++    }
++    public static final class AES128_ECB_NoPadding extends OidImpl {
++        public AES128_ECB_NoPadding() {
++            super(16, "ECB", "NOPADDING");
++        }
++    }
++    public static final class AES192_ECB_NoPadding extends OidImpl {
++        public AES192_ECB_NoPadding() {
++            super(24, "ECB", "NOPADDING");
++        }
++    }
++    public static final class AES256_ECB_NoPadding extends OidImpl {
++        public AES256_ECB_NoPadding() {
++            super(32, "ECB", "NOPADDING");
++        }
++    }
++    public static final class AES128_CBC_NoPadding extends OidImpl {
++        public AES128_CBC_NoPadding() {
++            super(16, "CBC", "NOPADDING");
++        }
++    }
++    public static final class AES192_CBC_NoPadding extends OidImpl {
++        public AES192_CBC_NoPadding() {
++            super(24, "CBC", "NOPADDING");
++        }
++    }
++    public static final class AES256_CBC_NoPadding extends OidImpl {
++        public AES256_CBC_NoPadding() {
++            super(32, "CBC", "NOPADDING");
++        }
++    }
++    public static final class AES128_OFB_NoPadding extends OidImpl {
++        public AES128_OFB_NoPadding() {
++            super(16, "OFB", "NOPADDING");
++        }
++    }
++    public static final class AES192_OFB_NoPadding extends OidImpl {
++        public AES192_OFB_NoPadding() {
++            super(24, "OFB", "NOPADDING");
++        }
++    }
++    public static final class AES256_OFB_NoPadding extends OidImpl {
++        public AES256_OFB_NoPadding() {
++            super(32, "OFB", "NOPADDING");
++        }
++    }
++    public static final class AES128_CFB_NoPadding extends OidImpl {
++        public AES128_CFB_NoPadding() {
++            super(16, "CFB", "NOPADDING");
++        }
++    }
++    public static final class AES192_CFB_NoPadding extends OidImpl {
++        public AES192_CFB_NoPadding() {
++            super(24, "CFB", "NOPADDING");
++        }
++    }
++    public static final class AES256_CFB_NoPadding extends OidImpl {
++        public AES256_CFB_NoPadding() {
++            super(32, "CFB", "NOPADDING");
++        }
++    }
++
++    // utility method used by AESCipher and AESWrapCipher
++    static final void checkKeySize(Key key, int fixedKeySize)
++        throws InvalidKeyException {
++        if (fixedKeySize != -1) {
++            if (key == null) {
++                throw new InvalidKeyException("The key must not be null");
++            }
++            byte[] value = key.getEncoded();
++            if (value == null) {
++                throw new InvalidKeyException("Key encoding must not be null");
++            } else if (value.length != fixedKeySize) {
++                throw new InvalidKeyException("The key must be " +
++                    fixedKeySize*8 + " bits");
++            }
++        }
++    }
++
+     /*
+      * internal CipherCore object which does the real work.
+      */
+     private CipherCore core = null;
+ 
++    /*
++     * needed to support AES oids which associates a fixed key size
++     * to the cipher object.
++     */
++    private final int fixedKeySize; // in bytes, -1 if no restriction
++
+     /**
+      * Creates an instance of AES cipher with default ECB mode and
+      * PKCS5Padding.
+@@ -60,9 +163,9 @@
+      * @exception SecurityException if this constructor fails to verify
+      * its own integrity
+      */
+-    public AESCipher() {
+-        SunJCE.ensureIntegrity(getClass());
++    protected AESCipher(int keySize) {
+         core = new CipherCore(new AESCrypt(), AESConstants.AES_BLOCK_SIZE);
++        fixedKeySize = keySize;
+     }
+ 
+     /**
+@@ -187,6 +290,7 @@
+      */
+     protected void engineInit(int opmode, Key key, SecureRandom random)
+         throws InvalidKeyException {
++        checkKeySize(key, fixedKeySize);
+         core.init(opmode, key, random);
+     }
+ 
+@@ -218,6 +322,7 @@
+                               AlgorithmParameterSpec params,
+                               SecureRandom random)
+         throws InvalidKeyException, InvalidAlgorithmParameterException {
++        checkKeySize(key, fixedKeySize);
+         core.init(opmode, key, params, random);
+     }
+ 
+@@ -225,6 +330,7 @@
+                               AlgorithmParameters params,
+                               SecureRandom random)
+         throws InvalidKeyException, InvalidAlgorithmParameterException {
++        checkKeySize(key, fixedKeySize);
+         core.init(opmode, key, params, random);
+     }
+ 
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/AESWrapCipher.java	2014-10-08 23:39:30.602719423 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2004, 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
+@@ -43,8 +43,27 @@
+  *
+  * @see AESCipher
+  */
+-public final class AESWrapCipher extends CipherSpi {
+-
++abstract class AESWrapCipher extends CipherSpi {
++    public static final class General extends AESWrapCipher {
++        public General() {
++            super(-1);
++        }
++    }
++    public static final class AES128 extends AESWrapCipher {
++        public AES128() {
++            super(16);
++        }
++    }
++    public static final class AES192 extends AESWrapCipher {
++        public AES192() {
++            super(24);
++        }
++    }
++    public static final class AES256 extends AESWrapCipher {
++        public AES256() {
++            super(32);
++        }
++    }
+     private static final byte[] IV = {
+         (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6,
+         (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6
+@@ -62,6 +81,12 @@
+      */
+     private boolean decrypting = false;
+ 
++    /*
++     * needed to support AES oids which associates a fixed key size
++     * to the cipher object.
++     */
++    private final int fixedKeySize; // in bytes, -1 if no restriction
++
+     /**
+      * Creates an instance of AES KeyWrap cipher with default
+      * mode, i.e. "ECB" and padding scheme, i.e. "NoPadding".
+@@ -69,9 +94,11 @@
+      * @exception SecurityException if this constructor fails to verify
+      * its own integrity
+      */
+-    public AESWrapCipher() {
++    public AESWrapCipher(int keySize) {
+         SunJCE.ensureIntegrity(getClass());
+         cipher = new AESCrypt();
++        fixedKeySize = keySize;
++
+     }
+ 
+     /**
+@@ -174,6 +201,7 @@
+             throw new UnsupportedOperationException("This cipher can " +
+                 "only be used for key wrapping and unwrapping");
+         }
++        AESCipher.checkKeySize(key, fixedKeySize);
+         cipher.init(decrypting, key.getAlgorithm(), key.getEncoded());
+     }
+ 
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	2014-10-08 23:37:10.076777154 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 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
+@@ -80,10 +80,10 @@
+      * @param random the source of randomness
+      */
+     public void initialize(int keysize, SecureRandom random) {
+-        if ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0)) {
++        if ((keysize < 512) || (keysize > 2048) || (keysize % 64 != 0)) {
+             throw new InvalidParameterException("Keysize must be multiple "
+                                                 + "of 64, and can only range "
+-                                                + "from 512 to 1024 "
++                                                + "from 512 to 2048 "
+                                                 + "(inclusive)");
+         }
+         this.pSize = keysize;
+@@ -115,11 +115,11 @@
+ 
+         params = (DHParameterSpec)algParams;
+         pSize = params.getP().bitLength();
+-        if ((pSize < 512) || (pSize > 1024) ||
++        if ((pSize < 512) || (pSize > 2048) ||
+             (pSize % 64 != 0)) {
+             throw new InvalidAlgorithmParameterException
+                 ("Prime size must be multiple of 64, and can only range "
+-                 + "from 512 to 1024 (inclusive)");
++                 + "from 512 to 2048 (inclusive)");
+         }
+ 
+         // exponent size is optional, could be 0
+@@ -156,10 +156,11 @@
+         BigInteger g = params.getG();
+ 
+         if (lSize <= 0) {
++            lSize = pSize >> 1;
+             // use an exponent size of (pSize / 2) but at least 384 bits
+-            lSize = Math.max(384, pSize >> 1);
+-            // if lSize is larger than pSize, limit by pSize
+-            lSize = Math.min(lSize, pSize);
++            if (lSize < 384) {
++                lSize = 384;
++            }
+         }
+ 
+         BigInteger x;
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	2014-10-08 23:37:10.076777154 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 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
+@@ -68,10 +68,10 @@
+      * @param random the source of randomness
+      */
+     protected void engineInit(int keysize, SecureRandom random) {
+-        if ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0)) {
++        if ((keysize < 512) || (keysize > 2048) || (keysize % 64 != 0)) {
+             throw new InvalidParameterException("Keysize must be multiple "
+                                                 + "of 64, and can only range "
+-                                                + "from 512 to 1024 "
++                                                + "from 512 to 2048 "
+                                                 + "(inclusive)");
+         }
+         this.primeSize = keysize;
+@@ -100,10 +100,10 @@
+             DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec;
+ 
+             primeSize = dhParamSpec.getPrimeSize();
+-            if ((primeSize<512) || (primeSize>1024) || (primeSize%64 != 0)) {
++            if ((primeSize<512) || (primeSize>2048) || (primeSize%64 != 0)) {
+                 throw new InvalidAlgorithmParameterException
+                     ("Modulus size must be multiple of 64, and can only range "
+-                     + "from 512 to 1024 (inclusive)");
++                     + "from 512 to 2048 (inclusive)");
+             }
+ 
+             exponentSize = dhParamSpec.getExponentSize();
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java	2014-10-08 23:36:49.400491428 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java	2014-10-08 23:37:10.076777154 +0100
+@@ -176,16 +176,67 @@
+                 put("Cipher.Blowfish SupportedKeyFormats", "RAW");
+ 
+                 put("Cipher.AES", "com.sun.crypto.provider.AESCipher");
++                put("Cipher.AES", "com.sun.crypto.provider.AESCipher$General");
+                 put("Alg.Alias.Cipher.Rijndael", "AES");
+                 put("Cipher.AES SupportedModes", BLOCK_MODES128);
+                 put("Cipher.AES SupportedPaddings", BLOCK_PADS);
+                 put("Cipher.AES SupportedKeyFormats", "RAW");
+ 
+-                put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher");
++                put("Cipher.AES_128/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_ECB_NoPadding");
++                put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding");
++                put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding");
++                put("Cipher.AES_128/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CBC_NoPadding");
++                put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding");
++                put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding");
++                put("Cipher.AES_128/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_OFB_NoPadding");
++                put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding");
++                put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding");
++                put("Cipher.AES_128/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding");
++                put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
++                put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
++
++                put("Cipher.AES_192/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding");
++		put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding");
++		put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding");
++		put("Cipher.AES_192/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CBC_NoPadding");
++		put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding");
++		put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding");
++		put("Cipher.AES_192/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_OFB_NoPadding");
++		put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding");
++		put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding");
++		put("Cipher.AES_192/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding");
++		put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
++		put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
++
++
++		put("Cipher.AES_256/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding");
++		put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding");
++		put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding");
++		put("Cipher.AES_256/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CBC_NoPadding");
++		put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding");
++		put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding");
++		put("Cipher.AES_256/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_OFB_NoPadding");
++		put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding");
++		put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding");
++		put("Cipher.AES_256/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding");
++		put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
++		put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
++		
++		put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher$General");
+                 put("Cipher.AESWrap SupportedModes", "ECB");
+                 put("Cipher.AESWrap SupportedPaddings", "NOPADDING");
+                 put("Cipher.AESWrap SupportedKeyFormats", "RAW");
+ 
++		put("Cipher.AESWrap_128", "com.sun.crypto.provider.AESWrapCipher$AES128");
++		put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.5", "AESWrap_128");
++		put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.5", "AESWrap_128");
++		put("Cipher.AESWrap_192", "com.sun.crypto.provider.AESWrapCipher$AES192");
++		put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.25", "AESWrap_192");
++		put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.25", "AESWrap_192");
++		put("Cipher.AESWrap_256", "com.sun.crypto.provider.AESWrapCipher$AES256");
++		put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.45", "AESWrap_256");
++		put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.45", "AESWrap_256");
++
+                 put("Cipher.RC2",
+                     "com.sun.crypto.provider.RC2Cipher");
+                 put("Cipher.RC2 SupportedModes", BLOCK_MODES);
+@@ -200,7 +251,7 @@
+                 put("Cipher.ARCFOUR SupportedKeyFormats", "RAW");
+ 
+                 /*
+-                 *  Key(pair) Generator engines
++                 * Key(pair) Generator engines
+                  */
+                 put("KeyGenerator.DES",
+                     "com.sun.crypto.provider.DESKeyGenerator");
+@@ -229,6 +280,8 @@
+ 
+                 put("KeyGenerator.HmacSHA1",
+                     "com.sun.crypto.provider.HmacSHA1KeyGenerator");
++		put("Alg.Alias.KeyGenerator.OID.1.2.840.113549.2.7", "HmacSHA1");
++		put("Alg.Alias.KeyGenerator.1.2.840.113549.2.7", "HmacSHA1");
+ 
+                 put("KeyGenerator.HmacSHA224",
+                     "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA224");
+@@ -411,6 +464,8 @@
+                  */
+                 put("Mac.HmacMD5", "com.sun.crypto.provider.HmacMD5");
+                 put("Mac.HmacSHA1", "com.sun.crypto.provider.HmacSHA1");
++		put("Alg.Alias.Mac.OID.1.2.840.113549.2.7", "HmacSHA1");
++		put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1");
+                 put("Mac.HmacSHA224",
+                     "com.sun.crypto.provider.HmacCore$HmacSHA224");
+                 put("Alg.Alias.Mac.OID.1.2.840.113549.2.8", "HmacSHA224");
+diff -Nru openjdk.orig/jdk/src/share/classes/java/security/interfaces/DSAKeyPairGenerator.java openjdk/jdk/src/share/classes/java/security/interfaces/DSAKeyPairGenerator.java
+--- openjdk.orig/jdk/src/share/classes/java/security/interfaces/DSAKeyPairGenerator.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/java/security/interfaces/DSAKeyPairGenerator.java	2014-10-08 23:37:10.076777154 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 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
+@@ -62,6 +62,9 @@
+  * interface is all that is needed when you accept defaults for algorithm-specific
+  * parameters.
+  *
++ * <p>Note: Some earlier implementations of this interface may not support
++ * larger sizes of DSA parameters such as 2048 and 3072-bit.
++ *
+  * @see java.security.KeyPairGenerator
+  */
+ public interface DSAKeyPairGenerator {
+@@ -78,7 +81,7 @@
+      * can be null.
+      *
+      * @exception InvalidParameterException if the <code>params</code>
+-     * value is invalid or null.
++     * value is invalid, null, or unsupported.
+      */
+    public void initialize(DSAParams params, SecureRandom random)
+    throws InvalidParameterException;
+@@ -97,7 +100,7 @@
+      * default parameters for modulus lengths of 512 and 1024 bits.
+      *
+      * @param modlen the modulus length in bits. Valid values are any
+-     * multiple of 8 between 512 and 1024, inclusive.
++     * multiple of 64 between 512 and 1024, inclusive, 2048, and 3072.
+      *
+      * @param random the random bit source to use to generate key bits;
+      * can be null.
+@@ -105,10 +108,9 @@
+      * @param genParams whether or not to generate new parameters for
+      * the modulus length requested.
+      *
+-     * @exception InvalidParameterException if <code>modlen</code> is not
+-     * between 512 and 1024, or if <code>genParams</code> is false and
+-     * there are no precomputed parameters for the requested modulus
+-     * length.
++     * @exception InvalidParameterException if <code>modlen</code> is
++     * invalid, or unsupported, or if <code>genParams</code> is false and there
++     * are no precomputed parameters for the requested modulus length.
+      */
+     public void initialize(int modlen, boolean genParams, SecureRandom random)
+     throws InvalidParameterException;
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java	2014-10-08 23:36:47.440464344 +0100
++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java	2014-10-08 23:38:45.190091692 +0100
+@@ -164,6 +164,10 @@
+     // if we do the padding
+     private int bytesBuffered;
+ 
++    // length of key size in bytes; currently only used by AES given its oid
++    // specification mandates a fixed size of the key
++    private int fixedKeySize = -1;
++
+     P11Cipher(Token token, String algorithm, long mechanism)
+             throws PKCS11Exception, NoSuchAlgorithmException {
+         super();
+@@ -172,19 +176,26 @@
+         this.mechanism = mechanism;
+ 
+         String algoParts[] = algorithm.split("/");
+-        keyAlgorithm = algoParts[0];
+ 
+-        if (keyAlgorithm.equals("AES")) {
++        if (algoParts[0].startsWith("AES")) {
+             blockSize = 16;
+-        } else if (keyAlgorithm.equals("RC4") ||
+-                keyAlgorithm.equals("ARCFOUR")) {
+-            blockSize = 0;
+-        } else { // DES, DESede, Blowfish
+-            blockSize = 8;
+-        }
+-        this.blockMode =
++            int index = algoParts[0].indexOf('_');
++            if (index != -1) {
++                // should be well-formed since we specify what we support
++                fixedKeySize = Integer.parseInt(algoParts[0].substring(index+1))/8;
++            }
++            keyAlgorithm = "AES";
++        } else {
++            keyAlgorithm = algoParts[0];
++            if (keyAlgorithm.equals("RC4") ||
++                    keyAlgorithm.equals("ARCFOUR")) {
++                blockSize = 0;
++            } else { // DES, DESede, Blowfish
++                blockSize = 8;
++            }
++            this.blockMode =
+                 (algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB);
+-
++        }
+         String defPadding = (blockSize == 0 ? "NoPadding" : "PKCS5Padding");
+         String paddingStr =
+                 (algoParts.length > 2 ? algoParts[2] : defPadding);
+@@ -333,6 +344,9 @@
+             SecureRandom random)
+             throws InvalidKeyException, InvalidAlgorithmParameterException {
+         cancelOperation();
++        if (fixedKeySize != -1 && key.getEncoded().length != fixedKeySize) {
++            throw new InvalidKeyException("Key size is invalid");
++        }
+         switch (opmode) {
+             case Cipher.ENCRYPT_MODE:
+                 encrypt = true;
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java openjdk/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java	2014-10-08 23:36:49.512492977 +0100
++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java	2014-10-08 23:38:03.717518477 +0100
+@@ -401,12 +401,8 @@
+         return System.identityHashCode(this);
+     }
+ 
+-    private static String[] s(String s1) {
+-        return new String[] {s1};
+-    }
+-
+-    private static String[] s(String s1, String s2) {
+-        return new String[] {s1, s2};
++    private static String[] s(String ...aliases) {
++        return aliases;
+     }
+ 
+     private static final class Descriptor {
+@@ -523,7 +519,8 @@
+                 m(CKM_MD2));
+         d(MD, "MD5",            P11Digest,
+                 m(CKM_MD5));
+-        d(MD, "SHA1",           P11Digest, s("SHA", "SHA-1"),
++        d(MD, "SHA1",           P11Digest,
++                s("SHA", "SHA-1", "1.3.14.3.2.26", "OID.1.3.14.3.2.26"),
+                 m(CKM_SHA_1));
+ 
+         d(MD, "SHA-224",        P11Digest,
+@@ -542,6 +539,7 @@
+         d(MAC, "HmacMD5",       P11MAC,
+                 m(CKM_MD5_HMAC));
+         d(MAC, "HmacSHA1",      P11MAC,
++                s("1.2.840.113549.2.7", "OID.1.2.840.113549.2.7"),
+                 m(CKM_SHA_1_HMAC));
+         d(MAC, "HmacSHA224",    P11MAC,
+                 s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"),
+@@ -563,6 +561,7 @@
+         d(KPG, "RSA",           P11KeyPairGenerator,
+                 m(CKM_RSA_PKCS_KEY_PAIR_GEN));
+         d(KPG, "DSA",           P11KeyPairGenerator,
++                s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
+                 m(CKM_DSA_KEY_PAIR_GEN));
+         d(KPG, "DH",            P11KeyPairGenerator,    s("DiffieHellman"),
+                 m(CKM_DH_PKCS_KEY_PAIR_GEN));
+@@ -585,6 +584,7 @@
+         d(KF, "RSA",            P11RSAKeyFactory,
+                 m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509));
+         d(KF, "DSA",            P11DSAKeyFactory,
++                s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
+                 m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1));
+         d(KF, "DH",             P11DHKeyFactory,        s("DiffieHellman"),
+                 m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
+@@ -608,6 +608,7 @@
+         d(SKF, "DESede",        P11SecretKeyFactory,
+                 m(CKM_DES3_CBC));
+         d(SKF, "AES",           P11SecretKeyFactory,
++                s("2.16.840.1.101.3.4.1", "OID.2.16.840.1.101.3.4.1"),
+                 m(CKM_AES_CBC));
+         d(SKF, "Blowfish",      P11SecretKeyFactory,
+                 m(CKM_BLOWFISH_CBC));
+@@ -633,10 +634,28 @@
+                 m(CKM_DES3_ECB));
+         d(CIP, "AES/CBC/NoPadding",             P11Cipher,
+                 m(CKM_AES_CBC));
++        d(CIP, "AES_128/CBC/NoPadding",          P11Cipher,
++                s("2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"),
++                m(CKM_AES_CBC));
++        d(CIP, "AES_192/CBC/NoPadding",          P11Cipher,
++                s("2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"),
++                m(CKM_AES_CBC));
++        d(CIP, "AES_256/CBC/NoPadding",          P11Cipher,
++                s("2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42"),
++                m(CKM_AES_CBC));
+         d(CIP, "AES/CBC/PKCS5Padding",          P11Cipher,
+                 m(CKM_AES_CBC_PAD, CKM_AES_CBC));
+         d(CIP, "AES/ECB/NoPadding",             P11Cipher,
+                 m(CKM_AES_ECB));
++        d(CIP, "AES_128/ECB/NoPadding",          P11Cipher,
++                s("2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"),
++                m(CKM_AES_ECB));
++        d(CIP, "AES_192/ECB/NoPadding",          P11Cipher,
++                s("2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"),
++                m(CKM_AES_ECB));
++        d(CIP, "AES_256/ECB/NoPadding",          P11Cipher,
++                s("2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41"),
++                m(CKM_AES_ECB));
+         d(CIP, "AES/ECB/PKCS5Padding",          P11Cipher,      s("AES"),
+                 m(CKM_AES_ECB));
+         d(CIP, "AES/CTR/NoPadding",             P11Cipher,
+@@ -650,13 +669,16 @@
+         d(CIP, "RSA/ECB/PKCS1Padding",          P11RSACipher,
+                 m(CKM_RSA_PKCS));
+ 
+-        d(SIG, "RawDSA",        P11Signature,           s("NONEwithDSA"),
++        d(SIG, "RawDSA",        P11Signature,   s("NONEwithDSA"),
+                 m(CKM_DSA));
+-        d(SIG, "DSA",           P11Signature,           s("SHA1withDSA"),
++        d(SIG, "DSA",           P11Signature,
++                s("SHA1withDSA", "1.3.14.3.2.13", "1.3.14.3.2.27",
++                  "1.2.840.10040.4.3", "OID.1.2.840.10040.4.3"),
+                 m(CKM_DSA_SHA1, CKM_DSA));
+         d(SIG, "NONEwithECDSA", P11Signature,
+                 m(CKM_ECDSA));
+-        d(SIG, "SHA1withECDSA", P11Signature,           s("ECDSA"),
++        d(SIG, "SHA1withECDSA", P11Signature,
++                s("ECDSA", "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1"),
+                 m(CKM_ECDSA_SHA1, CKM_ECDSA));
+         d(SIG, "SHA224withECDSA",       P11Signature,
+                 s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"),
+@@ -671,10 +693,14 @@
+                 s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"),
+                 m(CKM_ECDSA));
+         d(SIG, "MD2withRSA",    P11Signature,
++                s("1.2.840.113549.1.1.2", "OID.1.2.840.113549.1.1.2"),
+                 m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+         d(SIG, "MD5withRSA",    P11Signature,
++                s("1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4"),
+                 m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+         d(SIG, "SHA1withRSA",   P11Signature,
++                s("1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5",
++                  "1.3.14.3.2.29"),
+                 m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+         d(SIG, "SHA224withRSA", P11Signature,
+                 s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"),
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/DSA.java openjdk/jdk/src/share/classes/sun/security/provider/DSA.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/DSA.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/DSA.java	2014-10-08 23:37:11.636798712 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2004, 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
+@@ -45,14 +45,15 @@
+ 
+ /**
+  * The Digital Signature Standard (using the Digital Signature
+- * Algorithm), as described in fips186 of the National Instute of
+- * Standards and Technology (NIST), using fips180-1 (SHA-1).
++ * Algorithm), as described in fips186-3 of the National Instute of
++ * Standards and Technology (NIST), using SHA digest algorithms
++ * from FIPS180-3.
+  *
+  * This file contains both the signature implementation for the
+- * commonly used SHA1withDSA (DSS) as well as RawDSA, used by TLS
+- * among others. RawDSA expects the 20 byte SHA-1 digest as input
+- * via update rather than the original data like other signature
+- * implementations.
++ * commonly used SHA1withDSA (DSS), SHA224withDSA, SHA256withDSA,
++ * as well as RawDSA, used by TLS among others. RawDSA expects
++ * the 20 byte SHA-1 digest as input via update rather than the
++ * original data like other signature implementations.
+  *
+  * @author Benjamin Renaud
+  *
+@@ -78,129 +79,19 @@
+     /* The private key, if any */
+     private BigInteger presetX;
+ 
+-    /* The random seed used to generate k */
+-    private int[] Kseed;
+-
+-    /* The random seed used to generate k (specified by application) */
+-    private byte[] KseedAsByteArray;
+-
+-    /*
+-     * The random seed used to generate k
+-     * (prevent the same Kseed from being used twice in a row
+-     */
+-    private int[] previousKseed;
+-
+     /* The RNG used to output a seed for generating k */
+     private SecureRandom signingRandom;
+ 
++    /* The message digest object used */
++    private final MessageDigest md;
++
+     /**
+      * Construct a blank DSA object. It must be
+      * initialized before being usable for signing or verifying.
+      */
+-    DSA() {
++    DSA(MessageDigest md) {
+         super();
+-    }
+-
+-    /**
+-     * Return the 20 byte hash value and reset the digest.
+-     */
+-    abstract byte[] getDigest() throws SignatureException;
+-
+-    /**
+-     * Reset the digest.
+-     */
+-    abstract void resetDigest();
+-
+-    /**
+-     * Standard SHA1withDSA implementation.
+-     */
+-    public static final class SHA1withDSA extends DSA {
+-
+-        /* The SHA hash for the data */
+-        private final MessageDigest dataSHA;
+-
+-        public SHA1withDSA() throws NoSuchAlgorithmException {
+-            dataSHA = MessageDigest.getInstance("SHA-1");
+-        }
+-
+-        /**
+-         * Update a byte to be signed or verified.
+-         */
+-        protected void engineUpdate(byte b) {
+-            dataSHA.update(b);
+-        }
+-
+-        /**
+-         * Update an array of bytes to be signed or verified.
+-         */
+-        protected void engineUpdate(byte[] data, int off, int len) {
+-            dataSHA.update(data, off, len);
+-        }
+-
+-        protected void engineUpdate(ByteBuffer b) {
+-            dataSHA.update(b);
+-        }
+-
+-        byte[] getDigest() {
+-            return dataSHA.digest();
+-        }
+-
+-        void resetDigest() {
+-            dataSHA.reset();
+-        }
+-    }
+-
+-    /**
+-     * RawDSA implementation.
+-     *
+-     * RawDSA requires the data to be exactly 20 bytes long. If it is
+-     * not, a SignatureException is thrown when sign()/verify() is called
+-     * per JCA spec.
+-     */
+-    public static final class RawDSA extends DSA {
+-
+-        // length of the SHA-1 digest (20 bytes)
+-        private final static int SHA1_LEN = 20;
+-
+-        // 20 byte digest buffer
+-        private final byte[] digestBuffer;
+-
+-        // offset into the buffer
+-        private int ofs;
+-
+-        public RawDSA() {
+-            digestBuffer = new byte[SHA1_LEN];
+-        }
+-
+-        protected void engineUpdate(byte b) {
+-            if (ofs == SHA1_LEN) {
+-                ofs = SHA1_LEN + 1;
+-                return;
+-            }
+-            digestBuffer[ofs++] = b;
+-        }
+-
+-        protected void engineUpdate(byte[] data, int off, int len) {
+-            if (ofs + len > SHA1_LEN) {
+-                ofs = SHA1_LEN + 1;
+-                return;
+-            }
+-            System.arraycopy(data, off, digestBuffer, ofs, len);
+-            ofs += len;
+-        }
+-
+-        byte[] getDigest() throws SignatureException {
+-            if (ofs != SHA1_LEN) {
+-                throw new SignatureException
+-                        ("Data for RawDSA must be exactly 20 bytes long");
+-            }
+-            ofs = 0;
+-            return digestBuffer;
+-        }
+-
+-        void resetDigest() {
+-            ofs = 0;
+-        }
++        this.md = md;
+     }
+ 
+     /**
+@@ -217,13 +108,25 @@
+             throw new InvalidKeyException("not a DSA private key: " +
+                                           privateKey);
+         }
++
+         java.security.interfaces.DSAPrivateKey priv =
+             (java.security.interfaces.DSAPrivateKey)privateKey;
++
++        // check for algorithm specific constraints before doing initialization
++        DSAParams params = priv.getParams();
++        if (params == null) {
++            throw new InvalidKeyException("DSA private key lacks parameters");
++        }
++        checkKey(params);
++
++        this.params = params;
+         this.presetX = priv.getX();
+         this.presetY = null;
+-        initialize(priv.getParams());
++        this.presetP = params.getP();
++        this.presetQ = params.getQ();
++        this.presetG = params.getG();
++        this.md.reset();
+     }
+-
+     /**
+      * Initialize the DSA object with a DSA public key.
+      *
+@@ -240,17 +143,43 @@
+         }
+         java.security.interfaces.DSAPublicKey pub =
+             (java.security.interfaces.DSAPublicKey)publicKey;
++
++        // check for algorithm specific constraints before doing initialization
++        DSAParams params = pub.getParams();
++        if (params == null) {
++            throw new InvalidKeyException("DSA public key lacks parameters");
++        }
++        checkKey(params);
++
++        this.params = params;
+         this.presetY = pub.getY();
+         this.presetX = null;
+-        initialize(pub.getParams());
++        this.presetP = params.getP();
++        this.presetQ = params.getQ();
++        this.presetG = params.getG();
++        this.md.reset();
+     }
+ 
+-    private void initialize(DSAParams params) throws InvalidKeyException {
+-        resetDigest();
+-        setParams(params);
++    /**
++     * Update a byte to be signed or verified.
++     */
++    protected void engineUpdate(byte b) {
++        md.update(b);
+     }
+ 
+     /**
++     * Update an array of bytes to be signed or verified.
++     */
++    protected void engineUpdate(byte[] data, int off, int len) {
++        md.update(data, off, len);
++    }
++
++    protected void engineUpdate(ByteBuffer b) {
++        md.update(b);
++    }
++
++
++    /**
+      * Sign all the data thus far updated. The signature is formatted
+      * according to the Canonical Encoding Rules, returned as a DER
+      * sequence of Integer, r and s.
+@@ -352,23 +281,51 @@
+         }
+     }
+ 
++    @Deprecated
++    protected void engineSetParameter(String key, Object param) {
++        throw new InvalidParameterException("No parameter accepted");
++    }
++
++    @Deprecated
++    protected Object engineGetParameter(String key) {
++        return null;
++    }
++
++    protected void checkKey(DSAParams params) throws InvalidKeyException {
++        // FIPS186-3 states in sec4.2 that a hash function which provides
++        // a lower security strength than the (L, N) pair ordinarily should
++        // not be used.
++        int valueN = params.getQ().bitLength();
++        if (valueN > md.getDigestLength()*8) {
++            throw new InvalidKeyException("Key is too strong for this signature algorithm");
++        }
++    }
++
+     private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,
+                          BigInteger k) {
+         BigInteger temp = g.modPow(k, p);
+-        return temp.remainder(q);
+-   }
++        return temp.mod(q);
++    }
+ 
+     private BigInteger generateS(BigInteger x, BigInteger q,
+             BigInteger r, BigInteger k) throws SignatureException {
+ 
+-        byte[] s2 = getDigest();
+-        BigInteger temp = new BigInteger(1, s2);
++        byte[] s2;
++        try {
++            s2 = md.digest();
++        } catch (RuntimeException re) {
++            // Only for RawDSA due to its 20-byte length restriction
++            throw new SignatureException(re.getMessage());
++        }
++        // get the leftmost min(N, outLen) bits of the digest value
++        int nBytes = q.bitLength()/8;
++        if (nBytes < s2.length) {
++            s2 = Arrays.copyOfRange(s2, 0, nBytes);
++        }
++        BigInteger z = new BigInteger(1, s2);
+         BigInteger k1 = k.modInverse(q);
+ 
+-        BigInteger s = x.multiply(r);
+-        s = temp.add(s);
+-        s = k1.multiply(s);
+-        return s.remainder(q);
++        return x.multiply(r).add(z).multiply(k1).mod(q);
+     }
+ 
+     private BigInteger generateW(BigInteger p, BigInteger q,
+@@ -380,54 +337,41 @@
+              BigInteger q, BigInteger g, BigInteger w, BigInteger r)
+              throws SignatureException {
+ 
+-        byte[] s2 = getDigest();
+-        BigInteger temp = new BigInteger(1, s2);
+-
+-        temp = temp.multiply(w);
+-        BigInteger u1 = temp.remainder(q);
++        byte[] s2;
++        try {
++            s2 = md.digest();
++        } catch (RuntimeException re) {
++            // Only for RawDSA due to its 20-byte length restriction
++            throw new SignatureException(re.getMessage());
++        }
++        // get the leftmost min(N, outLen) bits of the digest value
++        int nBytes = q.bitLength()/8;
++        if (nBytes < s2.length) {
++            s2 = Arrays.copyOfRange(s2, 0, nBytes);
++        }
++        BigInteger z = new BigInteger(1, s2);
+ 
+-        BigInteger u2 = (r.multiply(w)).remainder(q);
++        BigInteger u1 = z.multiply(w).mod(q);
++        BigInteger u2 = (r.multiply(w)).mod(q);
+ 
+         BigInteger t1 = g.modPow(u1,p);
+         BigInteger t2 = y.modPow(u2,p);
+         BigInteger t3 = t1.multiply(t2);
+-        BigInteger t5 = t3.remainder(p);
+-        return t5.remainder(q);
++        BigInteger t5 = t3.mod(p);
++        return t5.mod(q);
+     }
+ 
+-    /*
+-     * Please read bug report 4044247 for an alternative, faster,
+-     * NON-FIPS approved method to generate K
+-     */
+-    private BigInteger generateK(BigInteger q) {
+-
+-        BigInteger k = null;
+-
+-        // The application specified a Kseed for us to use.
+-        // Note that we do not allow usage of the same Kseed twice in a row
+-        if (Kseed != null && !Arrays.equals(Kseed, previousKseed)) {
+-            k = generateK(Kseed, q);
+-            if (k.signum() > 0 && k.compareTo(q) < 0) {
+-                previousKseed = new int [Kseed.length];
+-                System.arraycopy(Kseed, 0, previousKseed, 0, Kseed.length);
+-                return k;
+-            }
+-        }
+-
+-        // The application did not specify a Kseed for us to use.
+-        // We'll generate a new Kseed by getting random bytes from
+-        // a SecureRandom object.
++    // NOTE: This following impl is defined in FIPS 186-3 AppendixB.2.2.
++    // Original DSS algos such as SHA1withDSA and RawDSA uses a different
++    // algorithm defined in FIPS 186-1 Sec3.2, and thus need to override this.
++    protected BigInteger generateK(BigInteger q) {
+         SecureRandom random = getSigningRandom();
++        byte[] kValue = new byte[q.bitLength()/8];
+ 
+         while (true) {
+-            int[] seed = new int[5];
+-
+-            for (int i = 0; i < 5; i++)
+-                seed[i] = random.nextInt();
+-            k = generateK(seed, q);
++            random.nextBytes(kValue);
++            BigInteger k = new BigInteger(1, kValue).mod(q);
+             if (k.signum() > 0 && k.compareTo(q) < 0) {
+-                previousKseed = new int [seed.length];
+-                System.arraycopy(seed, 0, previousKseed, 0, seed.length);
+                 return k;
+             }
+         }
+@@ -435,7 +379,7 @@
+ 
+     // Use the application-specified SecureRandom Object if provided.
+     // Otherwise, use our default SecureRandom Object.
+-    private SecureRandom getSigningRandom() {
++    protected SecureRandom getSigningRandom() {
+         if (signingRandom == null) {
+             if (appRandom != null) {
+                 signingRandom = appRandom;
+@@ -447,171 +391,6 @@
+     }
+ 
+     /**
+-     * Compute k for a DSA signature.
+-     *
+-     * @param seed the seed for generating k. This seed should be
+-     * secure. This is what is refered to as the KSEED in the DSA
+-     * specification.
+-     *
+-     * @param g the g parameter from the DSA key pair.
+-     */
+-    private BigInteger generateK(int[] seed, BigInteger q) {
+-
+-        // check out t in the spec.
+-        int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476,
+-                    0xC3D2E1F0, 0x67452301 };
+-        //
+-        int[] tmp = DSA.SHA_7(seed, t);
+-        byte[] tmpBytes = new byte[tmp.length * 4];
+-        for (int i = 0; i < tmp.length; i++) {
+-            int k = tmp[i];
+-            for (int j = 0; j < 4; j++) {
+-                tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
+-            }
+-        }
+-        BigInteger k = new BigInteger(1, tmpBytes).mod(q);
+-        return k;
+-    }
+-
+-   // Constants for each round
+-    private static final int round1_kt = 0x5a827999;
+-    private static final int round2_kt = 0x6ed9eba1;
+-    private static final int round3_kt = 0x8f1bbcdc;
+-    private static final int round4_kt = 0xca62c1d6;
+-
+-   /**
+-    * Computes set 1 thru 7 of SHA-1 on m1. */
+-   static int[] SHA_7(int[] m1, int[] h) {
+-
+-       int[] W = new int[80];
+-       System.arraycopy(m1,0,W,0,m1.length);
+-       int temp = 0;
+-
+-        for (int t = 16; t <= 79; t++){
+-            temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
+-            W[t] = ((temp << 1) | (temp >>>(32 - 1)));
+-        }
+-
+-       int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4];
+-       for (int i = 0; i < 20; i++) {
+-            temp = ((a<<5) | (a>>>(32-5))) +
+-                ((b&c)|((~b)&d))+ e + W[i] + round1_kt;
+-            e = d;
+-            d = c;
+-            c = ((b<<30) | (b>>>(32-30)));
+-            b = a;
+-            a = temp;
+-        }
+-
+-        // Round 2
+-        for (int i = 20; i < 40; i++) {
+-            temp = ((a<<5) | (a>>>(32-5))) +
+-                (b ^ c ^ d) + e + W[i] + round2_kt;
+-            e = d;
+-            d = c;
+-            c = ((b<<30) | (b>>>(32-30)));
+-            b = a;
+-            a = temp;
+-        }
+-
+-        // Round 3
+-        for (int i = 40; i < 60; i++) {
+-            temp = ((a<<5) | (a>>>(32-5))) +
+-                ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
+-            e = d;
+-            d = c;
+-            c = ((b<<30) | (b>>>(32-30)));
+-            b = a;
+-            a = temp;
+-        }
+-
+-        // Round 4
+-        for (int i = 60; i < 80; i++) {
+-            temp = ((a<<5) | (a>>>(32-5))) +
+-                (b ^ c ^ d) + e + W[i] + round4_kt;
+-            e = d;
+-            d = c;
+-            c = ((b<<30) | (b>>>(32-30)));
+-            b = a;
+-            a = temp;
+-        }
+-       int[] md = new int[5];
+-       md[0] = h[0] + a;
+-       md[1] = h[1] + b;
+-       md[2] = h[2] + c;
+-       md[3] = h[3] + d;
+-       md[4] = h[4] + e;
+-       return md;
+-   }
+-
+-
+-    /**
+-     * This implementation recognizes the following parameter:<dl>
+-     *
+-     * <dt><tt>Kseed</tt>
+-     *
+-     * <dd>a byte array.
+-     *
+-     * </dl>
+-     *
+-     * @deprecated
+-     */
+-    @Deprecated
+-    protected void engineSetParameter(String key, Object param) {
+-        if (key.equals("KSEED")) {
+-            if (param instanceof byte[]) {
+-                Kseed = byteArray2IntArray((byte[])param);
+-                KseedAsByteArray = (byte[])param;
+-            } else {
+-                debug("unrecognized param: " + key);
+-                throw new InvalidParameterException("Kseed not a byte array");
+-            }
+-        } else {
+-            throw new InvalidParameterException("invalid parameter");
+-        }
+-    }
+-
+-    /**
+-     * Return the value of the requested parameter. Recognized
+-     * parameters are:
+-     *
+-     * <dl>
+-     *
+-     * <dt><tt>Kseed</tt>
+-     *
+-     * <dd>a byte array.
+-     *
+-     * </dl>
+-     *
+-     * @return the value of the requested parameter.
+-     *
+-     * @see java.security.SignatureEngine
+-     *
+-     * @deprecated
+-     */
+-    @Deprecated
+-    protected Object engineGetParameter(String key) {
+-        if (key.equals("KSEED")) {
+-            return KseedAsByteArray;
+-        } else {
+-            return null;
+-        }
+-    }
+-
+-    /**
+-     * Set the algorithm object.
+-     */
+-    private void setParams(DSAParams params) throws InvalidKeyException {
+-        if (params == null) {
+-            throw new InvalidKeyException("DSA public key lacks parameters");
+-        }
+-        this.params = params;
+-        this.presetP = params.getP();
+-        this.presetQ = params.getQ();
+-        this.presetG = params.getG();
+-    }
+-
+-    /**
+      * Return a human readable rendition of the engine.
+      */
+     public String toString() {
+@@ -632,47 +411,336 @@
+         return printable;
+     }
+ 
+-    /*
+-     * Utility routine for converting a byte array into an int array
++    private static void debug(Exception e) {
++        if (debug) {
++            e.printStackTrace();
++        }
++    }
++
++    private static void debug(String s) {
++        if (debug) {
++            System.err.println(s);
++        }
++    }
++
++    /**
++     * Standard SHA224withDSA implementation as defined in FIPS186-3.
+      */
+-    private int[] byteArray2IntArray(byte[] byteArray) {
++    public static final class SHA224withDSA extends DSA {
++        public SHA224withDSA() throws NoSuchAlgorithmException {
++            super(MessageDigest.getInstance("SHA-224"));
++        }
++    }
++
++    /**
++     * Standard SHA256withDSA implementation as defined in FIPS186-3.
++     */
++    public static final class SHA256withDSA extends DSA {
++        public SHA256withDSA() throws NoSuchAlgorithmException {
++            super(MessageDigest.getInstance("SHA-256"));
++        }
++    }
++
++    static class LegacyDSA extends DSA {
++        /* The random seed used to generate k */
++        private int[] kSeed;
++        /* The random seed used to generate k (specified by application) */
++        private byte[] kSeedAsByteArray;
++        /*
++         * The random seed used to generate k
++         * (prevent the same Kseed from being used twice in a row
++         */
++        private int[] kSeedLast;
++
++        public LegacyDSA(MessageDigest md) throws NoSuchAlgorithmException {
++            super(md);
++        }
++
++        @Deprecated
++        protected void engineSetParameter(String key, Object param) {
++            if (key.equals("KSEED")) {
++                if (param instanceof byte[]) {
++                    kSeed = byteArray2IntArray((byte[])param);
++                    kSeedAsByteArray = (byte[])param;
++                } else {
++                    debug("unrecognized param: " + key);
++                    throw new InvalidParameterException("kSeed not a byte array");
++                }
++            } else {
++                throw new InvalidParameterException("Unsupported parameter");
++            }
++        }
++
++        @Deprecated
++        protected Object engineGetParameter(String key) {
++           if (key.equals("KSEED")) {
++               return kSeedAsByteArray;
++           } else {
++               return null;
++           }
++        }
++
++        @Override
++        protected void checkKey(DSAParams params) throws InvalidKeyException {
++            int valueL = params.getP().bitLength();
++            if (valueL > 1024) {
++                throw new InvalidKeyException("Key is too long for this algorithm");
++            }
++        }
++
++        /*
++         * Please read bug report 4044247 for an alternative, faster,
++         * NON-FIPS approved method to generate K
++         */
++        @Override
++        protected BigInteger generateK(BigInteger q) {
++            BigInteger k = null;
++
++            // The application specified a kSeed for us to use.
++            // Note: we dis-allow usage of the same Kseed twice in a row
++            if (kSeed != null && !Arrays.equals(kSeed, kSeedLast)) {
++                k = generateKUsingKSeed(kSeed, q);
++                if (k.signum() > 0 && k.compareTo(q) < 0) {
++                    kSeedLast = kSeed.clone();
++                    return k;
++                }
++            }
++
++            // The application did not specify a Kseed for us to use.
++            // We'll generate a new Kseed by getting random bytes from
++            // a SecureRandom object.
++            SecureRandom random = getSigningRandom();
++
++            while (true) {
++                int[] seed = new int[5];
++
++                for (int i = 0; i < 5; i++) seed[i] = random.nextInt();
++
++                k = generateKUsingKSeed(seed, q);
++                if (k.signum() > 0 && k.compareTo(q) < 0) {
++                    kSeedLast = seed;
++                    return k;
++                }
++            }
++        }
++
++        /**
++         * Compute k for the DSA signature as defined in the original DSS,
++         * i.e. FIPS186.
++         *
++         * @param seed the seed for generating k. This seed should be
++         * secure. This is what is refered to as the KSEED in the DSA
++         * specification.
++         *
++         * @param g the g parameter from the DSA key pair.
++         */
++        private BigInteger generateKUsingKSeed(int[] seed, BigInteger q) {
++
++            // check out t in the spec.
++            int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476,
++                        0xC3D2E1F0, 0x67452301 };
++            //
++            int[] tmp = SHA_7(seed, t);
++            byte[] tmpBytes = new byte[tmp.length * 4];
++            for (int i = 0; i < tmp.length; i++) {
++                int k = tmp[i];
++                for (int j = 0; j < 4; j++) {
++                    tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
++                }
++            }
++            BigInteger k = new BigInteger(1, tmpBytes).mod(q);
++            return k;
++        }
++
++        // Constants for each round
++        private static final int round1_kt = 0x5a827999;
++        private static final int round2_kt = 0x6ed9eba1;
++        private static final int round3_kt = 0x8f1bbcdc;
++        private static final int round4_kt = 0xca62c1d6;
++
++        /**
++         * Computes set 1 thru 7 of SHA-1 on m1. */
++        static int[] SHA_7(int[] m1, int[] h) {
+ 
+-        int j = 0;
+-        byte[] newBA;
+-        int mod = byteArray.length % 4;
+-
+-        // guarantee that the incoming byteArray is a multiple of 4
+-        // (pad with 0's)
+-        switch (mod) {
++            int[] W = new int[80];
++            System.arraycopy(m1,0,W,0,m1.length);
++            int temp = 0;
++
++            for (int t = 16; t <= 79; t++){
++                temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
++                W[t] = ((temp << 1) | (temp >>>(32 - 1)));
++            }
++
++            int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4];
++            for (int i = 0; i < 20; i++) {
++                temp = ((a<<5) | (a>>>(32-5))) +
++                    ((b&c)|((~b)&d))+ e + W[i] + round1_kt;
++                e = d;
++                d = c;
++                c = ((b<<30) | (b>>>(32-30)));
++                b = a;
++                a = temp;
++            }
++
++            // Round 2
++            for (int i = 20; i < 40; i++) {
++                temp = ((a<<5) | (a>>>(32-5))) +
++                    (b ^ c ^ d) + e + W[i] + round2_kt;
++                e = d;
++                d = c;
++                c = ((b<<30) | (b>>>(32-30)));
++                b = a;
++                a = temp;
++            }
++
++            // Round 3
++            for (int i = 40; i < 60; i++) {
++                temp = ((a<<5) | (a>>>(32-5))) +
++                    ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
++                e = d;
++                d = c;
++                c = ((b<<30) | (b>>>(32-30)));
++                b = a;
++                a = temp;
++            }
++
++            // Round 4
++            for (int i = 60; i < 80; i++) {
++                temp = ((a<<5) | (a>>>(32-5))) +
++                    (b ^ c ^ d) + e + W[i] + round4_kt;
++                e = d;
++                d = c;
++                c = ((b<<30) | (b>>>(32-30)));
++                b = a;
++                a = temp;
++            }
++            int[] md = new int[5];
++            md[0] = h[0] + a;
++            md[1] = h[1] + b;
++            md[2] = h[2] + c;
++            md[3] = h[3] + d;
++            md[4] = h[4] + e;
++            return md;
++        }
++
++        /*
++         * Utility routine for converting a byte array into an int array
++         */
++        private int[] byteArray2IntArray(byte[] byteArray) {
++
++            int j = 0;
++            byte[] newBA;
++            int mod = byteArray.length % 4;
++
++            // guarantee that the incoming byteArray is a multiple of 4
++            // (pad with 0's)
++            switch (mod) {
+             case 3:     newBA = new byte[byteArray.length + 1]; break;
+             case 2:     newBA = new byte[byteArray.length + 2]; break;
+             case 1:     newBA = new byte[byteArray.length + 3]; break;
+             default:    newBA = new byte[byteArray.length + 0]; break;
+-        }
+-        System.arraycopy(byteArray, 0, newBA, 0, byteArray.length);
++            }
++            System.arraycopy(byteArray, 0, newBA, 0, byteArray.length);
+ 
+-        // copy each set of 4 bytes in the byte array into an integer
+-        int[] newSeed = new int[newBA.length / 4];
+-        for (int i = 0; i < newBA.length; i += 4) {
+-            newSeed[j] = newBA[i + 3] & 0xFF;
+-            newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00;
+-            newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000;
+-            newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000;
+-            j++;
+-        }
++            // copy each set of 4 bytes in the byte array into an integer
++            int[] newSeed = new int[newBA.length / 4];
++            for (int i = 0; i < newBA.length; i += 4) {
++                newSeed[j] = newBA[i + 3] & 0xFF;
++                newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00;
++                newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000;
++                newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000;
++                j++;
++            }
+ 
+-        return newSeed;
++            return newSeed;
++        }
+     }
+ 
+-    private static void debug(Exception e) {
+-        if (debug) {
+-            e.printStackTrace();
++    public static final class SHA1withDSA extends LegacyDSA {
++        public SHA1withDSA() throws NoSuchAlgorithmException {
++            super(MessageDigest.getInstance("SHA-1"));
+         }
+     }
+ 
+-    private static void debug(String s) {
+-        if (debug) {
+-            System.err.println(s);
++    /**
++     * RawDSA implementation.
++     *
++     * RawDSA requires the data to be exactly 20 bytes long. If it is
++     * not, a SignatureException is thrown when sign()/verify() is called
++     * per JCA spec.
++     */
++    public static final class RawDSA extends LegacyDSA {
++        // Internal special-purpose MessageDigest impl for RawDSA
++        // Only override whatever methods used
++        // NOTE: no clone support
++        public static final class NullDigest20 extends MessageDigest {
++            // 20 byte digest buffer
++            private final byte[] digestBuffer = new byte[20];
++
++            // offset into the buffer; use Integer.MAX_VALUE to indicate
++            // out-of-bound condition
++            private int ofs = 0;
++
++            protected NullDigest20() {
++                super("NullDigest20");
++            }
++            protected void engineUpdate(byte input) {
++                if (ofs == digestBuffer.length) {
++                    ofs = Integer.MAX_VALUE;
++                } else {
++                    digestBuffer[ofs++] = input;
++                }
++            }
++            protected void engineUpdate(byte[] input, int offset, int len) {
++                if (ofs + len > digestBuffer.length) {
++                    ofs = Integer.MAX_VALUE;
++                } else {
++                    System.arraycopy(input, offset, digestBuffer, ofs, len);
++                    ofs += len;
++                }
++            }
++            protected final void engineUpdate(ByteBuffer input) {
++                int inputLen = input.remaining();
++                if (ofs + inputLen > digestBuffer.length) {
++                    ofs = Integer.MAX_VALUE;
++                } else {
++                    input.get(digestBuffer, ofs, inputLen);
++                    ofs += inputLen;
++                }
++            }
++            protected byte[] engineDigest() throws RuntimeException {
++                if (ofs != digestBuffer.length) {
++                    throw new RuntimeException
++                        ("Data for RawDSA must be exactly 20 bytes long");
++                }
++                reset();
++                return digestBuffer;
++            }
++            protected int engineDigest(byte[] buf, int offset, int len)
++                throws DigestException {
++                if (ofs != digestBuffer.length) {
++                    throw new DigestException
++                        ("Data for RawDSA must be exactly 20 bytes long");
++                }
++                if (len < digestBuffer.length) {
++                    throw new DigestException
++                        ("Output buffer too small; must be at least 20 bytes");
++                }
++                System.arraycopy(digestBuffer, 0, buf, offset, digestBuffer.length);
++                reset();
++                return digestBuffer.length;
++            }
++
++            protected void engineReset() {
++                ofs = 0;
++            }
++            protected final int engineGetDigestLength() {
++                return digestBuffer.length;
++            }
++        }
++
++        public RawDSA() throws NoSuchAlgorithmException {
++            super(new NullDigest20());
+         }
+     }
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java openjdk/jdk/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java	2014-10-08 23:37:11.636798712 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 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
+@@ -48,8 +48,9 @@
+ public class DSAKeyPairGenerator extends KeyPairGenerator
+ implements java.security.interfaces.DSAKeyPairGenerator {
+ 
+-    /* The modulus length */
+-    private int modlen;
++    /* Length for prime P and subPrime Q in bits */
++    private int plen;
++    private int qlen;
+ 
+     /* whether to force new parameters to be generated for each KeyPair */
+     private boolean forceNewParameters;
+@@ -65,20 +66,23 @@
+         initialize(1024, null);
+     }
+ 
+-    private static void checkStrength(int strength) {
+-        if ((strength < 512) || (strength > 1024) || (strength % 64 != 0)) {
++    private static void checkStrength(int sizeP, int sizeQ) {
++        if ((sizeP >= 512) && (sizeP <= 1024) && (sizeP % 64 == 0)
++            && sizeQ == 160) {
++            // traditional - allow for backward compatibility
++            // L=multiples of 64 and between 512 and 1024 (inclusive)
++            // N=160
++        } else if (sizeP == 2048 && (sizeQ == 224 || sizeQ == 256)) {
++            // L=2048, N=224 or 256
++        } else {
+             throw new InvalidParameterException
+-                ("Modulus size must range from 512 to 1024 "
+-                 + "and be a multiple of 64");
++                ("Unsupported prime and subprime size combination: " +
++                 sizeP + ", " + sizeQ);
+         }
+     }
+ 
+     public void initialize(int modlen, SecureRandom random) {
+-        checkStrength(modlen);
+-        this.random = random;
+-        this.modlen = modlen;
+-        this.params = null;
+-        this.forceNewParameters = false;
++        initialize(modlen, false, random);
+     }
+ 
+     /**
+@@ -86,18 +90,27 @@
+      * is false, a set of pre-computed parameters is used.
+      */
+     public void initialize(int modlen, boolean genParams, SecureRandom random) {
+-        checkStrength(modlen);
++        int subPrimeLen = -1;
++        if (modlen <= 1024) {
++            subPrimeLen = 160;
++        } else if (modlen == 2048) {
++            subPrimeLen = 224;
++        }
++        checkStrength(modlen, subPrimeLen);
+         if (genParams) {
+             params = null;
+         } else {
+-            params = ParameterCache.getCachedDSAParameterSpec(modlen);
++            params = ParameterCache.getCachedDSAParameterSpec(modlen,
++                subPrimeLen);
+             if (params == null) {
+                 throw new InvalidParameterException
+                     ("No precomputed parameters for requested modulus size "
+                      + "available");
+             }
++
+         }
+-        this.modlen = modlen;
++        this.plen = modlen;
++        this.qlen = subPrimeLen;
+         this.random = random;
+         this.forceNewParameters = genParams;
+     }
+@@ -136,9 +149,11 @@
+     }
+ 
+     private void initialize0(DSAParameterSpec params, SecureRandom random) {
+-        int modlen = params.getP().bitLength();
+-        checkStrength(modlen);
+-        this.modlen = modlen;
++        int sizeP = params.getP().bitLength();
++        int sizeQ = params.getQ().bitLength();
++        checkStrength(sizeP, sizeQ);
++        this.plen = sizeP;
++        this.qlen = sizeQ;
+         this.params = params;
+         this.random = random;
+         this.forceNewParameters = false;
+@@ -156,11 +171,11 @@
+         try {
+             if (forceNewParameters) {
+                 // generate new parameters each time
+-                spec = ParameterCache.getNewDSAParameterSpec(modlen, random);
++                spec = ParameterCache.getNewDSAParameterSpec(plen, qlen, random);
+             } else {
+                 if (params == null) {
+                     params =
+-                        ParameterCache.getDSAParameterSpec(modlen, random);
++                        ParameterCache.getDSAParameterSpec(plen, qlen, random);
+                 }
+                 spec = params;
+             }
+@@ -203,43 +218,14 @@
+      */
+     private BigInteger generateX(SecureRandom random, BigInteger q) {
+         BigInteger x = null;
++        byte[] temp = new byte[qlen];
+         while (true) {
+-            int[] seed = new int[5];
+-            for (int i = 0; i < 5; i++) {
+-                seed[i] = random.nextInt();
+-            }
+-            x = generateX(seed, q);
++            random.nextBytes(temp);
++            x = new BigInteger(1, temp).mod(q);
+             if (x.signum() > 0 && (x.compareTo(q) < 0)) {
+-                break;
+-            }
+-        }
+-        return x;
+-    }
+-
+-    /**
+-     * Given a seed, generate the private key component of the key
+-     * pair. In the terminology used in the DSA specification
+-     * (FIPS-186) seed is the XSEED quantity.
+-     *
+-     * @param seed the seed to use to generate the private key.
+-     */
+-    BigInteger generateX(int[] seed, BigInteger q) {
+-
+-        // check out t in the spec.
+-        int[] t = { 0x67452301, 0xEFCDAB89, 0x98BADCFE,
+-                    0x10325476, 0xC3D2E1F0 };
+-        //
+-
+-        int[] tmp = DSA.SHA_7(seed, t);
+-        byte[] tmpBytes = new byte[tmp.length * 4];
+-        for (int i = 0; i < tmp.length; i++) {
+-            int k = tmp[i];
+-            for (int j = 0; j < 4; j++) {
+-                tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
++                return x;
+             }
+         }
+-        BigInteger x = new BigInteger(1, tmpBytes).mod(q);
+-        return x;
+     }
+ 
+     /**
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/DSAParameterGenerator.java openjdk/jdk/src/share/classes/sun/security/provider/DSAParameterGenerator.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/DSAParameterGenerator.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/DSAParameterGenerator.java	2014-10-08 23:37:11.636798712 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 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
+@@ -32,10 +32,12 @@
+ import java.security.NoSuchAlgorithmException;
+ import java.security.NoSuchProviderException;
+ import java.security.InvalidParameterException;
++import java.security.MessageDigest;
+ import java.security.SecureRandom;
+ import java.security.spec.AlgorithmParameterSpec;
+ import java.security.spec.InvalidParameterSpecException;
+ import java.security.spec.DSAParameterSpec;
++import sun.security.spec.DSAGenParameterSpec;
+ 
+ /**
+  * This class generates parameters for the DSA algorithm. It uses a default
+@@ -54,8 +56,14 @@
+ 
+ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
+ 
+-    // the modulus length
+-    private int modLen = 1024; // default
++    // the default parameters
++    private static final DSAGenParameterSpec DEFAULTS =
++        new DSAGenParameterSpec(1024, 160, 160);
++
++    // the length of prime P, subPrime Q, and seed in bits
++    private int valueL = -1;
++    private int valueN = -1;
++    private int seedLen = -1;
+ 
+     // the source of randomness
+     private SecureRandom random;
+@@ -65,11 +73,7 @@
+     private static final BigInteger ONE = BigInteger.valueOf(1);
+     private static final BigInteger TWO = BigInteger.valueOf(2);
+ 
+-    // Make a SHA-1 hash function
+-    private SHA sha;
+-
+     public DSAParameterGenerator() {
+-        this.sha = new SHA();
+     }
+ 
+     /**
+@@ -80,19 +84,18 @@
+      * @param random the source of randomness
+      */
+     protected void engineInit(int strength, SecureRandom random) {
+-        /*
+-         * Bruce Schneier, "Applied Cryptography", 2nd Edition,
+-         * Description of DSA:
+-         * [...] The algorithm uses the following parameter:
+-         * p=a prime number L bits long, when L ranges from 512 to 1024 and is
+-         * a multiple of 64. [...]
+-         */
+-        if ((strength < 512) || (strength > 1024) || (strength % 64 != 0)) {
++        if ((strength >= 512) && (strength <= 1024) && (strength % 64 == 0)) {
++            this.valueN = 160;
++        } else if (strength == 2048) {
++            this.valueN = 224;
++//      } else if (strength == 3072) {
++//          this.valueN = 256;
++        } else {
+             throw new InvalidParameterException
+-                ("Prime size must range from 512 to 1024 "
+-                 + "and be a multiple of 64");
++                ("Prime size should be 512 - 1024, or 2048");
+         }
+-        this.modLen = strength;
++        this.valueL = strength;
++        this.seedLen = valueN;
+         this.random = random;
+     }
+ 
+@@ -100,7 +103,7 @@
+      * Initializes this parameter generator with a set of
+      * algorithm-specific parameter generation values.
+      *
+-     * @param params the set of algorithm-specific parameter generation values
++     * @param genParamSpec the set of algorithm-specific parameter generation values
+      * @param random the source of randomness
+      *
+      * @exception InvalidAlgorithmParameterException if the given parameter
+@@ -109,7 +112,19 @@
+     protected void engineInit(AlgorithmParameterSpec genParamSpec,
+                               SecureRandom random)
+         throws InvalidAlgorithmParameterException {
++        if (!(genParamSpec instanceof DSAGenParameterSpec)) {
+             throw new InvalidAlgorithmParameterException("Invalid parameter");
++        }
++        DSAGenParameterSpec dsaGenParams = (DSAGenParameterSpec) genParamSpec;
++        if (dsaGenParams.getPrimePLength() > 2048) {
++            throw new InvalidParameterException
++                ("Prime size should be 512 - 1024, or 2048");
++        }
++        // directly initialize using the already validated values
++        this.valueL = dsaGenParams.getPrimePLength();
++        this.valueN = dsaGenParams.getSubprimeQLength();
++        this.seedLen = dsaGenParams.getSeedLength();
++        this.random = random;
+     }
+ 
+     /**
+@@ -123,15 +138,21 @@
+             if (this.random == null) {
+                 this.random = new SecureRandom();
+             }
+-
+-            BigInteger[] pAndQ = generatePandQ(this.random, this.modLen);
++            if (valueL == -1) {
++                try {
++                    engineInit(DEFAULTS, this.random);
++                } catch (InvalidAlgorithmParameterException iape) {
++                    // should never happen
++                }
++            }
++            BigInteger[] pAndQ = generatePandQ(this.random, valueL,
++                                               valueN, seedLen);
+             BigInteger paramP = pAndQ[0];
+             BigInteger paramQ = pAndQ[1];
+             BigInteger paramG = generateG(paramP, paramQ);
+ 
+-            DSAParameterSpec dsaParamSpec = new DSAParameterSpec(paramP,
+-                                                                 paramQ,
+-                                                                 paramG);
++            DSAParameterSpec dsaParamSpec =
++                new DSAParameterSpec(paramP, paramQ, paramG);
+             algParams = AlgorithmParameters.getInstance("DSA", "SUN");
+             algParams.init(dsaParamSpec);
+         } catch (InvalidParameterSpecException e) {
+@@ -156,102 +177,98 @@
+      *
+      * @param random the source of randomness to generate the
+      * seed
+-     * @param L the size of <code>p</code>, in bits.
++     * @param valueL the size of <code>p</code>, in bits.
++     * @param valueN the size of <code>q</code>, in bits.
++     * @param seedLen the length of <code>seed</code>, in bits.
+      *
+      * @return an array of BigInteger, with <code>p</code> at index 0 and
+-     * <code>q</code> at index 1.
++     * <code>q</code> at index 1, the seed at index 2, and the counter value
++     * at index 3.
+      */
+-    BigInteger[] generatePandQ(SecureRandom random, int L) {
+-        BigInteger[] result = null;
+-        byte[] seed = new byte[20];
+-
+-        while(result == null) {
+-            for (int i = 0; i < 20; i++) {
+-                seed[i] = (byte)random.nextInt();
+-            }
+-            result = generatePandQ(seed, L);
++    private static BigInteger[] generatePandQ(SecureRandom random, int valueL,
++                                              int valueN, int seedLen) {
++        String hashAlg = null;
++        if (valueN == 160) {
++            hashAlg = "SHA";
++        } else if (valueN == 224) {
++            hashAlg = "SHA-224";
++        } else if (valueN == 256) {
++            hashAlg = "SHA-256";
++        }
++        MessageDigest hashObj = null;
++        try {
++            hashObj = MessageDigest.getInstance(hashAlg);
++        } catch (NoSuchAlgorithmException nsae) {
++            // should never happen
++            nsae.printStackTrace();
+         }
+-        return result;
+-    }
+ 
+-    /*
+-     * Generates the prime and subprime parameters for DSA.
+-     *
+-     * <p>The seed parameter corresponds to the <code>SEED</code> parameter
+-     * referenced in the FIPS specification of the DSA algorithm,
+-     * and L is the size of <code>p</code>, in bits.
+-     *
+-     * @param seed the seed to generate the parameters
+-     * @param L the size of <code>p</code>, in bits.
+-     *
+-     * @return an array of BigInteger, with <code>p</code> at index 0,
+-     * <code>q</code> at index 1, the seed at index 2, and the counter value
+-     * at index 3, or null if the seed does not yield suitable numbers.
+-     */
+-    BigInteger[] generatePandQ(byte[] seed, int L) {
++        /* Step 3, 4: Useful variables */
++        int outLen = hashObj.getDigestLength()*8;
++        int n = (valueL - 1) / outLen;
++        int b = (valueL - 1) % outLen;
++        byte[] seedBytes = new byte[seedLen/8];
++        BigInteger twoSl = TWO.pow(seedLen);
++        int primeCertainty = 80; // for 1024-bit prime P
++        if (valueL == 2048) {
++            primeCertainty = 112;
++            //} else if (valueL == 3072) {
++            //    primeCertainty = 128;
++        }
+ 
+-        /* Useful variables */
+-        int g = seed.length * 8;
+-        int n = (L - 1) / 160;
+-        int b = (L - 1) % 160;
+-
+-        BigInteger SEED = new BigInteger(1, seed);
+-        BigInteger TWOG = TWO.pow(2 * g);
+-
+-        /* Step 2 (Step 1 is getting seed). */
+-        byte[] U1 = SHA(seed);
+-        byte[] U2 = SHA(toByteArray((SEED.add(ONE)).mod(TWOG)));
+-
+-        xor(U1, U2);
+-        byte[] U = U1;
+-
+-        /* Step 3: For q by setting the msb and lsb to 1 */
+-        U[0] |= 0x80;
+-        U[19] |= 1;
+-        BigInteger q = new BigInteger(1, U);
+-
+-        /* Step 5 */
+-         if (!q.isProbablePrime(80)) {
+-             return null;
+-
+-         } else {
+-             BigInteger V[] = new BigInteger[n + 1];
+-             BigInteger offset = TWO;
+-
+-             /* Step 6 */
+-             for (int counter = 0; counter < 4096; counter++) {
+-
+-                 /* Step 7 */
+-                 for (int k = 0; k <= n; k++) {
+-                     BigInteger K = BigInteger.valueOf(k);
+-                     BigInteger tmp = (SEED.add(offset).add(K)).mod(TWOG);
+-                     V[k] = new BigInteger(1, SHA(toByteArray(tmp)));
+-                 }
+-
+-                 /* Step 8 */
+-                 BigInteger W = V[0];
+-                 for (int i = 1; i < n; i++) {
+-                     W = W.add(V[i].multiply(TWO.pow(i * 160)));
+-                 }
+-                 W = W.add((V[n].mod(TWO.pow(b))).multiply(TWO.pow(n * 160)));
+-
+-                 BigInteger TWOLm1 = TWO.pow(L - 1);
+-                 BigInteger X = W.add(TWOLm1);
+-
+-                 /* Step 9 */
+-                 BigInteger c = X.mod(q.multiply(TWO));
+-                 BigInteger p = X.subtract(c.subtract(ONE));
+-
+-                 /* Step 10 - 13 */
+-                 if (p.compareTo(TWOLm1) > -1 && p.isProbablePrime(80)) {
+-                     BigInteger[] result = {p, q, SEED,
+-                                            BigInteger.valueOf(counter)};
+-                     return result;
+-                 }
+-                 offset = offset.add(BigInteger.valueOf(n)).add(ONE);
++        BigInteger resultP, resultQ, seed = null;
++        int counter;
++        while (true) {
++            do {
++                /* Step 5 */
++                random.nextBytes(seedBytes);
++                seed = new BigInteger(1, seedBytes);
++
++                /* Step 6 */
++                BigInteger U = new BigInteger(1, hashObj.digest(seedBytes)).
++                    mod(TWO.pow(valueN - 1));
++
++                /* Step 7 */
++                resultQ = TWO.pow(valueN - 1).add(U).add(ONE). subtract(U.mod(TWO));
++            } while (!resultQ.isProbablePrime(primeCertainty));
++
++            /* Step 10 */
++            BigInteger offset = ONE;
++            /* Step 11 */
++            for (counter = 0; counter < 4*valueL; counter++) {
++                BigInteger V[] = new BigInteger[n + 1];
++                /* Step 11.1 */
++                for (int j = 0; j <= n; j++) {
++                    BigInteger J = BigInteger.valueOf(j);
++                    BigInteger tmp = (seed.add(offset).add(J)).mod(twoSl);
++                    byte[] vjBytes = hashObj.digest(toByteArray(tmp));
++                    V[j] = new BigInteger(1, vjBytes);
++                }
++                /* Step 11.2 */
++                BigInteger W = V[0];
++                for (int i = 1; i < n; i++) {
++                    W = W.add(V[i].multiply(TWO.pow(i * outLen)));
++                }
++                W = W.add((V[n].mod(TWO.pow(b))).multiply(TWO.pow(n * outLen)));
++                /* Step 11.3 */
++                BigInteger twoLm1 = TWO.pow(valueL - 1);
++                BigInteger X = W.add(twoLm1);
++                /* Step 11.4, 11.5 */
++                BigInteger c = X.mod(resultQ.multiply(TWO));
++                resultP = X.subtract(c.subtract(ONE));
++                /* Step 11.6, 11.7 */
++                if (resultP.compareTo(twoLm1) > -1
++                    && resultP.isProbablePrime(primeCertainty)) {
++                    /* Step 11.8 */
++                    BigInteger[] result = {resultP, resultQ, seed,
++                                           BigInteger.valueOf(counter)};
++                    return result;
++                }
++                /* Step 11.9 */
++                offset = offset.add(BigInteger.valueOf(n)).add(ONE);
+              }
+-             return null;
+-         }
++        }
++
+     }
+ 
+     /*
+@@ -262,31 +279,24 @@
+      *
+      * @param the <code>g</code>
+      */
+-    BigInteger generateG(BigInteger p, BigInteger q) {
++    private static BigInteger generateG(BigInteger p, BigInteger q) {
+         BigInteger h = ONE;
++        /* Step 1 */
+         BigInteger pMinusOneOverQ = (p.subtract(ONE)).divide(q);
+-        BigInteger g = ONE;
+-        while (g.compareTo(TWO) < 0) {
+-            g = h.modPow(pMinusOneOverQ, p);
++        BigInteger resultG = ONE;
++        while (resultG.compareTo(TWO) < 0) {
++            /* Step 3 */
++            resultG = h.modPow(pMinusOneOverQ, p);
+             h = h.add(ONE);
+         }
+-        return g;
+-    }
+-
+-    /*
+-     * Returns the SHA-1 digest of some data
+-     */
+-    private byte[] SHA(byte[] array) {
+-        sha.engineReset();
+-        sha.engineUpdate(array, 0, array.length);
+-        return sha.engineDigest();
++        return resultG;
+     }
+ 
+     /*
+      * Converts the result of a BigInteger.toByteArray call to an exact
+      * signed magnitude representation for any positive number.
+      */
+-    private byte[] toByteArray(BigInteger bigInt) {
++    private static byte[] toByteArray(BigInteger bigInt) {
+         byte[] result = bigInt.toByteArray();
+         if (result[0] == 0) {
+             byte[] tmp = new byte[result.length - 1];
+@@ -295,13 +305,4 @@
+         }
+         return result;
+     }
+-
+-    /*
+-     * XORs U2 into U1
+-     */
+-    private void xor(byte[] U1, byte[] U2) {
+-        for (int i = 0; i < U1.length; i++) {
+-            U1[i] ^= U2[i];
+-        }
+-    }
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/ParameterCache.java openjdk/jdk/src/share/classes/sun/security/provider/ParameterCache.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/ParameterCache.java	2014-07-14 04:24:45.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/ParameterCache.java	2014-10-08 23:37:11.636798712 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 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
+@@ -26,6 +26,7 @@
+ package sun.security.provider;
+ 
+ import java.util.*;
++import java.util.concurrent.ConcurrentHashMap;
+ import java.math.BigInteger;
+ 
+ import java.security.*;
+@@ -34,6 +35,8 @@
+ 
+ import javax.crypto.spec.DHParameterSpec;
+ 
++import sun.security.spec.DSAGenParameterSpec;
++
+ /**
+  * Cache for DSA and DH parameter specs. Used by the KeyPairGenerators
+  * in the Sun, SunJCE, and SunPKCS11 provider if no parameters have been
+@@ -55,11 +58,17 @@
+     private final static Map<Integer,DHParameterSpec> dhCache;
+ 
+     /**
+-     * Return cached DSA parameters for the given keylength, or null if none
+-     * are available in the cache.
++     * Return cached DSA parameters for the given length combination of
++     * prime and subprime, or null if none are available in the cache.
+      */
+-    public static DSAParameterSpec getCachedDSAParameterSpec(int keyLength) {
+-        return dsaCache.get(Integer.valueOf(keyLength));
++    public static DSAParameterSpec getCachedDSAParameterSpec(int primeLen,
++            int subprimeLen) {
++        // ensure the sum is unique in all cases, i.e.
++        // case#1: (512 <= p <= 1024) AND q=160
++        // case#2: p=2048 AND q=224
++        // case#3: p=2048 AND q=256
++        // (NOT-YET-SUPPORTED)case#4: p=3072 AND q=256
++        return dsaCache.get(Integer.valueOf(primeLen+subprimeLen));
+     }
+ 
+     /**
+@@ -71,18 +80,39 @@
+     }
+ 
+     /**
+-     * Return DSA parameters for the given keylength. Uses cache if possible,
+-     * generates new parameters and adds them to the cache otherwise.
++     * Return DSA parameters for the given primeLen. Uses cache if
++     * possible, generates new parameters and adds them to the cache
++     * otherwise.
+      */
+-    public static DSAParameterSpec getDSAParameterSpec(int keyLength,
++    public static DSAParameterSpec getDSAParameterSpec(int primeLen,
+             SecureRandom random)
+-            throws NoSuchAlgorithmException, InvalidParameterSpecException {
+-        DSAParameterSpec spec = getCachedDSAParameterSpec(keyLength);
++            throws NoSuchAlgorithmException, InvalidParameterSpecException,
++                   InvalidAlgorithmParameterException {
++        if (primeLen <= 1024) {
++            return getDSAParameterSpec(primeLen, 160, random);
++        } else if (primeLen == 2048) {
++            return getDSAParameterSpec(primeLen, 224, random);
++        } else {
++            return null;
++        }
++    }
++
++    /**
++     * Return DSA parameters for the given primeLen and subprimeLen.
++     * Uses cache if possible, generates new parameters and adds them to the
++     * cache otherwise.
++     */
++    public static DSAParameterSpec getDSAParameterSpec(int primeLen,
++            int subprimeLen, SecureRandom random)
++            throws NoSuchAlgorithmException, InvalidParameterSpecException,
++                   InvalidAlgorithmParameterException {
++        DSAParameterSpec spec =
++            getCachedDSAParameterSpec(primeLen, subprimeLen);
+         if (spec != null) {
+             return spec;
+         }
+-        spec = getNewDSAParameterSpec(keyLength, random);
+-        dsaCache.put(Integer.valueOf(keyLength), spec);
++        spec = getNewDSAParameterSpec(primeLen, subprimeLen, random);
++        dsaCache.put(Integer.valueOf(primeLen + subprimeLen), spec);
+         return spec;
+     }
+ 
+@@ -107,28 +137,28 @@
+     }
+ 
+     /**
+-     * Return new DSA parameters for the given keylength. Do not lookup in
+-     * cache and do not cache the newly generated parameters. This method
+-     * really only exists for the legacy method
++     * Return new DSA parameters for the given length combination of prime and
++     * sub prime. Do not lookup in cache and do not cache the newly generated
++     * parameters. This method really only exists for the legacy method
+      * DSAKeyPairGenerator.initialize(int, boolean, SecureRandom).
+      */
+-    public static DSAParameterSpec getNewDSAParameterSpec(int keyLength,
+-            SecureRandom random)
+-            throws NoSuchAlgorithmException, InvalidParameterSpecException {
++    public static DSAParameterSpec getNewDSAParameterSpec(int primeLen,
++            int subprimeLen, SecureRandom random)
++            throws NoSuchAlgorithmException, InvalidParameterSpecException,
++                   InvalidAlgorithmParameterException {
+         AlgorithmParameterGenerator gen =
+                 AlgorithmParameterGenerator.getInstance("DSA");
+-        gen.init(keyLength, random);
++        DSAGenParameterSpec genParams =
++            new DSAGenParameterSpec(primeLen, subprimeLen);
++        gen.init(genParams, random);
+         AlgorithmParameters params = gen.generateParameters();
+         DSAParameterSpec spec = params.getParameterSpec(DSAParameterSpec.class);
+         return spec;
+     }
+ 
+     static {
+-        // XXX change to ConcurrentHashMap once available
+-        dhCache = Collections.synchronizedMap
+-                        (new HashMap<Integer,DHParameterSpec>());
+-        dsaCache = Collections.synchronizedMap
+-                        (new HashMap<Integer,DSAParameterSpec>());
++        dhCache = new ConcurrentHashMap<Integer,DHParameterSpec>();
++        dsaCache = new ConcurrentHashMap<Integer,DSAParameterSpec>();
+ 
+         /*
+          * We support precomputed parameter for 512, 768 and 1024 bit
+@@ -210,17 +240,99 @@
+                            "83dfe15ae59f06928b665e807b552564014c3bfecf" +
+                            "492a", 16);
+ 
+-        dsaCache.put(Integer.valueOf(512),
++        dsaCache.put(Integer.valueOf(512+160),
+                                 new DSAParameterSpec(p512, q512, g512));
+-        dsaCache.put(Integer.valueOf(768),
++        dsaCache.put(Integer.valueOf(768+160),
+                                 new DSAParameterSpec(p768, q768, g768));
+-        dsaCache.put(Integer.valueOf(1024),
++        dsaCache.put(Integer.valueOf(1024+160),
+                                 new DSAParameterSpec(p1024, q1024, g1024));
++        /*
++         * L = 2048, N = 224
++         * SEED = 584236080cfa43c09b02354135f4cc5198a19efada08bd866d601ba4
++         * counter = 2666
++         */
++        BigInteger p2048_224 =
++            new BigInteger("8f7935d9b9aae9bfabed887acf4951b6f32ec59e3b" +
++                           "af3718e8eac4961f3efd3606e74351a9c4183339b8" +
++                           "09e7c2ae1c539ba7475b85d011adb8b47987754984" +
++                           "695cac0e8f14b3360828a22ffa27110a3d62a99345" +
++                           "3409a0fe696c4658f84bdd20819c3709a01057b195" +
++                           "adcd00233dba5484b6291f9d648ef883448677979c" +
++                           "ec04b434a6ac2e75e9985de23db0292fc1118c9ffa" +
++                           "9d8181e7338db792b730d7b9e349592f6809987215" +
++                           "3915ea3d6b8b4653c633458f803b32a4c2e0f27290" +
++                           "256e4e3f8a3b0838a1c450e4e18c1a29a37ddf5ea1" +
++                           "43de4b66ff04903ed5cf1623e158d487c608e97f21" +
++                           "1cd81dca23cb6e380765f822e342be484c05763939" +
++                           "601cd667", 16);
++
++        BigInteger q2048_224 =
++            new BigInteger("baf696a68578f7dfdee7fa67c977c785ef32b233ba" +
++                           "e580c0bcd5695d", 16);
++
++        BigInteger g2048_224 =
++            new BigInteger("16a65c58204850704e7502a39757040d34da3a3478" +
++                           "c154d4e4a5c02d242ee04f96e61e4bd0904abdac8f" +
++                           "37eeb1e09f3182d23c9043cb642f88004160edf9ca" +
++                           "09b32076a79c32a627f2473e91879ba2c4e744bd20" +
++                           "81544cb55b802c368d1fa83ed489e94e0fa0688e32" +
++                           "428a5c78c478c68d0527b71c9a3abb0b0be12c4468" +
++                           "9639e7d3ce74db101a65aa2b87f64c6826db3ec72f" +
++                           "4b5599834bb4edb02f7c90e9a496d3a55d535bebfc" +
++                           "45d4f619f63f3dedbb873925c2f224e07731296da8" +
++                           "87ec1e4748f87efb5fdeb75484316b2232dee553dd" +
++                           "af02112b0d1f02da30973224fe27aeda8b9d4b2922" +
++                           "d9ba8be39ed9e103a63c52810bc688b7e2ed4316e1" +
++                           "ef17dbde", 16);
++        dsaCache.put(Integer.valueOf(2048+224),
++                     new DSAParameterSpec(p2048_224, q2048_224, g2048_224));
++
++        /*
++         * L = 2048, N = 256
++         * SEED = b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536
++         * counter = 497
++         */
++        BigInteger p2048_256 =
++            new BigInteger("95475cf5d93e596c3fcd1d902add02f427f5f3c721" +
++                           "0313bb45fb4d5bb2e5fe1cbd678cd4bbdd84c9836b" +
++                           "e1f31c0777725aeb6c2fc38b85f48076fa76bcd814" +
++                           "6cc89a6fb2f706dd719898c2083dc8d896f84062e2" +
++                           "c9c94d137b054a8d8096adb8d51952398eeca852a0" +
++                           "af12df83e475aa65d4ec0c38a9560d5661186ff98b" +
++                           "9fc9eb60eee8b030376b236bc73be3acdbd74fd61c" +
++                           "1d2475fa3077b8f080467881ff7e1ca56fee066d79" +
++                           "506ade51edbb5443a563927dbc4ba520086746175c" +
++                           "8885925ebc64c6147906773496990cb714ec667304" +
++                           "e261faee33b3cbdf008e0c3fa90650d97d3909c927" +
++                           "5bf4ac86ffcb3d03e6dfc8ada5934242dd6d3bcca2" +
++                           "a406cb0b", 16);
++
++        BigInteger q2048_256 =
++            new BigInteger("f8183668ba5fc5bb06b5981e6d8b795d30b8978d43" +
++                           "ca0ec572e37e09939a9773", 16);
++
++        BigInteger g2048_256 =
++            new BigInteger("42debb9da5b3d88cc956e08787ec3f3a09bba5f48b" +
++                           "889a74aaf53174aa0fbe7e3c5b8fcd7a53bef563b0" +
++                           "e98560328960a9517f4014d3325fc7962bf1e04937" +
++                           "0d76d1314a76137e792f3f0db859d095e4a5b93202" +
++                           "4f079ecf2ef09c797452b0770e1350782ed57ddf79" +
++                           "4979dcef23cb96f183061965c4ebc93c9c71c56b92" +
++                           "5955a75f94cccf1449ac43d586d0beee43251b0b22" +
++                           "87349d68de0d144403f13e802f4146d882e057af19" +
++                           "b6f6275c6676c8fa0e3ca2713a3257fd1b27d0639f" +
++                           "695e347d8d1cf9ac819a26ca9b04cb0eb9b7b03598" +
++                           "8d15bbac65212a55239cfc7e58fae38d7250ab9991" +
++                           "ffbc97134025fe8ce04c4399ad96569be91a546f49" +
++                           "78693c7a", 16);
++        dsaCache.put(Integer.valueOf(2048+256),
++                                new DSAParameterSpec(p2048_256, q2048_256, g2048_256));
+ 
+         // use DSA parameters for DH as well
+         dhCache.put(Integer.valueOf(512), new DHParameterSpec(p512, g512));
+         dhCache.put(Integer.valueOf(768), new DHParameterSpec(p768, g768));
+         dhCache.put(Integer.valueOf(1024), new DHParameterSpec(p1024, g1024));
++        dhCache.put(Integer.valueOf(2048), new DHParameterSpec(p2048_224, g2048_224));
+     }
+ 
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/provider/SunEntries.java openjdk/jdk/src/share/classes/sun/security/provider/SunEntries.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/provider/SunEntries.java	2014-10-08 23:36:49.404491484 +0100
++++ openjdk/jdk/src/share/classes/sun/security/provider/SunEntries.java	2014-10-08 23:37:11.636798712 +0100
+@@ -47,6 +47,10 @@
+  *   SHA-2 family of hash functions includes SHA-224, SHA-256, SHA-384,
+  *   and SHA-512.
+  *
++ * - SHA-224withDSA/SHA-256withDSA are the signature schemes
++ *   described in FIPS 186-3. The associated object identifiers are
++ *   "OID.2.16.840.1.101.3.4.3.1", and "OID.2.16.840.1.101.3.4.3.2".
++
+  * - DSA is the key generation scheme as described in FIPS 186.
+  *   Aliases for DSA include the OID strings "OID.1.3.14.3.2.12"
+  *   and "OID.1.2.840.10040.4.1".
+@@ -106,11 +110,15 @@
+         map.put("Signature.SHA1withDSA", "sun.security.provider.DSA$SHA1withDSA");
+         map.put("Signature.NONEwithDSA", "sun.security.provider.DSA$RawDSA");
+         map.put("Alg.Alias.Signature.RawDSA", "NONEwithDSA");
++        map.put("Signature.SHA224withDSA", "sun.security.provider.DSA$SHA224withDSA");
++        map.put("Signature.SHA256withDSA", "sun.security.provider.DSA$SHA256withDSA");
+ 
+         String dsaKeyClasses = "java.security.interfaces.DSAPublicKey" +
+                 "|java.security.interfaces.DSAPrivateKey";
+         map.put("Signature.SHA1withDSA SupportedKeyClasses", dsaKeyClasses);
+         map.put("Signature.NONEwithDSA SupportedKeyClasses", dsaKeyClasses);
++        map.put("Signature.SHA224withDSA SupportedKeyClasses", dsaKeyClasses);
++        map.put("Signature.SHA256withDSA SupportedKeyClasses", dsaKeyClasses);
+ 
+         map.put("Alg.Alias.Signature.DSA", "SHA1withDSA");
+         map.put("Alg.Alias.Signature.DSS", "SHA1withDSA");
+@@ -124,6 +132,10 @@
+         map.put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
+         map.put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA");
+         map.put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA");
++        map.put("Alg.Alias.Signature.OID.2.16.840.1.101.3.4.3.1", "SHA224withDSA");
++        map.put("Alg.Alias.Signature.2.16.840.1.101.3.4.3.1", "SHA224withDSA");
++        map.put("Alg.Alias.Signature.OID.2.16.840.1.101.3.4.3.2", "SHA256withDSA");
++        map.put("Alg.Alias.Signature.2.16.840.1.101.3.4.3.2", "SHA256withDSA");
+ 
+         /*
+          *  Key Pair Generator engines
+@@ -143,6 +155,8 @@
+ 
+         map.put("Alg.Alias.MessageDigest.SHA-1", "SHA");
+         map.put("Alg.Alias.MessageDigest.SHA1", "SHA");
++        map.put("Alg.Alias.MessageDigest.1.3.14.3.2.26", "SHA");
++        map.put("Alg.Alias.MessageDigest.OID.1.3.14.3.2.26", "SHA");
+ 
+         map.put("MessageDigest.SHA-224", "sun.security.provider.SHA2$SHA224");
+         map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.4", "SHA-224");
+@@ -169,15 +183,17 @@
+          */
+         map.put("AlgorithmParameters.DSA",
+             "sun.security.provider.DSAParameters");
+-        map.put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA");
++        map.put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.1", "DSA");
+         map.put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1", "DSA");
++        map.put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA");
+ 
+         /*
+          * Key factories
+          */
+         map.put("KeyFactory.DSA", "sun.security.provider.DSAKeyFactory");
+-        map.put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA");
++        map.put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSA");
+         map.put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");
++        map.put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA");
+ 
+         /*
+          * Certificates
+@@ -234,9 +250,13 @@
+         /*
+          * KeySize
+          */
++        map.put("Signature.NONEwithDSA KeySize", "1024");
+         map.put("Signature.SHA1withDSA KeySize", "1024");
+-        map.put("KeyPairGenerator.DSA KeySize", "1024");
+-        map.put("AlgorithmParameterGenerator.DSA KeySize", "1024");
++        map.put("Signature.SHA224withDSA KeySize", "2048");
++        map.put("Signature.SHA256withDSA KeySize", "2048");
++
++        map.put("KeyPairGenerator.DSA KeySize", "2048");
++        map.put("AlgorithmParameterGenerator.DSA KeySize", "2048");
+ 
+         /*
+          * Implementation type: software or hardware
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/spec/DSAGenParameterSpec.java openjdk/jdk/src/share/classes/sun/security/spec/DSAGenParameterSpec.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/spec/DSAGenParameterSpec.java	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/spec/DSAGenParameterSpec.java	2014-10-08 23:37:11.636798712 +0100
+@@ -0,0 +1,129 @@
++/*
++ * 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.spec;
++
++import java.security.spec.AlgorithmParameterSpec;
++
++/**
++ * This immutable class specifies the set of parameters used for
++ * generating DSA parameters as specified in
++ * <a href="http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf">FIPS 186-3 Digital Signature Standard (DSS)</a>.
++ *
++ * @see AlgorithmParameterSpec
++ *
++ * @since 8
++ */
++public final class DSAGenParameterSpec implements AlgorithmParameterSpec {
++
++    private final int pLen;
++    private final int qLen;
++    private final int seedLen;
++
++    /**
++     * Creates a domain parameter specification for DSA parameter
++     * generation using <code>primePLen</code> and <code>subprimeQLen</code>.
++     * The value of <code>subprimeQLen</code> is also used as the default
++     * length of the domain parameter seed in bits.
++     * @param primePLen the desired length of the prime P in bits.
++     * @param subprimeQLen the desired length of the sub-prime Q in bits.
++     * @exception IllegalArgumentException if <code>primePLen</code>
++     * or <code>subprimeQLen</code> is illegal per the specification of
++     * FIPS 186-3.
++     */
++    public DSAGenParameterSpec(int primePLen, int subprimeQLen) {
++        this(primePLen, subprimeQLen, subprimeQLen);
++    }
++
++    /**
++     * Creates a domain parameter specification for DSA parameter
++     * generation using <code>primePLen</code>, <code>subprimeQLen</code>,
++     * and <code>seedLen</code>.
++     * @param primePLen the desired length of the prime P in bits.
++     * @param subprimeQLen the desired length of the sub-prime Q in bits.
++     * @param seedLen the desired length of the domain parameter seed in bits,
++     * shall be equal to or greater than <code>subprimeQLen</code>.
++     * @exception IllegalArgumentException if <code>primePLenLen</code>,
++     * <code>subprimeQLen</code>, or <code>seedLen</code> is illegal per the
++     * specification of FIPS 186-3.
++     */
++    public DSAGenParameterSpec(int primePLen, int subprimeQLen, int seedLen) {
++        switch (primePLen) {
++        case 1024:
++            if (subprimeQLen != 160) {
++                throw new IllegalArgumentException
++                    ("subprimeQLen must be 160 when primePLen=1024");
++            }
++            break;
++        case 2048:
++            if (subprimeQLen != 224 && subprimeQLen != 256) {
++               throw new IllegalArgumentException
++                   ("subprimeQLen must be 224 or 256 when primePLen=2048");
++            }
++            break;
++        case 3072:
++            if (subprimeQLen != 256) {
++                throw new IllegalArgumentException
++                    ("subprimeQLen must be 256 when primePLen=3072");
++            }
++            break;
++        default:
++            throw new IllegalArgumentException
++                ("primePLen must be 1024, 2048, or 3072");
++        }
++        if (seedLen < subprimeQLen) {
++            throw new IllegalArgumentException
++                ("seedLen must be equal to or greater than subprimeQLen");
++        }
++        this.pLen = primePLen;
++        this.qLen = subprimeQLen;
++        this.seedLen = seedLen;
++    }
++
++    /**
++     * Returns the desired length of the prime P of the
++     * to-be-generated DSA domain parameters in bits.
++     * @return the length of the prime P.
++     */
++    public int getPrimePLength() {
++        return pLen;
++    }
++
++    /**
++     * Returns the desired length of the sub-prime Q of the
++     * to-be-generated DSA domain parameters in bits.
++     * @return the length of the sub-prime Q.
++     */
++    public int getSubprimeQLength() {
++        return qLen;
++    }
++
++    /**
++     * Returns the desired length of the domain parameter seed in bits.
++     * @return the length of the domain parameter seed.
++     */
++    public int getSeedLength() {
++        return seedLen;
++    }
++}
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/x509/AlgorithmId.java openjdk/jdk/src/share/classes/sun/security/x509/AlgorithmId.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/x509/AlgorithmId.java	2014-10-08 23:36:49.476492479 +0100
++++ openjdk/jdk/src/share/classes/sun/security/x509/AlgorithmId.java	2014-10-08 23:37:11.636798712 +0100
+@@ -508,6 +508,9 @@
+         if (name.equalsIgnoreCase("EC")) {
+             return EC_oid;
+         }
++        if (name.equalsIgnoreCase("ECDH")) {
++            return AlgorithmId.ECDH_oid;
++        }
+ 
+         // Common signature types
+         if (name.equalsIgnoreCase("MD5withRSA")
+@@ -527,6 +530,12 @@
+             || name.equalsIgnoreCase("SHA-1/DSA")) {
+             return AlgorithmId.sha1WithDSA_oid;
+         }
++        if (name.equalsIgnoreCase("SHA224WithDSA")) {
++            return AlgorithmId.sha224WithDSA_oid;
++        }
++        if (name.equalsIgnoreCase("SHA256WithDSA")) {
++            return AlgorithmId.sha256WithDSA_oid;
++        }
+         if (name.equalsIgnoreCase("SHA1WithRSA")
+             || name.equalsIgnoreCase("SHA1/RSA")) {
+             return AlgorithmId.sha1WithRSAEncryption_oid;
+@@ -645,6 +654,7 @@
+     public static final ObjectIdentifier DSA_oid;
+     public static final ObjectIdentifier DSA_OIW_oid;
+     public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1);
++    public static final ObjectIdentifier ECDH_oid = oid(1, 3, 132, 1, 12);
+     public static final ObjectIdentifier RSA_oid;
+     public static final ObjectIdentifier RSAEncryption_oid;
+ 
+@@ -685,6 +695,10 @@
+     public static final ObjectIdentifier shaWithDSA_OIW_oid;
+     public static final ObjectIdentifier sha1WithDSA_OIW_oid;
+     public static final ObjectIdentifier sha1WithDSA_oid;
++    public static final ObjectIdentifier sha224WithDSA_oid =
++                                            oid(2, 16, 840, 1, 101, 3, 4, 3, 1);
++    public static final ObjectIdentifier sha256WithDSA_oid =
++                                            oid(2, 16, 840, 1, 101, 3, 4, 3, 2);
+ 
+     public static final ObjectIdentifier sha1WithECDSA_oid =
+                                             oid(1, 2, 840, 10045, 4, 1);
+@@ -716,7 +730,6 @@
+     public static ObjectIdentifier pbeWithSHA1AndRC2_40_oid =
+         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 6});
+ 
+-
+     static {
+     /*
+      * Note the preferred OIDs are named simply with no "OIW" or
+@@ -876,6 +889,8 @@
+         nameTable.put(DSA_oid, "DSA");
+         nameTable.put(DSA_OIW_oid, "DSA");
+         nameTable.put(EC_oid, "EC");
++        nameTable.put(ECDH_oid, "ECDH");
++
+         nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA");
+         nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA");
+         nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA");
+@@ -886,6 +901,8 @@
+         nameTable.put(sha1WithDSA_oid, "SHA1withDSA");
+         nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA");
+         nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA");
++        nameTable.put(sha224WithDSA_oid, "SHA224withDSA");
++        nameTable.put(sha256WithDSA_oid, "SHA256withDSA");
+         nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA");
+         nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA");
+         nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA");
+diff -Nru openjdk.orig/jdk/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java openjdk/jdk/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java
+--- openjdk.orig/jdk/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java	2014-10-08 23:37:11.636798712 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 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
+@@ -23,7 +23,7 @@
+ 
+ /**
+  * @test
+- * @bug 6330287 6331386
++ * @bug 6330287 6331386 7044060
+  * @summary verify that DHKeyPairGenerator returns keys of the expected size
+  * (modulus and exponent)
+  * -and-
+@@ -57,7 +57,8 @@
+      * Sizes and values for various lengths.
+      */
+     private enum Sizes {
+-        two56(256), three84(384), five12(512), seven68(768), ten24(1024);
++        two56(256), three84(384), five12(512), seven68(768), ten24(1024),
++        twenty48(2048);
+ 
+         private final int intSize;
+         private final BigInteger bigIntValue;
+@@ -82,7 +83,8 @@
+         KeyPair kp;
+         KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", "SunJCE");
+ 
+-        // Sun's default uses a default psize of 1024/lsize of 512
++        // Sun's default uses a default psize of 1024 and
++        // lsize of (pSize / 2) but at least 384 bits
+         kp = kpg.generateKeyPair();
+         checkKeyPair(kp, Sizes.ten24, Sizes.five12);
+ 
+@@ -114,6 +116,20 @@
+         kp = kpg.generateKeyPair();
+         checkKeyPair(kp, Sizes.seven68, Sizes.three84);
+ 
++        // test w/ only pSize
++        kpg.initialize(Sizes.twenty48.getIntSize());
++        kp = kpg.generateKeyPair();
++        checkKeyPair(kp, Sizes.twenty48, Sizes.ten24);
++
++        publicKey = (DHPublicKey)kp.getPublic();
++        p = publicKey.getParams().getP();
++        g = publicKey.getParams().getG();
++
++        // test w/ all values specified
++        kpg.initialize(new DHParameterSpec(p, g, Sizes.five12.getIntSize()));
++        kp = kpg.generateKeyPair();
++        checkKeyPair(kp, Sizes.twenty48, Sizes.five12);
++
+         System.out.println("OK");
+     }
+ 
+diff -Nru openjdk.orig/jdk/test/sun/security/pkcs11/ec/TestECDH2.java openjdk/jdk/test/sun/security/pkcs11/ec/TestECDH2.java
+--- openjdk.orig/jdk/test/sun/security/pkcs11/ec/TestECDH2.java	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/jdk/test/sun/security/pkcs11/ec/TestECDH2.java	2014-10-08 23:37:11.636798712 +0100
+@@ -0,0 +1,127 @@
++/*
++ * 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.
++ *
++ * 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 6405536
++ * @summary basic test of ECDSA signatures for P-256 and P-384 from the
++ * example data in "Suite B Implementer's Guide to FIPS 186-3".
++ * @library ..
++ * @library ../../../../java/security/testlibrary
++ * @compile -XDignore.symbol.file TestECDH2.java
++ * @run main TestECDH2
++ */
++
++import java.io.*;
++import java.util.*;
++import java.math.BigInteger;
++
++import java.security.*;
++import java.security.spec.*;
++import java.security.interfaces.*;
++import javax.crypto.*;
++
++import sun.security.ec.NamedCurve;
++
++public class TestECDH2 extends PKCS11Test {
++
++    // values of the keys we use for the tests
++
++    // keypair using NIST P-256
++    private final static String privD256 = "70a12c2db16845ed56ff68cfc21a472b3f04d7d6851bf6349f2d7d5b3452b38a";
++    private final static String pubX256 = "8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8";
++    private final static String pubY256 = "d8a12ba61d599235f67d9cb4d58f1783d3ca43e78f0a5abaa624079936c0c3a9";
++
++    // keypair using NIST P-384
++    private final static String privD384 = "c838b85253ef8dc7394fa5808a5183981c7deef5a69ba8f4f2117ffea39cfcd90e95f6cbc854abacab701d50c1f3cf24";
++    private final static String pubX384 = "1fbac8eebd0cbf35640b39efe0808dd774debff20a2a329e91713baf7d7f3c3e81546d883730bee7e48678f857b02ca0";
++    private final static String pubY384 = "eb213103bd68ce343365a8a4c3d4555fa385f5330203bdd76ffad1f3affb95751c132007e1b240353cb0a4cf1693bdf9";
++
++    private KeyFactory kf = null;
++    private KeyPairGenerator kpg = null;
++
++    private static void testKeyAgreement(KeyPair kpA, KeyPair kpB, Provider p)
++        throws Exception {
++        KeyAgreement ka1 = KeyAgreement.getInstance("ECDH", p);
++        ka1.init(kpA.getPrivate());
++        ka1.doPhase(kpB.getPublic(), true);
++        byte[] s1 = ka1.generateSecret();
++
++        KeyAgreement ka2 = KeyAgreement.getInstance("ECDH", p);
++        ka2.init(kpB.getPrivate());
++        ka2.doPhase(kpA.getPublic(), true);
++        byte[] s2 = ka2.generateSecret();
++        if (Arrays.equals(s1, s2) == false) {
++            System.out.println("expected: " + toString(s1));
++            System.out.println("actual:   " + toString(s2));
++            throw new Exception("Generated secrets do not match");
++        }
++    }
++
++    private KeyPair genECKeyPair(String curvName, String privD, String pubX,
++                                 String pubY) throws Exception {
++        ECParameterSpec ecParams = NamedCurve.getECParameterSpec(curvName);
++        ECPrivateKeySpec privKeySpec =
++            new ECPrivateKeySpec(new BigInteger(privD, 16), ecParams);
++        ECPublicKeySpec pubKeySpec =
++            new ECPublicKeySpec(new ECPoint(new BigInteger(pubX, 16),
++                                            new BigInteger(pubY, 16)),
++                                ecParams);
++        PrivateKey privKey = kf.generatePrivate(privKeySpec);
++        PublicKey pubKey = kf.generatePublic(pubKeySpec);
++        return new KeyPair(pubKey, privKey);
++    }
++    private KeyPair genECKeyPair(String curvName) throws Exception {
++        ECGenParameterSpec genParams = new ECGenParameterSpec(curvName);
++        kpg.initialize(genParams, null);
++        return kpg.generateKeyPair();
++    }
++    public static void main(String[] args) throws Exception {
++        main(new TestECDH2());
++    }
++
++    public void main(Provider provider) throws Exception {
++        if (provider.getService("KeyAgreement", "ECDH") == null) {
++            System.out.println("ECDH not supported, skipping");
++            return;
++        }
++
++        kf = KeyFactory.getInstance("EC", provider);
++        kpg = KeyPairGenerator.getInstance("EC", provider);
++
++        System.out.println("Testing against NIST P-256");
++
++        long start = System.currentTimeMillis();
++        KeyPair kp256A = genECKeyPair("secp256r1", privD256, pubX256, pubY256);
++        KeyPair kp256B = genECKeyPair("secp256r1");
++        testKeyAgreement(kp256A, kp256B, provider);
++
++        System.out.println("Testing against NIST P-384");
++        KeyPair kp384A = genECKeyPair("secp384r1", privD384, pubX384, pubY384);
++        KeyPair kp384B = genECKeyPair("secp384r1");
++        testKeyAgreement(kp384A, kp384B, provider);
++
++        long stop = System.currentTimeMillis();
++        System.out.println("All tests passed (" + (stop - start) + " ms).");
++    }
++}
+diff -Nru openjdk.orig/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java openjdk/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java
+--- openjdk.orig/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java	2014-10-08 23:37:11.636798712 +0100
+@@ -0,0 +1,122 @@
++/*
++ * 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.
++ *
++ * 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 6405536
++ * @summary basic test of ECDSA signatures for P-256 and P-384 from the
++ * example data in "Suite B Implementer's Guide to FIPS 186-3".
++ * @library ..
++ * @library ../../../../java/security/testlibrary
++ * @compile -XDignore.symbol.file TestECDSA2.java
++ * @run main TestECDSA2
++ */
++
++import java.io.*;
++import java.util.*;
++import java.math.BigInteger;
++
++import java.security.*;
++import java.security.spec.*;
++import java.security.interfaces.*;
++
++import sun.security.ec.NamedCurve;
++
++public class TestECDSA2 extends PKCS11Test {
++
++    // values of the keys we use for the tests
++
++    // keypair using NIST P-256
++    private final static String privD256 = "70a12c2db16845ed56ff68cfc21a472b3f04d7d6851bf6349f2d7d5b3452b38a";
++    private final static String pubX256 = "8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8";
++    private final static String pubY256 = "d8a12ba61d599235f67d9cb4d58f1783d3ca43e78f0a5abaa624079936c0c3a9";
++
++    // keypair using NIST P-384
++    private final static String privD384 = "c838b85253ef8dc7394fa5808a5183981c7deef5a69ba8f4f2117ffea39cfcd90e95f6cbc854abacab701d50c1f3cf24";
++    private final static String pubX384 = "1fbac8eebd0cbf35640b39efe0808dd774debff20a2a329e91713baf7d7f3c3e81546d883730bee7e48678f857b02ca0";
++    private final static String pubY384 = "eb213103bd68ce343365a8a4c3d4555fa385f5330203bdd76ffad1f3affb95751c132007e1b240353cb0a4cf1693bdf9";
++
++    // data to be signed
++    private final static byte[] data = "This is only a test message. It is 48 bytes long".getBytes();
++
++    private KeyFactory kf = null;
++
++    private static void testSignAndVerify(String alg, KeyPair kp, Provider p) throws Exception {
++        Signature s = Signature.getInstance(alg, p);
++        s.initSign(kp.getPrivate());
++        s.update(data);
++        byte[] result = s.sign();
++
++        s.initVerify(kp.getPublic());
++        s.update(data);
++        if (!s.verify(result)) {
++            throw new Exception("Error: Signature verification failed");
++        }
++        System.out.println(p.getName() + ": " + alg + " Passed");
++    }
++
++    private KeyPair genECKeyPair(String curvName, String privD, String pubX, String pubY) throws Exception {
++        ECParameterSpec ecParams = NamedCurve.getECParameterSpec(curvName);
++        ECPrivateKeySpec privKeySpec =
++            new ECPrivateKeySpec(new BigInteger(privD, 16), ecParams);
++        ECPublicKeySpec pubKeySpec =
++            new ECPublicKeySpec(new ECPoint(new BigInteger(pubX, 16), new BigInteger(pubY, 16)),
++                                ecParams);
++        PrivateKey privKey = kf.generatePrivate(privKeySpec);
++        PublicKey pubKey = kf.generatePublic(pubKeySpec);
++        return new KeyPair(pubKey, privKey);
++    }
++
++    public static void main(String[] args) throws Exception {
++        main(new TestECDSA2());
++    }
++
++    public void main(Provider provider) throws Exception {
++        boolean testP256 =
++            (provider.getService("Signature", "SHA256withECDSA") != null);
++
++        boolean testP384 =
++            (provider.getService("Signature", "SHA384withECDSA") != null);
++
++        if (!testP256 && !testP384) {
++            System.out.println("ECDSA not supported, skipping");
++            return;
++        }
++
++        kf = KeyFactory.getInstance("EC", provider);
++
++        long start = System.currentTimeMillis();
++        if (testP256) {
++            // can use secp256r1, NIST P-256, X9.62 prime256v1, or 1.2.840.10045.3.1.7
++            KeyPair kp = genECKeyPair("secp256r1", privD256, pubX256, pubY256);
++            testSignAndVerify("SHA256withECDSA", kp, provider);
++        }
++        if (testP384) {
++            // can use secp384r1, NIST P-384, 1.3.132.0.34
++            KeyPair kp = genECKeyPair("secp384r1", privD384, pubX384, pubY384);
++            testSignAndVerify("SHA384withECDSA", kp, provider);
++        }
++        long stop = System.currentTimeMillis();
++        System.out.println("All tests passed (" + (stop - start) + " ms).");
++    }
++}
+diff -Nru openjdk.orig/jdk/test/sun/security/provider/DSA/TestAlgParameterGenerator.java openjdk/jdk/test/sun/security/provider/DSA/TestAlgParameterGenerator.java
+--- openjdk.orig/jdk/test/sun/security/provider/DSA/TestAlgParameterGenerator.java	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/jdk/test/sun/security/provider/DSA/TestAlgParameterGenerator.java	2014-10-08 23:37:11.636798712 +0100
+@@ -0,0 +1,117 @@
++/*
++ * 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.
++ *
++ * 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 7044060
++ * @summary verify that DSA parameter generation works
++ * @run main/othervm/timeout=300 TestAlgParameterGenerator
++ */
++import java.security.*;
++import java.security.spec.*;
++import java.security.interfaces.*;
++
++public class TestAlgParameterGenerator {
++
++    private static void checkParamStrength(AlgorithmParameters param,
++                                           int strength) throws Exception {
++        String algo = param.getAlgorithm();
++        if (!algo.equalsIgnoreCase("DSA")) {
++            throw new Exception("Unexpected type of parameters: " + algo);
++        }
++        DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class);
++        int valueL = spec.getP().bitLength();
++        if (strength != valueL) {
++            System.out.println("Expected " + strength + " but actual " + valueL);
++            throw new Exception("Wrong P strength");
++        }
++    }
++    private static void checkParamStrength(AlgorithmParameters param,
++                                           DSAGenParameterSpec genParam)
++        throws Exception {
++        String algo = param.getAlgorithm();
++        if (!algo.equalsIgnoreCase("DSA")) {
++            throw new Exception("Unexpected type of parameters: " + algo);
++        }
++        DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class);
++        int valueL = spec.getP().bitLength();
++        int strength = genParam.getPrimePLength();
++        if (strength != valueL) {
++            System.out.println("P: Expected " + strength + " but actual " + valueL);
++            throw new Exception("Wrong P strength");
++        }
++        int valueN = spec.getQ().bitLength();
++        strength = genParam.getSubprimeQLength();
++        if (strength != valueN) {
++            System.out.println("Q: Expected " + strength + " but actual " + valueN);
++            throw new Exception("Wrong Q strength");
++        }
++    }
++
++    public static void main(String[] args) throws Exception {
++        AlgorithmParameterGenerator apg =
++            AlgorithmParameterGenerator.getInstance("DSA", "SUN");
++
++        long start, stop;
++        // make sure no-init still works
++        start = System.currentTimeMillis();
++        AlgorithmParameters param = apg.generateParameters();
++        stop = System.currentTimeMillis();
++        System.out.println("Time: " + (stop - start) + " ms.");
++        checkParamStrength(param, 1024);
++
++        // make sure the old model works
++        int[] strengths = { 512, 768, 1024 };
++        for (int i = 0; i < strengths.length; i++) {
++            int sizeP = strengths[i];
++            System.out.println("Generating " + sizeP + "-bit DSA Parameters");
++            start = System.currentTimeMillis();
++            apg.init(sizeP);
++            param = apg.generateParameters();
++            stop = System.currentTimeMillis();
++            System.out.println("Time: " + (stop - start) + " ms.");
++            checkParamStrength(param, sizeP);
++        }
++
++        // now the newer model
++        DSAGenParameterSpec spec1 = new DSAGenParameterSpec(1024, 160);
++        DSAGenParameterSpec spec2 = new DSAGenParameterSpec(2048, 224);
++        DSAGenParameterSpec spec3 = new DSAGenParameterSpec(2048, 256);
++        //DSAGenParameterSpec spec4 = new DSAGenParameterSpec(3072, 256);
++        DSAGenParameterSpec[] specSet = {
++            spec1, spec2, spec3//, spec4
++        };
++        for (int i = 0; i < specSet.length; i++) {
++            DSAGenParameterSpec genParam = specSet[i];
++            System.out.println("Generating (" + genParam.getPrimePLength() +
++                               ", " + genParam.getSubprimeQLength() +
++                               ") DSA Parameters");
++            start = System.currentTimeMillis();
++            apg.init(genParam, null);
++            param = apg.generateParameters();
++            stop = System.currentTimeMillis();
++            System.out.println("Time: " + (stop - start) + " ms.");
++            checkParamStrength(param, genParam);
++        }
++    }
++}
+diff -Nru openjdk.orig/jdk/test/sun/security/provider/DSA/TestDSA2.java openjdk/jdk/test/sun/security/provider/DSA/TestDSA2.java
+--- openjdk.orig/jdk/test/sun/security/provider/DSA/TestDSA2.java	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/jdk/test/sun/security/provider/DSA/TestDSA2.java	2014-10-08 23:37:11.636798712 +0100
+@@ -0,0 +1,96 @@
++/*
++ * 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.
++ *
++ * 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 7044060
++ * @run main/othervm/timeout=250 TestDSA2
++ * @summary verify that DSA signature works using SHA and SHA-224 and SHA-256 digests.
++ */
++
++
++import java.security.*;
++import java.security.spec.*;
++import java.security.interfaces.*;
++
++public class TestDSA2 {
++
++    // NOTE: need to explictly specify provider since the more
++    // preferred provider SunPKCS11 provider only supports up
++    // 1024 bits.
++    private static final String PROV = "SUN";
++
++    private static final String[] SIG_ALGOS = {
++        "SHA1withDSA", "SHA224withDSA", "SHA256withDSA"
++    };
++
++    private static final int[] KEYSIZES = {
++        1024, 2048
++    };
++
++    public static void main(String[] args) throws Exception {
++        boolean[] expectedToPass = { true, true, true };
++        test(1024, expectedToPass);
++        boolean[] expectedToPass2 = { false, true, true };
++        test(2048, expectedToPass2);
++    }
++
++    private static void test(int keySize, boolean[] testStatus)
++        throws Exception {
++        byte[] data = "1234567890".getBytes();
++        System.out.println("Test against key size: " + keySize);
++
++        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", PROV);
++        keyGen.initialize(keySize, new SecureRandom());
++        KeyPair pair = keyGen.generateKeyPair();
++
++        if (testStatus.length != SIG_ALGOS.length) {
++            throw new RuntimeException("TestError: incorrect status array!");
++        }
++        for (int i = 0; i < SIG_ALGOS.length; i++) {
++            Signature dsa = Signature.getInstance(SIG_ALGOS[i], PROV);
++            try {
++                dsa.initSign(pair.getPrivate());
++                dsa.update(data);
++                byte[] sig = dsa.sign();
++                dsa.initVerify(pair.getPublic());
++                dsa.update(data);
++                boolean verifies = dsa.verify(sig);
++                if (verifies == testStatus[i]) {
++                    System.out.println(SIG_ALGOS[i] + ": Passed");
++                } else {
++                    System.out.println(SIG_ALGOS[i] + ": should " +
++                                       (testStatus[i]? "pass":"fail"));
++                    throw new RuntimeException(SIG_ALGOS[i] + ": Unexpected Test result!");
++
++                }
++            } catch (Exception ex) {
++                if (testStatus[i]) {
++                    ex.printStackTrace();
++                    throw new RuntimeException(SIG_ALGOS[i] + ": Unexpected exception " + ex);
++                } else {
++                    System.out.println(SIG_ALGOS[i] + ": Passed, expected " + ex);
++                }
++            }
++        }
++    }
++}
+diff -Nru openjdk.orig/jdk/test/sun/security/provider/DSA/TestKeyPairGenerator.java openjdk/jdk/test/sun/security/provider/DSA/TestKeyPairGenerator.java
+--- openjdk.orig/jdk/test/sun/security/provider/DSA/TestKeyPairGenerator.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/provider/DSA/TestKeyPairGenerator.java	2014-10-08 23:37:11.636798712 +0100
+@@ -24,7 +24,7 @@
+ /*
+  * @test
+  * @bug 4800108
+- * @summary verify that precomputed DSA parameters are always used (512, 768, 1024 bit)
++ * @summary verify that precomputed DSA parameters are always used (512, 768, 1024, 2048 bit)
+  * @run main/othervm/timeout=15 TestKeyPairGenerator
+  */
+ 
+@@ -78,6 +78,10 @@
+         kp = kpg.generateKeyPair();
+         checkKeyLength(kp, 512);
+ 
++        kpg.initialize(2048);
++        kp = kpg.generateKeyPair();
++        checkKeyLength(kp, 2048);
++
+         long stop = System.currentTimeMillis();
+         System.out.println("Time: " + (stop - start) + " ms.");
+     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/7106773-512_bits_rsa.patch	Thu Oct 09 02:25:23 2014 +0100
@@ -0,0 +1,1336 @@
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/util/KeyLength.java openjdk/jdk/src/share/classes/sun/security/util/KeyLength.java
+--- openjdk.orig/jdk/src/share/classes/sun/security/util/KeyLength.java	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/jdk/src/share/classes/sun/security/util/KeyLength.java	2014-10-08 23:56:02.320447941 +0100
+@@ -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 -Nru openjdk.orig/jdk/src/windows/classes/sun/security/mscapi/Key.java openjdk/jdk/src/windows/classes/sun/security/mscapi/Key.java
+--- openjdk.orig/jdk/src/windows/classes/sun/security/mscapi/Key.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/src/windows/classes/sun/security/mscapi/Key.java	2014-10-08 23:56:02.320447941 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 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
+@@ -25,6 +25,8 @@
+ 
+ package sun.security.mscapi;
+ 
++import sun.security.util.Length;
++
+ /**
+  * The handle for an RSA or DSA key using the Microsoft Crypto API.
+  *
+@@ -35,7 +37,7 @@
+  * @since 1.6
+  * @author  Stanley Man-Kit Ho
+  */
+-abstract class Key implements java.security.Key
++abstract class Key implements java.security.Key, Length
+ {
+ 
+     // Native handle
+@@ -81,7 +83,8 @@
+     /**
+      * Return bit length of the key.
+      */
+-    public int bitLength()
++    @Override
++    public int length()
+     {
+         return keyLength;
+     }
+diff -Nru openjdk.orig/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java openjdk/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java
+--- openjdk.orig/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java	2014-10-08 23:57:43.965856392 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 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
+@@ -198,12 +198,12 @@
+             mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
+             publicKey = (sun.security.mscapi.Key)key;
+             privateKey = null;
+-            outputSize = publicKey.bitLength() / 8;
++            outputSize = publicKey.length() / 8;
+         } else if (key instanceof PrivateKey) {
+             mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
+             privateKey = (sun.security.mscapi.Key)key;
+             publicKey = null;
+-            outputSize = privateKey.bitLength() / 8;
++            outputSize = privateKey.length() / 8;
+         } else {
+             throw new InvalidKeyException("Unknown key type: " + key);
+         }
+@@ -358,7 +358,7 @@
+     protected int engineGetKeySize(Key key) throws InvalidKeyException {
+ 
+         if (key instanceof sun.security.mscapi.Key) {
+-            return ((sun.security.mscapi.Key) key).bitLength();
++            return ((sun.security.mscapi.Key) key).length();
+         } else {
+             throw new InvalidKeyException("Unsupported key type: " + key);
+         }
+diff -Nru openjdk.orig/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java openjdk/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java
+--- openjdk.orig/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java	2014-10-08 23:52:11.237246746 +0100
++++ openjdk/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java	2014-10-08 23:56:50.913121240 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 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
+@@ -297,7 +297,7 @@
+ 
+         // Check against the local and global values to make sure
+         // the sizes are ok.  Round up to nearest byte.
+-        RSAKeyFactory.checkKeyLengths(((privateKey.bitLength() + 7) & ~7),
++        RSAKeyFactory.checkKeyLengths(((privateKey.length() + 7) & ~7),
+             null, RSAKeyPairGenerator.KEY_SIZE_MIN,
+             RSAKeyPairGenerator.KEY_SIZE_MAX);
+ 
+diff -Nru openjdk.orig/jdk/test/sun/security/mscapi/ShortRSAKey1024.sh openjdk/jdk/test/sun/security/mscapi/ShortRSAKey1024.sh
+--- openjdk.orig/jdk/test/sun/security/mscapi/ShortRSAKey1024.sh	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/jdk/test/sun/security/mscapi/ShortRSAKey1024.sh	2014-10-08 23:56:02.320447941 +0100
+@@ -0,0 +1,85 @@
++#!/bin/sh
++
++#
++# 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.
++#
++# 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 7106773
++# @summary 512 bits RSA key cannot work with SHA384 and SHA512
++# @run shell ShortRSAKey1024.sh
++
++# 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 7106773.1024 \
++            -keysize 1024 \
++            -dname "cn=localhost,c=US" \
++            -noprompt
++
++        echo
++        echo "Running the test..."
++        ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\ShortRSAKeyWithinTLS.java
++        ${TESTJAVA}/bin/java ShortRSAKeyWithinTLS 7106773.1024 1024 \
++            TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
++
++        rc=$?
++
++        echo
++        echo "Removing the temporary RSA keypair from the Windows-My store..."
++        ${TESTJAVA}/bin/keytool \
++            -delete \
++            -storetype Windows-My \
++            -alias 7106773.1024
++
++        echo done.
++        exit $rc
++        ;;
++
++    * )
++        echo "This test is not intended for '$OS' - passing test"
++        exit 0
++        ;;
++esac
+diff -Nru openjdk.orig/jdk/test/sun/security/mscapi/ShortRSAKey512.sh openjdk/jdk/test/sun/security/mscapi/ShortRSAKey512.sh
+--- openjdk.orig/jdk/test/sun/security/mscapi/ShortRSAKey512.sh	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/jdk/test/sun/security/mscapi/ShortRSAKey512.sh	2014-10-08 23:56:02.320447941 +0100
+@@ -0,0 +1,86 @@
++#!/bin/sh
++
++#
++# 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.
++#
++# 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 7106773
++# @summary 512 bits RSA key cannot work with SHA384 and SHA512
++# @run shell ShortRSAKey512.sh
++
++# 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 7106773.512 \
++            -keysize 512 \
++            -dname "cn=localhost,c=US" \
++            -noprompt
++
++        echo
++        echo "Running the test..."
++        ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\ShortRSAKeyWithinTLS.java
++        ${TESTJAVA}/bin/java ShortRSAKeyWithinTLS 7106773.512 512 \
++            TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
++
++
++        rc=$?
++
++        echo
++        echo "Removing the temporary RSA keypair from the Windows-My store..."
++        ${TESTJAVA}/bin/keytool \
++            -delete \
++            -storetype Windows-My \
++            -alias 7106773.512
++
++        echo done.
++        exit $rc
++        ;;
++
++    * )
++        echo "This test is not intended for '$OS' - passing test"
++        exit 0
++        ;;
++esac
+diff -Nru openjdk.orig/jdk/test/sun/security/mscapi/ShortRSAKey768.sh openjdk/jdk/test/sun/security/mscapi/ShortRSAKey768.sh
+--- openjdk.orig/jdk/test/sun/security/mscapi/ShortRSAKey768.sh	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/jdk/test/sun/security/mscapi/ShortRSAKey768.sh	2014-10-08 23:56:02.320447941 +0100
+@@ -0,0 +1,85 @@
++#!/bin/sh
++
++#
++# 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.
++#
++# 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 7106773
++# @summary 512 bits RSA key cannot work with SHA384 and SHA512
++# @run shell ShortRSAKey768.sh
++
++# 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 7106773.768 \
++            -keysize 768 \
++            -dname "cn=localhost,c=US" \
++            -noprompt
++
++        echo
++        echo "Running the test..."
++        ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\ShortRSAKeyWithinTLS.java
++        ${TESTJAVA}/bin/java ShortRSAKeyWithinTLS 7106773.768 768 \
++            TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
++
++        rc=$?
++
++        echo
++        echo "Removing the temporary RSA keypair from the Windows-My store..."
++        ${TESTJAVA}/bin/keytool \
++            -delete \
++            -storetype Windows-My \
++            -alias 7106773.768
++
++        echo done.
++        exit $rc
++        ;;
++
++    * )
++        echo "This test is not intended for '$OS' - passing test"
++        exit 0
++        ;;
++esac
+diff -Nru openjdk.orig/jdk/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java openjdk/jdk/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java
+--- openjdk.orig/jdk/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/jdk/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java	2014-10-08 23:56:02.324447997 +0100
+@@ -0,0 +1,355 @@
++/*
++ * 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.
++ *
++ * 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.io.*;
++import java.net.*;
++import java.util.*;
++import java.security.*;
++import javax.net.*;
++import javax.net.ssl.*;
++import java.lang.reflect.*;
++
++import sun.security.util.KeyLength;
++
++public class ShortRSAKeyWithinTLS {
++
++    /*
++     * =============================================================
++     * Set the various variables needed for the tests, then
++     * specify what tests to run on each side.
++     */
++
++    /*
++     * Should we run the client or server in a separate thread?
++     * Both sides can throw exceptions, but do you have a preference
++     * as to which side should be the main thread.
++     */
++    static boolean separateServerThread = false;
++
++    /*
++     * Is the server ready to serve?
++     */
++    volatile static boolean serverReady = false;
++
++    /*
++     * Turn on SSL debugging?
++     */
++    static boolean debug = false;
++
++    /*
++     * If the client or server is doing some kind of object creation
++     * that the other side depends on, and that thread prematurely
++     * exits, you may experience a hang.  The test harness will
++     * terminate all hung threads after its timeout has expired,
++     * currently 3 minutes by default, but you might try to be
++     * smart about it....
++     */
++
++    /*
++     * Define the server side of the test.
++     *
++     * If the server prematurely exits, serverReady will be set to true
++     * to avoid infinite hangs.
++     */
++    void doServerSide() throws Exception {
++
++        // load the key store
++        KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
++        ks.load(null, null);
++        System.out.println("Loaded keystore: Windows-MY");
++
++        // check key size
++        checkKeySize(ks);
++
++        // initialize the SSLContext
++        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
++        kmf.init(ks, null);
++
++        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
++        tmf.init(ks);
++
++        SSLContext ctx = SSLContext.getInstance("TLS");
++        ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
++
++        ServerSocketFactory ssf = ctx.getServerSocketFactory();
++        SSLServerSocket sslServerSocket = (SSLServerSocket)
++                                ssf.createServerSocket(serverPort);
++        sslServerSocket.setNeedClientAuth(true);
++        serverPort = sslServerSocket.getLocalPort();
++        System.out.println("serverPort = " + serverPort);
++
++        /*
++         * Signal Client, we're ready for his connect.
++         */
++        serverReady = true;
++
++        SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
++        InputStream sslIS = sslSocket.getInputStream();
++        OutputStream sslOS = sslSocket.getOutputStream();
++
++        sslIS.read();
++        sslOS.write(85);
++        sslOS.flush();
++
++        sslSocket.close();
++    }
++
++    /*
++     * Define the client side of the test.
++     *
++     * If the server prematurely exits, serverReady will be set to true
++     * to avoid infinite hangs.
++     */
++    void doClientSide() throws Exception {
++
++        /*
++         * Wait for server to get started.
++         */
++        while (!serverReady) {
++            Thread.sleep(50);
++        }
++
++        // load the key store
++        KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
++        ks.load(null, null);
++        System.out.println("Loaded keystore: Windows-MY");
++
++        // initialize the SSLContext
++        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
++        kmf.init(ks, null);
++
++        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
++        tmf.init(ks);
++
++        SSLContext ctx = SSLContext.getInstance("TLS");
++        ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
++
++        SSLSocketFactory sslsf = ctx.getSocketFactory();
++        SSLSocket sslSocket = (SSLSocket)
++            sslsf.createSocket("localhost", serverPort);
++
++        if (clientProtocol != null) {
++            sslSocket.setEnabledProtocols(new String[] {clientProtocol});
++        }
++
++        if (clientCiperSuite != null) {
++            sslSocket.setEnabledCipherSuites(new String[] {clientCiperSuite});
++        }
++
++        InputStream sslIS = sslSocket.getInputStream();
++        OutputStream sslOS = sslSocket.getOutputStream();
++
++        sslOS.write(280);
++        sslOS.flush();
++        sslIS.read();
++
++        sslSocket.close();
++    }
++
++    private void checkKeySize(KeyStore ks) throws Exception {
++        PrivateKey privateKey = null;
++        PublicKey publicKey = null;
++
++        if (ks.containsAlias(keyAlias)) {
++            System.out.println("Loaded entry: " + keyAlias);
++            privateKey = (PrivateKey)ks.getKey(keyAlias, null);
++            publicKey = (PublicKey)ks.getCertificate(keyAlias).getPublicKey();
++
++            int privateKeySize = KeyLength.getKeySize(privateKey);
++            if (privateKeySize != keySize) {
++                throw new Exception("Expected key size is " + keySize +
++                        ", but the private key size is " + privateKeySize);
++            }
++
++            int publicKeySize = KeyLength.getKeySize(publicKey);
++            if (publicKeySize != keySize) {
++                throw new Exception("Expected key size is " + keySize +
++                        ", but the public key size is " + publicKeySize);
++            }
++        }
++    }
++
++    /*
++     * =============================================================
++     * The remainder is just support stuff
++     */
++
++    // use any free port by default
++    volatile int serverPort = 0;
++
++    volatile Exception serverException = null;
++    volatile Exception clientException = null;
++
++    private static String keyAlias;
++    private static int keySize;
++    private static String clientProtocol = null;
++    private static String clientCiperSuite = null;
++
++    private static void parseArguments(String[] args) {
++        keyAlias = args[0];
++        keySize = Integer.parseInt(args[1]);
++
++        if (args.length > 2) {
++            clientProtocol = args[2];
++        }
++
++        if (args.length > 3) {
++            clientCiperSuite = args[3];
++        }
++    }
++
++    public static void main(String[] args) throws Exception {
++        if (debug) {
++            System.setProperty("javax.net.debug", "all");
++        }
++
++        // Get the customized arguments.
++        parseArguments(args);
++
++        new ShortRSAKeyWithinTLS();
++    }
++
++    Thread clientThread = null;
++    Thread serverThread = null;
++
++    /*
++     * Primary constructor, used to drive remainder of the test.
++     *
++     * Fork off the other side, then do your work.
++     */
++    ShortRSAKeyWithinTLS() throws Exception {
++        try {
++            if (separateServerThread) {
++                startServer(true);
++                startClient(false);
++            } else {
++                startClient(true);
++                startServer(false);
++            }
++        } catch (Exception e) {
++            // swallow for now.  Show later
++        }
++
++        /*
++         * Wait for other side to close down.
++         */
++        if (separateServerThread) {
++            serverThread.join();
++        } else {
++            clientThread.join();
++        }
++
++        /*
++         * When we get here, the test is pretty much over.
++         * Which side threw the error?
++         */
++        Exception local;
++        Exception remote;
++        String whichRemote;
++
++        if (separateServerThread) {
++            remote = serverException;
++            local = clientException;
++            whichRemote = "server";
++        } else {
++            remote = clientException;
++            local = serverException;
++            whichRemote = "client";
++        }
++
++        /*
++         * If both failed, return the curthread's exception, but also
++         * print the remote side Exception
++         */
++        if ((local != null) && (remote != null)) {
++            System.out.println(whichRemote + " also threw:");
++            remote.printStackTrace();
++            System.out.println();
++            throw local;
++        }
++
++        if (remote != null) {
++            throw remote;
++        }
++
++        if (local != null) {
++            throw local;
++        }
++    }
++
++    void startServer(boolean newThread) throws Exception {
++        if (newThread) {
++            serverThread = new Thread() {
++                public void run() {
++                    try {
++                        doServerSide();
++                    } catch (Exception e) {
++                        /*
++                         * Our server thread just died.
++                         *
++                         * Release the client, if not active already...
++                         */
++                        System.err.println("Server died...");
++                        serverReady = true;
++                        serverException = e;
++                    }
++                }
++            };
++            serverThread.start();
++        } else {
++            try {
++                doServerSide();
++            } catch (Exception e) {
++                serverException = e;
++            } finally {
++                serverReady = true;
++            }
++        }
++    }
++
++    void startClient(boolean newThread) throws Exception {
++        if (newThread) {
++            clientThread = new Thread() {
++                public void run() {
++                    try {
++                        doClientSide();
++                    } catch (Exception e) {
++                        /*
++                         * Our client thread just died.
++                         */
++                        System.err.println("Client died...");
++                        clientException = e;
++                    }
++                }
++            };
++            clientThread.start();
++        } else {
++            try {
++                doClientSide();
++            } catch (Exception e) {
++                clientException = e;
++            }
++        }
++    }
++}
++
+diff -Nru openjdk.orig/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java openjdk/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java
+--- openjdk.orig/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java	2014-10-08 23:56:02.324447997 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, 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
+@@ -155,6 +155,14 @@
+         SSLSocket sslSocket = (SSLSocket)
+             sslsf.createSocket("localhost", serverPort);
+ 
++        if (clientProtocol != null) {
++            sslSocket.setEnabledProtocols(new String[] {clientProtocol});
++        }
++
++        if (clientCiperSuite != null) {
++            sslSocket.setEnabledCipherSuites(new String[] {clientCiperSuite});
++        }
++
+         InputStream sslIS = sslSocket.getInputStream();
+         OutputStream sslOS = sslSocket.getOutputStream();
+ 
+@@ -176,7 +184,22 @@
+     volatile Exception serverException = null;
+     volatile Exception clientException = null;
+ 
++    private static String clientProtocol = null;
++    private static String clientCiperSuite = null;
++
++    private static void parseArguments(String[] args) {
++        if (args.length > 0) {
++            clientProtocol = args[0];
++        }
++
++        if (args.length > 1) {
++            clientCiperSuite = args[1];
++        }
++    }
++
+     public static void main(String[] args) throws Exception {
++        // Get the customized arguments.
++        parseArguments(args);
+         main(new ClientAuth());
+     }
+ 
+diff -Nru openjdk.orig/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.sh openjdk/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.sh
+--- openjdk.orig/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.sh	2014-07-14 04:24:44.000000000 +0100
++++ openjdk/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.sh	2014-10-08 23:56:02.324447997 +0100
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2003, 2006, 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
+@@ -22,8 +22,9 @@
+ #
+ 
+ # @test
+-# @bug 4938185
++# @bug 4938185 7106773
+ # @summary KeyStore support for NSS cert/key databases
++#          512 bits RSA key cannot work with SHA384 and SHA512
+ #
+ # @run shell ClientAuth.sh
+ 
+@@ -126,6 +127,7 @@
+ 	${TESTSRC}${FS}ClientAuth.java
+ 
+ # run test
++echo "Run ClientAuth ..."
+ ${TESTJAVA}${FS}bin${FS}java \
+ 	-classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \
+ 	-DDIR=${TESTSRC}${FS}ClientAuthData${FS} \
+@@ -139,6 +141,27 @@
+ 
+ # save error status
+ status=$?
++
++# return if failed
++if [ "${status}" != "0" ] ; then
++    exit $status
++fi
++
++# run test with specified TLS protocol and cipher suite
++echo "Run ClientAuth TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
++${TESTJAVA}${FS}bin${FS}java \
++	-classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \
++	-DDIR=${TESTSRC}${FS}ClientAuthData${FS} \
++	-DCUSTOM_DB_DIR=${TESTCLASSES} \
++	-DCUSTOM_P11_CONFIG=${TESTSRC}${FS}ClientAuthData${FS}p11-nss.txt \
++	-DNO_DEFAULT=true \
++	-DNO_DEIMOS=true \
++	-Dtest.src=${TESTSRC} \
++	-Dtest.classes=${TESTCLASSES} \
++	ClientAuth TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
++
++# save error status
++status=$?
+ 
+ # return
+ exit $status
+diff -Nru openjdk.orig/jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java openjdk/jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java
+--- openjdk.orig/jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java	2014-10-08 23:56:03.904469889 +0100
+@@ -0,0 +1,414 @@
++/*
++ * 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.
++ */
++
++/*
++ * @test
++ * @bug 7106773
++ * @summary 512 bits RSA key cannot work with SHA384 and SHA512
++ *
++ *     SunJSSE does not support dynamic system properties, no way to re-use
++ *     system properties in samevm/agentvm mode.
++ * @run main/othervm ShortRSAKey512 PKIX
++ * @run main/othervm ShortRSAKey512 SunX509
++ */
++
++import java.net.*;
++import java.util.*;
++import java.io.*;
++import javax.net.ssl.*;
++import java.security.KeyStore;
++import java.security.KeyFactory;
++import java.security.cert.Certificate;
++import java.security.cert.CertificateFactory;
++import java.security.spec.*;
++import java.security.interfaces.*;
++import sun.misc.BASE64Decoder;
++
++
++public class ShortRSAKey512 {
++
++    /*
++     * =============================================================
++     * Set the various variables needed for the tests, then
++     * specify what tests to run on each side.
++     */
++
++    /*
++     * Should we run the client or server in a separate thread?
++     * Both sides can throw exceptions, but do you have a preference
++     * as to which side should be the main thread.
++     */
++    static boolean separateServerThread = false;
++
++    /*
++     * Where do we find the keystores?
++     */
++    // Certificates and key used in the test.
++    static String trustedCertStr =
++        "-----BEGIN CERTIFICATE-----\n" +
++        "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
++        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
++        "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
++        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
++        "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" +
++        "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" +
++        "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" +
++        "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" +
++        "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" +
++        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
++        "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" +
++        "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" +
++        "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" +
++        "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" +
++        "-----END CERTIFICATE-----";
++
++    static String targetCertStr =
++        "-----BEGIN CERTIFICATE-----\n" +
++        "MIICNDCCAZ2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
++        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
++        "MTExMTA3MTM1NTUyWhcNMzEwNzI1MTM1NTUyWjBPMQswCQYDVQQGEwJVUzENMAsG\n" +
++        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" +
++        "BAMTCWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3Pb49OSPfOD2G\n" +
++        "HSXFCFx1GJEZfqG9ZUf7xuIi/ra5dLjPGAaoY5QF2QOa8VnOriQCXDfyXHxsuRnE\n" +
++        "OomxL7EVAgMBAAGjeDB2MAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUXNCJK3/dtCIc\n" +
++        "xb+zlA/JINlvs/MwHwYDVR0jBBgwFoAUuXzV2d+nTAOu/Q4nWzGVbMfzdeEwJwYD\n" +
++        "VR0lBCAwHgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAzANBgkqhkiG9w0B\n" +
++        "AQQFAAOBgQB2qIDUxA2caMPpGtUACZAPRUtrGssCINIfItETXJZCx/cRuZ5sP4D9\n" +
++        "N1acoNDn0hCULe3lhXAeTC9NZ97680yJzregQMV5wATjo1FGsKY30Ma+sc/nfzQW\n" +
++        "+h/7RhYtoG0OTsiaDCvyhI6swkNJzSzrAccPY4+ZgU8HiDLzZTmM3Q==\n" +
++        "-----END CERTIFICATE-----";
++
++    // Private key in the format of PKCS#8, key size is 512 bits.
++    static String targetPrivateKey =
++        "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtz2+PTkj3zg9hh0l\n" +
++        "xQhcdRiRGX6hvWVH+8biIv62uXS4zxgGqGOUBdkDmvFZzq4kAlw38lx8bLkZxDqJ\n" +
++        "sS+xFQIDAQABAkByx/5Oo2hQ/w2q4L8z+NTRlJ3vdl8iIDtC/4XPnfYfnGptnpG6\n" +
++        "ZThQRvbMZiai0xHQPQMszvAHjZVme1eDl3EBAiEA3aKJHynPVCEJhpfCLWuMwX5J\n" +
++        "1LntwJO7NTOyU5m8rPECIQDTpzn5X44r2rzWBDna/Sx7HW9IWCxNgUD2Eyi2nA7W\n" +
++        "ZQIgJerEorw4aCAuzQPxiGu57PB6GRamAihEAtoRTBQlH0ECIQDN08FgTtnesgCU\n" +
++        "DFYLLcw1CiHvc7fZw4neBDHCrC8NtQIgA8TOUkGnpCZlQ0KaI8KfKWI+vxFcgFnH\n" +
++        "3fnqsTgaUs4=";
++
++    static char passphrase[] = "passphrase".toCharArray();
++
++    /*
++     * Is the server ready to serve?
++     */
++    volatile static boolean serverReady = false;
++
++    /*
++     * Turn on SSL debugging?
++     */
++    static boolean debug = false;
++
++    /*
++     * Define the server side of the test.
++     *
++     * If the server prematurely exits, serverReady will be set to true
++     * to avoid infinite hangs.
++     */
++    void doServerSide() throws Exception {
++        SSLContext context = generateSSLContext(null, targetCertStr,
++                                            targetPrivateKey);
++        SSLServerSocketFactory sslssf = context.getServerSocketFactory();
++        SSLServerSocket sslServerSocket =
++            (SSLServerSocket)sslssf.createServerSocket(serverPort);
++        serverPort = sslServerSocket.getLocalPort();
++
++        /*
++         * Signal Client, we're ready for his connect.
++         */
++        serverReady = true;
++
++        SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();
++        InputStream sslIS = sslSocket.getInputStream();
++        OutputStream sslOS = sslSocket.getOutputStream();
++
++        sslIS.read();
++        sslOS.write('A');
++        sslOS.flush();
++
++        sslSocket.close();
++    }
++
++    /*
++     * Define the client side of the test.
++     *
++     * If the server prematurely exits, serverReady will be set to true
++     * to avoid infinite hangs.
++     */
++    void doClientSide() throws Exception {
++
++        /*
++         * Wait for server to get started.
++         */
++        while (!serverReady) {
++            Thread.sleep(50);
++        }
++
++        SSLContext context = generateSSLContext(trustedCertStr, null, null);
++        SSLSocketFactory sslsf = context.getSocketFactory();
++
++        SSLSocket sslSocket =
++            (SSLSocket)sslsf.createSocket("localhost", serverPort);
++
++        // enable TLSv1.2 only
++        sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
++
++        // enable a block cipher
++        sslSocket.setEnabledCipherSuites(
++            new String[] {"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"});
++
++        InputStream sslIS = sslSocket.getInputStream();
++        OutputStream sslOS = sslSocket.getOutputStream();
++
++        sslOS.write('B');
++        sslOS.flush();
++        sslIS.read();
++
++        sslSocket.close();
++    }
++
++    /*
++     * =============================================================
++     * The remainder is just support stuff
++     */
++    private static String tmAlgorithm;        // trust manager
++
++    private static void parseArguments(String[] args) {
++        tmAlgorithm = args[0];
++    }
++
++    private static SSLContext generateSSLContext(String trustedCertStr,
++            String keyCertStr, String keySpecStr) throws Exception {
++
++        // generate certificate from cert string
++        CertificateFactory cf = CertificateFactory.getInstance("X.509");
++
++        // create a key store
++        KeyStore ks = KeyStore.getInstance("JKS");
++        ks.load(null, null);
++
++        // import the trused cert
++        Certificate trusedCert = null;
++        ByteArrayInputStream is = null;
++        if (trustedCertStr != null) {
++            is = new ByteArrayInputStream(trustedCertStr.getBytes());
++            trusedCert = cf.generateCertificate(is);
++            is.close();
++
++            ks.setCertificateEntry("RSA Export Signer", trusedCert);
++        }
++
++        if (keyCertStr != null) {
++            // generate the private key.
++            PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
++                                new BASE64Decoder().decodeBuffer(keySpecStr));
++            KeyFactory kf = KeyFactory.getInstance("RSA");
++            RSAPrivateKey priKey =
++                    (RSAPrivateKey)kf.generatePrivate(priKeySpec);
++
++            // generate certificate chain
++            is = new ByteArrayInputStream(keyCertStr.getBytes());
++            Certificate keyCert = cf.generateCertificate(is);
++            is.close();
++
++            Certificate[] chain = null;
++            if (trusedCert != null) {
++                chain = new Certificate[2];
++                chain[0] = keyCert;
++                chain[1] = trusedCert;
++            } else {
++                chain = new Certificate[1];
++                chain[0] = keyCert;
++            }
++
++            // import the key entry.
++            ks.setKeyEntry("Whatever", priKey, passphrase, chain);
++        }
++
++        // create SSL context
++        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
++        tmf.init(ks);
++
++        SSLContext ctx = SSLContext.getInstance("TLS");
++        if (keyCertStr != null && !keyCertStr.isEmpty()) {
++            KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
++            kmf.init(ks, passphrase);
++
++            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
++            ks = null;
++        } else {
++            ctx.init(null, tmf.getTrustManagers(), null);
++        }
++
++        return ctx;
++    }
++
++
++    // use any free port by default
++    volatile int serverPort = 0;
++
++    volatile Exception serverException = null;
++    volatile Exception clientException = null;
++
++    public static void main(String[] args) throws Exception {
++        if (debug)
++            System.setProperty("javax.net.debug", "all");
++
++        /*
++         * Get the customized arguments.
++         */
++        parseArguments(args);
++
++        /*
++         * Start the tests.
++         */
++        new ShortRSAKey512();
++    }
++
++    Thread clientThread = null;
++    Thread serverThread = null;
++
++    /*
++     * Primary constructor, used to drive remainder of the test.
++     *
++     * Fork off the other side, then do your work.
++     */
++    ShortRSAKey512() throws Exception {
++        try {
++            if (separateServerThread) {
++                startServer(true);
++                startClient(false);
++            } else {
++                startClient(true);
++                startServer(false);
++            }
++        } catch (Exception e) {
++            // swallow for now.  Show later
++        }
++
++        /*
++         * Wait for other side to close down.
++         */
++        if (separateServerThread) {
++            serverThread.join();
++        } else {
++            clientThread.join();
++        }
++
++        /*
++         * When we get here, the test is pretty much over.
++         * Which side threw the error?
++         */
++        Exception local;
++        Exception remote;
++        String whichRemote;
++
++        if (separateServerThread) {
++            remote = serverException;
++            local = clientException;
++            whichRemote = "server";
++        } else {
++            remote = clientException;
++            local = serverException;
++            whichRemote = "client";
++        }
++
++        /*
++         * If both failed, return the curthread's exception, but also
++         * print the remote side Exception
++         */
++        if ((local != null) && (remote != null)) {
++            System.out.println(whichRemote + " also threw:");
++            remote.printStackTrace();
++            System.out.println();
++            throw local;
++        }
++
++        if (remote != null) {
++            throw remote;
++        }
++
++        if (local != null) {
++            throw local;
++        }
++    }
++
++    void startServer(boolean newThread) throws Exception {
++        if (newThread) {
++            serverThread = new Thread() {
++                public void run() {
++                    try {
++                        doServerSide();
++                    } catch (Exception e) {
++                        /*
++                         * Our server thread just died.
++                         *
++                         * Release the client, if not active already...
++                         */
++                        System.err.println("Server died...");
++                        serverReady = true;
++                        serverException = e;
++                    }
++                }
++            };
++            serverThread.start();
++        } else {
++            try {
++                doServerSide();
++            } catch (Exception e) {
++                serverException = e;
++            } finally {
++                serverReady = true;
++            }
++        }
++    }
++
++    void startClient(boolean newThread) throws Exception {
++        if (newThread) {
++            clientThread = new Thread() {
++                public void run() {
++                    try {
++                        doClientSide();
++                    } catch (Exception e) {
++                        /*
++                         * Our client thread just died.
++                         */
++                        System.err.println("Client died...");
++                        clientException = e;
++                    }
++                }
++            };
++            clientThread.start();
++        } else {
++            try {
++                doClientSide();
++            } catch (Exception e) {
++                clientException = e;
++            }
++        }
++    }
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/7180907-jarsigner_sha-256.patch	Thu Oct 09 02:25:23 2014 +0100
@@ -0,0 +1,142 @@
+# HG changeset patch
+# User weijun
+# Date 1412803649 -3600
+#      Wed Oct 08 22:27:29 2014 +0100
+# Node ID ef55e24d58e0ccf31cced3ec5718c7de7ae160ae
+# Parent  869b3b5d079f0c828b56ac3261491d29ed4eae86
+7180907: Jarsigner -verify fails if rsa file used sha-256 with authenticated attributes
+Reviewed-by: xuelei, vinnie
+
+diff -r 869b3b5d079f -r ef55e24d58e0 src/share/classes/sun/security/pkcs/SignerInfo.java
+--- openjdk/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java	Wed Oct 08 22:20:38 2014 +0100
++++ openjdk/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java	Wed Oct 08 22:27:29 2014 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2006, 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
+@@ -273,6 +273,24 @@
+         return certList;
+     }
+ 
++    // Copied from com.sun.crypto.provider.OAEPParameters.
++    private static String convertToStandardName(String internalName) {
++        if (internalName.equals("SHA")) {
++            return "SHA-1";
++        } else if (internalName.equals("SHA224")) {
++            return "SHA-224";
++        } else if (internalName.equals("SHA256")) {
++            return "SHA-256";
++        } else if (internalName.equals("SHA384")) {
++            return "SHA-384";
++        } else if (internalName.equals("SHA512")) {
++            return "SHA-512";
++        } else {
++            return internalName;
++        }
++    }
++
++
+     /* Returns null if verify fails, this signerInfo if
+        verify succeeds. */
+     SignerInfo verify(PKCS7 block, byte[] data)
+@@ -313,7 +331,8 @@
+                 if (messageDigest == null) // fail if there is no message digest
+                     return null;
+ 
+-                MessageDigest md = MessageDigest.getInstance(digestAlgname);
++                MessageDigest md = MessageDigest.getInstance(
++                        convertToStandardName(digestAlgname));
+                 byte[] computedMessageDigest = md.digest(data);
+ 
+                 if (messageDigest.length != computedMessageDigest.length)
+diff -r 869b3b5d079f -r ef55e24d58e0 test/sun/security/x509/AlgorithmId/NonStandardNames.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/test/sun/security/x509/AlgorithmId/NonStandardNames.java	Wed Oct 08 22:27:29 2014 +0100
+@@ -0,0 +1,84 @@
++/*
++ * 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.
++ *
++ * 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 7180907
++ * @summary Jarsigner -verify fails if rsa file used sha-256 with authenticated attributes
++ */
++
++import java.security.MessageDigest;
++import java.security.Signature;
++import java.security.cert.X509Certificate;
++import sun.security.pkcs.ContentInfo;
++import sun.security.pkcs.PKCS7;
++import sun.security.pkcs.PKCS9Attribute;
++import sun.security.pkcs.PKCS9Attributes;
++import sun.security.pkcs.SignerInfo;
++import sun.security.x509.CertAndKeyGen;
++import sun.security.x509.AlgorithmId;
++import sun.security.x509.X500Name;
++
++public class NonStandardNames {
++
++    public static void main(String[] args) throws Exception {
++
++        byte[] data = "Hello".getBytes();
++        X500Name n = new X500Name("cn=Me");
++
++        CertAndKeyGen cakg = new CertAndKeyGen("RSA", "SHA256withRSA");
++        cakg.generate(1024);
++        X509Certificate cert = cakg.getSelfCertificate(n, 1000);
++
++        MessageDigest md = MessageDigest.getInstance("SHA-256");
++        PKCS9Attributes authed = new PKCS9Attributes(new PKCS9Attribute[]{
++            new PKCS9Attribute(PKCS9Attribute.CONTENT_TYPE_OID, ContentInfo.DATA_OID),
++            new PKCS9Attribute(PKCS9Attribute.MESSAGE_DIGEST_OID, md.digest(data)),
++        });
++
++        Signature s = Signature.getInstance("SHA256withRSA");
++        s.initSign(cakg.getPrivateKey());
++        s.update(authed.getDerEncoding());
++        byte[] sig = s.sign();
++
++        SignerInfo signerInfo = new SignerInfo(
++                n,
++                cert.getSerialNumber(),
++                AlgorithmId.get("SHA-256"),
++                authed,
++                AlgorithmId.get("SHA256withRSA"),
++                sig,
++                null
++                );
++
++        PKCS7 pkcs7 = new PKCS7(
++                new AlgorithmId[] {signerInfo.getDigestAlgorithmId()},
++                new ContentInfo(data),
++                new X509Certificate[] {cert},
++                new SignerInfo[] {signerInfo});
++
++        if (pkcs7.verify(signerInfo, data) == null) {
++            throw new Exception("Not verified");
++        }
++    }
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/8006935-long_keys_in_hmac_prf.patch	Thu Oct 09 02:25:23 2014 +0100
@@ -0,0 +1,41 @@
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java openjdk/jdk/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java	2014-07-14 04:24:43.000000000 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java	2014-10-08 23:47:13.825128435 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 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
+@@ -181,13 +181,28 @@
+         int off = secret.length >> 1;
+         int seclen = off + (secret.length & 1);
+ 
++        byte[] secKey = secret;
++        int keyLen = seclen;
+         byte[] output = new byte[outputLength];
+ 
+         // P_MD5(S1, label + seed)
+-        expand(md5, 16, secret, 0, seclen, labelBytes, seed, output);
++        // If we have a long secret, digest it first.
++        if (seclen > 64) {              // 64: block size of HMAC-MD5
++            md5.update(secret, 0, seclen);
++            secKey = md5.digest();
++            keyLen = secKey.length;
++        }
++        expand(md5, 16, secKey, 0, keyLen, labelBytes, seed, output);
+ 
+         // P_SHA-1(S2, label + seed)
+-        expand(sha, 20, secret, off, seclen, labelBytes, seed, output);
++        // If we have a long secret, digest it first.
++        if (seclen > 64) {              // 64: block size of HMAC-SHA1
++            sha.update(secret, off, seclen);
++            secKey = sha.digest();
++            keyLen = secKey.length;
++            off = 0;
++        }
++	expand(sha, 20, secKey, off, keyLen, labelBytes, seed, output);
+ 
+         return output;
+     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/8049480-jarsigner_openjdk_9.patch	Thu Oct 09 02:25:23 2014 +0100
@@ -0,0 +1,295 @@
+# HG changeset patch
+# User weijun
+# Date 1412804569 -3600
+#      Wed Oct 08 22:42:49 2014 +0100
+# Node ID 2adb6892881f4e3b359026854562b2ac70c63bef
+# Parent  ef55e24d58e0ccf31cced3ec5718c7de7ae160ae
+8049480: Current versions of Java can't verify jars signed and timestamped with Java 9
+Reviewed-by: xuelei, mullan
+
+diff -r ef55e24d58e0 -r 2adb6892881f src/share/classes/com/sun/crypto/provider/OAEPParameters.java
+--- openjdk/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java	Wed Oct 08 22:27:29 2014 +0100
++++ openjdk/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java	Wed Oct 08 22:42:49 2014 +0100
+@@ -106,20 +106,6 @@
+         }
+     }
+ 
+-    private static String convertToStandardName(String internalName) {
+-        if (internalName.equals("SHA")) {
+-            return "SHA-1";
+-        } else if (internalName.equals("SHA256")) {
+-            return "SHA-256";
+-        } else if (internalName.equals("SHA384")) {
+-            return "SHA-384";
+-        } else if (internalName.equals("SHA512")) {
+-            return "SHA-512";
+-        } else {
+-            return internalName;
+-        }
+-    }
+-
+     protected void engineInit(byte[] encoded)
+         throws IOException {
+         DerInputStream der = new DerInputStream(encoded);
+@@ -131,7 +117,7 @@
+             DerValue data = datum[i];
+             if (data.isContextSpecific((byte) 0x00)) {
+                 // hash algid
+-                mdName = convertToStandardName(AlgorithmId.parse
++                mdName = AlgorithmId.getStandardDigestName(AlgorithmId.parse
+                     (data.data.getDerValue()).getName());
+             } else if (data.isContextSpecific((byte) 0x01)) {
+                 // mgf algid
+@@ -140,7 +126,8 @@
+                     throw new IOException("Only MGF1 mgf is supported");
+                 }
+                 AlgorithmId params = AlgorithmId.parse(new DerValue(val.getEncodedParams()));
+-                String mgfDigestName = convertToStandardName(params.getName());
++                String mgfDigestName = AlgorithmId.getStandardDigestName(
++                        params.getName());
+                 if (mgfDigestName.equals("SHA-1")) {
+                     mgfSpec = MGF1ParameterSpec.SHA1;
+                 } else if (mgfDigestName.equals("SHA-224")) {
+diff -r ef55e24d58e0 -r 2adb6892881f src/share/classes/sun/security/pkcs/SignerInfo.java
+--- openjdk/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java	Wed Oct 08 22:27:29 2014 +0100
++++ openjdk/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java	Wed Oct 08 22:42:49 2014 +0100
+@@ -273,24 +273,6 @@
+         return certList;
+     }
+ 
+-    // Copied from com.sun.crypto.provider.OAEPParameters.
+-    private static String convertToStandardName(String internalName) {
+-        if (internalName.equals("SHA")) {
+-            return "SHA-1";
+-        } else if (internalName.equals("SHA224")) {
+-            return "SHA-224";
+-        } else if (internalName.equals("SHA256")) {
+-            return "SHA-256";
+-        } else if (internalName.equals("SHA384")) {
+-            return "SHA-384";
+-        } else if (internalName.equals("SHA512")) {
+-            return "SHA-512";
+-        } else {
+-            return internalName;
+-        }
+-    }
+-
+-
+     /* Returns null if verify fails, this signerInfo if
+        verify succeeds. */
+     SignerInfo verify(PKCS7 block, byte[] data)
+@@ -332,7 +314,7 @@
+                     return null;
+ 
+                 MessageDigest md = MessageDigest.getInstance(
+-                        convertToStandardName(digestAlgname));
++                        AlgorithmId.getStandardDigestName(digestAlgname));
+                 byte[] computedMessageDigest = md.digest(data);
+ 
+                 if (messageDigest.length != computedMessageDigest.length)
+diff -r ef55e24d58e0 -r 2adb6892881f src/share/classes/sun/security/util/SignatureFileVerifier.java
+--- openjdk/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java	Wed Oct 08 22:27:29 2014 +0100
++++ openjdk/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java	Wed Oct 08 22:42:49 2014 +0100
+@@ -41,6 +41,7 @@
+ import sun.misc.BASE64Decoder;
+ 
+ import sun.security.jca.Providers;
++import sun.security.x509.AlgorithmId;
+ 
+ public class SignatureFileVerifier {
+ 
+@@ -611,7 +612,8 @@
+         throws NoSuchAlgorithmException, SignatureException {
+ 
+         MessageDigest md =
+-            MessageDigest.getInstance(token.getHashAlgorithm().getName());
++            MessageDigest.getInstance(AlgorithmId.getStandardDigestName(
++                    token.getHashAlgorithm().getName()));
+ 
+         if (!Arrays.equals(token.getHashedMessage(), md.digest(signature))) {
+             throw new SignatureException("Signature timestamp (#" +
+diff -r ef55e24d58e0 -r 2adb6892881f src/share/classes/sun/security/x509/AlgorithmId.java
+--- openjdk/jdk/src/share/classes/sun/security/x509/AlgorithmId.java	Wed Oct 08 22:27:29 2014 +0100
++++ openjdk/jdk/src/share/classes/sun/security/x509/AlgorithmId.java	Wed Oct 08 22:42:49 2014 +0100
+@@ -891,4 +891,21 @@
+         nameTable.put(pbeWithSHA1AndDESede_oid, "PBEWithSHA1AndDESede");
+         nameTable.put(pbeWithSHA1AndRC2_40_oid, "PBEWithSHA1AndRC2_40");
+     }
++
++    // Copied from com.sun.crypto.provider.OAEPParameters.convertToStandardName()
++    public static String getStandardDigestName(String internalName) {
++        if (internalName.equals("SHA")) {
++            return "SHA-1";
++        } else if (internalName.equals("SHA224")) {
++            return "SHA-224";
++        } else if (internalName.equals("SHA256")) {
++            return "SHA-256";
++        } else if (internalName.equals("SHA384")) {
++            return "SHA-384";
++        } else if (internalName.equals("SHA512")) {
++            return "SHA-512";
++        } else {
++            return internalName;
++        }
++    }
+ }
+diff -r ef55e24d58e0 -r 2adb6892881f test/sun/security/tools/jarsigner/TimestampAlg.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/test/sun/security/tools/jarsigner/TimestampAlg.java	Wed Oct 08 22:42:49 2014 +0100
+@@ -0,0 +1,156 @@
++/*
++ * 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.
++ */
++
++/**
++ * @test
++ * @bug 8049480
++ * @summary Current versions of Java can't verify jars signed and timestamped with Java 9
++ */
++
++import java.io.InputStream;
++import java.nio.file.Files;
++import java.nio.file.Paths;
++import java.util.jar.JarEntry;
++import java.util.jar.JarFile;
++
++public class TimestampAlg {
++
++    public static void main(String[] args) throws Exception {
++        // This is a very simple jar file signed by JDK 9 with a timestamp
++        // using the SHA-256 message digest algorithm.
++        String var =
++            "504b0304140008080800c28ee844000000000000000000000000140000004d45" +
++            "54412d494e462f4d414e49464553542e4d4615cd4d0b82301c80f1fb60df61c7" +
++            "42666a9928749846f4aa8924745cf9d716b6c59c48df3ebd3e87df73e152d4d0" +
++            "195a82ee849211716d07a344033750d1f83785d076e830b8be1fb80e15d28096" +
++            "bca535ef4c058fbe21b34cf3670b2451faab3437a333c708a3947f20220ca362" +
++            "cfa8e7afe95634e32b22af821df2d6786d5ff637cf3abfe3f05e4190a42779b5" +
++            "76470532cbd56a798105db4cd01f504b07082c3740c69c000000a6000000504b" +
++            "0304140008080800c28ee8440000000000000000000000000f0000004d455441" +
++            "2d494e462f4f4c442e534675cf416f823018c6f13b09dfa1c7ed50575014493c" +
++            "80bae8a6a091383db6f082955a595b86ecd34fb3db92dd9ed32fff67c74b494d" +
++            "a300ef41697e9501727ac4b6768b10bbde10cf7809dae03595bcf81d5ce2d018" +
++            "c5596340072872bdecd02554f17c70f16fc730cfb4a8c6b0ad934fdfb6d0e854" +
++            "fbb794ecd52eeecbe5e45f394071bd9ef30c34131f87a3e956c561efb0938e56" +
++            "b7573d5c6cd3599bbe2ddd28acfafe9d992aa006721c758fe2718fe0b6753c6f" +
++            "e410cca50125a9c005d52607d694e82951341380a657555f1535f7a3cfb6655b" +
++            "31bd4080c2bf55016a98a8f2512948f7e5968dfbbe495fcca6383bdfe753a467" +
++            "90ca41a297861544cd270fe807504b0708521a35550201000048010000504b03" +
++            "04140008080800c28ee844000000000000000000000000100000004d4554412d" +
++            "494e462f4f4c442e52534185947b38d37d1fc7fdb61923530eb39e688622a77e" +
++            "5b666ab9939c9544c831ee39d42c9511e576d8c8b9876745b5743b5414268718" +
++            "b969548e95d61c2224b47423a648393d73dd5d4fe5b9afe7f9f3f3b9deefeff5" +
++            "bd3e9ff7e7053210ba708476bc55fc6719400292c340a8800cc4460800e06441" +
++            "1938c23bde0af083c22080b81828fd5d08e430200f4006a41664003772a01000" +
++            "028145a66e3cba6af9a601a44516246e1d2805873ac1a0f2d093545f70b3920c" +
++            "ce00248246e04ec20e02e8262a09200e6ff0adfc2f3d0350fbf149d12fa00c40" +
++            "564cd497823000406cb4ef6571fdec06c95a370fde860e89425861e16e0b19a1" +
++            "4c6c4f52d6102dd3a6bf45e740d9a0bed342ee5e832885fa1a979dc7e6161253" +
++            "4c2cda0362e5ec02ae440e44e80c56bffc4ab4f349f3b1f6bddae8c2979fca4b" +
++            "5e7e46ac2fa529481dd8d750a26dcd7d74deb8dde7fc70c072465af0a1e359af" +
++            "4cf4b1aaa14fc4238cee096ca3133575d52179a7e7da8990f6ed5da71ca84c37" +
++            "2d3117c356b1ac2cdde3c8600ead44f8878b2f8f10831f4d5d590a28d95b316c" +
++            "cf456277a83533e12ea42a14c8fc05da6b2483b74ab7c4e70a2dd60f417d2f97" +
++            "3359bb233e3d6b5ab60202e7bd7b4fd7f228febd1f0403b0c62f4190b69264bf" +
++            "72426589ab516d00040a880137b0200654114d4d050943c11490e82d88b38ecd" +
++            "26a42c027cd749ffe67955e7d9357b81aece4e877d49ee62b8afeed7a755fa9e" +
++            "786d6edc5d7e5ae3603e5d6e39d0cbc74300c35eb354282842a183159763c67a" +
++            "35b0b1ac1929e7b8ad510da5aa454d5eb3034cf11d27f594326384873f7c8949" +
++            "1a7f4a3cfccb892faf873c621292bd597072cdcd732d1ee7490e611ec28c90f9" +
++            "81bbd71ef0e4b50c4e93869c9af8c9d3d154169bbf8dff7aa706ebac1f6d2589" +
++            "8078532a9867e31d7f576365bc0c6c132fb7719b58d88ebcf438715768aea361" +
++            "f7017f614acfaf465e6d794b84e317b2937d66a8f5cea13666d541cce02705a8" +
++            "cef2d6d2f69b96ac88fec9998228a7c1d96d09c315b29797ecda02250dc7383a" +
++            "6f2bf75b0f17d48c07afa48c640d3478dd3ad18963c0712003ae27ca3a885a9b" +
++            "bcef71fef1027e8e228c01885dede0446717674996f8f413f59a5c3f91a001c0" +
++            "b632f78891424ce58a58df39727a6cc492ea4c94d5f23f6ad1276561d6eb057f" +
++            "befab3e5baff5dec50224a891fb49c29ab6cd6cab3f7731d097fc3d65e949b33" +
++            "b7a578f0b379e47a98c0a91b5fb0ce685952a78afc5cfa0e373df4a035c15132" +
++            "bb62a6387ad8caaadab680b8a169805e49b69e5ad8409de9b7079b6def2af45a" +
++            "dada5e7cdee4b5359892d1803dfc765dd18849fd0bf44b64866ed654fc117ea6" +
++            "5e6b1922eff99b73f0c77257e994d307defc9a29cedd1ac7be68a626d6edf96e" +
++            "c692bdf22ee792369dd535a0dfa7d711396996f692895df223eaaa5f47414f45" +
++            "b2c3b39d65772575c5cf4a437319b00990011b834b7f1b0c623d048963c07a44" +
++            "4dfe4f60813d12b5b87f0b16ea0f6e0096e30973075d454238d411260ee2d6a8" +
++            "61aa68a6bb3119ab837aaa39abd612eab39f9da4665c977e0cff019201a19384" +
++            "d3222b5a160ffe07340620c10d220998e65d3431411e13916b4e44ae191143fa" +
++            "be91cb1605ff6d2db96470d220e2af3c40f6ed5d032ee2cfe022bafd240fa1fd" +
++            "5f6e3567dd9071543e381b57bdd80cb1575a376abcc947495167e61e6e32a1ae" +
++            "93d416c8bc197b6bda347e6bcc6553839ed0a78d7ac28d57f2f7f8cd857d14e4" +
++            "497caa1cd34e1829aa7574aa3984ad39934e765598bdf0356c31a8f5c4a316d6" +
++            "c6beedf3add584c5769a6901a7836d3b32e3a03c58c739a6969e0260a002f463" +
++            "2773e84174c7faa41086e0d5d0ceaefc4df5a443d4e8af8a462dd67181ce11be" +
++            "a6ef64ce907252a0d0e6f03ef467e6763c244c48574856017d294607d3f87d5b" +
++            "0eb9eba2c60dc6c70dddfb837914babf172574ef99a4bb1e361353de4d95c576" +
++            "c494e1e9bce62d4fd08ad5e731691d1895636525bb79d76b2f1ce07d1604aa95" +
++            "8d9dfc8b5b6ee01110b3ca2d75181a44c528300ede3c612715c04d7baf786a18" +
++            "87b5f95861180fa256055b006005b67aa0923a70405c5c022af903f0187b3458" +
++            "748cc0bdfeac15adcb7029a17883d0f5ef80573caa61574bb66747bc61aae3ca" +
++            "0c3fe8bcd223d54fd7f5a2270843f9559a99f76aff45d965ba91374fa05a706f" +
++            "479416999389d4e29eb74a1984a30face935fd2118a580a3cd5a6567c2e21e92" +
++            "bb358c54822aaa049a8f47712889ee4507ae4ffd150ba50f444f99701c49fa97" +
++            "72edc44e69cfcda9cffc9f75c49fdb6b28b9699a2567289979dfd42664626232" +
++            "75b682be2baf3856623e37bb47c15e3e8e084771e4f3e7b53265efbc48e616cd" +
++            "ed18c4a546de3f5bd793857c9c7a99615161b7cdcca53fa1d4c119a33bb150a4" +
++            "6e4996450724eed76ae3d2dbc02f147228353241beba27e585a3dd556b8e5c2e" +
++            "5f4a3328fd214663223ec27d4fb134873a85630026a204ee5e059ee29a807f3f" +
++            "82ffcd3b2437cc1bf95a6813dec5195b38cd227002c6f5f53dcd1212f7182038" +
++            "9877b7ddf1ff2c0c65993b9524d3b41eca82ded2b951471c871b741fddd9fdc7" +
++            "70a79bb91c3d91f3a9aa8f880ec22099418c65654a7e3a25c4d8925e98e1e390" +
++            "1437e8767c9debf521e5c93ad5026ab8e5ef9696983ba6d0335e17de6ba65747" +
++            "91a0fb6ecdf20bde55874082a7f19b4332ddbba24d4eb98a9b0e55e4294f37be" +
++            "edd62a3e3ebccf8ded49f3a029fa76becf3389a386d2d62faca4f85cbb643489" +
++            "2e2abfd66dbe727f4fe28d8f8d551e0f8f4c8eda346c66d1bc6fa7a68eabdfb7" +
++            "0d0a34e65910bba73413ad8680dfaa473753ae9e2fd032d8f6cc66d19c57e679" +
++            "7fcc33cce8df504b0708267c480f1b08000030090000504b0304140008080800" +
++            "b78ee844000000000000000000000000090004004d4554412d494e462ffeca00" +
++            "000300504b0708000000000200000000000000504b0304140008080800b78ee8" +
++            "440000000000000000000000000100000041f3cb2fc9c8cc4be70200504b0708" +
++            "3c0a34d30a00000008000000504b01021400140008080800c28ee8442c3740c6" +
++            "9c000000a60000001400000000000000000000000000000000004d4554412d49" +
++            "4e462f4d414e49464553542e4d46504b01021400140008080800c28ee844521a" +
++            "355502010000480100000f00000000000000000000000000de0000004d455441" +
++            "2d494e462f4f4c442e5346504b01021400140008080800c28ee844267c480f1b" +
++            "0800003009000010000000000000000000000000001d0200004d4554412d494e" +
++            "462f4f4c442e525341504b01021400140008080800b78ee84400000000020000" +
++            "00000000000900040000000000000000000000760a00004d4554412d494e462f" +
++            "feca0000504b01021400140008080800b78ee8443c0a34d30a00000008000000" +
++            "0100000000000000000000000000b30a000041504b0506000000000500050027" +
++            "010000ec0a00000000";
++        byte[] data = new byte[var.length()/2];
++        for (int i=0; i<data.length; i++) {
++            data[i] = Integer.valueOf(var.substring(2*i,2*i+2), 16).byteValue();
++        }
++        Files.write(Paths.get("x.jar"), data);
++
++        try (JarFile jf = new JarFile("x.jar")) {
++            JarEntry je = jf.getJarEntry("A");
++            try (InputStream is = jf.getInputStream(je)) {
++                is.read(new byte[10]);
++            }
++            if (je.getCertificates().length != 1) {
++                throw new Exception();
++            }
++        }
++    }
++}