1 /*
   2  * Copyright (c) 2015, 2016, 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  /*
  25  * @test
  26  * @bug 8023546 8151834
  27  * @modules java.base/sun.security.x509
  28  *          java.base/sun.security.tools.keytool
  29  * @summary Test prime exponent (p) lengths 63 and 65 bytes with SunMSCAPI.
  30  *         The seed 76 has the fastest test execution now (only 5 rounds) and is
  31  *         hard-coded in run tag. This number might change if algorithms for
  32  *         RSA key pair generation or BigInteger prime searching gets updated.
  33  * @requires os.family == "windows"
  34  * @run main SmallPrimeExponentP 76
  35  */
  36 import sun.security.tools.keytool.CertAndKeyGen;
  37 import sun.security.x509.X500Name;
  38 
  39 import java.security.KeyStore;
  40 import java.security.SecureRandom;
  41 import java.security.cert.X509Certificate;
  42 import java.security.interfaces.RSAPrivateCrtKey;
  43 import java.util.Random;
  44 
  45 public class SmallPrimeExponentP {
  46 
  47     public static void main(String argv[]) throws Exception {
  48 
  49         long seed = Long.parseLong(argv[0]);
  50         System.out.println("Seed for SecureRandom = " + seed + "L");
  51 
  52         KeyStore ks = KeyStore.getInstance("Windows-MY");
  53         ks.load(null, null);
  54 
  55         CertAndKeyGen ckg = new CertAndKeyGen("RSA", "SHA1withRSA");
  56         ckg.setRandom(new MySecureRandom(seed));
  57 
  58         boolean see63 = false;
  59         boolean see65 = false;
  60         while (!see63 || !see65) {
  61             ckg.generate(1024);
  62             RSAPrivateCrtKey k = (RSAPrivateCrtKey) ckg.getPrivateKey();
  63 
  64             int len = k.getPrimeExponentP().toByteArray().length;
  65             System.out.println("Length of P = " + len);
  66             if (len == 63 || len == 65) {
  67                 if (len == 63) {
  68                     if (see63) {
  69                         continue;
  70                     } else {
  71                         see63 = true;
  72                     }
  73                 }
  74                 if (len == 65) {
  75                     if (see65) {
  76                         continue;
  77                     } else {
  78                         see65 = true;
  79                     }
  80                 }
  81                 ks.setKeyEntry("anything", k, null, new X509Certificate[]{
  82                     ckg.getSelfCertificate(new X500Name("CN=Me"), 1000)
  83                 });
  84             }
  85         }
  86         ks.store(null, null);
  87     }
  88 
  89     static class MySecureRandom extends SecureRandom {
  90 
  91         final Random random;
  92 
  93         public MySecureRandom(long seed) {
  94             random = new Random(seed);
  95         }
  96 
  97         @Override
  98         public void nextBytes(byte[] bytes) {
  99             random.nextBytes(bytes);
 100         }
 101     }
 102 }