1 /*
2  * Copyright (c) 2013, 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 /*
25  * @test
26  * @bug 8005408 8079129 8048830
27  * @summary KeyStore API enhancements
28  * @run main StoreSecretKeyTest
29  */
30 
31 import java.io.*;
32 import java.security.*;
33 import java.security.cert.*;
34 import java.security.cert.Certificate;
35 import java.util.*;
36 import javax.crypto.*;
37 import javax.crypto.spec.*;
38 
39 // Store a secret key in a keystore and retrieve it again.
40 
41 public class StoreSecretKeyTest {
42     private final static String DIR = System.getProperty("test.src", ".");
43     private static final char[] PASSWORD = "passphrase".toCharArray();
44     private static final String KEYSTORE = "keystore.p12";
45     private static final String CERT = DIR + "/trusted.pem";
46     private static final String ALIAS = "my trusted cert";
47     private static final String ALIAS2 = "my secret key";
48     private enum ALGORITHM {
49         DES(56),
50         DESede(168),
51         AES(128);
52         final int len;
ALGORITHM(int l)53         ALGORITHM(int l) {
54             len = l;
55         }
getLength()56         final int getLength() {
57             return len;
58         }
59     }
main(String[] args)60     public static void main(String[] args) throws Exception {
61         boolean isSecretkeyAlgSupported = false;
62         // Skip test if AES is unavailable
63         try {
64             SecretKeyFactory.getInstance("AES");
65         } catch (NoSuchAlgorithmException nsae) {
66             System.out.println("AES is unavailable. Skipping test...");
67             return;
68         }
69 
70         for (ALGORITHM alg : ALGORITHM.values()) {
71             isSecretkeyAlgSupported |= testSecretKeyAlgorithm(alg);
72         }
73         if (!isSecretkeyAlgSupported) {
74             throw new Exception("None of the SecretKey algorithms is "
75                     + "supported");
76         }
77     }
78 
testSecretKeyAlgorithm(ALGORITHM algorithm)79     private static boolean testSecretKeyAlgorithm(ALGORITHM algorithm) throws
80             Exception {
81 
82         System.out.println("Testing algorithm : " + algorithm.name());
83         new File(KEYSTORE).delete();
84         try {
85             KeyStore keystore = KeyStore.getInstance("PKCS12");
86             keystore.load(null, null);
87 
88             // Set trusted certificate entry
89             Certificate cert = loadCertificate(CERT);
90             keystore.setEntry(ALIAS,
91             new KeyStore.TrustedCertificateEntry(cert), null);
92             // Set secret key entry
93             SecretKey secretKey = generateSecretKey(algorithm.name(),
94                     algorithm.len);
95             if(secretKey == null) {
96                 return false;
97             }
98             keystore.setEntry(ALIAS2,
99                 new KeyStore.SecretKeyEntry(secretKey),
100                 new KeyStore.PasswordProtection(PASSWORD));
101 
102             try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) {
103                 System.out.println("Storing keystore to: " + KEYSTORE);
104                 keystore.store(outStream, PASSWORD);
105             }
106 
107             try (FileInputStream inStream = new FileInputStream(KEYSTORE)) {
108                 System.out.println("Loading keystore from: " + KEYSTORE);
109                 keystore.load(inStream, PASSWORD);
110                 System.out.println("Loaded keystore with " + keystore.size() +
111                     " entries");
112             }
113 
114             KeyStore.Entry entry = keystore.getEntry(ALIAS2,
115                 new KeyStore.PasswordProtection(PASSWORD));
116             System.out.println("Retrieved entry: " + entry);
117 
118             if (entry instanceof KeyStore.SecretKeyEntry) {
119                 System.out.println("Retrieved secret key entry: " + entry);
120             } else {
121                 throw new Exception("Not a secret key entry");
122             }
123         } catch (KeyStoreException | UnrecoverableKeyException ex) {
124             System.out.println("Unable to check SecretKey algorithm due to "
125                     + "exception: " + ex.getMessage());
126             return false;
127         }
128         return true;
129     }
130 
generateSecretKey(String algorithm, int size)131     private static SecretKey generateSecretKey(String algorithm, int size)
132         throws NoSuchAlgorithmException {
133         KeyGenerator generator = KeyGenerator.getInstance(algorithm);
134         generator.init(size);
135         return generator.generateKey();
136     }
137 
loadCertificate(String certFile)138     private static Certificate loadCertificate(String certFile)
139         throws Exception {
140         X509Certificate cert = null;
141         try (FileInputStream certStream = new FileInputStream(certFile)) {
142             CertificateFactory factory =
143                 CertificateFactory.getInstance("X.509");
144             return factory.generateCertificate(certStream);
145         }
146     }
147 }
148