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