8181048: Refactor existing providers to refer to the same constants for default values for key length
authorvaleriep
Thu, 13 Jul 2017 20:41:59 +0000
changeset 47421 f9e03aef3a49
parent 47420 a2bf68a0365f
child 47422 7a4b85711089
8181048: Refactor existing providers to refer to the same constants for default values for key length Reviewed-by: mullan, ahgross
src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java
src/java.base/share/classes/com/sun/crypto/provider/DHParameterGenerator.java
src/java.base/share/classes/sun/security/provider/DSAKeyPairGenerator.java
src/java.base/share/classes/sun/security/provider/DSAParameterGenerator.java
src/java.base/share/classes/sun/security/provider/SunEntries.java
src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java
src/java.base/share/classes/sun/security/tools/keytool/Main.java
src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java
src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java
src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyPairGenerator.java
src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java
test/jdk/java/security/Signature/Offsets.java
test/jdk/java/security/SignedObject/Chain.java
test/jdk/sun/security/provider/DSA/TestAlgParameterGenerator.java
test/jdk/sun/security/provider/DSA/TestKeyPairGenerator.java
test/jdk/sun/security/provider/DSA/TestLegacyDSAKeyPairGenerator.java
--- a/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	Thu Jul 13 20:41:59 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -33,6 +33,7 @@
 import javax.crypto.spec.DHGenParameterSpec;
 
 import sun.security.provider.ParameterCache;
+import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
 
 /**
  * This class represents the key pair generator for Diffie-Hellman key pairs.
@@ -42,8 +43,7 @@
  * <ul>
  * <li>By providing the size in bits of the prime modulus -
  * This will be used to create a prime modulus and base generator, which will
- * then be used to create the Diffie-Hellman key pair. The default size of the
- * prime modulus is 2048 bits.
+ * then be used to create the Diffie-Hellman key pair.
  * <li>By providing a prime modulus and base generator
  * </ul>
  *
@@ -68,7 +68,7 @@
 
     public DHKeyPairGenerator() {
         super();
-        initialize(2048, null);
+        initialize(DEF_DH_KEY_SIZE, null);
     }
 
     private static void checkKeySize(int keysize)
--- a/src/java.base/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	Thu Jul 13 20:41:59 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -31,6 +31,8 @@
 import javax.crypto.spec.DHParameterSpec;
 import javax.crypto.spec.DHGenParameterSpec;
 
+import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
+
 /*
  * This class generates parameters for the Diffie-Hellman algorithm.
  * The parameters are a prime, a base, and optionally the length in bits of
@@ -38,7 +40,6 @@
  *
  * <p>The Diffie-Hellman parameter generation accepts the size in bits of the
  * prime modulus and the size in bits of the random exponent as input.
- * The size of the prime modulus defaults to 2048 bits.
  *
  * @author Jan Luehe
  *
@@ -50,7 +51,7 @@
 public final class DHParameterGenerator extends AlgorithmParameterGeneratorSpi {
 
     // The size in bits of the prime modulus
-    private int primeSize = 2048;
+    private int primeSize = DEF_DH_KEY_SIZE;
 
     // The size in bits of the random exponent (private value)
     private int exponentSize = 0;
--- a/src/java.base/share/classes/sun/security/provider/DSAKeyPairGenerator.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/src/java.base/share/classes/sun/security/provider/DSAKeyPairGenerator.java	Thu Jul 13 20:41:59 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -35,6 +35,8 @@
 import java.security.spec.DSAParameterSpec;
 
 import sun.security.jca.JCAUtil;
+import static sun.security.util.SecurityProviderConstants.DEF_DSA_KEY_SIZE;
+import static sun.security.util.SecurityProviderConstants.getDefDSASubprimeSize;
 
 /**
  * This class generates DSA key parameters and public/private key
@@ -45,15 +47,14 @@
  * @author Andreas Sterbenz
  *
  */
-public class DSAKeyPairGenerator extends KeyPairGenerator
-        implements java.security.interfaces.DSAKeyPairGenerator {
+class DSAKeyPairGenerator extends KeyPairGenerator {
 
     /* 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;
+    boolean forceNewParameters;
 
     /* preset algorithm parameters. */
     private DSAParameterSpec params;
@@ -61,9 +62,9 @@
     /* The source of random bits to use */
     private SecureRandom random;
 
-    public DSAKeyPairGenerator() {
+    DSAKeyPairGenerator(int defaultKeySize) {
         super("DSA");
-        initialize(1024, null);
+        initialize(defaultKeySize, null);
     }
 
     private static void checkStrength(int sizeP, int sizeQ) {
@@ -84,61 +85,7 @@
     }
 
     public void initialize(int modlen, SecureRandom random) {
-        // generate new parameters when no precomputed ones available.
-        initialize(modlen, true, random);
-        this.forceNewParameters = false;
-    }
-
-    /**
-     * Initializes the DSA key pair generator. If <code>genParams</code>
-     * is false, a set of pre-computed parameters is used.
-     */
-    @Override
-    public void initialize(int modlen, boolean genParams, SecureRandom random)
-            throws InvalidParameterException {
-
-        int subPrimeLen = -1;
-        if (modlen <= 1024) {
-            subPrimeLen = 160;
-        } else if (modlen == 2048) {
-            subPrimeLen = 224;
-        } else if (modlen == 3072) {
-            subPrimeLen = 256;
-        }
-        checkStrength(modlen, subPrimeLen);
-        if (genParams) {
-            params = null;
-        } else {
-            params = ParameterCache.getCachedDSAParameterSpec(modlen,
-                subPrimeLen);
-            if (params == null) {
-                throw new InvalidParameterException
-                    ("No precomputed parameters for requested modulus size "
-                     + "available");
-            }
-
-        }
-        this.plen = modlen;
-        this.qlen = subPrimeLen;
-        this.random = random;
-        this.forceNewParameters = genParams;
-    }
-
-    /**
-     * Initializes the DSA object using a DSA parameter object.
-     *
-     * @param params a fully initialized DSA parameter object.
-     */
-    @Override
-    public void initialize(DSAParams params, SecureRandom random)
-            throws InvalidParameterException {
-
-        if (params == null) {
-            throw new InvalidParameterException("Params must not be null");
-        }
-        DSAParameterSpec spec = new DSAParameterSpec
-                                (params.getP(), params.getQ(), params.getG());
-        initialize0(spec, random);
+        init(modlen, random, false);
     }
 
     /**
@@ -157,10 +104,21 @@
             throw new InvalidAlgorithmParameterException
                 ("Inappropriate parameter");
         }
-        initialize0((DSAParameterSpec)params, random);
+        init((DSAParameterSpec)params, random, false);
     }
 
-    private void initialize0(DSAParameterSpec params, SecureRandom random) {
+    void init(int modlen, SecureRandom random, boolean forceNew) {
+        int subPrimeLen = getDefDSASubprimeSize(modlen);
+        checkStrength(modlen, subPrimeLen);
+        this.plen = modlen;
+        this.qlen = subPrimeLen;
+        this.params = null;
+        this.random = random;
+        this.forceNewParameters = forceNew;
+    }
+
+    void init(DSAParameterSpec params, SecureRandom random,
+        boolean forceNew) {
         int sizeP = params.getP().bitLength();
         int sizeQ = params.getQ().bitLength();
         checkStrength(sizeP, sizeQ);
@@ -168,7 +126,7 @@
         this.qlen = sizeQ;
         this.params = params;
         this.random = random;
-        this.forceNewParameters = false;
+        this.forceNewParameters = forceNew;
     }
 
     /**
@@ -197,7 +155,7 @@
         return generateKeyPair(spec.getP(), spec.getQ(), spec.getG(), random);
     }
 
-    public KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g,
+    private KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g,
                                    SecureRandom random) {
 
         BigInteger x = generateX(random, q);
@@ -252,4 +210,55 @@
         return y;
     }
 
+    public static final class Current extends DSAKeyPairGenerator {
+        public Current() {
+            super(DEF_DSA_KEY_SIZE);
+        }
+    }
+
+    public static final class Legacy extends DSAKeyPairGenerator
+        implements java.security.interfaces.DSAKeyPairGenerator {
+
+        public Legacy() {
+            super(1024);
+        }
+
+        /**
+         * Initializes the DSA key pair generator. If <code>genParams</code>
+         * is false, a set of pre-computed parameters is used.
+         */
+        @Override
+        public void initialize(int modlen, boolean genParams,
+            SecureRandom random) throws InvalidParameterException {
+            if (genParams) {
+                super.init(modlen, random, true);
+            } else {
+                DSAParameterSpec cachedParams =
+                    ParameterCache.getCachedDSAParameterSpec(modlen,
+                        getDefDSASubprimeSize(modlen));
+                if (cachedParams == null) {
+                    throw new InvalidParameterException
+                        ("No precomputed parameters for requested modulus" +
+                         " size available");
+                }
+                super.init(cachedParams, random, false);
+            }
+        }
+
+        /**
+         * Initializes the DSA object using a DSA parameter object.
+         *
+         * @param params a fully initialized DSA parameter object.
+         */
+        @Override
+        public void initialize(DSAParams params, SecureRandom random)
+            throws InvalidParameterException {
+            if (params == null) {
+                throw new InvalidParameterException("Params must not be null");
+             }
+             DSAParameterSpec spec = new DSAParameterSpec
+                 (params.getP(), params.getQ(), params.getG());
+             super.init(spec, random, false);
+        }
+    }
 }
--- a/src/java.base/share/classes/sun/security/provider/DSAParameterGenerator.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/src/java.base/share/classes/sun/security/provider/DSAParameterGenerator.java	Thu Jul 13 20:41:59 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -34,15 +34,18 @@
 import java.security.InvalidParameterException;
 import java.security.MessageDigest;
 import java.security.SecureRandom;
+import java.security.ProviderException;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.InvalidParameterSpecException;
 import java.security.spec.DSAParameterSpec;
 import java.security.spec.DSAGenParameterSpec;
 
+import static sun.security.util.SecurityProviderConstants.DEF_DSA_KEY_SIZE;
+import static sun.security.util.SecurityProviderConstants.getDefDSASubprimeSize;
+
+
 /**
- * This class generates parameters for the DSA algorithm. It uses a default
- * prime modulus size of 1024 bits, which can be overwritten during
- * initialization.
+ * This class generates parameters for the DSA algorithm.
  *
  * @author Jan Luehe
  *
@@ -56,10 +59,6 @@
 
 public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
 
-    // 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;
@@ -80,18 +79,14 @@
      */
     @Override
     protected void engineInit(int strength, SecureRandom random) {
-        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 {
+        if ((strength != 2048) && (strength != 3072) &&
+            ((strength < 512) || (strength > 1024) || (strength % 64 != 0))) {
             throw new InvalidParameterException(
-                "Unexpected strength (size of prime): " + strength + ". " +
-                "Prime size should be 512 - 1024, or 2048, 3072");
+                "Unexpected strength (size of prime): " + strength +
+                ". Prime size should be 512-1024, 2048, or 3072");
         }
         this.valueL = strength;
+        this.valueN = getDefDSASubprimeSize(strength);
         this.seedLen = valueN;
         this.random = random;
     }
@@ -110,7 +105,6 @@
     @Override
     protected void engineInit(AlgorithmParameterSpec genParamSpec,
             SecureRandom random) throws InvalidAlgorithmParameterException {
-
         if (!(genParamSpec instanceof DSAGenParameterSpec)) {
             throw new InvalidAlgorithmParameterException("Invalid parameter");
         }
@@ -136,11 +130,7 @@
                 this.random = new SecureRandom();
             }
             if (valueL == -1) {
-                try {
-                    engineInit(DEFAULTS, this.random);
-                } catch (InvalidAlgorithmParameterException iape) {
-                    // should never happen
-                }
+                engineInit(DEF_DSA_KEY_SIZE, this.random);
             }
             BigInteger[] pAndQ = generatePandQ(this.random, valueL,
                                                valueN, seedLen);
@@ -206,13 +196,17 @@
         int b = (valueL - 1) % outLen;
         byte[] seedBytes = new byte[seedLen/8];
         BigInteger twoSl = BigInteger.TWO.pow(seedLen);
-        int primeCertainty = 80; // for 1024-bit prime P
-        if (valueL == 2048) {
+        int primeCertainty = -1;
+        if (valueL <= 1024) {
+            primeCertainty = 80;
+        } else if (valueL == 2048) {
             primeCertainty = 112;
         } else if (valueL == 3072) {
             primeCertainty = 128;
         }
-
+        if (primeCertainty < 0) {
+            throw new ProviderException("Invalid valueL: " + valueL);
+        }
         BigInteger resultP, resultQ, seed = null;
         int counter;
         while (true) {
--- a/src/java.base/share/classes/sun/security/provider/SunEntries.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/src/java.base/share/classes/sun/security/provider/SunEntries.java	Thu Jul 13 20:41:59 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -29,6 +29,7 @@
 import java.net.*;
 import java.util.Map;
 import java.security.*;
+import sun.security.action.GetPropertyAction;
 
 /**
  * Defines the entries of the SUN provider.
@@ -74,6 +75,10 @@
 
 final class SunEntries {
 
+    private static final boolean useLegacyDSA =
+        Boolean.parseBoolean(GetPropertyAction.privilegedGetProperty
+            ("jdk.security.legacyDSAKeyPairGenerator"));
+
     private SunEntries() {
         // empty
     }
@@ -174,8 +179,9 @@
         /*
          *  Key Pair Generator engines
          */
-        map.put("KeyPairGenerator.DSA",
-            "sun.security.provider.DSAKeyPairGenerator");
+        String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$";
+        dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current");
+        map.put("KeyPairGenerator.DSA", dsaKPGImplClass);
         map.put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
         map.put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
         map.put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");
--- a/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java	Thu Jul 13 20:41:59 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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,6 +32,7 @@
 import java.security.spec.RSAKeyGenParameterSpec;
 
 import sun.security.jca.JCAUtil;
+import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
 
 /**
  * RSA keypair generation. Standard algorithm, minimum key length 512 bit.
@@ -55,7 +56,7 @@
 
     public RSAKeyPairGenerator() {
         // initialize to default in case the app does not call initialize()
-        initialize(2048, null);
+        initialize(DEF_RSA_KEY_SIZE, null);
     }
 
     // initialize the generator. See JCA doc
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Thu Jul 13 20:41:59 2017 +0000
@@ -74,6 +74,7 @@
 import sun.security.provider.X509Factory;
 import sun.security.provider.certpath.ssl.SSLServerCertStore;
 import sun.security.util.Password;
+import sun.security.util.SecurityProviderConstants;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.crypto.SecretKeyFactory;
@@ -1817,9 +1818,12 @@
     {
         if (keysize == -1) {
             if ("EC".equalsIgnoreCase(keyAlgName)) {
-                keysize = 256;
-            } else {
-                keysize = 2048;     // RSA and DSA
+                keysize = SecurityProviderConstants.DEF_EC_KEY_SIZE;
+            } else if ("RSA".equalsIgnoreCase(keyAlgName)) {
+                keysize = SecurityProviderConstants.DEF_RSA_KEY_SIZE;
+            } else if ("DSA".equalsIgnoreCase(keyAlgName)) {
+                // hardcode for now as DEF_DSA_KEY_SIZE is still 1024
+                keysize = 2048; // SecurityProviderConstants.DEF_DSA_KEY_SIZE;
             }
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java	Thu Jul 13 20:41:59 2017 +0000
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2017, 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.util.regex.PatternSyntaxException;
+import java.security.InvalidParameterException;
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Various constants such as version number, default key length, used by
+ * the JDK security/crypto providers.
+ */
+public final class SecurityProviderConstants {
+    private static final Debug debug =
+        Debug.getInstance("jca", "ProviderConfig");
+
+    // Cannot create one of these
+    private SecurityProviderConstants () {
+    }
+
+    public static final int getDefDSASubprimeSize(int primeSize) {
+        if (primeSize <= 1024) {
+            return 160;
+        } else if (primeSize == 2048) {
+            return 224;
+        } else if (primeSize == 3072) {
+            return 256;
+        } else {
+            throw new InvalidParameterException("Invalid DSA Prime Size: " +
+                primeSize);
+        }
+    }
+
+    public static final int DEF_DSA_KEY_SIZE;
+    public static final int DEF_RSA_KEY_SIZE;
+    public static final int DEF_DH_KEY_SIZE;
+    public static final int DEF_EC_KEY_SIZE;
+
+    private static final String KEY_LENGTH_PROP =
+        "jdk.security.defaultKeySize";
+    static {
+        String keyLengthStr = GetPropertyAction.privilegedGetProperty
+            (KEY_LENGTH_PROP);
+        int dsaKeySize = 1024;
+        int rsaKeySize = 2048;
+        int dhKeySize = 2048;
+        int ecKeySize = 256;
+
+        if (keyLengthStr != null) {
+            try {
+                String[] pairs = keyLengthStr.split(",");
+                for (String p : pairs) {
+                    String[] algoAndValue = p.split(":");
+                    if (algoAndValue.length != 2) {
+                        // invalid pair, skip to next pair
+                        if (debug != null) {
+                            debug.println("Ignoring invalid pair in " +
+                                KEY_LENGTH_PROP + " property: " + p);
+                        }
+                        continue;
+                    }
+                    String algoName = algoAndValue[0].trim().toUpperCase();
+                    int value = -1;
+                    try {
+                        value = Integer.parseInt(algoAndValue[1].trim());
+                    } catch (NumberFormatException nfe) {
+                        // invalid value, skip to next pair
+                        if (debug != null) {
+                            debug.println("Ignoring invalid value in " +
+                                KEY_LENGTH_PROP + " property: " + p);
+                        }
+                        continue;
+                    }
+                    if (algoName.equals("DSA")) {
+                        dsaKeySize = value;
+                    } else if (algoName.equals("RSA")) {
+                        rsaKeySize = value;
+                    } else if (algoName.equals("DH")) {
+                        dhKeySize = value;
+                    } else if (algoName.equals("EC")) {
+                        ecKeySize = value;
+                    } else {
+                        if (debug != null) {
+                            debug.println("Ignoring unsupported algo in " +
+                                KEY_LENGTH_PROP + " property: " + p);
+                        }
+                        continue;
+                    }
+                    if (debug != null) {
+                        debug.println("Overriding default " + algoName +
+                            " keysize with value from " +
+                            KEY_LENGTH_PROP + " property: " + value);
+                    }
+                }
+            } catch (PatternSyntaxException pse) {
+                // if property syntax is not followed correctly
+                if (debug != null) {
+                    debug.println("Unexpected exception while parsing " +
+                        KEY_LENGTH_PROP + " property: " + pse);
+                }
+            }
+        }
+        DEF_DSA_KEY_SIZE = dsaKeySize;
+        DEF_RSA_KEY_SIZE = rsaKeySize;
+        DEF_DH_KEY_SIZE = dhKeySize;
+        DEF_EC_KEY_SIZE = ecKeySize;
+    }
+}
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Thu Jul 13 20:41:59 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -33,11 +33,13 @@
 import javax.crypto.spec.DHParameterSpec;
 
 import sun.security.provider.ParameterCache;
+import static sun.security.util.SecurityProviderConstants.*;
 
 import static sun.security.pkcs11.TemplateManager.*;
 import sun.security.pkcs11.wrapper.*;
 import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
 
+
 import sun.security.rsa.RSAKeyFactory;
 
 /**
@@ -98,7 +100,7 @@
         // override lower limit to disallow unsecure keys being generated
         // override upper limit to deter DOS attack
         if (algorithm.equals("EC")) {
-            keySize = 256;
+            keySize = DEF_EC_KEY_SIZE;
             if ((minKeyLen == -1) || (minKeyLen < 112)) {
                 minKeyLen = 112;
             }
@@ -107,13 +109,11 @@
             }
         } else {
             if (algorithm.equals("DSA")) {
-                // keep default keysize at 1024 since larger keysizes may be
-                // incompatible with SHA1withDSA and SHA-2 Signature algs
-                // may not be supported by native pkcs11 implementations
-                keySize = 1024;
+                keySize = DEF_DSA_KEY_SIZE;
+            } else if (algorithm.equals("RSA")) {
+                keySize = DEF_RSA_KEY_SIZE;
             } else {
-                // RSA and DH
-                keySize = 2048;
+                keySize = DEF_DH_KEY_SIZE;
             }
             if ((minKeyLen == -1) || (minKeyLen < 512)) {
                 minKeyLen = 512;
--- a/src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyPairGenerator.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyPairGenerator.java	Thu Jul 13 20:41:59 2017 +0000
@@ -39,6 +39,7 @@
 import sun.security.jca.JCAUtil;
 import sun.security.util.ECParameters;
 import sun.security.util.ECUtil;
+import static sun.security.util.SecurityProviderConstants.DEF_EC_KEY_SIZE;
 
 /**
  * EC keypair generator.
@@ -50,7 +51,6 @@
 
     private static final int KEY_SIZE_MIN = 112; // min bits (see ecc_impl.h)
     private static final int KEY_SIZE_MAX = 571; // max bits (see ecc_impl.h)
-    private static final int KEY_SIZE_DEFAULT = 256;
 
     // used to seed the keypair generator
     private SecureRandom random;
@@ -66,7 +66,7 @@
      */
     public ECKeyPairGenerator() {
         // initialize to default in case the app does not call initialize()
-        initialize(KEY_SIZE_DEFAULT, null);
+        initialize(DEF_EC_KEY_SIZE, null);
     }
 
     // initialize the generator. See JCA doc
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java	Thu Jul 13 20:41:59 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -31,6 +31,7 @@
 import java.security.spec.RSAKeyGenParameterSpec;
 
 import sun.security.rsa.RSAKeyFactory;
+import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
 
 /**
  * RSA keypair generator.
@@ -45,14 +46,13 @@
     // Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
     static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
     static final int KEY_SIZE_MAX = 16384;
-    private static final int KEY_SIZE_DEFAULT = 2048;
 
     // size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
     private int keySize;
 
     public RSAKeyPairGenerator() {
         // initialize to default in case the app does not call initialize()
-        initialize(KEY_SIZE_DEFAULT, null);
+        initialize(DEF_RSA_KEY_SIZE, null);
     }
 
     // initialize the generator. See JCA doc
@@ -76,7 +76,7 @@
 
         int tmpSize;
         if (params == null) {
-            tmpSize = KEY_SIZE_DEFAULT;
+            tmpSize = DEF_RSA_KEY_SIZE;
         } else if (params instanceof RSAKeyGenParameterSpec) {
 
             if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {
--- a/test/jdk/java/security/Signature/Offsets.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/test/jdk/java/security/Signature/Offsets.java	Thu Jul 13 20:41:59 2017 +0000
@@ -34,7 +34,7 @@
 
 /*
  * @test
- * @bug 8050374
+ * @bug 8050374 8181048
  * @key randomness
  * @summary This test validates signature verification
  *          Signature.verify(byte[], int, int). The test uses RandomFactory to
@@ -106,18 +106,25 @@
         Signature signature = Signature.getInstance(algorithm, provider);
 
         String keyAlgo;
+        int keySize = 2048;
         if (algorithm.contains("RSA")) {
             keyAlgo = "RSA";
         } else if (algorithm.contains("ECDSA")) {
             keyAlgo = "EC";
+            keySize = 256;
         } else if (algorithm.contains("DSA")) {
             keyAlgo = "DSA";
+            if (algorithm.startsWith("SHAwith") ||
+                    algorithm.startsWith("SHA1with")) {
+                keySize = 1024;
+            }
         } else {
             throw new RuntimeException("Test doesn't support this signature "
                     + "algorithm: " + algorithm);
         }
 
         KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlgo, provider);
+        kpg.initialize(keySize);
         KeyPair kp = kpg.generateKeyPair();
         PublicKey pubkey = kp.getPublic();
         PrivateKey privkey = kp.getPrivate();
--- a/test/jdk/java/security/SignedObject/Chain.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/test/jdk/java/security/SignedObject/Chain.java	Thu Jul 13 20:41:59 2017 +0000
@@ -32,7 +32,7 @@
 
 /*
  * @test
- * @bug 8050374
+ * @bug 8050374 8181048
  * @summary Verify a chain of signed objects
  */
 public class Chain {
@@ -97,22 +97,28 @@
         final Provider provider;
         final KeyAlg keyAlg;
         final SigAlg sigAlg;
+        final int keySize;
 
-        Test(SigAlg sigAlg, KeyAlg keyAlg, Provider privider) {
-            this.provider = privider;
+        Test(SigAlg sigAlg, KeyAlg keyAlg, Provider provider) {
+            this(sigAlg, keyAlg, provider, -1);
+        }
+
+        Test(SigAlg sigAlg, KeyAlg keyAlg, Provider provider, int keySize) {
+            this.provider = provider;
             this.keyAlg = keyAlg;
             this.sigAlg = sigAlg;
+            this.keySize = keySize;
         }
     }
 
     private static final Test[] tests = {
-        new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Default),
+        new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Default, 1024),
         new Test(SigAlg.MD2withRSA, KeyAlg.RSA, Provider.Default),
         new Test(SigAlg.MD5withRSA, KeyAlg.RSA, Provider.Default),
         new Test(SigAlg.SHA1withRSA, KeyAlg.RSA, Provider.Default),
-        new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Sun),
-        new Test(SigAlg.SHA224withDSA, KeyAlg.DSA, Provider.Sun),
-        new Test(SigAlg.SHA256withDSA, KeyAlg.DSA, Provider.Sun),
+        new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Sun, 1024),
+        new Test(SigAlg.SHA224withDSA, KeyAlg.DSA, Provider.Sun, 2048),
+        new Test(SigAlg.SHA256withDSA, KeyAlg.DSA, Provider.Sun, 2048),
     };
 
     private static final String str = "to-be-signed";
@@ -148,6 +154,9 @@
                 kpg = KeyPairGenerator.getInstance(test.keyAlg.name);
             }
             for (int j=0; j < N; j++) {
+                if (test.keySize != -1) {
+                    kpg.initialize(test.keySize);
+                }
                 KeyPair kp = kpg.genKeyPair();
                 KeyPair anotherKp = kpg.genKeyPair();
                 privKeys[j] = kp.getPrivate();
--- a/test/jdk/sun/security/provider/DSA/TestAlgParameterGenerator.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/test/jdk/sun/security/provider/DSA/TestAlgParameterGenerator.java	Thu Jul 13 20:41:59 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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 7044060 8055351
+ * @bug 7044060 8055351 8181048
  * @summary verify that DSA parameter generation works
  * @run main/timeout=600 TestAlgParameterGenerator
  */
@@ -81,7 +81,6 @@
         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};
--- a/test/jdk/sun/security/provider/DSA/TestKeyPairGenerator.java	Wed Jul 12 10:55:40 2017 +0800
+++ b/test/jdk/sun/security/provider/DSA/TestKeyPairGenerator.java	Thu Jul 13 20:41:59 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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 4800108 8072452
+ * @bug 4800108 8072452 8181048
  * @summary verify that precomputed DSA parameters are always used (512, 768,
  *          1024, 2048, 3072 bit)
  * @run main/othervm/timeout=15 TestKeyPairGenerator
@@ -59,15 +59,12 @@
         // on JDKs that do not have the fix
         kpg = KeyPairGenerator.getInstance("DSA", "SUN");
         kp = kpg.generateKeyPair();
-        checkKeyLength(kp, 1024);
 
         kpg = KeyPairGenerator.getInstance("DSA", "SUN");
         kp = kpg.generateKeyPair();
-        checkKeyLength(kp, 1024);
 
         // some other basic tests
         kp = kpg.generateKeyPair();
-        checkKeyLength(kp, 1024);
 
         kpg.initialize(1024);
         kp = kpg.generateKeyPair();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/provider/DSA/TestLegacyDSAKeyPairGenerator.java	Thu Jul 13 20:41:59 2017 +0000
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, 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 8181048
+ * @summary verify that when the returned DSA KeyPairGenerator is
+ * an instance of java.security.interfaces.DSAKeyPairGenerator,
+ * the behavior is compliant with the javadoc spec.
+ * @run main/othervm -Djdk.security.legacyDSAKeyPairGenerator=tRUe TestLegacyDSAKeyPairGenerator
+ */
+
+import java.security.*;
+import java.security.interfaces.*;
+
+public class TestLegacyDSAKeyPairGenerator {
+
+    private static void checkKeyLength(KeyPair kp, int len) throws Exception {
+        DSAPublicKey key = (DSAPublicKey)kp.getPublic();
+        int n = key.getParams().getP().bitLength();
+        System.out.println("Key length: " + n);
+        if (len != n) {
+            throw new Exception("Wrong key length");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", "SUN");
+        // check the returned object implements the legacy interface
+        if (!(kpg instanceof DSAKeyPairGenerator)) {
+            throw new Exception("Should be an instance of DSAKeyPairGenerator");
+        }
+        System.out.println("Returned an instance of DSAKeyPairGenerator");
+        // check the default key size is 1024 when initiaize(..) is not called
+        KeyPair kp1 = kpg.generateKeyPair();
+        checkKeyLength(kp1, 1024);
+        KeyPair kp2 = kpg.generateKeyPair();
+        checkKeyLength(kp2, 1024);
+        System.out.println("Used 1024 default key size");
+
+        // check kp1 and kp2 uses the same DSA parameters p, q, g
+        DSAParams param1 = ((DSAPublicKey)kp1.getPublic()).getParams();
+        DSAParams param2 = ((DSAPublicKey)kp2.getPublic()).getParams();
+        if ((param1.getP().compareTo(param2.getP()) != 0) ||
+            (param1.getQ().compareTo(param2.getQ()) != 0) ||
+            (param1.getG().compareTo(param2.getG()) != 0)) {
+            throw new RuntimeException("Key params mismatch");
+        }
+        System.out.println("Used same default params");
+
+        // check that the documented exception is thrown if no cached parameters
+        int sizeNotInCache = (1024 - 64);
+        try {
+            ((DSAKeyPairGenerator)kpg).initialize(sizeNotInCache, false, null);
+            throw new RuntimeException("Expected IPE not thrown");
+        } catch (InvalidParameterException ipe) {
+            System.out.println("Throwed expected IPE");
+        }
+        ((DSAKeyPairGenerator)kpg).initialize(sizeNotInCache, true, null);
+        KeyPair kp = kpg.generateKeyPair();
+        checkKeyLength(kp, sizeNotInCache);
+        System.out.println("Generated requested key size");
+    }
+}