001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.tomcat.util.net.jsse;
018:
019: import java.io.IOException;
020: import java.security.KeyStore;
021: import java.security.SecureRandom;
022: import java.security.Security;
023:
024: import javax.net.ssl.SSLServerSocket;
025: import javax.net.ssl.SSLSocket;
026:
027: /*
028: 1. Make the JSSE's jars available, either as an installed
029: extension (copy them into jre/lib/ext) or by adding
030: them to the Tomcat classpath.
031: 2. keytool -genkey -alias tomcat -keyalg RSA
032: Use "changeit" as password ( this is the default we use )
033: */
034:
035: /**
036: * SSL server socket factory. It _requires_ a valid RSA key and
037: * JSSE.
038: *
039: * @author Harish Prabandham
040: * @author Costin Manolache
041: * @author Stefan Freyr Stefansson
042: * @author EKR -- renamed to JSSESocketFactory
043: * @author Bill Barker
044: */
045: public class JSSE13SocketFactory extends JSSESocketFactory {
046: /**
047: * Flag for client authentication
048: */
049: protected boolean clientAuth = false;
050:
051: public JSSE13SocketFactory() {
052: super ();
053: }
054:
055: /**
056: * Reads the keystore and initializes the SSL socket factory.
057: *
058: * NOTE: This method is identical in functionality to the method of the
059: * same name in JSSE14SocketFactory, except that this method is used with
060: * JSSE 1.0.x (which is an extension to the 1.3 JVM), whereas the other is
061: * used with JSSE 1.1.x (which ships with the 1.4 JVM). Therefore, this
062: * method uses classes in com.sun.net.ssl, which have since moved to
063: * javax.net.ssl, and explicitly registers the required security providers,
064: * which come standard in a 1.4 JVM.
065: */
066: void init() throws IOException {
067: try {
068: Security.addProvider(new sun.security.provider.Sun());
069: Security
070: .addProvider(new com.sun.net.ssl.internal.ssl.Provider());
071:
072: String clientAuthStr = (String) attributes
073: .get("clientauth");
074: if ("true".equalsIgnoreCase(clientAuthStr)
075: || "yes".equalsIgnoreCase(clientAuthStr)
076: || "want".equalsIgnoreCase(clientAuthStr)) {
077: clientAuth = true;
078: }
079:
080: // SSL protocol variant (e.g., TLS, SSL v3, etc.)
081: String protocol = (String) attributes.get("protocol");
082: if (protocol == null)
083: protocol = defaultProtocol;
084:
085: // Certificate encoding algorithm (e.g., SunX509)
086: String algorithm = (String) attributes.get("algorithm");
087: if (algorithm == null)
088: algorithm = defaultAlgorithm;
089:
090: // Set up KeyManager, which will extract server key
091: com.sun.net.ssl.KeyManagerFactory kmf = com.sun.net.ssl.KeyManagerFactory
092: .getInstance(algorithm);
093: String keystoreType = (String) attributes
094: .get("keystoreType");
095: if (keystoreType == null) {
096: keystoreType = defaultKeystoreType;
097: }
098: String keystorePass = getKeystorePassword();
099: kmf.init(getKeystore(keystoreType, keystorePass),
100: keystorePass.toCharArray());
101:
102: // Set up TrustManager
103: com.sun.net.ssl.TrustManager[] tm = null;
104: String truststoreType = (String) attributes
105: .get("truststoreType");
106: if (truststoreType == null) {
107: truststoreType = keystoreType;
108: }
109: KeyStore trustStore = getTrustStore(truststoreType);
110: if (trustStore != null) {
111: com.sun.net.ssl.TrustManagerFactory tmf = com.sun.net.ssl.TrustManagerFactory
112: .getInstance("SunX509");
113: tmf.init(trustStore);
114: tm = tmf.getTrustManagers();
115: }
116:
117: // Create and init SSLContext
118: com.sun.net.ssl.SSLContext context = com.sun.net.ssl.SSLContext
119: .getInstance(protocol);
120: context.init(kmf.getKeyManagers(), tm, new SecureRandom());
121:
122: // Create proxy
123: sslProxy = context.getServerSocketFactory();
124:
125: // Determine which cipher suites to enable
126: String requestedCiphers = (String) attributes
127: .get("ciphers");
128: if (requestedCiphers != null) {
129: enabledCiphers = getEnabledCiphers(requestedCiphers,
130: sslProxy.getSupportedCipherSuites());
131: }
132:
133: } catch (Exception e) {
134: if (e instanceof IOException)
135: throw (IOException) e;
136: throw new IOException(e.getMessage());
137: }
138: }
139:
140: protected String[] getEnabledProtocols(SSLServerSocket socket,
141: String requestedProtocols) {
142: return null;
143: }
144:
145: protected void setEnabledProtocols(SSLServerSocket socket,
146: String[] protocols) {
147: }
148:
149: protected void configureClientAuth(SSLServerSocket socket) {
150: socket.setNeedClientAuth(clientAuth);
151: }
152:
153: protected void configureClientAuth(SSLSocket socket) {
154: // In JSSE 1.0.2 docs it does not explicitly
155: // state whether SSLSockets returned from
156: // SSLServerSocket.accept() inherit this setting.
157: socket.setNeedClientAuth(clientAuth);
158: }
159:
160: }
|