Mercurial > hg > release > icedtea6-1.13
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(); ++ } ++ } ++ } ++}