001    /*
002     * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Java14.java $
003     * $Revision: 121 $
004     * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
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            // overwrite password
109            for (int i = 0; i < password.length; i++) {
110                password[i] = '*';
111            }
112            return kmf;
113        }
114    
115        protected final Object buildTrustManagerFactory(KeyStore ks)
116            throws NoSuchAlgorithmException, KeyStoreException {
117            String alg = TrustManagerFactory.getDefaultAlgorithm();
118            TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg);
119            tmf.init(ks);
120            return tmf;
121        }
122    
123        protected final Object[] retrieveKeyManagers(Object keyManagerFactory) {
124            KeyManagerFactory kmf = (KeyManagerFactory) keyManagerFactory;
125            return kmf.getKeyManagers();
126        }
127    
128        protected final Object[] retrieveTrustManagers(Object trustManagerFactory) {
129            TrustManagerFactory tmf = (TrustManagerFactory) trustManagerFactory;
130            return tmf.getTrustManagers();
131        }
132    
133        protected final SSLSocketFactory buildSSLSocketFactory(Object ssl) {
134            return ((SSLContext) ssl).getSocketFactory();
135        }
136    
137        protected final SSLServerSocketFactory buildSSLServerSocketFactory(Object ssl) {
138            return ((SSLContext) ssl).getServerSocketFactory();
139        }
140    
141        protected final RuntimeException buildRuntimeException(Exception cause) {
142            return new RuntimeException(cause);
143        }
144    
145        protected final SSLSocket buildSocket(SSL ssl) throws IOException {
146            SSLSocketFactory sf = ssl.getSSLSocketFactory();
147            SSLSocket s = (SSLSocket) sf.createSocket();
148            ssl.doPreConnectSocketStuff(s);
149            return s;
150        }
151    
152        protected final SSLSocket buildSocket(SSL ssl, String remoteHost,
153                                              int remotePort, InetAddress localHost,
154                                              int localPort, int timeout)
155            throws IOException {
156            SSLSocket s = buildSocket(ssl);
157            s = (SSLSocket) connectSocket(s, null, remoteHost, remotePort,
158                localHost, localPort, timeout);
159            ssl.doPostConnectSocketStuff(s, remoteHost);
160            return s;
161        }
162    
163        protected final Socket connectSocket(Socket s, SocketFactory sf,
164                                             String remoteHost, int remotePort,
165                                             InetAddress localHost, int localPort,
166                                             int timeout)
167            throws IOException {
168            if (s == null) {
169                if (sf == null) {
170                    s = new Socket();
171                } else {
172                    s = sf.createSocket();
173                }
174            }
175            InetSocketAddress dest = new InetSocketAddress(remoteHost, remotePort);
176            InetSocketAddress src = new InetSocketAddress(localHost, localPort);
177            s.bind(src);
178            s.connect(dest, timeout);
179            return s;
180        }
181    
182        protected final SSLServerSocket buildServerSocket(SSL ssl)
183            throws IOException {
184            ServerSocket s = ssl.getSSLServerSocketFactory().createServerSocket();
185            SSLServerSocket ss = (SSLServerSocket) s;
186            ssl.doPreConnectServerSocketStuff(ss);
187            return ss;
188        }
189    
190        protected final void wantClientAuth(Object o, boolean wantClientAuth) {
191            SSLSocket s;
192            SSLServerSocket ss;
193            if (o instanceof SSLSocket) {
194                s = (SSLSocket) o;
195                s.setWantClientAuth(wantClientAuth);
196            } else if (o instanceof SSLServerSocket) {
197                ss = (SSLServerSocket) o;
198                ss.setWantClientAuth(wantClientAuth);
199            } else {
200                throw new ClassCastException("need SSLSocket or SSLServerSocket");
201            }
202        }
203    
204        protected final void enabledProtocols(Object o, String[] enabledProtocols) {
205            SSLSocket s;
206            SSLServerSocket ss;
207            if (o instanceof SSLSocket) {
208                s = (SSLSocket) o;
209                s.setEnabledProtocols(enabledProtocols);
210            } else if (o instanceof SSLServerSocket) {
211                ss = (SSLServerSocket) o;
212                ss.setEnabledProtocols(enabledProtocols);
213            } else {
214                throw new ClassCastException("need SSLSocket or SSLServerSocket");
215            }
216        }
217    
218        protected void checkTrusted(Object trustManager, X509Certificate[] chain,
219                                    String authType)
220            throws CertificateException {
221            X509TrustManager tm = (X509TrustManager) trustManager;
222            tm.checkServerTrusted(chain, authType);
223        }
224    
225        protected final Object initSSL(SSL ssl, TrustChain tc, KeyMaterial k)
226            throws NoSuchAlgorithmException, KeyStoreException,
227            CertificateException, KeyManagementException, IOException {
228            SSLContext context = SSLContext.getInstance(ssl.getDefaultProtocol());
229            TrustManager[] trustManagers = null;
230            KeyManager[] keyManagers = null;
231            if (tc != null) {
232                trustManagers = (TrustManager[]) tc.getTrustManagers();
233            }
234            if (k != null) {
235                keyManagers = (KeyManager[]) k.getKeyManagers();
236            }
237            if (keyManagers != null) {
238                for (int i = 0; i < keyManagers.length; i++) {
239                    if (keyManagers[i] instanceof X509KeyManager) {
240                        X509KeyManager km = (X509KeyManager) keyManagers[i];
241                        keyManagers[i] = new Java14KeyManagerWrapper(km, k, ssl);
242                    }
243                }
244            }
245            if (trustManagers != null) {
246                for (int i = 0; i < trustManagers.length; i++) {
247                    if (trustManagers[i] instanceof X509TrustManager) {
248                        X509TrustManager tm = (X509TrustManager) trustManagers[i];
249                        trustManagers[i] = new Java14TrustManagerWrapper(tm, tc, ssl);
250                    }
251                }
252            }
253            context.init(keyManagers, trustManagers, null);
254            return context;
255        }
256    
257    
258    }