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    
032    package org.apache.commons.ssl;
033    
034    import javax.net.SocketFactory;
035    import javax.net.ssl.KeyManager;
036    import javax.net.ssl.KeyManagerFactory;
037    import javax.net.ssl.SSLContext;
038    import javax.net.ssl.SSLPeerUnverifiedException;
039    import javax.net.ssl.SSLServerSocket;
040    import javax.net.ssl.SSLServerSocketFactory;
041    import javax.net.ssl.SSLSession;
042    import javax.net.ssl.SSLSocket;
043    import javax.net.ssl.SSLSocketFactory;
044    import javax.net.ssl.TrustManager;
045    import javax.net.ssl.TrustManagerFactory;
046    import javax.net.ssl.X509KeyManager;
047    import javax.net.ssl.X509TrustManager;
048    import java.io.IOException;
049    import java.net.InetAddress;
050    import java.net.InetSocketAddress;
051    import java.net.ServerSocket;
052    import java.net.Socket;
053    import java.security.KeyManagementException;
054    import java.security.KeyStore;
055    import java.security.KeyStoreException;
056    import java.security.NoSuchAlgorithmException;
057    import java.security.UnrecoverableKeyException;
058    import java.security.cert.Certificate;
059    import java.security.cert.CertificateException;
060    import 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     */
069    public 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    }