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