1/*
2 * Copyright (c) 2003, 2012, 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 4893959 6383200
27 * @summary basic test for PBEWithSHA1AndDESede, PBEWithSHA1AndRC2_40/128
28 *          and PBEWithSHA1AndRC4_40/128
29 * @author Valerie Peng
30 * @key randomness
31 */
32
33import java.io.*;
34import java.util.*;
35import java.security.*;
36import javax.crypto.*;
37import javax.crypto.spec.*;
38import javax.crypto.interfaces.PBEKey;
39
40public class PKCS12Cipher {
41
42    private static void runTest(String alg, byte[] plaintext,
43                                char[] password, Provider p)
44        throws Exception {
45        Cipher cipher = Cipher.getInstance(alg, p);
46        PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
47        SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBE", p);
48        AlgorithmParameters pbeParams = null;
49        SecretKey key = keyFac.generateSecret(pbeKeySpec);
50        cipher.init(Cipher.ENCRYPT_MODE, key, pbeParams);
51        byte[] enc1 = cipher.doFinal(plaintext);
52        byte[] enc2 = cipher.doFinal(plaintext);
53        if (Arrays.equals(enc1, enc2) == false) {
54            throw new Exception("Re-encryption test failed");
55        }
56        pbeParams = cipher.getParameters();
57        cipher.init(Cipher.DECRYPT_MODE, key, pbeParams);
58        byte[] dec = cipher.doFinal(enc1);
59        if (Arrays.equals(plaintext, dec) == false) {
60            throw new Exception("decryption test for " + alg + " failed");
61        }
62
63        PBEParameterSpec spec = (PBEParameterSpec)
64            pbeParams.getParameterSpec(PBEParameterSpec.class);
65        PBEKey key2 = new
66            MyPBEKey(password, spec.getSalt(), spec.getIterationCount());
67        cipher.init(Cipher.DECRYPT_MODE, key2, pbeParams);
68        byte[] dec2 = cipher.doFinal(enc1);
69        if (Arrays.equals(dec2, dec) == false) {
70            throw new Exception("Re-decryption test#1 failed");
71        }
72
73        cipher.init(Cipher.DECRYPT_MODE, key2, (AlgorithmParameters) null);
74        byte[] dec3 = cipher.doFinal(enc1);
75        if (Arrays.equals(dec3, dec) == false) {
76            throw new Exception("Re-decryption test#2 failed");
77        }
78
79        System.out.println("passed: " + alg);
80    }
81
82    public static void main(String[] argv) throws Exception {
83        byte[] input = new byte[1024];
84        new SecureRandom().nextBytes(input);
85        char[] PASSWD = { 'p','a','s','s','w','o','r','d' };
86        long start = System.currentTimeMillis();
87        Provider p = Security.getProvider("SunJCE");
88        System.out.println("Testing provider " + p.getName() + "...");
89        runTest("PBEWithSHA1AndDESede", input, PASSWD, p);
90        runTest("PBEWithSHA1AndRC2_40", input, PASSWD, p);
91        runTest("PBEWithSHA1AndRC2_128", input, PASSWD, p);
92        runTest("PBEWithSHA1AndRC4_40", input, PASSWD, p);
93        runTest("PBEWithSHA1AndRC4_128", input, PASSWD, p);
94        System.out.println("All tests passed");
95        long stop = System.currentTimeMillis();
96        System.out.println("Done (" + (stop - start) + " ms).");
97    }
98}
99
100class MyPBEKey implements PBEKey {
101    char[] passwd;
102    byte[] salt;
103    int iCount;
104    MyPBEKey(char[] passwd, byte[] salt, int iCount) {
105        this.passwd = passwd;
106        this.salt = salt;
107        this.iCount = iCount;
108    }
109    public char[] getPassword() { return passwd; }
110    public byte[] getSalt() { return salt; }
111    public int getIterationCount() { return iCount; }
112    public String getAlgorithm() { return "PBE"; }
113    public String getFormat() { return "RAW"; }
114    public byte[] getEncoded() { return null; }
115}
116