1 package org.objectweb.celtix.bus.transports.https; 2 3 import java.io.ByteArrayInputStream ; 4 import java.io.ByteArrayOutputStream ; 5 import java.io.DataInputStream ; 6 import java.io.FileInputStream ; 7 import java.io.IOException ; 8 import java.lang.reflect.Method ; 9 import java.net.URLConnection ; 10 import java.security.KeyStore ; 11 import java.security.cert.CertificateFactory ; 12 import java.security.cert.X509Certificate ; 13 import java.util.List ; 14 import java.util.logging.Handler ; 15 import java.util.logging.Level ; 16 import java.util.logging.Logger ; 17 18 import javax.net.ssl.HttpsURLConnection; 19 import javax.net.ssl.KeyManager; 20 import javax.net.ssl.KeyManagerFactory; 21 import javax.net.ssl.SSLContext; 22 import javax.net.ssl.TrustManager; 23 import javax.net.ssl.TrustManagerFactory; 24 25 import org.objectweb.celtix.bus.configuration.security.SSLClientPolicy; 26 import org.objectweb.celtix.common.logging.LogUtils; 27 import org.objectweb.celtix.configuration.Configuration; 28 29 30 31 public final class JettySslClientConfigurer { 32 private static final long serialVersionUID = 1L; 33 private static final Logger LOG = LogUtils.getL7dLogger(JettySslClientConfigurer.class); 34 private static final String DEFAUL_KEYSTORE_TYPE = "PKCS12"; 35 private static final String DEFAUL_TRUST_STORE_TYPE = "JKS"; 36 private static final String DEFAULT_SECURE_SOCKET_PROTOCOL = "TLSv1"; 37 private static final String CERTIFICATE_FACTORY_TYPE = "X.509"; 38 private static final String PKCS12_TYPE = "PKCS12"; 39 40 SSLClientPolicy sslPolicy; 41 42 private String keyStoreLocation; 43 private String keyStorePassword; 44 private String keyPassword; 45 private String keyStoreType = DEFAUL_KEYSTORE_TYPE; 46 private String [] cipherSuites; 47 private String trustStoreLocation; 48 private String trustStoreType = DEFAUL_TRUST_STORE_TYPE; 49 private String keystoreKeyManagerFactoryAlgorithm; 50 private String trustStoreKeyManagerFactoryAlgorithm; 51 private HttpsURLConnection httpsConnection; 52 private String secureSocketProtocol; 53 private Configuration config; 54 55 public JettySslClientConfigurer(SSLClientPolicy sslPolicyParam, 56 URLConnection connection, 57 Configuration configurationParam) { 58 59 this.sslPolicy = sslPolicyParam; 60 this.httpsConnection = (HttpsURLConnection)connection; 61 62 config = configurationParam; 63 64 } 65 66 public void configure() { 67 setupSecurityConfigurer(); 68 setupKeystore(); 69 setupKeystoreType(); 70 setupKeystorePassword(); 71 setupKeyPassword(); 72 setupKeystoreAlgorithm(); 73 setupTrustStoreAlgorithm(); 74 setupCiphersuites(); 75 setupTrustStore(); 76 setupTrustStoreType(); 77 setupSecureSocketProtocol(); 78 setupSessionCaching(); 79 setupSessionCacheKey(); 80 setupMaxChainLength(); 81 setupCertValidator(); 82 setupProxyHost(); 83 setupProxyPort(); 84 85 if (keyStoreType.equalsIgnoreCase(PKCS12_TYPE)) { 86 setupSSLContextPKCS12(); 87 } else { 88 setupSSLContext(); 89 } 90 91 } 92 93 private boolean setupSSLContext() { 94 95 if ((keyStorePassword != null) && (keyPassword != null) && (!keyStorePassword.equals(keyPassword))) { 97 LogUtils.log(LOG, Level.WARNING, "KEY_PASSWORD_NOT_SAME_KEYSTORE_PASSWORD"); 98 } 99 try { 100 SSLContext sslctx = SSLContext.getInstance(secureSocketProtocol); 101 102 KeyManagerFactory kmf = 103 KeyManagerFactory.getInstance(keystoreKeyManagerFactoryAlgorithm); 104 KeyStore ks = KeyStore.getInstance(keyStoreType); 105 FileInputStream fis = new FileInputStream (keyStoreLocation); 106 DataInputStream dis = new DataInputStream (fis); 107 byte[] bytes = new byte[dis.available()]; 108 dis.readFully(bytes); 109 ByteArrayInputStream bin = new ByteArrayInputStream (bytes); 110 111 KeyManager[] keystoreManagers = null; 112 if (keyStorePassword != null) { 113 try { 114 ks.load(bin, keyStorePassword.toCharArray()); 115 kmf.init(ks, keyStorePassword.toCharArray()); 116 keystoreManagers = kmf.getKeyManagers(); 117 LogUtils.log(LOG, Level.INFO, "LOADED_KEYSTORE", new Object []{keyStoreLocation}); 118 } catch (Exception e) { 119 LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_KEYSTORE", 120 new Object []{keyStoreLocation, e.getMessage()}); 121 } 122 } 123 if ((keyStorePassword == null) && (keyStoreLocation != null)) { 124 LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_KEYSTORE_NULL_PASSWORD", 125 new Object []{keyStoreLocation}); 126 } 127 128 130 TrustManager[] trustStoreManagers = null; 131 KeyStore trustedCertStore = KeyStore.getInstance(trustStoreType); 132 133 trustedCertStore.load(new FileInputStream (trustStoreLocation), null); 134 TrustManagerFactory tmf = 135 TrustManagerFactory.getInstance(trustStoreKeyManagerFactoryAlgorithm); 136 try { 137 tmf.init(trustedCertStore); 138 trustStoreManagers = tmf.getTrustManagers(); 139 LogUtils.log(LOG, Level.INFO, "LOADED_TRUST_STORE", new Object []{trustStoreLocation}); 140 } catch (Exception e) { 141 LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_TRUST_STORE", 142 new Object []{trustStoreLocation, e.getMessage()}); 143 } 144 sslctx.init(keystoreManagers, trustStoreManagers, null); 145 146 httpsConnection.setSSLSocketFactory(new SSLSocketFactoryWrapper(sslctx.getSocketFactory(), 147 cipherSuites)); 148 149 150 151 } catch (Exception e) { 152 LogUtils.log(LOG, Level.SEVERE, "SSL_CONTEXT_INIT_FAILURE", new Object []{e.getMessage()}); 153 return false; 154 } 155 return true; 156 } 157 158 159 private boolean setupSSLContextPKCS12() { 160 161 if ((keyStorePassword != null) && (keyPassword != null) && (!keyStorePassword.equals(keyPassword))) { 163 LogUtils.log(LOG, Level.WARNING, "KEY_PASSWORD_NOT_SAME_KEYSTORE_PASSWORD"); 164 } 165 try { 166 SSLContext sslctx = SSLContext.getInstance(secureSocketProtocol); 167 KeyManagerFactory kmf = 168 KeyManagerFactory.getInstance(keystoreKeyManagerFactoryAlgorithm); 169 KeyStore ks = KeyStore.getInstance(keyStoreType); 170 KeyManager[] keystoreManagers = null; 171 172 173 byte[] sslCert = loadClientCredential(keyStoreLocation); 174 175 if (sslCert != null && sslCert.length > 0 && keyStorePassword != null) { 176 ByteArrayInputStream bin = new ByteArrayInputStream (sslCert); 177 try { 178 ks.load(bin, keyStorePassword.toCharArray()); 179 kmf.init(ks, keyStorePassword.toCharArray()); 180 keystoreManagers = kmf.getKeyManagers(); 181 LogUtils.log(LOG, Level.INFO, "LOADED_KEYSTORE", new Object []{keyStoreLocation}); 182 } catch (Exception e) { 183 LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_KEYSTORE", 184 new Object []{keyStoreLocation, e.getMessage()}); 185 } 186 } 187 if ((keyStorePassword == null) && (keyStoreLocation != null)) { 188 LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_KEYSTORE_NULL_PASSWORD", 189 new Object []{keyStoreLocation}); 190 } 191 192 TrustManager[] trustStoreManagers = new TrustManager[1]; 195 196 KeyStore trustedCertStore = KeyStore.getInstance(trustStoreType); 197 trustedCertStore.load(null, "".toCharArray()); 198 CertificateFactory cf = CertificateFactory.getInstance(CERTIFICATE_FACTORY_TYPE); 199 byte[] caCert = loadCACert(trustStoreLocation); 200 try { 201 if (caCert != null) { 202 ByteArrayInputStream cabin = new ByteArrayInputStream (caCert); 203 X509Certificate cert = (X509Certificate )cf.generateCertificate(cabin); 204 trustedCertStore.setCertificateEntry(cert.getIssuerDN().toString(), cert); 205 cabin.close(); 206 } 207 } catch (Exception e) { 208 LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_TRUST_STORE", 209 new Object []{trustStoreLocation, e.getMessage()}); 210 } 211 TrustManagerFactory tmf = 212 TrustManagerFactory.getInstance(trustStoreKeyManagerFactoryAlgorithm); 213 214 tmf.init(trustedCertStore); 215 LogUtils.log(LOG, Level.INFO, "LOADED_TRUST_STORE", new Object []{trustStoreLocation}); 216 217 trustStoreManagers = tmf.getTrustManagers(); 218 219 220 sslctx.init(keystoreManagers, trustStoreManagers, null); 221 httpsConnection.setSSLSocketFactory(new SSLSocketFactoryWrapper(sslctx.getSocketFactory(), 222 cipherSuites)); 223 224 } catch (Exception e) { 225 LogUtils.log(LOG, Level.SEVERE, "SSL_CONTEXT_INIT_FAILURE", new Object []{e.getMessage()}); 226 return false; 227 } 228 return true; 229 } 230 231 232 233 private static byte[] loadClientCredential(String fileName) throws IOException { 234 if (fileName == null) { 235 return null; 236 } 237 FileInputStream in = new FileInputStream (fileName); 238 ByteArrayOutputStream out = new ByteArrayOutputStream (); 239 byte[] buf = new byte[512]; 240 int i = in.read(buf); 241 while (i > 0) { 242 out.write(buf, 0, i); 243 i = in.read(buf); 244 } 245 in.close(); 246 return out.toByteArray(); 247 } 248 249 250 251 private static byte[] loadCACert(String fileName) throws IOException { 252 if (fileName == null) { 253 return null; 254 } 255 FileInputStream in = new FileInputStream (fileName); 256 ByteArrayOutputStream out = new ByteArrayOutputStream (); 257 byte[] buf = new byte[512]; 258 int i = in.read(buf); 259 260 while (i > 0) { 261 out.write(buf, 0, i); 262 i = in.read(buf); 263 } 264 in.close(); 265 return out.toByteArray(); 266 } 267 268 269 public void setupKeystore() { 270 if (sslPolicy.isSetKeystore()) { 271 keyStoreLocation = sslPolicy.getKeystore(); 272 LogUtils.log(LOG, Level.INFO, "KEY_STORE_SET", new Object []{keyStoreLocation}); 273 return; 274 } 275 keyStoreLocation = System.getProperty("javax.net.ssl.keyStore"); 276 if (keyStoreLocation != null) { 277 LogUtils.log(LOG, Level.INFO, "KEY_STORE_SYSTEM_PROPERTY_SET", new Object []{keyStoreLocation}); 278 return; 279 } 280 281 keyStoreLocation = System.getProperty("user.home") + "/.keystore"; 282 LogUtils.log(LOG, Level.INFO, "KEY_STORE_NOT_SET", new Object []{keyStoreLocation}); 283 284 } 285 286 public void setupKeystoreType() { 287 if (!sslPolicy.isSetKeystoreType()) { 288 LogUtils.log(LOG, Level.INFO, "KEY_STORE_TYPE_NOT_SET", new Object []{DEFAUL_KEYSTORE_TYPE}); 289 return; 290 } 291 keyStoreType = sslPolicy.getKeystoreType(); 292 LogUtils.log(LOG, Level.INFO, "KEY_STORE_TYPE_SET", new Object []{keyStoreType}); 293 } 294 295 public void setupKeystorePassword() { 296 if (sslPolicy.isSetKeystorePassword()) { 297 LogUtils.log(LOG, Level.INFO, "KEY_STORE_PASSWORD_SET"); 298 keyStorePassword = sslPolicy.getKeystorePassword(); 299 return; 300 } 301 keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword"); 302 if (keyStorePassword != null) { 303 LogUtils.log(LOG, Level.INFO, "KEY_STORE_PASSWORD_SYSTEM_PROPERTY_SET"); 304 return; 305 } 306 LogUtils.log(LOG, Level.INFO, "KEY_STORE_PASSWORD_NOT_SET"); 307 308 } 309 310 public void setupKeyPassword() { 311 if (sslPolicy.isSetKeyPassword()) { 312 LogUtils.log(LOG, Level.INFO, "KEY_PASSWORD_SET"); 313 keyPassword = sslPolicy.getKeyPassword(); 314 return; 315 } 316 keyPassword = System.getProperty("javax.net.ssl.keyStorePassword"); 317 if (keyPassword != null) { 318 LogUtils.log(LOG, Level.INFO, "KEY_PASSWORD_SYSTEM_PROPERTY_SET"); 319 return; 320 } 321 322 LogUtils.log(LOG, Level.INFO, "KEY_PASSWORD_NOT_SET"); 323 } 324 325 326 327 public void setupKeystoreAlgorithm() { 328 if (sslPolicy.isSetKeystoreAlgorithm()) { 329 keystoreKeyManagerFactoryAlgorithm = sslPolicy.getKeystoreAlgorithm(); 330 LogUtils.log(LOG, Level.INFO, 331 "KEY_STORE_ALGORITHM_SET", 332 new Object [] {keystoreKeyManagerFactoryAlgorithm}); 333 return; 334 } 335 keystoreKeyManagerFactoryAlgorithm = KeyManagerFactory.getDefaultAlgorithm(); 336 LogUtils.log(LOG, Level.INFO, 337 "KEY_STORE_ALGORITHM_NOT_SET", 338 new Object [] {keystoreKeyManagerFactoryAlgorithm}); 339 } 340 341 public void setupTrustStoreAlgorithm() { 342 if (sslPolicy.isSetKeystoreAlgorithm()) { 343 trustStoreKeyManagerFactoryAlgorithm = sslPolicy.getTrustStoreAlgorithm(); 344 LogUtils.log(LOG, Level.INFO, 345 "TRUST_STORE_ALGORITHM_SET", 346 new Object [] {trustStoreKeyManagerFactoryAlgorithm}); 347 return; 348 } 349 trustStoreKeyManagerFactoryAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 350 LogUtils.log(LOG, Level.INFO, 351 "TRUST_STORE_ALGORITHM_NOT_SET", 352 new Object [] {trustStoreKeyManagerFactoryAlgorithm}); 353 } 354 355 public void setupCiphersuites() { 356 if (sslPolicy.isSetCiphersuites()) { 357 358 List <String > cipherSuitesList = sslPolicy.getCiphersuites(); 359 int numCipherSuites = cipherSuitesList.size(); 360 cipherSuites = new String [numCipherSuites]; 361 String ciphsStr = null; 362 for (int i = 0; i < numCipherSuites; i++) { 363 cipherSuites[i] = cipherSuitesList.get(i); 364 if (ciphsStr == null) { 365 ciphsStr = cipherSuites[i]; 366 } else { 367 ciphsStr += ", " + cipherSuites[i]; 368 } 369 } 370 LogUtils.log(LOG, Level.INFO, "CIPHERSUITE_SET", new Object []{ciphsStr}); 371 return; 372 } 373 LogUtils.log(LOG, Level.INFO, "CIPHERSUITE_NOT_SET"); 374 } 375 376 public void setupTrustStore() { 377 if (sslPolicy.isSetTrustStore()) { 378 trustStoreLocation = sslPolicy.getTrustStore(); 379 LogUtils.log(LOG, Level.INFO, "TRUST_STORE_SET", new Object []{trustStoreLocation}); 380 return; 381 } 382 383 trustStoreLocation = System.getProperty("javax.net.ssl.trustStore"); 384 if (trustStoreLocation != null) { 385 LogUtils.log(LOG, Level.INFO, "TRUST_STORE_SYSTEM_PROPERTY_SET", 386 new Object []{trustStoreLocation}); 387 return; 388 } 389 390 trustStoreLocation = System.getProperty("java.home") + "/lib/security/cacerts"; 391 LogUtils.log(LOG, Level.INFO, "TRUST_STORE_NOT_SET", new Object []{trustStoreLocation}); 392 393 } 394 395 public void setupTrustStoreType() { 396 if (!sslPolicy.isSetTrustStoreType()) { 397 LogUtils.log(LOG, Level.INFO, "TRUST_STORE_TYPE_NOT_SET", new Object []{DEFAUL_TRUST_STORE_TYPE}); 398 return; 400 } 401 trustStoreType = sslPolicy.getTrustStoreType(); 402 LogUtils.log(LOG, Level.INFO, "TRUST_STORE_TYPE_SET", new Object []{trustStoreType}); 403 } 404 405 406 public void setupSecureSocketProtocol() { 407 if (!sslPolicy.isSetSecureSocketProtocol()) { 408 LogUtils.log(LOG, Level.INFO, "SECURE_SOCKET_PROTOCOL_NOT_SET"); 409 secureSocketProtocol = DEFAULT_SECURE_SOCKET_PROTOCOL; 410 return; 411 } 412 secureSocketProtocol = sslPolicy.getSecureSocketProtocol(); 413 LogUtils.log(LOG, Level.INFO, "SECURE_SOCKET_PROTOCOL_SET", new Object [] {secureSocketProtocol}); 414 } 415 416 public boolean setupSessionCaching() { 417 if (sslPolicy.isSetSessionCaching()) { 418 LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA", 419 new Object []{"SessionCaching"}); 420 } 421 return true; 422 } 423 424 public boolean setupSessionCacheKey() { 425 if (sslPolicy.isSetSessionCacheKey()) { 426 LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA", 427 new Object []{"SessionCacheKey"}); 428 } 429 return true; 430 } 431 432 public boolean setupMaxChainLength() { 433 if (sslPolicy.isSetMaxChainLength()) { 434 LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA", 435 new Object []{"MaxChainLength"}); 436 } 437 return true; 438 } 439 440 public boolean setupCertValidator() { 441 if (sslPolicy.isSetCertValidator()) { 442 LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA", 443 new Object []{"CertValidator"}); 444 } 445 return true; 446 } 447 448 public boolean setupProxyHost() { 449 if (sslPolicy.isSetProxyHost()) { 450 LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA", 451 new Object []{"ProxyHost"}); 452 } 453 return true; 454 } 455 456 public boolean setupProxyPort() { 457 if (sslPolicy.isSetProxyPort()) { 458 LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA", 459 new Object []{"ProxyPort"}); 460 } 461 return true; 462 } 463 464 465 public void setupSecurityConfigurer() { 466 String systemProperty = "celtix.security.configurer.celtix." 467 + config.getId() + ".http-client"; 468 String securityConfigurerName = 469 System.getProperty(systemProperty); 470 471 if ((securityConfigurerName == null) 472 || (securityConfigurerName.equals(""))) { 473 return; 474 } 475 LogUtils.log(LOG, Level.WARNING, "UNOFFICIAL_SECURITY_CONFIGURER"); 476 477 try { 478 Class clazz = Class.forName(securityConfigurerName); 479 Method configure = clazz.getDeclaredMethod("configure", SSLClientPolicy.class); 480 Object [] params = new Object []{sslPolicy}; 481 Object configurer = clazz.newInstance(); 482 configure.invoke(configurer, params); 483 LogUtils.log(LOG, Level.INFO, "SUCCESS_INVOKING_SECURITY_CONFIGURER", 484 new Object []{securityConfigurerName}); 485 } catch (Exception e) { 486 LogUtils.log(LOG, Level.SEVERE, "ERROR_INVOKING_SECURITY_CONFIGURER", 487 new Object []{securityConfigurerName, e.getMessage()}); 488 } 489 } 490 491 protected HttpsURLConnection getHttpsConnection() { 492 return httpsConnection; 493 } 494 495 496 499 500 501 protected boolean testAllDataHasSetupMethod() { 502 Method [] sslPolicyMethods = sslPolicy.getClass().getDeclaredMethods(); 503 Class [] classArgs = null; 504 505 for (int i = 0; i < sslPolicyMethods.length; i++) { 506 String sslPolicyMethodName = sslPolicyMethods[i].getName(); 507 if (sslPolicyMethodName.startsWith("isSet")) { 508 String dataName = 509 sslPolicyMethodName.substring("isSet".length(), sslPolicyMethodName.length()); 510 String thisMethodName = "setup" + dataName; 511 try { 512 this.getClass().getMethod(thisMethodName, classArgs); 513 } catch (Exception e) { 514 e.printStackTrace(); 515 return false; 516 } 517 518 } 519 } 520 return true; 521 } 522 523 protected void addLogHandler(Handler handler) { 524 LOG.addHandler(handler); 525 } 526 527 } 528 529 | Popular Tags |