1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44:
45: import ;
46: import ;
47: import ;
48: import ;
49:
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66:
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72:
73: import ;
74: import ;
75:
76: import ;
77: import ;
78: import ;
79: import ;
80:
81: import ;
82: import ;
83:
84:
88: public class X509KeyManagerFactory extends KeyManagerFactorySpi
89: {
90:
91:
92:
93:
94: private Manager current;
95:
96:
97:
98:
99: public X509KeyManagerFactory()
100: {
101: super();
102: }
103:
104:
105:
106:
107: protected KeyManager[] engineGetKeyManagers()
108: {
109: if (current == null)
110: {
111: throw new IllegalStateException();
112: }
113: return new KeyManager[] { current };
114: }
115:
116: protected void engineInit(ManagerFactoryParameters params)
117: throws InvalidAlgorithmParameterException
118: {
119: if (params instanceof NullManagerParameters)
120: {
121: current = new Manager(Collections.EMPTY_MAP, Collections.EMPTY_MAP);
122: }
123: else if (params instanceof PrivateCredentials)
124: {
125: List chains = ((PrivateCredentials) params).getCertChains();
126: List keys = ((PrivateCredentials) params).getPrivateKeys();
127: int i = 0;
128: HashMap certMap = new HashMap();
129: HashMap keyMap = new HashMap();
130: Iterator c = chains.iterator();
131: Iterator k = keys.iterator();
132: while (c.hasNext() && k.hasNext())
133: {
134: certMap.put(String.valueOf(i), c.next());
135: keyMap.put(String.valueOf(i), k.next());
136: i++;
137: }
138: current = new Manager(keyMap, certMap);
139: }
140: else
141: {
142: throw new InvalidAlgorithmParameterException();
143: }
144: }
145:
146: protected void engineInit(KeyStore store, char[] passwd)
147: throws KeyStoreException, NoSuchAlgorithmException,
148: UnrecoverableKeyException
149: {
150: if (store == null)
151: {
152: String s = Util.getProperty("javax.net.ssl.keyStoreType");
153: if (s == null)
154: s = KeyStore.getDefaultType();
155: store = KeyStore.getInstance(s);
156: s = Util.getProperty("javax.net.ssl.keyStore");
157: if (s == null)
158: return;
159: String p = Util.getProperty("javax.net.ssl.keyStorePassword");
160: try
161: {
162: store.load(new FileInputStream(s), p != null ? p.toCharArray() : null);
163: }
164: catch (IOException ioe)
165: {
166: throw new KeyStoreException(ioe.toString());
167: }
168: catch (CertificateException ce)
169: {
170: throw new KeyStoreException(ce.toString());
171: }
172: }
173:
174: HashMap p = new HashMap();
175: HashMap c = new HashMap();
176: Enumeration aliases = store.aliases();
177: UnrecoverableKeyException exception = null;
178: while (aliases.hasMoreElements())
179: {
180: String alias = (String) aliases.nextElement();
181: if (!store.isKeyEntry(alias))
182: {
183: continue;
184: }
185: X509Certificate[] chain = null;
186: Certificate[] chain2 = store.getCertificateChain (alias);
187: if (chain2 != null && chain2.length > 0 &&
188: (chain2[0] instanceof X509Certificate))
189: {
190: chain = toX509Chain(chain2);
191: }
192: else
193: {
194: continue;
195: }
196: PrivateKey key = null;
197: try
198: {
199: key = (PrivateKey) store.getKey(alias, passwd);
200: }
201: catch (UnrecoverableKeyException uke)
202: {
203: exception = uke;
204: continue;
205: }
206: if (key == null)
207: {
208: continue;
209: }
210: p.put(alias, key);
211: c.put(alias, chain);
212: }
213: if (p.isEmpty () && c.isEmpty ())
214: {
215: if (exception != null)
216: {
217: throw exception;
218: }
219: throw new KeyStoreException ("no private credentials found");
220: }
221: current = this.new Manager(p, c);
222: }
223:
224: private static X509Certificate[] toX509Chain(Certificate[] chain)
225: {
226: if (chain instanceof X509Certificate[])
227: {
228: return (X509Certificate[]) chain;
229: }
230: X509Certificate[] _chain = new X509Certificate[chain.length];
231: for (int i = 0; i < chain.length; i++)
232: _chain[i] = (X509Certificate) chain[i];
233: return _chain;
234: }
235:
236:
237:
238:
239: private class Manager implements X509KeyManager
240: {
241:
242:
243:
244: private final Map privateKeys;
245: private final Map certChains;
246:
247:
248:
249:
250: Manager(Map privateKeys, Map certChains)
251: {
252: this.privateKeys = privateKeys;
253: this.certChains = certChains;
254: }
255:
256:
257:
258:
259: public String chooseClientAlias(String[] keyTypes, Principal[] issuers,
260: Socket socket)
261: {
262: for (int i = 0; i < keyTypes.length; i++)
263: {
264: String[] s = getClientAliases(keyTypes[i], issuers);
265: if (s.length > 0)
266: return s[0];
267: }
268: return null;
269: }
270:
271: public String[] getClientAliases(String keyType, Principal[] issuers)
272: {
273: return getAliases(keyType, issuers);
274: }
275:
276: public String chooseServerAlias(String keyType, Principal[] issuers,
277: Socket socket)
278: {
279: String[] s = getServerAliases(keyType, issuers);
280: if (s.length > 0)
281: return s[0];
282: return null;
283: }
284:
285: public String[] getServerAliases(String keyType, Principal[] issuers)
286: {
287: return getAliases(keyType, issuers);
288: }
289:
290: private String[] getAliases(String keyType, Principal[] issuers)
291: {
292: LinkedList l = new LinkedList();
293: for (Iterator i = privateKeys.keySet().iterator(); i.hasNext(); )
294: {
295: String alias = (String) i.next();
296: X509Certificate[] chain = getCertificateChain(alias);
297: if (chain.length == 0)
298: continue;
299: PrivateKey privKey = getPrivateKey(alias);
300: if (privKey == null)
301: continue;
302: PublicKey pubKey = chain[0].getPublicKey();
303: if (keyType.equals("RSA") || keyType.equals("DHE_RSA") ||
304: keyType.equals("SRP_RSA") || keyType.equals("rsa_sign"))
305: {
306: if (!(privKey instanceof RSAPrivateKey) ||
307: !(pubKey instanceof RSAPublicKey))
308: continue;
309: }
310: if (keyType.equals("DHE_DSS") || keyType.equals("dss_sign") ||
311: keyType.equals("SRP_DSS"))
312: {
313: if (!(privKey instanceof DSAPrivateKey) ||
314: !(pubKey instanceof DSAPublicKey))
315: continue;
316: }
317: if (keyType.equals("DH_RSA") || keyType.equals("rsa_fixed_dh"))
318: {
319: if (!(privKey instanceof DHPrivateKey) ||
320: !(pubKey instanceof DHPublicKey))
321: continue;
322: if (!chain[0].getSigAlgName().equalsIgnoreCase("RSA"))
323: continue;
324: }
325: if (keyType.equals("DH_DSS") || keyType.equals("dss_fixed_dh"))
326: {
327: if (!(privKey instanceof DHPrivateKey) ||
328: !(pubKey instanceof DHPublicKey))
329: continue;
330: if (!chain[0].getSigAlgName().equalsIgnoreCase("DSA"))
331: continue;
332: }
333: if (issuers == null || issuers.length == 0)
334: {
335: l.add(alias);
336: continue;
337: }
338: for (int j = 0; j < issuers.length; j++)
339: if (chain[0].getIssuerDN().equals(issuers[j]))
340: {
341: l.add(alias);
342: break;
343: }
344: }
345: return (String[]) l.toArray(new String[l.size()]);
346: }
347:
348: public X509Certificate[] getCertificateChain(String alias)
349: {
350: X509Certificate[] c = (X509Certificate[]) certChains.get(alias);
351: return c != null ? (X509Certificate[]) c.clone() : null;
352: }
353:
354: public PrivateKey getPrivateKey(String alias)
355: {
356: return (PrivateKey) privateKeys.get(alias);
357: }
358: }
359: }