1 package com.ca.commons.jndi; 2 3 7 8 import java.io.*; 9 import java.net.*; 10 import javax.net.SocketFactory; 11 import javax.net.ssl.SSLSocketFactory; 12 import java.lang.reflect.Constructor ; 13 import java.lang.reflect.Method ; 14 15 import java.security.KeyStore ; 16 import java.security.GeneralSecurityException ; 17 18 import javax.net.ssl.*; 21 import javax.naming.NamingException ; 23 24 42 43 public class JndiSocketFactory extends SSLSocketFactory 44 { 45 46 50 51 private static SSLSocketFactory factory = null; 52 53 58 59 private static JndiSocketFactory default_factory = null; 60 61 62 private static KeyStore clientKeystore; 63 64 68 69 private static final String DEFAULT_KEYSTORE_TYPE = "JKS"; 70 71 76 77 private static final String PKI_INTERNAL_TYPE = "KSE"; 78 79 80 84 85 private static ClassLoader myClassLoader = null; 86 87 91 92 public static void setClassLoader(ClassLoader newLoader) 93 { 94 myClassLoader = newLoader; 95 } 96 97 102 103 private static ClassLoader getClassLoader() 104 { 105 if (myClassLoader == null) 106 myClassLoader = ClassLoader.getSystemClassLoader(); 107 108 return myClassLoader; 109 } 110 111 112 113 116 117 public static void setDebugOn() 118 { 119 137 138 System.setProperty("javax.net.debug", "ssl handshake verbose"); 139 } 140 141 172 173 public static void init(String caKeystoreFile, String clientKeystoreFile, 174 char[] caPassphrase, char[] clientPassphrase, 175 String caKeystoreType, String clientKeystoreType) 176 throws NamingException 177 { 178 if (default_factory != null) 179 return; 180 181 try 182 { 183 checkFileSanity(caKeystoreFile, clientKeystoreFile, clientPassphrase); 184 185 if (caKeystoreFile == null) 187 caKeystoreFile = clientKeystoreFile; 188 189 SSLContext sslctx; 190 191 198 214 216 String protocol = System.getProperty("sslversion", "TLS"); if (!"TLS".equals(protocol)) 220 System.out.println("SECURITY: Using non-standard ssl version: '" + protocol + "'"); 221 sslctx = SSLContext.getInstance(protocol); 223 224 229 230 KeyManagerFactory clientKeyManagerFactory = null; 231 TrustManagerFactory caTrustManagerFactory; 232 KeyStore caKeystore; 233 234 235 if ((clientPassphrase!=null) && (clientPassphrase.length>0)) 236 { 237 245 246 247 if (PKI_INTERNAL_TYPE.equals(clientKeystoreType)) 248 { 249 try 250 { 251 Class c = getClassLoader().loadClass("com.ca.commons.security.openssl.ParsePkcs12"); 252 if (c==null) 253 { 254 System.out.println("PKI internal error"); 255 return; 256 } 257 258 Constructor constructor = c.getConstructor(new Class [] {String .class, byte[].class}); 259 260 int size = clientPassphrase.length; 262 byte[] password = new byte[size]; 263 for (int i=0; i<size; i++) 264 password[i] = (byte) clientPassphrase[i]; 265 266 Object pkcs12Parser = constructor.newInstance(new Object [] {clientKeystoreFile, password}); 267 268 Method getSunKeyStore = c.getMethod("getSunKeyStore", new Class [] {String .class} ); 269 270 clientKeystore = (KeyStore ) getSunKeyStore.invoke(pkcs12Parser, new Object [] {"MyFriend"}); 271 272 for (int i=0; i<size; i++) password[i] = 0; 274 } 275 catch (Exception e) 276 { 277 System.err.println("unable to load pkcs12 parser (not in class path?)"); 278 e.printStackTrace(); 279 return; 280 } 281 } 282 else 283 { 284 287 288 if (clientKeystoreType == null) 289 clientKeystoreType = DEFAULT_KEYSTORE_TYPE; 290 291 clientKeystore = KeyStore.getInstance(clientKeystoreType); 293 297 298 if (clientKeystoreFile != null) 299 clientKeystore.load(new FileInputStream(clientKeystoreFile), clientPassphrase); 300 } 301 304 305 clientKeyManagerFactory = KeyManagerFactory.getInstance("SunX509"); 306 307 311 312 clientKeyManagerFactory.init(clientKeystore, clientPassphrase); 313 314 } 315 316 320 321 KeyManager[] keyManagers = null; 322 if (clientKeyManagerFactory != null) 323 keyManagers = clientKeyManagerFactory.getKeyManagers(); 324 325 328 329 if (caKeystoreType == null) 330 caKeystoreType = DEFAULT_KEYSTORE_TYPE; 331 332 caKeystore = KeyStore.getInstance(caKeystoreType); 333 334 337 338 if (caKeystoreFile != null) 339 { 340 344 caKeystore.load(new FileInputStream(caKeystoreFile), caPassphrase); 345 } 346 347 350 351 caTrustManagerFactory = TrustManagerFactory.getInstance("SunX509"); 352 353 356 357 caTrustManagerFactory.init(caKeystore); 358 359 363 364 TrustManager[] trustManagers = caTrustManagerFactory.getTrustManagers(); 365 366 367 368 sslctx.init(keyManagers, trustManagers, null); 369 370 synchronized(JndiSocketFactory.class) 371 { 372 factory = sslctx.getSocketFactory(); 373 374 default_factory = new JndiSocketFactory(); 375 } 376 } 377 catch (GeneralSecurityException e) 378 { 379 NamingException ne = new NamingException ("security error: unable to initialise JndiSocketFactory"); 380 ne.initCause(e); 381 throw ne; 382 } 383 catch (IOException e) 384 { 385 NamingException ne = new NamingException ("file access error: unable to initialise JndiSocketFactory"); 386 ne.initCause(e); 387 throw ne; 388 } 389 } 390 391 397 398 private static void checkFileSanity(String caKeystoreFile, String clientKeystoreFile, char[] clientPassphrase) 399 throws NamingException 400 { 401 if (clientKeystoreFile == null && caKeystoreFile == null) 402 throw new NamingException ("SSL Initialisation error: No valid keystore files available."); 403 404 if (caKeystoreFile != null) 405 if (new File(caKeystoreFile).exists() == false) 406 throw new NamingException ("SSL Initialisation error: file '" + caKeystoreFile + "' does not exist."); 407 408 if (clientKeystoreFile != null && clientPassphrase != null) 409 if (new File(clientKeystoreFile).exists() == false) 410 throw new NamingException ("SSL Initialisation error: file '" + clientKeystoreFile + "' does not exist."); 411 } 412 413 414 415 416 417 418 462 463 466 public JndiSocketFactory() 467 { 468 } 469 470 475 476 public static SocketFactory getDefault() 477 { 478 synchronized(JndiSocketFactory.class) 479 { 480 if (default_factory == null) 481 default_factory = new JndiSocketFactory(); 482 } 483 484 return (SocketFactory)default_factory; 485 } 486 487 488 public static KeyStore getClientKeyStore() { 489 return clientKeystore; 490 } 491 492 501 public Socket createSocket(String host, int port) 502 throws IOException, UnknownHostException 503 { 504 return factory.createSocket(host, port); 505 } 506 507 516 public Socket createSocket(InetAddress host, int port) 517 throws IOException, UnknownHostException 518 { 519 return factory.createSocket(host, port); 520 } 521 522 523 535 public Socket createSocket(InetAddress host, int port, 536 InetAddress client_host, int client_port) 537 throws IOException, UnknownHostException 538 { 539 return factory.createSocket(host, port, client_host, client_port); 540 } 541 542 543 555 public Socket createSocket(String host, int port, 556 InetAddress client_host, int client_port) 557 throws IOException, UnknownHostException 558 { 559 return factory.createSocket(host, port, client_host, client_port); 560 } 561 562 565 public Socket createSocket(Socket socket, String host, int port, boolean autoclose) 566 throws IOException, UnknownHostException 567 { 568 return factory.createSocket(socket, host, port, autoclose); 569 } 570 571 574 public String [] getDefaultCipherSuites() 575 { 576 return factory.getDefaultCipherSuites(); 577 } 578 579 582 public String [] getSupportedCipherSuites() 583 { 584 return factory.getSupportedCipherSuites(); 585 } 586 } | Popular Tags |