1 23 package com.sun.enterprise.iiop; 24 25 import java.io.IOException ; 26 import java.io.Serializable ; 27 import java.net.InetSocketAddress ; 28 import java.net.ServerSocket ; 29 import java.net.Socket ; 30 import java.net.SocketException ; 31 import java.nio.channels.ServerSocketChannel ; 32 import java.nio.channels.SocketChannel ; 33 import java.rmi.server.RMISocketFactory ; 34 import java.security.KeyStore ; 35 import java.security.SecureRandom ; 36 import java.text.MessageFormat ; 37 import java.util.ArrayList ; 38 import java.util.Enumeration ; 39 import java.util.Hashtable ; 40 import java.util.Map ; 41 import java.util.Properties ; 42 import java.util.StringTokenizer ; 43 import java.util.logging.Level ; 44 import java.util.logging.Logger ; 45 import java.security.KeyStore ; 46 import java.security.SecureRandom ; 47 import java.rmi.server.RMISocketFactory ; 48 import javax.net.ssl.KeyManager; 49 import javax.net.ssl.KeyManagerFactory; 50 import javax.net.ssl.SSLContext; 51 import javax.net.ssl.SSLSocket; 52 import javax.net.ssl.SSLSocketFactory; 53 import javax.net.ssl.SSLServerSocket; 54 import javax.net.ssl.SSLServerSocketFactory; 55 import javax.net.ssl.TrustManagerFactory; 56 import javax.net.ssl.X509KeyManager; 57 58 import com.sun.corba.ee.impl.orbutil.ORBConstants; 59 import com.sun.corba.ee.pept.transport.Acceptor; 60 import com.sun.corba.ee.spi.orb.ORB; 61 import com.sun.corba.ee.spi.transport.ORBSocketFactory; 62 63 import com.sun.enterprise.Switch; 64 import com.sun.enterprise.config.serverbeans.IiopListener; 65 import com.sun.enterprise.config.serverbeans.IiopService; 66 import com.sun.enterprise.config.serverbeans.ServerBeansFactory; 67 import com.sun.enterprise.config.serverbeans.Ssl; 68 import com.sun.enterprise.config.ConfigContext; 69 import com.sun.enterprise.iiop.security.SecurityMechanismSelector; 70 import com.sun.enterprise.iiop.security.ConnectionContext; 71 import com.sun.enterprise.security.CipherInfo; 72 import com.sun.enterprise.security.SSLUtils; 73 import com.sun.enterprise.security.ssl.J2EEKeyManager; 74 import com.sun.enterprise.server.J2EEServer; 75 import com.sun.enterprise.server.ApplicationServer; 76 import com.sun.enterprise.util.Utility; 77 import com.sun.enterprise.util.TypeUtil; 78 79 import com.sun.logging.LogDomains; 80 81 82 88 public class IIOPSSLSocketFactory implements ORBSocketFactory, Serializable 89 { 90 private static Logger _logger = null; 91 static{ 92 _logger=LogDomains.getLogger(LogDomains.CORBA_LOGGER); 93 com.sun.enterprise.security.KeyTool.initProvider(); 94 } 95 96 private static final String TLS = "TLS"; 97 private static final String SSL3 = "SSLv3"; 98 private static final String SSL2 = "SSLv2"; 99 private static final String SSL = "SSL"; 100 private static final String SSL_MUTUALAUTH = "SSL_MUTUALAUTH"; 101 private static final String PERSISTENT_SSL = "PERSISTENT_SSL"; 102 103 private static final int BACKLOG = 50; 104 105 private static SecureRandom sr = J2EEServer.secureRandom; 106 107 111 115 private Map portToSSLInfo = new Hashtable (); 116 120 private SSLInfo clientSslInfo = null; 121 122 private ORB orb; 123 124 127 public IIOPSSLSocketFactory() { 128 try { 129 if (Switch.getSwitch().getContainerType() == Switch.EJBWEB_CONTAINER) { 130 ConfigContext configContext = 131 ApplicationServer.getServerContext().getConfigContext(); 132 IiopService iiopBean = ServerBeansFactory.getIiopServiceBean(configContext); 133 134 IiopListener[] iiopListeners = iiopBean.getIiopListener(); 135 int listenersLength = (iiopListeners != null) ? iiopListeners.length : 0; 136 for (int i = 0; i < listenersLength; i++) { 137 Ssl ssl = iiopListeners[i].getSsl(); 138 SSLInfo sslInfo = null; 139 if (iiopListeners[i].isSecurityEnabled()) { 140 if (ssl != null) { 141 sslInfo = init(ssl.getCertNickname(), 142 ssl.isSsl2Enabled(), ssl.getSsl2Ciphers(), 143 ssl.isSsl3Enabled(), ssl.getSsl3TlsCiphers(), 144 ssl.isTlsEnabled()); 145 } else { 146 sslInfo = getDefaultSslInfo(); 147 } 148 portToSSLInfo.put( 149 new Integer (iiopListeners[i].getPort()), sslInfo); 150 } 151 } 152 153 if (iiopBean.getSslClientConfig() != null && 154 iiopBean.getSslClientConfig().isEnabled()) { 155 Ssl outboundSsl = iiopBean.getSslClientConfig().getSsl(); 156 if (outboundSsl != null) { 157 clientSslInfo = init(outboundSsl.getCertNickname(), 158 outboundSsl.isSsl2Enabled(), 159 outboundSsl.getSsl2Ciphers(), 160 outboundSsl.isSsl3Enabled(), 161 outboundSsl.getSsl3TlsCiphers(), 162 outboundSsl.isTlsEnabled()); 163 } 164 } 165 if (clientSslInfo == null) { 166 clientSslInfo = getDefaultSslInfo(); 167 } 168 } else { 169 com.sun.enterprise.config.clientbeans.Ssl clientSsl = 170 SSLUtils.getAppclientSsl(); 171 if (clientSsl != null) { 172 clientSslInfo = init(clientSsl.getCertNickname(), 173 clientSsl.isSsl2Enabled(), clientSsl.getSsl2Ciphers(), 174 clientSsl.isSsl3Enabled(), clientSsl.getSsl3TlsCiphers(), 175 clientSsl.isTlsEnabled()); 176 } else { clientSslInfo = getDefaultSslInfo(); 178 } 179 } 180 } catch (Exception e) { 181 _logger.log(Level.SEVERE,"iiop.init_exception",e); 182 throw new IllegalStateException (e.toString()); 183 } 184 } 185 186 189 private SSLInfo getDefaultSslInfo() throws Exception { 190 return init(null, false, null, true, null, true); 191 } 192 193 199 private SSLInfo init(String alias, 200 boolean ssl2Enabled, String ssl2Ciphers, 201 boolean ssl3Enabled, String ssl3TlsCiphers, 202 boolean tlsEnabled) throws Exception { 203 String protocol; 204 if (tlsEnabled) { 205 protocol = TLS; 206 } else if (ssl3Enabled) { 207 protocol = SSL3; 208 } else if (ssl2Enabled) { 209 protocol = SSL2; 210 } else { protocol = "SSL"; 212 } 213 214 String [] ssl3TlsCipherArr = null; 215 if (tlsEnabled || ssl3Enabled) { 216 ssl3TlsCipherArr = getEnabledCipherSuites(ssl3TlsCiphers, 217 false, ssl3Enabled, tlsEnabled); 218 } 219 220 String [] ssl2CipherArr = null; 221 if (ssl2Enabled) { 222 ssl2CipherArr = getEnabledCipherSuites(ssl2Ciphers, 223 true, false, false); 224 } 225 226 SSLContext ctx = SSLContext.getInstance(protocol); 227 228 KeyStore [] kstores = SSLUtils.getKeyStores(); 229 if (alias == null) { 230 if (_logger.isLoggable(Level.FINE)) { 232 _logger.log(Level.FINE, "Security: Alias unspecified! Keystore will fall back to default alias."); 233 } 234 237 KeyStore ks = kstores[0]; 238 if (ks != null && ks.size() > 0) { 239 Enumeration e = ks.aliases(); 240 while (e.hasMoreElements()) { 241 String temp = (String )e.nextElement(); 242 if (ks.isKeyEntry(temp)) { 243 alias = temp; 244 break; 245 } 246 } 247 } 248 } else { 249 if (!SSLUtils.isTokenKeyAlias(alias)) { 250 throw new IllegalStateException (getFormatMessage( 251 "iiop.cannot_find_keyalias", new Object [] { alias })); 252 } 253 } 254 255 KeyManager[] old = SSLUtils.getKeyManagers(); 256 int oldLength = (old != null)? old.length : 0; 257 KeyManager[] mgrs = new J2EEKeyManager[oldLength]; 258 259 for (int i = 0; i < oldLength; i++) { 260 if (_logger.isLoggable(Level.FINE)) { 261 StringBuffer msg = new StringBuffer ("Setting J2EEKeyManager for "); 262 msg.append(" alias : "+alias); 263 _logger.log(Level.FINE, msg.toString()); 264 } 265 mgrs[i] = new J2EEKeyManager((X509KeyManager)old[i], alias); 266 } 267 ctx.init(mgrs, SSLUtils.getTrustManagers(), sr); 268 269 return new SSLInfo(ctx, ssl3TlsCipherArr, ssl2CipherArr); 270 } 271 272 274 public void setORB(ORB orb) { 275 this.orb = orb; 276 } 277 278 287 public ServerSocket createServerSocket(String type, 288 InetSocketAddress inetSocketAddress) throws IOException { 289 290 if (_logger.isLoggable(Level.FINE)) { 291 _logger.log(Level.FINE, "Creating server socket for type =" + type 292 + " inetSocketAddress =" + inetSocketAddress); 293 } 294 295 if(type.equals(SSL_MUTUALAUTH) || type.equals(SSL) || 296 type.equals(PERSISTENT_SSL)) { 297 return createSSLServerSocket(type, inetSocketAddress); 298 } else { 299 ServerSocket serverSocket = null; 300 if (orb.getORBData().acceptorSocketType().equals( 301 ORBConstants.SOCKETCHANNEL)) { 302 ServerSocketChannel serverSocketChannel = 303 ServerSocketChannel.open(); 304 serverSocket = serverSocketChannel.socket(); 305 } else { 306 serverSocket = new ServerSocket (); 307 } 308 309 serverSocket.bind(inetSocketAddress); 310 return serverSocket; 311 } 312 } 313 314 321 public Socket createSocket(String type, InetSocketAddress inetSocketAddress) 322 throws IOException { 323 324 try { 325 String host = inetSocketAddress.getHostName(); 326 int port = inetSocketAddress.getPort(); 327 if (_logger.isLoggable(Level.FINE)) { 328 _logger.log(Level.FINE, "createSocket(" + type + ", " + host + ", " +port + ")"); 329 } 330 if (type.equals(SSL) || type.equals(SSL_MUTUALAUTH)) { 331 return createSSLSocket(host, port); 332 } else { 333 Socket socket = null; 334 if (_logger.isLoggable(Level.FINE)) { 335 _logger.log(Level.FINE, "Creating CLEAR_TEXT socket for:" +port); 336 } 337 338 if (orb.getORBData().connectionSocketType().equals( 339 ORBConstants.SOCKETCHANNEL)) { 340 SocketChannel socketChannel = 341 SocketChannel.open(inetSocketAddress); 342 socket = socketChannel.socket(); 343 } else { 344 socket = new Socket (inetSocketAddress.getHostName(), 345 inetSocketAddress.getPort()); 346 } 347 348 socket.setTcpNoDelay(true); 350 return socket; 351 } 352 } catch ( Exception ex ) { 353 if(_logger.isLoggable(Level.FINE)) { 354 _logger.log(Level.FINE,"Exception creating socket",ex); 355 } 356 throw new RuntimeException (ex); 357 } 358 } 359 360 public void setAcceptedSocketOptions(Acceptor acceptor, 361 ServerSocket serverSocket, Socket socket) throws SocketException { 362 363 if (_logger.isLoggable(Level.FINE)) { 364 _logger.log(Level.FINE, "setAcceptedSocketOptions: " + acceptor 365 + " " + serverSocket + " " + socket); 366 } 367 socket.setTcpNoDelay(true); 369 } 370 371 373 377 private ServerSocket createSSLServerSocket(String type, 378 InetSocketAddress inetSocketAddress) throws IOException { 379 380 if (inetSocketAddress == null) { 381 throw new IOException (getFormatMessage( 382 "iiop.invalid_sslserverport", 383 new Object [] { null })); 384 } 385 int port = inetSocketAddress.getPort(); 386 Integer iport = new Integer (port); 387 SSLInfo sslInfo = (SSLInfo)portToSSLInfo.get(iport); 388 if (sslInfo == null) { 389 throw new IOException (getFormatMessage( 390 "iiop.invalid_sslserverport", 391 new Object [] { iport })); 392 } 393 SSLServerSocketFactory ssf = sslInfo.getContext().getServerSocketFactory(); 394 String [] ssl3TlsCiphers = sslInfo.getSsl3TlsCiphers(); 395 String [] ssl2Ciphers = sslInfo.getSsl2Ciphers(); 396 String [] ciphers = null; 397 if (ssl3TlsCiphers != null || ssl2Ciphers != null) { 398 String [] socketCiphers = ssf.getDefaultCipherSuites(); 399 ciphers = mergeCiphers(socketCiphers, ssl3TlsCiphers, ssl2Ciphers); 400 } 401 402 String cs[] = null; 403 404 if(_logger.isLoggable(Level.FINE)) { 405 cs = ssf.getSupportedCipherSuites(); 406 for(int i=0; i < cs.length; ++i) { 407 _logger.log(Level.FINE,"Cipher Suite: " + cs[i]); 408 } 409 } 410 ServerSocket ss = null; 411 try{ 412 ss = ssf.createServerSocket(port, BACKLOG, inetSocketAddress.getAddress()); 416 if (ciphers != null) { 417 ((SSLServerSocket)ss).setEnabledCipherSuites(ciphers); 418 } 419 } catch(IOException e) { 420 _logger.log(Level.SEVERE, "iiop.createsocket_exception", 421 new Object [] { type, String.valueOf(port) }); 422 _logger.log(Level.SEVERE, "", e); 423 throw e; 424 } 425 426 try { 427 if(type.equals(SSL_MUTUALAUTH)) { 428 _logger.log(Level.FINE,"Setting Mutual auth"); 429 ((SSLServerSocket)ss).setNeedClientAuth(true); 430 } 431 } catch(Exception e) { 432 _logger.log(Level.SEVERE,"iiop.cipher_exception",e); 433 throw new IOException (e.getMessage()); 434 } 435 if(_logger.isLoggable(Level.FINE)) { 436 _logger.log(Level.FINE,"Created server socket:" + ss); 437 } 438 return ss; 439 } 440 441 447 private Socket createSSLSocket(String host, int port) 448 throws IOException { 449 450 SSLSocket socket = null; 451 SSLSocketFactory factory = null; 452 try{ 453 factory = clientSslInfo.getContext().getSocketFactory(); 456 457 if(_logger.isLoggable(Level.FINE)) { 458 _logger.log(Level.FINE,"Creating SSL Socket for host:" + host +" port:" + port); 459 } 460 String [] ssl3TlsCiphers = clientSslInfo.getSsl3TlsCiphers(); 461 String [] ssl2Ciphers = clientSslInfo.getSsl2Ciphers(); 462 String [] clientCiphers = null; 463 if (ssl3TlsCiphers != null || ssl2Ciphers != null) { 464 String [] socketCiphers = factory.getDefaultCipherSuites(); 465 clientCiphers = mergeCiphers(socketCiphers, ssl3TlsCiphers, ssl2Ciphers); 466 } 467 468 socket = (SSLSocket)factory.createSocket(host, port); 469 if (clientCiphers != null) { 470 socket.setEnabledCipherSuites(clientCiphers); 471 } 472 }catch(Exception e) { 473 if(_logger.isLoggable(Level.FINE)) { 474 _logger.log(Level.FINE, "iiop.createsocket_exception", 475 new Object [] { host, String.valueOf(port) }); 476 _logger.log(Level.FINE, "", e); 477 } 478 IOException e2 = new IOException ( 479 "Error opening SSL socket to host="+host+" port="+port); 480 e2.initCause(e); 481 throw e2; 482 } 483 return socket; 484 } 485 486 498 private String [] getEnabledCipherSuites(String cipherSuiteStr, 499 boolean ssl2Enabled, boolean ssl3Enabled, boolean tlsEnabled) { 500 String [] cipherArr = null; 501 if (cipherSuiteStr != null && cipherSuiteStr.length() > 0) { 502 ArrayList cipherList = new ArrayList (); 503 StringTokenizer tokens = new StringTokenizer (cipherSuiteStr, ","); 504 while (tokens.hasMoreTokens()) { 505 String cipherAction = tokens.nextToken(); 506 if (cipherAction.startsWith("+")) { 507 String cipher = cipherAction.substring(1); 508 CipherInfo cipherInfo = CipherInfo.getCipherInfo(cipher); 509 if (cipherInfo != null && 510 isValidProtocolCipher(cipherInfo, ssl2Enabled, 511 ssl3Enabled, tlsEnabled)) { 512 cipherList.add(cipherInfo.getCipherName()); 513 } else { 514 throw new IllegalStateException (getFormatMessage( 515 "iiop.unknown_cipher", 516 new Object [] { cipher })); 517 } 518 } else if (cipherAction.startsWith("-")) { 519 String cipher = cipherAction.substring(1); 520 CipherInfo cipherInfo = CipherInfo.getCipherInfo(cipher); 521 if (cipherInfo == null || 522 !isValidProtocolCipher(cipherInfo, ssl2Enabled, 523 ssl3Enabled, tlsEnabled)) { 524 throw new IllegalStateException (getFormatMessage( 525 "iiop.unknown_cipher", 526 new Object [] { cipher })); 527 } 528 } else if (cipherAction.trim().length() > 0) { 529 throw new IllegalStateException (getFormatMessage( 530 "iiop.invalid_cipheraction", 531 new Object [] { cipherAction })); 532 } 533 } 534 535 cipherArr = (String [])cipherList.toArray( 536 new String [cipherList.size()]); 537 } 538 return cipherArr; 539 } 540 541 547 private String [] mergeCiphers(String [] enableCiphers, 548 String [] ssl3TlsCiphers, String [] ssl2Ciphers) { 549 if (ssl3TlsCiphers == null && ssl2Ciphers == null) { 550 return null; 551 } 552 553 int eSize = (enableCiphers != null)? enableCiphers.length : 0; 554 555 if (_logger.isLoggable(Level.FINE)) { 556 StringBuffer buf = new StringBuffer ("Default socket ciphers: "); 557 for (int i = 0; i < eSize; i++) { 558 buf.append(enableCiphers[i] + ", "); 559 } 560 _logger.log(Level.FINE, buf.toString()); 561 } 562 563 ArrayList cList = new ArrayList (); 564 if (ssl3TlsCiphers != null) { 565 for (int i = 0; i < ssl3TlsCiphers.length; i++) { 566 cList.add(ssl3TlsCiphers[i]); 567 } 568 } else { 569 for (int i = 0; i < eSize; i++) { 570 String cipher = enableCiphers[i]; 571 CipherInfo cInfo = CipherInfo.getCipherInfo(cipher); 572 if (cInfo != null && (cInfo.isTLS() || cInfo.isSSL3())) { 573 cList.add(cipher); 574 } 575 } 576 } 577 578 if (ssl2Ciphers != null) { 579 for (int i = 0; i < ssl2Ciphers.length; i++) { 580 cList.add(ssl2Ciphers[i]); 581 } 582 } else { 583 for (int i = 0; i < eSize; i++) { 584 String cipher = enableCiphers[i]; 585 CipherInfo cInfo = CipherInfo.getCipherInfo(cipher); 586 if (cInfo != null && cInfo.isSSL2()) { 587 cList.add(cipher); 588 } 589 } 590 } 591 592 if (_logger.isLoggable(Level.FINE)) { 593 _logger.log(Level.FINE, "Merged socket ciphers: " + cList); 594 } 595 596 return (String [])cList.toArray(new String [cList.size()]); 597 } 598 599 606 private boolean isValidProtocolCipher(CipherInfo cipherInfo, 607 boolean ssl2Enabled, boolean ssl3Enabled, boolean tlsEnabled) { 608 return (tlsEnabled && cipherInfo.isTLS() || 609 ssl3Enabled && cipherInfo.isSSL3() || 610 ssl2Enabled && cipherInfo.isSSL2()); 611 } 612 613 619 private String getFormatMessage(String key, Object [] params) { 620 return MessageFormat.format( 621 _logger.getResourceBundle().getString(key), params); 622 } 623 624 class SSLInfo { 625 private SSLContext ctx; 626 private String [] ssl3TlsCiphers = null; 627 private String [] ssl2Ciphers = null; 628 629 SSLInfo(SSLContext ctx, String [] ssl3TlsCiphers, String [] ssl2Ciphers) { 630 this.ctx = ctx; 631 this.ssl3TlsCiphers = ssl3TlsCiphers; 632 this.ssl2Ciphers = ssl2Ciphers; 633 } 634 635 SSLContext getContext() { 636 return ctx; 637 } 638 639 String [] getSsl3TlsCiphers() { 640 return ssl3TlsCiphers; 641 } 642 643 String [] getSsl2Ciphers() { 644 return ssl2Ciphers; 645 } 646 } 647 } 648 | Popular Tags |