changeset 8547:4fcf12d3efe1

8181048: Refactor existing providers to refer to the same constants for default values for key length Reviewed-by: mullan, ahgross
author igerasim
date Thu, 23 Nov 2017 03:37:33 +0000
parents 0b4f7f108005
children 72f71c6b2bbc
files src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java src/share/classes/sun/security/action/GetPropertyAction.java src/share/classes/sun/security/ec/ECKeyPairGenerator.java src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java src/share/classes/sun/security/provider/DSAKeyPairGenerator.java src/share/classes/sun/security/provider/DSAParameterGenerator.java src/share/classes/sun/security/provider/SunEntries.java src/share/classes/sun/security/rsa/RSAKeyPairGenerator.java src/share/classes/sun/security/tools/keytool/Main.java src/share/classes/sun/security/util/SecurityProviderConstants.java src/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java test/java/security/Signature/Offsets.java test/java/security/SignedObject/Chain.java test/sun/security/provider/DSA/TestAlgParameterGenerator.java test/sun/security/provider/DSA/TestKeyPairGenerator.java test/sun/security/provider/DSA/TestLegacyDSAKeyPairGenerator.java
diffstat 17 files changed, 416 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, 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 1024 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(1024, null);
+        initialize(DEF_DH_KEY_SIZE, null);
     }
 
     /**
--- a/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, 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
@@ -30,6 +30,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
@@ -37,7 +39,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 1024 bits.
  *
  * @author Jan Luehe
  *
@@ -50,7 +51,7 @@
 extends AlgorithmParameterGeneratorSpi {
 
     // The size in bits of the prime modulus
-    private int primeSize = 1024;
+    private int primeSize = DEF_DH_KEY_SIZE;
 
     // The size in bits of the random exponent (private value)
     private int exponentSize = 0;
--- a/src/share/classes/sun/security/action/GetPropertyAction.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/src/share/classes/sun/security/action/GetPropertyAction.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -25,6 +25,9 @@
 
 package sun.security.action;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
 /**
  * A convenience class for retrieving the string value of a system
  * property as a privileged action.
@@ -46,8 +49,7 @@
  * @since 1.2
  */
 
-public class GetPropertyAction
-        implements java.security.PrivilegedAction<String> {
+public class GetPropertyAction implements PrivilegedAction<String> {
     private String theProp;
     private String defaultVal;
 
@@ -84,4 +86,26 @@
         String value = System.getProperty(theProp);
         return (value == null) ? defaultVal : value;
     }
+
+    /**
+     * Convenience method to get a property without going through doPrivileged
+     * if no security manager is present. This is unsafe for inclusion in a
+     * public API but allowable here since this class is by default restricted
+     * by the package.access security property.
+     *
+     * Note that this method performs a privileged action using caller-provided
+     * inputs. The caller of this method should take care to ensure that the
+     * inputs are not tainted and the returned property is not made accessible
+     * to untrusted code if it contains sensitive information.
+     *
+     * @param theProp the name of the system property.
+     */
+    public static String privilegedGetProperty(String theProp) {
+        if (System.getSecurityManager() == null) {
+            return System.getProperty(theProp);
+        } else {
+            return AccessController.doPrivileged(
+                    new GetPropertyAction(theProp));
+        }
+    }
 }
--- a/src/share/classes/sun/security/ec/ECKeyPairGenerator.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/src/share/classes/sun/security/ec/ECKeyPairGenerator.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -37,6 +37,7 @@
 import sun.security.ec.ECPrivateKeyImpl;
 import sun.security.ec.ECPublicKeyImpl;
 import sun.security.jca.JCAUtil;
+import static sun.security.util.SecurityProviderConstants.DEF_EC_KEY_SIZE;
 
 /**
  * EC keypair generator.
@@ -48,7 +49,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;
@@ -64,7 +64,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/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, 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;
             }
@@ -106,8 +108,13 @@
                 maxKeyLen = 2048;
             }
         } else {
-            // RSA, DH, and DSA
-            keySize = 1024;
+            if (algorithm.equals("DSA")) {
+                keySize = DEF_DSA_KEY_SIZE;
+            } else if (algorithm.equals("RSA")) {
+                keySize = DEF_RSA_KEY_SIZE;
+            } else {
+                keySize = DEF_DH_KEY_SIZE;
+            }
             if ((minKeyLen == -1) || (minKeyLen < 512)) {
                 minKeyLen = 512;
             }
--- a/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, 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) {
@@ -82,53 +83,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.
-     */
-    public void initialize(int modlen, boolean genParams, SecureRandom random) {
-        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,
-                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.
-     */
-    public void initialize(DSAParams params, SecureRandom random) {
-        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);
     }
 
     /**
@@ -147,10 +102,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);
@@ -158,7 +124,7 @@
         this.qlen = sizeQ;
         this.params = params;
         this.random = random;
-        this.forceNewParameters = false;
+        this.forceNewParameters = forceNew;
     }
 
     /**
@@ -187,7 +153,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);
@@ -242,4 +208,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/share/classes/sun/security/provider/DSAParameterGenerator.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/src/share/classes/sun/security/provider/DSAParameterGenerator.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, 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,16 +34,19 @@
 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 sun.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
  *
@@ -57,10 +60,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;
@@ -84,18 +83,16 @@
      * @param strength the strength (size of prime) in bits
      * @param random the source of randomness
      */
+    @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 {
-            throw new InvalidParameterException
-                ("Prime size should be 512 - 1024, or 2048");
+        if ((strength != 2048) &&
+            ((strength < 512) || (strength > 1024) || (strength % 64 != 0))) {
+            throw new InvalidParameterException(
+                "Unexpected strength (size of prime): " + strength +
+                ". Prime size should be 512-1024, or 2048");
         }
         this.valueL = strength;
+        this.valueN = getDefDSASubprimeSize(strength);
         this.seedLen = valueN;
         this.random = random;
     }
@@ -104,19 +101,20 @@
      * Initializes this parameter generator with a set of
      * algorithm-specific parameter generation values.
      *
-     * @param genParamSpec 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
      * generation values are inappropriate for this parameter generator
      */
+    @Override
     protected void engineInit(AlgorithmParameterSpec genParamSpec,
-                              SecureRandom random)
-        throws InvalidAlgorithmParameterException {
+            SecureRandom random) throws InvalidAlgorithmParameterException {
         if (!(genParamSpec instanceof DSAGenParameterSpec)) {
             throw new InvalidAlgorithmParameterException("Invalid parameter");
         }
-        DSAGenParameterSpec dsaGenParams = (DSAGenParameterSpec) genParamSpec;
+        DSAGenParameterSpec dsaGenParams = (DSAGenParameterSpec)genParamSpec;
         int primePLen = dsaGenParams.getPrimePLength();
         if (primePLen > 2048) {
             throw new InvalidParameterException
@@ -141,11 +139,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);
@@ -211,13 +205,16 @@
         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) {
+        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/share/classes/sun/security/provider/SunEntries.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/src/share/classes/sun/security/provider/SunEntries.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, 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
@@ -27,6 +27,7 @@
 
 import java.util.Map;
 import java.security.*;
+import sun.security.action.GetPropertyAction;
 
 /**
  * Defines the entries of the SUN provider.
@@ -76,6 +77,10 @@
 
 final class SunEntries {
 
+    private static final boolean useLegacyDSA =
+        Boolean.parseBoolean(GetPropertyAction.privilegedGetProperty
+            ("jdk.security.legacyDSAKeyPairGenerator"));
+
     private SunEntries() {
         // empty
     }
@@ -140,8 +145,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/share/classes/sun/security/rsa/RSAKeyPairGenerator.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/src/share/classes/sun/security/rsa/RSAKeyPairGenerator.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, 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(1024, null);
+        initialize(DEF_RSA_KEY_SIZE, null);
     }
 
     // initialize the generator. See JCA doc
--- a/src/share/classes/sun/security/tools/keytool/Main.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/src/share/classes/sun/security/tools/keytool/Main.java	Thu Nov 23 03:37:33 2017 +0000
@@ -77,6 +77,7 @@
 import sun.security.provider.X509Factory;
 import sun.security.provider.certpath.CertStoreHelper;
 import sun.security.util.Password;
+import sun.security.util.SecurityProviderConstants;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 
@@ -1615,11 +1616,12 @@
     {
         if (keysize == -1) {
             if ("EC".equalsIgnoreCase(keyAlgName)) {
-                keysize = 256;
+                keysize = SecurityProviderConstants.DEF_EC_KEY_SIZE;
             } else if ("RSA".equalsIgnoreCase(keyAlgName)) {
-                keysize = 2048;
-            } else {
-                keysize = 1024;
+                // hardcode for now as DEF_RSA_KEY_SIZE is still 1024
+                keysize = 2048; // SecurityProviderConstants.DEF_RSA_KEY_SIZE;
+            } else if ("DSA".equalsIgnoreCase(keyAlgName)) {
+                keysize = SecurityProviderConstants.DEF_DSA_KEY_SIZE;
             }
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/security/util/SecurityProviderConstants.java	Thu Nov 23 03:37:33 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 = 1024;
+        int dhKeySize = 1024;
+        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/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/src/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, 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
@@ -32,6 +32,7 @@
 
 import sun.security.jca.JCAUtil;
 import sun.security.rsa.RSAKeyFactory;
+import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
 
 /**
  * RSA keypair generator.
@@ -46,14 +47,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 = 1024;
 
     // 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
@@ -77,7 +77,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/java/security/Signature/Offsets.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/test/java/security/Signature/Offsets.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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,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
@@ -105,18 +105,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/java/security/SignedObject/Chain.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/test/java/security/SignedObject/Chain.java	Thu Nov 23 03:37:33 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 @@
             KeyPairGenerator 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/sun/security/provider/DSA/TestAlgParameterGenerator.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/test/sun/security/provider/DSA/TestAlgParameterGenerator.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 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
+ * @bug 7044060 8181048
  * @summary verify that DSA parameter generation works
  * @run main/othervm/timeout=300 TestAlgParameterGenerator
  */
@@ -80,7 +80,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/sun/security/provider/DSA/TestKeyPairGenerator.java	Tue Oct 08 11:07:31 2013 -0700
+++ b/test/sun/security/provider/DSA/TestKeyPairGenerator.java	Thu Nov 23 03:37:33 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 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
+ * @bug 4800108 8181048
  * @summary verify that precomputed DSA parameters are always used (512, 768, 1024, 2048 bit)
  * @run main/othervm/timeout=15 TestKeyPairGenerator
  */
@@ -56,15 +56,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/sun/security/provider/DSA/TestLegacyDSAKeyPairGenerator.java	Thu Nov 23 03:37:33 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");
+    }
+}