blob: f508c69a16b8ce61d11f26288a621d3afd5a4125 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2004-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.security.util;
27
28import java.io.*;
29import java.net.*;
30import java.security.*;
31import java.util.Arrays;
32
33import sun.net.www.ParseUtil;
34
35
36/**
37 * A utility class for getting a KeyStore instance from policy information.
38 * In addition, a supporting getInputStream method.
39 *
40 */
41public class PolicyUtil {
42
43 // standard PKCS11 KeyStore type
44 private static final String P11KEYSTORE = "PKCS11";
45
46 // reserved word
47 private static final String NONE = "NONE";
48
49 /*
50 * Fast path reading from file urls in order to avoid calling
51 * FileURLConnection.connect() which can be quite slow the first time
52 * it is called. We really should clean up FileURLConnection so that
53 * this is not a problem but in the meantime this fix helps reduce
54 * start up time noticeably for the new launcher. -- DAC
55 */
56 public static InputStream getInputStream(URL url) throws IOException {
57 if ("file".equals(url.getProtocol())) {
58 String path = url.getFile().replace('/', File.separatorChar);
59 path = ParseUtil.decode(path);
60 return new FileInputStream(path);
61 } else {
62 return url.openStream();
63 }
64 }
65
66 /**
67 * this is intended for use by policytool and the policy parser to
68 * instantiate a KeyStore from the information in the GUI/policy file
69 */
70 public static KeyStore getKeyStore
71 (URL policyUrl, // URL of policy file
72 String keyStoreName, // input: keyStore URL
73 String keyStoreType, // input: keyStore type
74 String keyStoreProvider, // input: keyStore provider
75 String storePassURL, // input: keyStore password
76 Debug debug)
77 throws KeyStoreException, MalformedURLException, IOException,
78 NoSuchProviderException, NoSuchAlgorithmException,
79 java.security.cert.CertificateException {
80
81 if (keyStoreName == null) {
82 throw new IllegalArgumentException("null KeyStore name");
83 }
84
85 char[] keyStorePassword = null;
86 try {
87 KeyStore ks;
88 if (keyStoreType == null) {
89 keyStoreType = KeyStore.getDefaultType();
90 }
91
92 if (P11KEYSTORE.equalsIgnoreCase(keyStoreType) &&
93 !NONE.equals(keyStoreName)) {
94 throw new IllegalArgumentException
95 ("Invalid value (" +
96 keyStoreName +
97 ") for keystore URL. If the keystore type is \"" +
98 P11KEYSTORE +
99 "\", the keystore url must be \"" +
100 NONE +
101 "\"");
102 }
103
104 if (keyStoreProvider != null) {
105 ks = KeyStore.getInstance(keyStoreType, keyStoreProvider);
106 } else {
107 ks = KeyStore.getInstance(keyStoreType);
108 }
109
110 if (storePassURL != null) {
111 URL passURL;
112 try {
113 passURL = new URL(storePassURL);
114 // absolute URL
115 } catch (MalformedURLException e) {
116 // relative URL
117 if (policyUrl == null) {
118 throw e;
119 }
120 passURL = new URL(policyUrl, storePassURL);
121 }
122
123 if (debug != null) {
124 debug.println("reading password"+passURL);
125 }
126
127 InputStream in = null;
128 try {
129 in = passURL.openStream();
130 keyStorePassword = Password.readPassword(in);
131 } finally {
132 if (in != null) {
133 in.close();
134 }
135 }
136 }
137
138 if (NONE.equals(keyStoreName)) {
139 ks.load(null, keyStorePassword);
140 return ks;
141 } else {
142 /*
143 * location of keystore is specified as absolute URL in policy
144 * file, or is relative to URL of policy file
145 */
146 URL keyStoreUrl = null;
147 try {
148 keyStoreUrl = new URL(keyStoreName);
149 // absolute URL
150 } catch (MalformedURLException e) {
151 // relative URL
152 if (policyUrl == null) {
153 throw e;
154 }
155 keyStoreUrl = new URL(policyUrl, keyStoreName);
156 }
157
158 if (debug != null) {
159 debug.println("reading keystore"+keyStoreUrl);
160 }
161
162 InputStream inStream = null;
163 try {
164 inStream =
165 new BufferedInputStream(getInputStream(keyStoreUrl));
166 ks.load(inStream, keyStorePassword);
167 } finally {
168 inStream.close();
169 }
170 return ks;
171 }
172 } finally {
173 if (keyStorePassword != null) {
174 Arrays.fill(keyStorePassword, ' ');
175 }
176 }
177 }
178}