1/*
2 * Copyright (c) 2003, 2011, 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 4508341 7055362
27 * @library ../../../java/security/testlibrary
28 * @summary Test the error conditions of
29 * EncryptedPrivateKeyInfo.getKeySpec(...) methods.
30 * @author Valerie Peng
31 */
32import java.security.*;
33import java.util.Arrays;
34import java.util.Vector;
35import java.security.spec.*;
36import javax.crypto.*;
37import javax.crypto.spec.*;
38
39public class GetKeySpecException {
40    private static final String cipherAlg = "PBEWithMD5AndDES";
41    private static final char[] passwd = { 'p','a','s','s','w','d' };
42    private static SecretKey cipherKey;
43    private static Cipher cipher = null;
44    private static byte[] encryptedData = null;
45    private static Provider sunjce = null;
46    private static final SecretKey INVALID_KEY =
47        new SecretKeySpec(new byte[8], "DES");
48    private static AlgorithmParameters BAD_PARAMS;
49    private static AlgorithmParameters GOOD_PARAMS;
50
51    static {
52        try {
53            sunjce = Security.getProvider("SunJCE");
54            PBEParameterSpec badParamSpec =
55                new PBEParameterSpec(new byte[10], 10);
56            BAD_PARAMS = AlgorithmParameters.getInstance(cipherAlg, sunjce);
57            BAD_PARAMS.init(badParamSpec);
58            PBEParameterSpec goodParamSpec =
59                new PBEParameterSpec(new byte[8], 1024);
60            GOOD_PARAMS = AlgorithmParameters.getInstance(cipherAlg, sunjce);
61            GOOD_PARAMS.init(goodParamSpec);
62            PBEKeySpec keySpec = new PBEKeySpec(passwd);
63            SecretKeyFactory skf =
64                SecretKeyFactory.getInstance(cipherAlg, "SunJCE");
65            cipherKey = skf.generateSecret(keySpec);
66        } catch (Exception ex) {
67            // should never happen
68            BAD_PARAMS = null;
69            GOOD_PARAMS = null;
70        }
71    }
72
73    private static void throwException(String msg) throws Exception {
74        throw new Exception(msg);
75    }
76
77    private static Provider[] removeProviders(String cipherAlg) {
78        Vector providers = new Vector();
79        boolean done = false;
80        while (!done) {
81            try {
82                Cipher c = Cipher.getInstance(cipherAlg);
83                Provider p = c.getProvider();
84                providers.add(p);
85                Security.removeProvider(p.getName());
86            } catch (NoSuchAlgorithmException nsae) {
87                done = true;
88            } catch (NoSuchPaddingException nspe) {
89                // should never happen
90            }
91        }
92        return (Provider[]) (providers.toArray(new Provider[0]));
93    }
94
95    private static void addProviders(Provider[] provs) {
96        for (int i=0; i<provs.length; i++) {
97            Security.addProvider(provs[i]);
98        }
99    }
100
101    public static void main(String[] args) throws Exception {
102        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
103        try {
104            main0(args);
105        } finally {
106            snapshot.restore();
107        }
108    }
109
110    public static void main0(String[] args) throws Exception {
111        if ((GOOD_PARAMS == null) || (BAD_PARAMS == null)) {
112            throw new Exception("Static parameter generation failed");
113        }
114        // use random data
115        byte[] encryptedData = new byte[30];
116        encryptedData[20] = (byte) 8;
117
118        PKCS8EncodedKeySpec pkcs8Spec = null;
119
120        // generate encrypted data and EncryptedPrivateKeyInfo objects
121        EncryptedPrivateKeyInfo epki =
122            new EncryptedPrivateKeyInfo(GOOD_PARAMS, encryptedData);
123        EncryptedPrivateKeyInfo epkiBad =
124            new EncryptedPrivateKeyInfo(BAD_PARAMS, encryptedData);
125
126        // TEST#1: getKeySpec(Cipher)
127        System.out.println("Testing getKeySpec(Cipher)...");
128        try {
129            pkcs8Spec = epki.getKeySpec((Cipher) null);
130            throwException("Should throw NPE for null Cipher!");
131        } catch (NullPointerException npe) {
132            System.out.println("Expected NPE thrown");
133        }
134
135        // TEST#2: getKeySpec(Key)
136        System.out.println("Testing getKeySpec(Key)...");
137        try {
138            pkcs8Spec = epki.getKeySpec((Key) null);
139            throwException("Should throw NPE for null Key!");
140        } catch (NullPointerException npe) {
141            System.out.println("Expected NPE thrown");
142        }
143        try {
144            pkcs8Spec = epki.getKeySpec(INVALID_KEY);
145            throwException("Should throw IKE for invalid Key!");
146        } catch (InvalidKeyException ikse) {
147            System.out.println("Expected IKE thrown");
148        }
149        try {
150            pkcs8Spec = epkiBad.getKeySpec(cipherKey);
151            throwException("Should throw IKE for corrupted epki!");
152        } catch (InvalidKeyException ike) {
153            System.out.println("Expected IKE thrown");
154        }
155        Provider[] removedProvs = null;
156        try {
157            removedProvs = removeProviders(cipherAlg);
158            pkcs8Spec = epki.getKeySpec(cipherKey);
159            throwException("Should throw NSAE if no matching impl!");
160        } catch (NoSuchAlgorithmException nsae) {
161            System.out.println("Expected NSAE thrown");
162            addProviders(removedProvs);
163        }
164        // TEST#3: getKeySpec(Key, String)
165        System.out.println("Testing getKeySpec(Key, String)...");
166        try {
167            pkcs8Spec = epki.getKeySpec(null, "SunJCE");
168            throwException("Should throw NPE for null Key!");
169        } catch (NullPointerException npe) {
170            System.out.println("Expected NPE thrown");
171        }
172        try {
173            pkcs8Spec = epki.getKeySpec(cipherKey, (String)null);
174            throwException("Should throw NPE for null String!");
175        } catch (NullPointerException npe) {
176            System.out.println("Expected NPE thrown");
177        }
178        try {
179            pkcs8Spec = epki.getKeySpec(INVALID_KEY, "SunJCE");
180            throwException("Should throw IKE for invalid Key!");
181        } catch (InvalidKeyException ikse) {
182            System.out.println("Expected IKE thrown");
183        }
184        try {
185            pkcs8Spec = epkiBad.getKeySpec(cipherKey, "SunJCE");
186            throwException("Should throw IKE for corrupted epki!");
187        } catch (InvalidKeyException ike) {
188            System.out.println("Expected IKE thrown");
189        }
190        try {
191            pkcs8Spec = epki.getKeySpec(cipherKey, "SUN");
192            throwException("Should throw NSAE for provider without " +
193                           "matching implementation!");
194        } catch (NoSuchAlgorithmException nsae) {
195            System.out.println("Expected NSAE thrown");
196        }
197        try {
198            Security.removeProvider("SunJCE");
199            pkcs8Spec = epki.getKeySpec(cipherKey, "SunJCE");
200            throwException("Should throw NSPE for unconfigured provider!");
201        } catch (NoSuchProviderException nspe) {
202            System.out.println("Expected NSPE thrown");
203            Security.addProvider(sunjce);
204        }
205        // TEST#4: getKeySpec(Key, Provider)
206        System.out.println("Testing getKeySpec(Key, Provider)...");
207        try {
208            pkcs8Spec = epki.getKeySpec(null, sunjce);
209            throwException("Should throw NPE for null Key!");
210        } catch (NullPointerException npe) {
211            System.out.println("Expected NPE thrown");
212        }
213        try {
214            pkcs8Spec = epki.getKeySpec(cipherKey, (Provider)null);
215            throwException("Should throw NPE for null Provider!");
216        } catch (NullPointerException npe) {
217            System.out.println("Expected NPE thrown");
218        }
219        try {
220            pkcs8Spec = epki.getKeySpec(INVALID_KEY, sunjce);
221            throwException("Should throw IKE for invalid Key!");
222        } catch (InvalidKeyException ikse) {
223            System.out.println("Expected IKE thrown");
224        }
225        try {
226            pkcs8Spec = epkiBad.getKeySpec(cipherKey, sunjce);
227            throwException("Should throw IKE for corrupted epki!");
228        } catch (InvalidKeyException ike) {
229            System.out.println("Expected IKE thrown");
230        }
231        System.out.println("All Tests Passed");
232    }
233}
234