1 /*
   2  * Copyright (c) 2003, 2004, 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 4532506 4999599
  27  * @summary Serializing KeyPair on one VM (Sun),
  28  *      and Deserializing on another (IBM) fails
  29  * @run main/othervm/java.security.policy=Serial.policy Serial
  30  */
  31 
  32 import java.io.*;
  33 import java.math.BigInteger;
  34 import java.security.*;
  35 import javax.crypto.*;
  36 import javax.crypto.spec.*;
  37 
  38 public class Serial {
  39 
  40     // providers
  41     private static final String SUN = "SUN";
  42     private static final String RSA = "SunRsaSign";
  43     private static final String JCE = "SunJCE";
  44 
  45     public static void main(String[] args) throws Exception {
  46 
  47         // generate DSA key pair
  48         KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", SUN);
  49         kpg.initialize(512);
  50         KeyPair dsaKp = kpg.genKeyPair();
  51 
  52         // serialize DSA key pair
  53         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  54         ObjectOutputStream oos = new ObjectOutputStream(baos);
  55         oos.writeObject(dsaKp);
  56         oos.close();
  57 
  58         // deserialize DSA key pair
  59         ObjectInputStream ois = new ObjectInputStream
  60                         (new ByteArrayInputStream(baos.toByteArray()));
  61         KeyPair dsaKp2 = (KeyPair)ois.readObject();
  62         ois.close();
  63 
  64         if (!dsaKp2.getPublic().equals(dsaKp.getPublic()) ||
  65             !dsaKp2.getPrivate().equals(dsaKp.getPrivate())) {
  66             throw new SecurityException("DSA test failed");
  67         }
  68 
  69         // generate RSA key pair
  70         kpg = KeyPairGenerator.getInstance("RSA", RSA);
  71         kpg.initialize(512);
  72         KeyPair rsaKp = kpg.genKeyPair();
  73 
  74         // serialize RSA key pair
  75         baos.reset();
  76         oos = new ObjectOutputStream(baos);
  77         oos.writeObject(rsaKp);
  78         oos.close();
  79 
  80         // deserialize RSA key pair
  81         ois = new ObjectInputStream
  82                         (new ByteArrayInputStream(baos.toByteArray()));
  83         KeyPair rsaKp2 = (KeyPair)ois.readObject();
  84         ois.close();
  85 
  86         if (!rsaKp2.getPublic().equals(rsaKp.getPublic()) ||
  87             !rsaKp2.getPrivate().equals(rsaKp.getPrivate())) {
  88             throw new SecurityException("RSA test failed");
  89         }
  90 
  91         // exclude test is ECF provider is installed, see 4923290
  92         if (Security.getProvider("SunPKCS11-Solaris") == null) {
  93             // generate DH key pair
  94             kpg = KeyPairGenerator.getInstance("DiffieHellman", JCE);
  95             kpg.initialize(new DHParameterSpec(skip1024Modulus, skip1024Base));
  96             KeyPair dhKp = kpg.genKeyPair();
  97 
  98             // serialize DH key pair
  99             baos.reset();
 100             oos = new ObjectOutputStream(baos);
 101             oos.writeObject(dhKp);
 102             oos.close();
 103 
 104             // deserialize DH key pair
 105             ois = new ObjectInputStream
 106                             (new ByteArrayInputStream(baos.toByteArray()));
 107             KeyPair dhKp2 = (KeyPair)ois.readObject();
 108             ois.close();
 109 
 110             if (!dhKp2.getPublic().equals(dhKp.getPublic()) ||
 111                 !dhKp2.getPrivate().equals(dhKp.getPrivate())) {
 112                 throw new SecurityException("DH test failed");
 113             }
 114         }
 115 
 116         // generate RC5 key
 117         SecretKeySpec rc5Key = new SecretKeySpec(new byte[128], "RC5");
 118 
 119         // serialize RC5 key
 120         baos.reset();
 121         oos = new ObjectOutputStream(baos);
 122         oos.writeObject(rc5Key);
 123         oos.close();
 124 
 125         // deserialize RC5 key
 126         ois = new ObjectInputStream
 127                         (new ByteArrayInputStream(baos.toByteArray()));
 128         SecretKey rc5Key2 = (SecretKey)ois.readObject();
 129         ois.close();
 130 
 131         if (!rc5Key.equals(rc5Key2)) {
 132             throw new SecurityException("RC5 test failed");
 133         }
 134 
 135         // generate PBE key
 136 
 137         // Salt
 138         byte[] salt = {
 139                 (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
 140                 (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
 141         };
 142 
 143         // Iteration count
 144         int count = 20;
 145 
 146         // Create PBE parameter set
 147         PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);
 148 
 149         char[] password = new char[] {'f', 'o', 'o'};
 150         PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
 151         SecretKeyFactory keyFac =
 152                         SecretKeyFactory.getInstance("PBEWithMD5AndDES", JCE);
 153         SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
 154 
 155         // serialize PBE key
 156         baos.reset();
 157         oos = new ObjectOutputStream(baos);
 158         oos.writeObject(pbeKey);
 159         oos.close();
 160 
 161         // deserialize PBE key
 162         ois = new ObjectInputStream
 163                         (new ByteArrayInputStream(baos.toByteArray()));
 164         SecretKey pbeKey2 = (SecretKey)ois.readObject();
 165         ois.close();
 166 
 167         if (!pbeKey.equals(pbeKey2)) {
 168             throw new SecurityException("PBE test failed");
 169         }
 170 
 171         checkKey("AES", 128);
 172         checkKey("Blowfish", -1);
 173         checkKey("DES", 56);
 174         checkKey("DESede", 168);
 175         checkKey("HmacMD5", -1);
 176         checkKey("HmacSHA1", -1);
 177     }
 178 
 179     private static void checkKey(String algorithm, int size) throws Exception {
 180         // generate key
 181         KeyGenerator kg = KeyGenerator.getInstance(algorithm, JCE);
 182         if (size > 0) {
 183             kg.init(size);
 184         }
 185         SecretKey key = kg.generateKey();
 186 
 187         // serialize key
 188         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 189         ObjectOutputStream oos = new ObjectOutputStream(baos);
 190         oos.writeObject(key);
 191         oos.close();
 192 
 193         // deserialize key
 194         ObjectInputStream ois = new ObjectInputStream
 195                                 (new ByteArrayInputStream(baos.toByteArray()));
 196         SecretKey key2 = (SecretKey)ois.readObject();
 197         ois.close();
 198 
 199         if (!key.equals(key2)) {
 200             throw new SecurityException(algorithm + " test failed");
 201         }
 202     }
 203 
 204     // The 1024 bit Diffie-Hellman modulus values used by SKIP
 205     private static final byte skip1024ModulusBytes[] = {
 206         (byte)0xF4, (byte)0x88, (byte)0xFD, (byte)0x58,
 207         (byte)0x4E, (byte)0x49, (byte)0xDB, (byte)0xCD,
 208         (byte)0x20, (byte)0xB4, (byte)0x9D, (byte)0xE4,
 209         (byte)0x91, (byte)0x07, (byte)0x36, (byte)0x6B,
 210         (byte)0x33, (byte)0x6C, (byte)0x38, (byte)0x0D,
 211         (byte)0x45, (byte)0x1D, (byte)0x0F, (byte)0x7C,
 212         (byte)0x88, (byte)0xB3, (byte)0x1C, (byte)0x7C,
 213         (byte)0x5B, (byte)0x2D, (byte)0x8E, (byte)0xF6,
 214         (byte)0xF3, (byte)0xC9, (byte)0x23, (byte)0xC0,
 215         (byte)0x43, (byte)0xF0, (byte)0xA5, (byte)0x5B,
 216         (byte)0x18, (byte)0x8D, (byte)0x8E, (byte)0xBB,
 217         (byte)0x55, (byte)0x8C, (byte)0xB8, (byte)0x5D,
 218         (byte)0x38, (byte)0xD3, (byte)0x34, (byte)0xFD,
 219         (byte)0x7C, (byte)0x17, (byte)0x57, (byte)0x43,
 220         (byte)0xA3, (byte)0x1D, (byte)0x18, (byte)0x6C,
 221         (byte)0xDE, (byte)0x33, (byte)0x21, (byte)0x2C,
 222         (byte)0xB5, (byte)0x2A, (byte)0xFF, (byte)0x3C,
 223         (byte)0xE1, (byte)0xB1, (byte)0x29, (byte)0x40,
 224         (byte)0x18, (byte)0x11, (byte)0x8D, (byte)0x7C,
 225         (byte)0x84, (byte)0xA7, (byte)0x0A, (byte)0x72,
 226         (byte)0xD6, (byte)0x86, (byte)0xC4, (byte)0x03,
 227         (byte)0x19, (byte)0xC8, (byte)0x07, (byte)0x29,
 228         (byte)0x7A, (byte)0xCA, (byte)0x95, (byte)0x0C,
 229         (byte)0xD9, (byte)0x96, (byte)0x9F, (byte)0xAB,
 230         (byte)0xD0, (byte)0x0A, (byte)0x50, (byte)0x9B,
 231         (byte)0x02, (byte)0x46, (byte)0xD3, (byte)0x08,
 232         (byte)0x3D, (byte)0x66, (byte)0xA4, (byte)0x5D,
 233         (byte)0x41, (byte)0x9F, (byte)0x9C, (byte)0x7C,
 234         (byte)0xBD, (byte)0x89, (byte)0x4B, (byte)0x22,
 235         (byte)0x19, (byte)0x26, (byte)0xBA, (byte)0xAB,
 236         (byte)0xA2, (byte)0x5E, (byte)0xC3, (byte)0x55,
 237         (byte)0xE9, (byte)0x2F, (byte)0x78, (byte)0xC7
 238     };
 239 
 240     // The SKIP 1024 bit modulus
 241     private static final BigInteger skip1024Modulus
 242     = new BigInteger(1, skip1024ModulusBytes);
 243 
 244     // The base used with the SKIP 1024 bit modulus
 245     private static final BigInteger skip1024Base = BigInteger.valueOf(2);
 246 }