001: package com.sun.portal.netlet.crypt.jsse;
002:
003: import java.io.IOException;
004: import java.net.Socket;
005: import java.security.GeneralSecurityException;
006: import java.util.Vector;
007:
008: import javax.net.ssl.HandshakeCompletedEvent;
009: import javax.net.ssl.HandshakeCompletedListener;
010: import javax.net.ssl.KeyManager;
011: import javax.net.ssl.SSLContext;
012: import javax.net.ssl.SSLSocket;
013: import javax.net.ssl.SSLSocketFactory;
014: import javax.net.ssl.TrustManager;
015:
016: /*
017: * The com.sun.portal.netlet.crypt.jsse.NetletJSSEWrapper creates a PKCS12 store or JKS store based on the
018: * store type provided by the user. It then does the handshake with
019: * the server The input and output stream can then be used to transfer data securely.
020: */
021:
022: public class NetletJSSEWrapper {
023:
024: private SSLContext sslContext = null;
025: private String keyStoreType = null;
026: private String keyStore = null;
027: private String keyStorePassword = null;
028:
029: private NetletJSSEAuthContext authContext = null;
030:
031: /*
032: */
033:
034: public NetletJSSEWrapper() {
035:
036: }
037:
038: /*
039: * TODO:
040: * Need to communicate back to Netlet Applet in case any of the javax.net.ssl
041: * parameters are invalid. This needs to be done only if PDC is eanbled
042: * While doing the same need to break any direct dependencies between
043: * these two packages, Perhaps a custom runtime exception would do ?
044: *
045: * -Rajesh T
046: */
047:
048: public void init(boolean requireClientCert) throws Exception {
049: keyStoreType = System.getProperty("javax.net.ssl.keyStoreType");
050: keyStore = System.getProperty("javax.net.ssl.keyStore");
051: keyStorePassword = System
052: .getProperty("javax.net.ssl.keyStorePassword");
053: if (keyStore == null || keyStoreType == null
054: || keyStorePassword == null) {
055: if (requireClientCert) {
056: throw new IllegalArgumentException(
057: "Key store not found: Set javax.net.ssl.keyStorePassword, javax.net.ssl.keyStore, javax.net.ssl.keyStoreType");
058: }
059: }
060: try {
061:
062: /*
063: * If PDC is enabled then these javax.net.ssl parameters cannot be null
064: */
065:
066: if (keyStoreType != null) {
067: if (keyStoreType.equals("jks")) {
068: authContext = new NetletJSSEAuthContextJKSImpl();
069: } else {
070: authContext = new NetletJSSEAuthContexPKCSImpl();
071: }
072: authContext.setKeyStorePassword(keyStorePassword);
073: authContext.setKeyStorePath(keyStore);
074: System.out
075: .println("Netlet running with Native KeyStore : System properties as in javax.net.ssl.keyStoreType, javax.net.ssl.keyStorePassword and javax.net.ssl.keyStore");
076: initJSSE();
077:
078: /*
079: * GW is running in SSL but PDC is disable, So don't bother about
080: * the Key store
081: */
082:
083: } else {
084: authContext = new NetletJSSEAuthContexPKCSImpl();
085: System.out
086: .println("Netlet running with JSSE :PDC Disabled ");
087: initJSSE();
088: }
089: } catch (Exception e) {
090: e.printStackTrace();
091: }
092: }
093:
094: /*
095: * Initializes the context
096: * @throws java.security.GeneralSecurityException
097: * @throws java.io.IOException
098: */
099:
100: private void initJSSE() throws GeneralSecurityException,
101: IOException {
102: setupSSLContext();
103: }
104:
105: /*
106: * setupSSLContext : Sets the SSL context with the trustmanager and key manager
107: * @throws java.security.GeneralSecurityException
108: * @throws java.io.IOException
109: */
110:
111: private void setupSSLContext() throws GeneralSecurityException,
112: IOException {
113: NetletTrustManager tm = new NetletTrustManager();
114: NetletKeyManager km = new NetletKeyManager(authContext);
115:
116: KeyManager[] kmg = { km };
117: TrustManager[] tmg = { tm };
118: sslContext = SSLContext.getInstance("SSL");
119: sslContext.init(kmg, tmg, null);
120: }
121:
122: /*
123: * Sets the SSL context and Initializes the SSL socket.
124: * @return SSLSocket
125: * @throws java.lang.Exception
126: */
127:
128: public Socket connect(String host, int port, String[] cipherSuites)
129: throws Exception {
130: return connect(null, host, port, cipherSuites);
131: }
132:
133: /*
134: * Upgrades a socket to JSSE SSL Socket
135: */
136:
137: public Socket connect(Socket tunnelSocket, String host, int port,
138: String[] cipherSuites) throws Exception {
139: SSLSocketFactory sf = sslContext.getSocketFactory();
140: SSLSocket socket = null;
141:
142: /*
143: * Upgrading a plain socket that has issued a sucessful CONNECT command
144: * to a proxy
145: */
146:
147: if (tunnelSocket != null) {
148: socket = (SSLSocket) sf.createSocket(tunnelSocket, host,
149: port, true);
150:
151: /*
152: * Creating a direct connection between the applet and the GW.
153: */
154:
155: } else {
156: socket = (SSLSocket) sf.createSocket(host, port);
157: }
158:
159: if (cipherSuites != null) {
160: String[] jsseCiphers = getJSSECipherSuites(cipherSuites);
161: if (jsseCiphers != null) {
162: socket.setEnabledCipherSuites(jsseCiphers);
163: }
164: }
165:
166: socket
167: .addHandshakeCompletedListener(new HandshakeCompletedListener() {
168: public void handshakeCompleted(
169: HandshakeCompletedEvent event) {
170: System.out.println("Handshake finished!");
171: System.out.println("\t CipherSuite:"
172: + event.getCipherSuite());
173: System.out.println("\t SessionId "
174: + event.getSession());
175: System.out.println("\t PeerHost "
176: + event.getSession().getPeerHost());
177: }
178: });
179:
180: return socket;
181: }
182:
183: /*
184: */
185:
186: public void cleanup() {
187: }
188:
189: private String[] getJSSECipherSuites(String cipherSuites[]) {
190:
191: Vector jsseCiphers = new Vector();
192:
193: for (int i = 0; i < cipherSuites.length; i++) {
194: if (cipherSuites[i] != null && cipherSuites[i] != "null"
195: && (!cipherSuites[i].startsWith("KSSL_"))) {
196: jsseCiphers.addElement(new String(cipherSuites[i]));
197: }
198: }
199: if (jsseCiphers.size() == 0) {
200: return null;
201: }
202:
203: String arrayofJSSECiphers[] = new String[jsseCiphers.size()];
204: for (int j = 0; j < jsseCiphers.size(); j++) {
205: arrayofJSSECiphers[j] = jsseCiphers.elementAt(j).toString();
206: }
207: return arrayofJSSECiphers;
208: }
209:
210: }
|