001/*
002 * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.11/src/java/org/apache/commons/ssl/Java14.java $
003 * $Revision: 155 $
004 * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $
005 *
006 * ====================================================================
007 * Licensed to the Apache Software Foundation (ASF) under one
008 * or more contributor license agreements.  See the NOTICE file
009 * distributed with this work for additional information
010 * regarding copyright ownership.  The ASF licenses this file
011 * to you under the Apache License, Version 2.0 (the
012 * "License"); you may not use this file except in compliance
013 * with the License.  You may obtain a copy of the License at
014 *
015 *   http://www.apache.org/licenses/LICENSE-2.0
016 *
017 * Unless required by applicable law or agreed to in writing,
018 * software distributed under the License is distributed on an
019 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
020 * KIND, either express or implied.  See the License for the
021 * specific language governing permissions and limitations
022 * under the License.
023 * ====================================================================
024 *
025 * This software consists of voluntary contributions made by many
026 * individuals on behalf of the Apache Software Foundation.  For more
027 * information on the Apache Software Foundation, please see
028 * <http://www.apache.org/>.
029 *
030 */
031
032package org.apache.commons.ssl;
033
034import javax.net.SocketFactory;
035import javax.net.ssl.KeyManager;
036import javax.net.ssl.KeyManagerFactory;
037import javax.net.ssl.SSLContext;
038import javax.net.ssl.SSLPeerUnverifiedException;
039import javax.net.ssl.SSLServerSocket;
040import javax.net.ssl.SSLServerSocketFactory;
041import javax.net.ssl.SSLSession;
042import javax.net.ssl.SSLSocket;
043import javax.net.ssl.SSLSocketFactory;
044import javax.net.ssl.TrustManager;
045import javax.net.ssl.TrustManagerFactory;
046import javax.net.ssl.X509KeyManager;
047import javax.net.ssl.X509TrustManager;
048import java.io.IOException;
049import java.net.InetAddress;
050import java.net.InetSocketAddress;
051import java.net.ServerSocket;
052import java.net.Socket;
053import java.security.KeyManagementException;
054import java.security.KeyStore;
055import java.security.KeyStoreException;
056import java.security.NoSuchAlgorithmException;
057import java.security.UnrecoverableKeyException;
058import java.security.cert.Certificate;
059import java.security.cert.CertificateException;
060import java.security.cert.X509Certificate;
061
062
063/**
064 * @author Credit Union Central of British Columbia
065 * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
066 * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
067 * @since 30-Jun-2006
068 */
069public final class Java14 extends JavaImpl {
070    private static Java14 instance = new Java14();
071
072    private Java14() {
073        try {
074            SSLSocketFactory.getDefault().createSocket();
075        }
076        catch (IOException ioe) {
077            ioe.hashCode();
078        }
079    }
080
081    public static Java14 getInstance() {
082        return instance;
083    }
084
085    public final String getVersion() {
086        return "Java14";
087    }
088
089    protected final String retrieveSubjectX500(X509Certificate cert) {
090        return cert.getSubjectX500Principal().toString();
091    }
092
093    protected final String retrieveIssuerX500(X509Certificate cert) {
094        return cert.getIssuerX500Principal().toString();
095    }
096
097    protected final Certificate[] retrievePeerCerts(SSLSession sslSession)
098        throws SSLPeerUnverifiedException {
099        return sslSession.getPeerCertificates();
100    }
101
102    protected final Object buildKeyManagerFactory(KeyStore ks, char[] password)
103        throws NoSuchAlgorithmException, KeyStoreException,
104        UnrecoverableKeyException {
105        String alg = KeyManagerFactory.getDefaultAlgorithm();
106        KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg);
107        kmf.init(ks, password);
108        return kmf;
109    }
110
111    protected final Object buildTrustManagerFactory(KeyStore ks)
112        throws NoSuchAlgorithmException, KeyStoreException {
113        String alg = TrustManagerFactory.getDefaultAlgorithm();
114        TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg);
115        tmf.init(ks);
116        return tmf;
117    }
118
119    protected final Object[] retrieveKeyManagers(Object keyManagerFactory) {
120        KeyManagerFactory kmf = (KeyManagerFactory) keyManagerFactory;
121        return kmf.getKeyManagers();
122    }
123
124    protected final Object[] retrieveTrustManagers(Object trustManagerFactory) {
125        TrustManagerFactory tmf = (TrustManagerFactory) trustManagerFactory;
126        return tmf.getTrustManagers();
127    }
128
129    protected final SSLSocketFactory buildSSLSocketFactory(Object ssl) {
130        return ((SSLContext) ssl).getSocketFactory();
131    }
132
133    protected final SSLServerSocketFactory buildSSLServerSocketFactory(Object ssl) {
134        return ((SSLContext) ssl).getServerSocketFactory();
135    }
136
137    protected final RuntimeException buildRuntimeException(Exception cause) {
138        return new RuntimeException(cause);
139    }
140
141    protected final SSLSocket buildSocket(SSL ssl) throws IOException {
142        SSLSocketFactory sf = ssl.getSSLSocketFactory();
143        SSLSocket s = (SSLSocket) sf.createSocket();
144        ssl.doPreConnectSocketStuff(s);
145        return s;
146    }
147
148    protected final SSLSocket buildSocket(SSL ssl, String remoteHost,
149                                          int remotePort, InetAddress localHost,
150                                          int localPort, int timeout)
151        throws IOException {
152        SSLSocket s = buildSocket(ssl);
153        s = (SSLSocket) connectSocket(s, null, remoteHost, remotePort,
154            localHost, localPort, timeout, ssl);
155        ssl.doPostConnectSocketStuff(s, remoteHost);
156        return s;
157    }
158
159
160    protected final Socket buildPlainSocket(
161            SSL ssl, String remoteHost, int remotePort, InetAddress localHost, int localPort, int timeout
162    ) throws IOException {
163        Socket s = SocketFactory.getDefault().createSocket();
164        ssl.doPreConnectSocketStuff(s);
165        s = connectSocket(
166                s, null, remoteHost, remotePort, localHost, localPort, timeout, ssl
167        );
168        ssl.doPostConnectSocketStuff(s, remoteHost);
169        return s;
170    }
171    
172    protected final Socket connectSocket(Socket s, SocketFactory sf,
173                                         String remoteHost, int remotePort,
174                                         InetAddress localHost, int localPort,
175                                         int timeout, SSL ssl)
176        throws IOException {
177        if (s == null) {
178            if (sf == null) {
179                s = new Socket();
180            } else {
181                s = sf.createSocket();
182            }
183        }
184
185        String orig = remoteHost;
186        remoteHost = ssl.dnsOverride(remoteHost);
187        InetSocketAddress dest = new InetSocketAddress(remoteHost, remotePort);
188        InetSocketAddress src = new InetSocketAddress(localHost, localPort);
189        s.bind(src);
190        s.connect(dest, timeout);
191        return s;
192    }
193
194    protected final SSLServerSocket buildServerSocket(SSL ssl)
195        throws IOException {
196        ServerSocket s = ssl.getSSLServerSocketFactory().createServerSocket();
197        SSLServerSocket ss = (SSLServerSocket) s;
198        ssl.doPreConnectServerSocketStuff(ss);
199        return ss;
200    }
201
202    protected final void wantClientAuth(Object o, boolean wantClientAuth) {
203        SSLSocket s;
204        SSLServerSocket ss;
205        if (o instanceof SSLSocket) {
206            s = (SSLSocket) o;
207            s.setWantClientAuth(wantClientAuth);
208        } else if (o instanceof SSLServerSocket) {
209            ss = (SSLServerSocket) o;
210            ss.setWantClientAuth(wantClientAuth);
211        } else {
212            throw new ClassCastException("need SSLSocket or SSLServerSocket");
213        }
214    }
215
216    protected final void enabledProtocols(Object o, String[] enabledProtocols) {
217        SSLSocket s;
218        SSLServerSocket ss;
219        if (o instanceof SSLSocket) {
220            s = (SSLSocket) o;
221            s.setEnabledProtocols(enabledProtocols);
222        } else if (o instanceof SSLServerSocket) {
223            ss = (SSLServerSocket) o;
224            ss.setEnabledProtocols(enabledProtocols);
225        } else {
226            throw new ClassCastException("need SSLSocket or SSLServerSocket");
227        }
228    }
229
230    protected void checkTrusted(Object trustManager, X509Certificate[] chain,
231                                String authType)
232        throws CertificateException {
233        X509TrustManager tm = (X509TrustManager) trustManager;
234        tm.checkServerTrusted(chain, authType);
235    }
236
237    protected final Object initSSL(SSL ssl, TrustChain tc, KeyMaterial k)
238        throws NoSuchAlgorithmException, KeyStoreException,
239        CertificateException, KeyManagementException, IOException {
240        SSLContext context = SSLContext.getInstance(ssl.getDefaultProtocol());
241        TrustManager[] trustManagers = null;
242        KeyManager[] keyManagers = null;
243        if (tc != null) {
244            trustManagers = (TrustManager[]) tc.getTrustManagers();
245        }
246        if (k != null) {
247            keyManagers = (KeyManager[]) k.getKeyManagers();
248        }
249        if (keyManagers != null) {
250            for (int i = 0; i < keyManagers.length; i++) {
251                if (keyManagers[i] instanceof X509KeyManager) {
252                    X509KeyManager km = (X509KeyManager) keyManagers[i];
253                    keyManagers[i] = new Java14KeyManagerWrapper(km, k, ssl);
254                }
255            }
256        }
257        if (trustManagers != null) {
258            for (int i = 0; i < trustManagers.length; i++) {
259                if (trustManagers[i] instanceof X509TrustManager) {
260                    X509TrustManager tm = (X509TrustManager) trustManagers[i];
261                    trustManagers[i] = new Java14TrustManagerWrapper(tm, tc, ssl);
262                }
263            }
264        }
265        context.init(keyManagers, trustManagers, null);
266        return context;
267    }
268
269
270}