PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/org/owasp/webscarab/plugin/SSLKeyManager.java

https://github.com/OWASP/OWASP-WebScarab
Java | 266 lines | 213 code | 37 blank | 16 comment | 37 complexity | 97f3b9f6457f80a8dbd0ee2c58215925 MD5 | raw file
Possible License(s): AGPL-1.0
  1. /*
  2. * SSLKeyManager.java
  3. *
  4. * Created on 20 July 2005, 10:05
  5. *
  6. * To change this template, choose Tools | Options and locate the template under
  7. * the Source Creation and Management node. Right-click the template and choose
  8. * Open. You can then make changes to the template in the Source Editor.
  9. */
  10. package org.owasp.webscarab.plugin;
  11. import javax.net.ssl.KeyManagerFactory;
  12. import javax.net.ssl.KeyManager;
  13. import javax.net.ssl.X509KeyManager;
  14. import java.security.KeyStore;
  15. import java.security.KeyStoreException;
  16. import java.security.Principal;
  17. import java.security.PrivateKey;
  18. import java.security.Provider;
  19. import java.security.Security;
  20. import java.security.cert.X509Certificate;
  21. import java.security.NoSuchAlgorithmException;
  22. import java.security.UnrecoverableKeyException;
  23. import java.security.cert.CertificateException;
  24. import java.net.Socket;
  25. import java.util.Map;
  26. import java.util.TreeMap;
  27. import java.util.Iterator;
  28. import java.util.List;
  29. import java.util.ArrayList;
  30. import java.util.Enumeration;
  31. import java.util.logging.Logger;
  32. import java.util.logging.Level;
  33. import java.io.IOException;
  34. import java.io.FileInputStream;
  35. import java.beans.PropertyChangeSupport;
  36. import java.beans.PropertyChangeListener;
  37. /**
  38. *
  39. * @author rdawes
  40. */
  41. public class SSLKeyManager implements X509KeyManager {
  42. public final static String KEY_PROPERTY = "KEYS";
  43. public final static String SELECTED_KEY = "SELECTED KEY";
  44. private static final String SEP = " -:- ";
  45. private String _preferredStore = null;
  46. private String _preferredAlias = null;
  47. private X509KeyManager _preferredKeyManager = null;
  48. private Map<String, KeyStore> _stores = new TreeMap<String, KeyStore>();
  49. private Map<String, X509KeyManager> _managers = new TreeMap<String, X509KeyManager>();
  50. private PropertyChangeSupport _changeSupport = new PropertyChangeSupport(this);
  51. private Logger _logger = Logger.getLogger(getClass().getName());
  52. /**
  53. * Creates a new instance of SSLKeyManager
  54. */
  55. public SSLKeyManager() {
  56. _logger.setLevel(Level.FINEST);
  57. if (System.getProperty("os.name", "").toLowerCase().indexOf("windows")>-1) {
  58. Provider provider;
  59. try {
  60. provider = (Provider) Class.forName("se.assembla.jce.provider.ms.MSProvider").newInstance();
  61. } catch (Throwable t) {
  62. return;
  63. }
  64. try {
  65. Security.insertProviderAt(provider, 2);
  66. KeyStore ks = KeyStore.getInstance("msks", "assembla");
  67. ks.load(null, null);
  68. addKeyStore("Microsoft CAPI store", ks, null);
  69. } catch (Exception e) {
  70. _logger.info("Microsoft CAPI interface not available: " + e);
  71. }
  72. }
  73. }
  74. public synchronized String addPKCS12KeyStore(String filename, String keyStorePassword, String keyPassword) throws KeyStoreException, UnrecoverableKeyException, IOException, CertificateException {
  75. if (keyStorePassword == null) keyStorePassword = "";
  76. if (keyPassword == null) keyPassword = keyStorePassword;
  77. try {
  78. KeyStore ks = KeyStore.getInstance("PKCS12");
  79. ks.load(new FileInputStream(filename), keyStorePassword.toCharArray());
  80. String description = "PKCS#12: " + filename;
  81. addKeyStore(description, ks, keyPassword.toCharArray());
  82. return description;
  83. } catch (NoSuchAlgorithmException nsae) {
  84. _logger.severe("No SunX509 suport: " + nsae);
  85. return null;
  86. }
  87. }
  88. public synchronized void addKeyStore(String description, KeyStore ks, char[] password) throws KeyStoreException, UnrecoverableKeyException {
  89. try {
  90. KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
  91. kmf.init(ks, password);
  92. KeyManager km = kmf.getKeyManagers()[0];
  93. if (!(km instanceof X509KeyManager))
  94. throw new KeyStoreException("KeyManager for " + description + "is not X509!");
  95. _stores.put(description, ks);
  96. _managers.put(description, (X509KeyManager) km);
  97. } catch (NoSuchAlgorithmException nsae) {
  98. _logger.severe("This should never happen! SunX509 algorithm not found: " + nsae.getMessage());
  99. }
  100. _changeSupport.firePropertyChange(KEY_PROPERTY, null, null);
  101. }
  102. public String[] getKeyStoreDescriptions() {
  103. return _stores.keySet().toArray(new String[0]);
  104. }
  105. public synchronized void removeKeyStore(String description) {
  106. _stores.remove(description);
  107. _changeSupport.firePropertyChange(KEY_PROPERTY, null, null);
  108. }
  109. public void addPropertyChangeListener(PropertyChangeListener listener) {
  110. _changeSupport.addPropertyChangeListener(listener);
  111. }
  112. public void removePropertyChangeListener(PropertyChangeListener listener) {
  113. _changeSupport.removePropertyChangeListener(listener);
  114. }
  115. public synchronized String[] getAliases(String description) {
  116. KeyStore ks = _stores.get(description);
  117. if (ks == null) {
  118. return null;
  119. }
  120. List<String> aliases = new ArrayList<String>();
  121. try {
  122. Enumeration<String> e = ks.aliases();
  123. while (e.hasMoreElements()) {
  124. aliases.add(e.nextElement());
  125. }
  126. } catch (KeyStoreException kse) {
  127. _logger.severe("Error enumerating aliases: " + kse.getMessage());
  128. }
  129. return aliases.toArray(new String[0]);
  130. }
  131. public synchronized boolean setPreferredAlias(String description, String alias) {
  132. String old = String.valueOf(_preferredStore) + SEP + String.valueOf(_preferredAlias);
  133. if (description != null && alias != null) {
  134. KeyStore ks = _stores.get(description);
  135. try {
  136. if (ks.isKeyEntry(alias)) {
  137. _preferredKeyManager = _managers.get(description);
  138. _preferredStore = description;
  139. _preferredAlias = alias;
  140. String now = String.valueOf(_preferredStore) + SEP + String.valueOf(_preferredAlias);
  141. if (!now.equals(old))
  142. _changeSupport.firePropertyChange(SELECTED_KEY, null, null);
  143. return true;
  144. }
  145. } catch (KeyStoreException kse) {
  146. _logger.severe("Unexpected KeyStore exception: " + kse.getMessage());
  147. }
  148. }
  149. _preferredKeyManager = null;
  150. _preferredStore = null;
  151. _preferredAlias = null;
  152. String now = String.valueOf(_preferredStore) + SEP + String.valueOf(_preferredAlias);
  153. if (!now.equals(old))
  154. _changeSupport.firePropertyChange(SELECTED_KEY, null, null);
  155. return false;
  156. }
  157. public String getPreferredStore() {
  158. return _preferredStore;
  159. }
  160. public String getPreferredAlias() {
  161. return _preferredAlias;
  162. }
  163. public synchronized String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
  164. _logger.entering(getClass().getName(), "chooseClientAlias");
  165. if (_preferredStore != null && _preferredAlias != null)
  166. return _preferredStore + SEP + _preferredAlias;
  167. return null;
  168. }
  169. public synchronized String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
  170. if (_preferredKeyManager != null)
  171. return _preferredKeyManager.chooseServerAlias(keyType, issuers, socket);
  172. Iterator<String> it = _managers.keySet().iterator();
  173. while (it.hasNext()) {
  174. String source = it.next();
  175. X509KeyManager km = _managers.get(source);
  176. String alias = km.chooseServerAlias(keyType, issuers, socket);
  177. if (alias != null) return source + SEP + alias;
  178. }
  179. return null;
  180. }
  181. public synchronized X509Certificate[] getCertificateChain(String alias) {
  182. String[] parts = alias.split(SEP, 2);
  183. String description = parts[0];
  184. alias = parts[1];
  185. X509KeyManager km = (X509KeyManager) _managers.get(description);
  186. return km.getCertificateChain(alias);
  187. }
  188. public synchronized String[] getClientAliases(String keyType, Principal[] issuers) {
  189. if (_preferredKeyManager != null)
  190. return _preferredKeyManager.getClientAliases(keyType, issuers);
  191. List<String> allAliases = new ArrayList<String>();
  192. Iterator<String> it = _managers.keySet().iterator();
  193. while (it.hasNext()) {
  194. String source = it.next();
  195. X509KeyManager km = _managers.get(source);
  196. String[] aliases = km.getClientAliases(keyType, issuers);
  197. if (aliases != null) {
  198. for (int i=0; i<aliases.length; i++) {
  199. allAliases.add(source + SEP + aliases[i]);
  200. }
  201. }
  202. }
  203. return allAliases.toArray(new String[0]);
  204. }
  205. public synchronized PrivateKey getPrivateKey(String alias) {
  206. String[] parts = alias.split(SEP, 2);
  207. String description = parts[0];
  208. alias = parts[1];
  209. X509KeyManager km = _managers.get(description);
  210. return km.getPrivateKey(alias);
  211. }
  212. public synchronized String[] getServerAliases(String keyType, Principal[] issuers) {
  213. if (_preferredKeyManager != null)
  214. return _preferredKeyManager.getServerAliases(keyType, issuers);
  215. List<String> allAliases = new ArrayList<String>();
  216. Iterator<String> it = _managers.keySet().iterator();
  217. while (it.hasNext()) {
  218. String source = it.next();
  219. X509KeyManager km = _managers.get(source);
  220. String[] aliases = km.getServerAliases(keyType, issuers);
  221. if (aliases != null) {
  222. for (int i=0; i<aliases.length; i++) {
  223. allAliases.add(source + SEP + aliases[i]);
  224. }
  225. }
  226. }
  227. return allAliases.toArray(new String[0]);
  228. }
  229. }