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