Home | History | Annotate | Download | only in ssl
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package javax.net.ssl;
     19 
     20 import java.io.IOException;
     21 import java.net.Socket;
     22 import java.security.NoSuchAlgorithmException;
     23 import java.security.Security;
     24 import javax.net.SocketFactory;
     25 import org.apache.harmony.security.fortress.Services;
     26 
     27 /**
     28  * The abstract factory implementation to create {@code SSLSocket}s.
     29  */
     30 public abstract class SSLSocketFactory extends SocketFactory {
     31     // FIXME EXPORT CONTROL
     32 
     33     // The default SSL socket factory
     34     private static SocketFactory defaultSocketFactory;
     35 
     36     private static int lastCacheVersion = -1;
     37 
     38     /**
     39      * Returns the default {@code SSLSocketFactory} instance. The default is
     40      * defined by the security property {@code 'ssl.SocketFactory.provider'}.
     41      *
     42      * @return the default ssl socket factory instance.
     43      */
     44     public static synchronized SocketFactory getDefault() {
     45         int newCacheVersion = Services.getCacheVersion();
     46         if (defaultSocketFactory != null && lastCacheVersion == newCacheVersion) {
     47             return defaultSocketFactory;
     48         }
     49         lastCacheVersion = newCacheVersion;
     50 
     51         String newName = Security.getProperty("ssl.SocketFactory.provider");
     52         if (newName != null) {
     53             /* The cache could have been invalidated, but the provider name didn't change. This
     54              * will be the most common state, so check for it early without resetting the default
     55              * SocketFactory.
     56              */
     57             if (defaultSocketFactory != null) {
     58                 if (newName.equals(defaultSocketFactory.getClass().getName())) {
     59                     return defaultSocketFactory;
     60                 } else {
     61                     defaultSocketFactory = null;
     62                 }
     63             }
     64 
     65             ClassLoader cl = Thread.currentThread().getContextClassLoader();
     66             if (cl == null) {
     67                 cl = ClassLoader.getSystemClassLoader();
     68             }
     69             try {
     70                 final Class<?> sfc = Class.forName(newName, true, cl);
     71                 defaultSocketFactory = (SocketFactory) sfc.newInstance();
     72             } catch (Exception e) {
     73                 System.logW("Could not create " + newName + " with ClassLoader "
     74                         + cl.toString() + ": " + e.getMessage());
     75             }
     76         } else {
     77             defaultSocketFactory = null;
     78         }
     79 
     80         if (defaultSocketFactory == null) {
     81             SSLContext context;
     82             try {
     83                 context = SSLContext.getDefault();
     84             } catch (NoSuchAlgorithmException e) {
     85                 context = null;
     86             }
     87             if (context != null) {
     88                 defaultSocketFactory = context.getSocketFactory();
     89             }
     90         }
     91 
     92         if (defaultSocketFactory == null) {
     93             // Use internal implementation
     94             defaultSocketFactory = new DefaultSSLSocketFactory("No SSLSocketFactory installed");
     95         }
     96 
     97         return defaultSocketFactory;
     98     }
     99 
    100     /**
    101      * Creates a new {@code SSLSocketFactory}.
    102      */
    103     public SSLSocketFactory() {
    104     }
    105 
    106     /**
    107      * Returns the names of the cipher suites that are enabled by default.
    108      *
    109      * @return the names of the cipher suites that are enabled by default.
    110      */
    111     public abstract String[] getDefaultCipherSuites();
    112 
    113     /**
    114      * Returns the names of the cipher suites that are supported and could be
    115      * enabled for an SSL connection.
    116      *
    117      * @return the names of the cipher suites that are supported.
    118      */
    119     public abstract String[] getSupportedCipherSuites();
    120 
    121     /**
    122      * Creates an {@code SSLSocket} over the specified socket that is connected
    123      * to the specified host at the specified port.
    124      *
    125      * @param s
    126      *            the socket.
    127      * @param host
    128      *            the host.
    129      * @param port
    130      *            the port number.
    131      * @param autoClose
    132      *            {@code true} if socket {@code s} should be closed when the
    133      *            created socket is closed, {@code false} if the socket
    134      *            {@code s} should be left open.
    135      * @return the creates ssl socket.
    136      * @throws IOException
    137      *             if creating the socket fails.
    138      * @throws java.net.UnknownHostException
    139      *             if the host is unknown.
    140      */
    141     public abstract Socket createSocket(Socket s, String host, int port, boolean autoClose)
    142             throws IOException;
    143 }
    144