PageRenderTime 36ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/org.eclipse.tcf/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/ssl/TCFSecurityManager.java

https://github.com/eswartz/emul
Java | 231 lines | 197 code | 20 blank | 14 comment | 53 complexity | 044b2f22c3ace94a29c997c212880fee MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * Wind River Systems - initial API and implementation
  10. *******************************************************************************/
  11. package org.eclipse.tm.tcf.ssl;
  12. import java.io.BufferedInputStream;
  13. import java.io.BufferedReader;
  14. import java.io.File;
  15. import java.io.FileInputStream;
  16. import java.io.IOException;
  17. import java.io.InputStream;
  18. import java.io.InputStreamReader;
  19. import java.net.Socket;
  20. import java.security.KeyFactory;
  21. import java.security.Principal;
  22. import java.security.PrivateKey;
  23. import java.security.cert.CertificateException;
  24. import java.security.cert.CertificateFactory;
  25. import java.security.cert.X509Certificate;
  26. import java.security.spec.PKCS8EncodedKeySpec;
  27. import java.util.ArrayList;
  28. import javax.net.ssl.KeyManager;
  29. import javax.net.ssl.SSLContext;
  30. import javax.net.ssl.TrustManager;
  31. import javax.net.ssl.X509ExtendedKeyManager;
  32. import javax.net.ssl.X509TrustManager;
  33. import org.eclipse.tm.tcf.Activator;
  34. import org.eclipse.tm.tcf.core.Base64;
  35. import org.eclipse.tm.tcf.protocol.Protocol;
  36. /**
  37. * This class implements keys and certificates management for secure TCF channels.
  38. */
  39. public class TCFSecurityManager {
  40. public static File getCertificatesDirectory() {
  41. File certs;
  42. try {
  43. certs = Activator.getDefault().getStateLocation().append("certificates").toFile(); //$NON-NLS-1$
  44. }
  45. catch (IllegalStateException e) {
  46. // An RCP workspace-less environment (-data @none)
  47. certs = new File(System.getProperty("user.home"), ".tcf");
  48. certs = new File(certs, "certificates");
  49. }
  50. if (!certs.exists()) certs.mkdirs();
  51. return certs;
  52. }
  53. public static File getSysCertificatesDirectory() {
  54. File file = null;
  55. String osname = System.getProperty("os.name", "");
  56. if (osname.startsWith("Windows")) {
  57. try {
  58. String sys_root = "SystemRoot";
  59. Process prs = Runtime.getRuntime().exec(new String[]{ "cmd", "/c", "set", sys_root }, null);
  60. BufferedReader inp = new BufferedReader(new InputStreamReader(prs.getInputStream()));
  61. for (;;) {
  62. String s = inp.readLine();
  63. if (s == null) break;
  64. int i = s.indexOf('=');
  65. if (i > 0) {
  66. String name = s.substring(0, i);
  67. if (name.equalsIgnoreCase(sys_root)) {
  68. File root = new File(s.substring(i + 1));
  69. if (root.exists()) file = new File(root, "TCF/ssl");
  70. }
  71. }
  72. }
  73. try {
  74. prs.getErrorStream().close();
  75. prs.getOutputStream().close();
  76. inp.close();
  77. }
  78. catch (IOException x) {
  79. }
  80. prs.waitFor();
  81. }
  82. catch (Throwable x) {
  83. }
  84. }
  85. else {
  86. file = new File("/etc/tcf/ssl");
  87. }
  88. if (file == null) return null;
  89. if (!file.exists()) return null;
  90. if (!file.isDirectory()) return null;
  91. return file;
  92. }
  93. public static SSLContext createSSLContext() {
  94. try {
  95. final File usr_certs = getCertificatesDirectory();
  96. final File sys_certs = getSysCertificatesDirectory();
  97. if (!usr_certs.exists()) usr_certs.mkdirs();
  98. final CertificateFactory cf = CertificateFactory.getInstance("X.509"); //$NON-NLS-1$
  99. SSLContext context = SSLContext.getInstance("TLS"); //$NON-NLS-1$
  100. X509ExtendedKeyManager km = new X509ExtendedKeyManager() {
  101. public X509Certificate[] getCertificateChain(String alias) {
  102. File f = new File(usr_certs, "local.cert"); //$NON-NLS-1$
  103. if (!f.exists() && sys_certs != null) f = new File(sys_certs, "local.cert"); //$NON-NLS-1$
  104. try {
  105. InputStream inp = new BufferedInputStream(new FileInputStream(f));
  106. X509Certificate cert = (X509Certificate)cf.generateCertificate(inp);
  107. inp.close();
  108. return new X509Certificate[] { cert };
  109. }
  110. catch (Exception x) {
  111. Protocol.log("Cannot read certificate: " + f, x); //$NON-NLS-1$
  112. return null;
  113. }
  114. }
  115. public PrivateKey getPrivateKey(String alias) {
  116. File f = new File(usr_certs, "local.priv"); //$NON-NLS-1$
  117. if (!f.exists() && sys_certs != null) f = new File(sys_certs, "local.priv"); //$NON-NLS-1$
  118. try {
  119. BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(f), "ASCII")); //$NON-NLS-1$
  120. StringBuffer bf = new StringBuffer();
  121. boolean app = false;
  122. for (;;) {
  123. String s = r.readLine();
  124. if (s == null) new Exception("Invalid format"); //$NON-NLS-1$
  125. else if (s.indexOf("-----BEGIN ") == 0) app = true; //$NON-NLS-1$
  126. else if (s.indexOf("-----END ") == 0) break; //$NON-NLS-1$
  127. else if (app) bf.append(s);
  128. }
  129. r.close();
  130. KeyFactory kf = KeyFactory.getInstance("RSA"); //$NON-NLS-1$
  131. byte[] bytes = Base64.toByteArray(bf.toString().toCharArray());
  132. return kf.generatePrivate(new PKCS8EncodedKeySpec(bytes));
  133. }
  134. catch (Exception x) {
  135. Protocol.log("Cannot read private key: " + f, x); //$NON-NLS-1$
  136. return null;
  137. }
  138. }
  139. public String[] getClientAliases(String keyType, Principal[] issuers) {
  140. return new String[] { "TCF" }; //$NON-NLS-1$
  141. }
  142. public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
  143. return "TCF"; //$NON-NLS-1$
  144. }
  145. public String[] getServerAliases(String keyType, Principal[] issuers) {
  146. return new String[] { "TCF" }; //$NON-NLS-1$
  147. }
  148. public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
  149. return "TCF"; //$NON-NLS-1$
  150. }
  151. };
  152. X509TrustManager tm = new X509TrustManager() {
  153. public void checkClientTrusted(X509Certificate[] chain, String auth_type) throws CertificateException {
  154. if ("RSA".equals(auth_type) && chain != null && chain.length == 1) { //$NON-NLS-1$
  155. for (X509Certificate cert : getAcceptedIssuers()) {
  156. if (cert.equals(chain[0])) return;
  157. }
  158. }
  159. throw new CertificateException("Client certificate validation failed"); //$NON-NLS-1$
  160. }
  161. public void checkServerTrusted(X509Certificate[] chain, String auth_type) throws CertificateException {
  162. if ("RSA".equals(auth_type) && chain != null && chain.length == 1) { //$NON-NLS-1$
  163. for (X509Certificate cert : getAcceptedIssuers()) {
  164. if (cert.equals(chain[0])) return;
  165. }
  166. }
  167. throw new CertificateException("Server certificate validation failed"); //$NON-NLS-1$
  168. }
  169. public X509Certificate[] getAcceptedIssuers() {
  170. ArrayList<X509Certificate> list = new ArrayList<X509Certificate>();
  171. for (String fnm : usr_certs.list()) {
  172. if (!fnm.endsWith(".cert")) continue; //$NON-NLS-1$
  173. try {
  174. InputStream inp = new BufferedInputStream(new FileInputStream(new File(usr_certs, fnm)));
  175. X509Certificate cert = (X509Certificate)cf.generateCertificate(inp);
  176. inp.close();
  177. list.add(cert);
  178. }
  179. catch (Throwable x) {
  180. Protocol.log("Cannot load certificate: " + fnm, x); //$NON-NLS-1$
  181. }
  182. }
  183. if (sys_certs != null) {
  184. String[] arr = sys_certs.list();
  185. if (arr != null) {
  186. for (String fnm : arr) {
  187. if (!fnm.endsWith(".cert")) continue; //$NON-NLS-1$
  188. try {
  189. InputStream inp = new BufferedInputStream(new FileInputStream(new File(sys_certs, fnm)));
  190. X509Certificate cert = (X509Certificate)cf.generateCertificate(inp);
  191. inp.close();
  192. list.add(cert);
  193. }
  194. catch (Throwable x) {
  195. Protocol.log("Cannot load certificate: " + fnm, x); //$NON-NLS-1$
  196. }
  197. }
  198. }
  199. }
  200. return list.toArray(new X509Certificate[list.size()]);
  201. }
  202. };
  203. context.init(new KeyManager[] { km }, new TrustManager[] { tm }, null);
  204. return context;
  205. }
  206. catch (Throwable x) {
  207. Protocol.log("Cannot initialize SSL context", x); //$NON-NLS-1$
  208. return null;
  209. }
  210. }
  211. }