    001/*
    002 * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Java14.java $
    003 * $Revision: 166 $
    004 * $Date: 2014-04-28 11:40:25 -0700 (Mon, 28 Apr 2014) $
    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 org.apache.commons.ssl.util.IPAddressParser;
    035
    036import java.io.IOException;
    037import java.net.InetAddress;
    038import java.net.InetSocketAddress;
    039import java.net.ServerSocket;
    040import java.net.Socket;
    041import java.net.UnknownHostException;
    042import java.security.KeyManagementException;
    043import java.security.KeyStore;
    044import java.security.KeyStoreException;
    045import java.security.NoSuchAlgorithmException;
    046import java.security.UnrecoverableKeyException;
    047import java.security.cert.Certificate;
    048import java.security.cert.CertificateException;
    049import java.security.cert.X509Certificate;
    050import javax.net.SocketFactory;
    051import javax.net.ssl.KeyManager;
    052import javax.net.ssl.KeyManagerFactory;
    053import javax.net.ssl.SSLContext;
    054import javax.net.ssl.SSLPeerUnverifiedException;
    055import javax.net.ssl.SSLServerSocket;
    056import javax.net.ssl.SSLServerSocketFactory;
    057import javax.net.ssl.SSLSession;
    058import javax.net.ssl.SSLSocket;
    059import javax.net.ssl.SSLSocketFactory;
    060import javax.net.ssl.TrustManager;
    061import javax.net.ssl.TrustManagerFactory;
    062import javax.net.ssl.X509KeyManager;
    063import javax.net.ssl.X509TrustManager;
    064
    065
    066/**
    067 * @author Credit Union Central of British Columbia
    068 * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
    069 * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
    070 * @since 30-Jun-2006
    071 */
    072public final class Java14 extends JavaImpl {
    073    private static Java14 instance = new Java14();
    074
    075    private Java14() {
    076        try {
    077            SSLSocketFactory.getDefault().createSocket();
    078        }
    079        catch (IOException ioe) {
    080            ioe.hashCode();
    081        }
    082    }
    083
    084    public static Java14 getInstance() {
    085        return instance;
    086    }
    087
    088    public final String getVersion() {
    089        return "Java14";
    090    }
    091
    092    protected final String retrieveSubjectX500(X509Certificate cert) {
    093        return cert.getSubjectX500Principal().toString();
    094    }
    095
    096    protected final String retrieveIssuerX500(X509Certificate cert) {
    097        return cert.getIssuerX500Principal().toString();
    098    }
    099
    100    protected final Certificate[] retrievePeerCerts(SSLSession sslSession)
    101        throws SSLPeerUnverifiedException {
    102        return sslSession.getPeerCertificates();
    103    }
    104
    105    protected final Object buildKeyManagerFactory(KeyStore ks, char[] password)
    106        throws NoSuchAlgorithmException, KeyStoreException,
    107        UnrecoverableKeyException {
    108        String alg = KeyManagerFactory.getDefaultAlgorithm();
    109        KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg);
    110        kmf.init(ks, password);
    111        return kmf;
    112    }
    113
    114    protected final Object buildTrustManagerFactory(KeyStore ks)
    115        throws NoSuchAlgorithmException, KeyStoreException {
    116        String alg = TrustManagerFactory.getDefaultAlgorithm();
    117        TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg);
    118        tmf.init(ks);
    119        return tmf;
    120    }
    121
    122    protected final Object[] retrieveKeyManagers(Object keyManagerFactory) {
    123        KeyManagerFactory kmf = (KeyManagerFactory) keyManagerFactory;
    124        return kmf.getKeyManagers();
    125    }
    126
    127    protected final Object[] retrieveTrustManagers(Object trustManagerFactory) {
    128        TrustManagerFactory tmf = (TrustManagerFactory) trustManagerFactory;
    129        return tmf.getTrustManagers();
    130    }
    131
    132    protected final SSLSocketFactory buildSSLSocketFactory(Object ssl) {
    133        return ((SSLContext) ssl).getSocketFactory();
    134    }
    135
    136    protected final SSLServerSocketFactory buildSSLServerSocketFactory(Object ssl) {
    137        return ((SSLContext) ssl).getServerSocketFactory();
    138    }
    139
    140    protected final RuntimeException buildRuntimeException(Exception cause) {
    141        return new RuntimeException(cause);
    142    }
    143
    144    protected final SSLSocket buildSocket(SSL ssl) throws IOException {
    145        SSLSocketFactory sf = ssl.getSSLSocketFactory();
    146        SSLSocket s = (SSLSocket) sf.createSocket();
    147        ssl.doPreConnectSocketStuff(s);
    148        return s;
    149    }
    150
    151    protected final SSLSocket buildSocket(SSL ssl, String remoteHost,
    152                                          int remotePort, InetAddress localHost,
    153                                          int localPort, int timeout)
    154        throws IOException {
    155        SSLSocket s = buildSocket(ssl);
    156        s = (SSLSocket) connectSocket(s, null, remoteHost, remotePort,
    157            localHost, localPort, timeout, ssl);
    158        ssl.doPostConnectSocketStuff(s, remoteHost);
    159        return s;
    160    }
    161
    162
    163    protected final Socket buildPlainSocket(
    164            SSL ssl, String remoteHost, int remotePort, InetAddress localHost, int localPort, int timeout
    165    ) throws IOException {
    166        Socket s = SocketFactory.getDefault().createSocket();
    167        ssl.doPreConnectSocketStuff(s);
    168        s = connectSocket(
    169                s, null, remoteHost, remotePort, localHost, localPort, timeout, ssl
    170        );
    171        ssl.doPostConnectSocketStuff(s, remoteHost);
    172        return s;
    173    }
    174
    175    protected final Socket connectSocket(Socket s, SocketFactory sf,
    176                                         String host, int remotePort,
    177                                         InetAddress localHost, int localPort,
    178                                         int timeout, SSL ssl)
    179        throws IOException {
    180        if (s == null) {
    181            if (sf == null) {
    182                s = new Socket();
    183            } else {
    184                s = sf.createSocket();
    185            }
    186        }
    187        host = ssl.dnsOverride(host);
    188        InetAddress remoteHost = Util.toInetAddress(host);
    189        InetSocketAddress dest = new InetSocketAddress(remoteHost, remotePort);
    190        InetSocketAddress src = new InetSocketAddress(localHost, localPort);
    191        s.bind(src);
    192        s.connect(dest, timeout);
    193        return s;
    194    }
    195
    196    protected final SSLServerSocket buildServerSocket(SSL ssl)
    197        throws IOException {
    198        ServerSocket s = ssl.getSSLServerSocketFactory().createServerSocket();
    199        SSLServerSocket ss = (SSLServerSocket) s;
    200        ssl.doPreConnectServerSocketStuff(ss);
    201        return ss;
    202    }
    203
    204    protected final void wantClientAuth(Object o, boolean wantClientAuth) {
    205        SSLSocket s;
    206        SSLServerSocket ss;
    207        if (o instanceof SSLSocket) {
    208            s = (SSLSocket) o;
    209            s.setWantClientAuth(wantClientAuth);
    210        } else if (o instanceof SSLServerSocket) {
    211            ss = (SSLServerSocket) o;
    212            ss.setWantClientAuth(wantClientAuth);
    213        } else {
    214            throw new ClassCastException("need SSLSocket or SSLServerSocket");
    215        }
    216    }
    217
    218    protected final void enabledProtocols(Object o, String[] enabledProtocols) {
    219        SSLSocket s;
    220        SSLServerSocket ss;
    221        if (o instanceof SSLSocket) {
    222            s = (SSLSocket) o;
    223            s.setEnabledProtocols(enabledProtocols);
    224        } else if (o instanceof SSLServerSocket) {
    225            ss = (SSLServerSocket) o;
    226            ss.setEnabledProtocols(enabledProtocols);
    227        } else {
    228            throw new ClassCastException("need SSLSocket or SSLServerSocket");
    229        }
    230    }
    231
    232    protected void checkTrusted(Object trustManager, X509Certificate[] chain,
    233                                String authType)
    234        throws CertificateException {
    235        X509TrustManager tm = (X509TrustManager) trustManager;
    236        tm.checkServerTrusted(chain, authType);
    237    }
    238
    239    protected final Object initSSL(SSL ssl, TrustChain tc, KeyMaterial k)
    240        throws NoSuchAlgorithmException, KeyStoreException,
    241        CertificateException, KeyManagementException, IOException {
    242        SSLContext context = SSLContext.getInstance(ssl.getDefaultProtocol());
    243        TrustManager[] trustManagers = null;
    244        KeyManager[] keyManagers = null;
    245        if (tc != null) {
    246            trustManagers = (TrustManager[]) tc.getTrustManagers();
    247        }
    248        if (k != null) {
    249            keyManagers = (KeyManager[]) k.getKeyManagers();
    250        }
    251        if (keyManagers != null) {
    252            for (int i = 0; i < keyManagers.length; i++) {
    253                if (keyManagers[i] instanceof X509KeyManager) {
    254                    X509KeyManager km = (X509KeyManager) keyManagers[i];
    255                    keyManagers[i] = new Java14KeyManagerWrapper(km, k, ssl);
    256                }
    257            }
    258        }
    259        if (trustManagers != null) {
    260            for (int i = 0; i < trustManagers.length; i++) {
    261                if (trustManagers[i] instanceof X509TrustManager) {
    262                    X509TrustManager tm = (X509TrustManager) trustManagers[i];
    263                    trustManagers[i] = new Java14TrustManagerWrapper(tm, tc, ssl);
    264                }
    265            }
    266        }
    267        context.init(keyManagers, trustManagers, null);
    268        return context;
    269    }
    270
    271
    272}