1 /*
2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 import java.security.KeyFactory;
25 import java.security.KeyPair;
26 import java.security.KeyPairGenerator;
27 import java.security.PrivateKey;
28 import java.security.PublicKey;
29 import java.security.interfaces.RSAKey;
30 import java.security.interfaces.RSAPrivateKey;
31 import java.security.interfaces.RSAPublicKey;
32 import java.security.spec.RSAPrivateKeySpec;
33 import java.security.spec.RSAPublicKeySpec;
34 
35 /**
36  * @test
37  * @bug 8044199
38  * @summary test if the private and public key size are the same as what is set
39  * through KeyPairGenerator.
40  * @run main KeySizeTest 512 10
41  * @run main KeySizeTest 768 10
42  * @run main KeySizeTest 1024 10
43  * @run main KeySizeTest 2048 5
44  * @run main KeySizeTest 4096 1
45  */
46 public class KeySizeTest {
47 
48     /**
49      * ALGORITHM name, fixed as RSA.
50      */
51     private static final String KEYALG = "RSA";
52 
53     /**
54      * JDK default RSA Provider.
55      */
56     private static final String PROVIDER_NAME = "SunRsaSign";
57 
main(String[] args)58     public static void main(String[] args) throws Exception {
59         int iKeyPairSize = Integer.parseInt(args[0]);
60         int maxLoopCnt = Integer.parseInt(args[1]);
61 
62         int failCount = 0;
63         KeyPairGenerator keyPairGen
64                 = KeyPairGenerator.getInstance(KEYALG, PROVIDER_NAME);
65         keyPairGen.initialize(iKeyPairSize);
66         // Generate RSA keypair
67         KeyPair keyPair = keyPairGen.generateKeyPair();
68 
69         // Get priavte and public keys
70         PrivateKey privateKey = keyPair.getPrivate();
71         PublicKey publicKey = keyPair.getPublic();
72         try {
73             if (!sizeTest(keyPair)) {
74                 failCount++;
75             }
76         } catch (Exception ex) {
77             ex.printStackTrace(System.err);
78             failCount++;
79         }
80 
81         for (int iCnt = 0; iCnt < maxLoopCnt; iCnt++) {
82 
83             // Get keysize (modulus) of keys
84             KeyFactory keyFact = KeyFactory.getInstance(KEYALG, PROVIDER_NAME);
85 
86             // Comparing binary length.
87             RSAPrivateKeySpec privateKeySpec
88                     = (RSAPrivateKeySpec) keyFact.getKeySpec(privateKey,
89                             RSAPrivateKeySpec.class);
90             int iPrivateKeySize = privateKeySpec.getModulus().bitLength();
91 
92             RSAPublicKeySpec publicKeySpec
93                     = (RSAPublicKeySpec) keyFact.getKeySpec(publicKey,
94                             RSAPublicKeySpec.class);
95             int iPublicKeySize = publicKeySpec.getModulus().bitLength();
96 
97             if ((iKeyPairSize != iPublicKeySize) || (iKeyPairSize != iPrivateKeySize)) {
98                 System.err.println("iKeyPairSize : " + iKeyPairSize);
99                 System.err.println("Generated a " + iPrivateKeySize
100                         + " bit RSA private key");
101                 System.err.println("Generated a " + iPublicKeySize
102                         + " bit RSA public key");
103                 failCount++;
104             }
105         }
106 
107         if (failCount > 0) {
108             throw new RuntimeException("There are " + failCount + " tests failed.");
109         }
110     }
111 
112     /**
113      * @param kpair test key pair.
114      * @return true if test passed. false if test failed.
115      */
sizeTest(KeyPair kpair)116     private static boolean sizeTest(KeyPair kpair) {
117         RSAPrivateKey priv = (RSAPrivateKey) kpair.getPrivate();
118         RSAPublicKey pub = (RSAPublicKey) kpair.getPublic();
119 
120         // test the getModulus method
121         if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) {
122             if (!priv.getModulus().equals(pub.getModulus())) {
123                 System.err.println("priv.getModulus() = " + priv.getModulus());
124                 System.err.println("pub.getModulus() = " + pub.getModulus());
125                 return false;
126             }
127         }
128         return true;
129     }
130 }
131