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 18package javax.net.ssl; 19 20import java.security.KeyManagementException; 21import java.security.NoSuchAlgorithmException; 22import java.security.NoSuchProviderException; 23import java.security.Provider; 24import java.security.SecureRandom; 25import java.security.Security; 26import org.apache.harmony.security.fortress.Engine; 27 28 29/** 30 * The public API for secure socket protocol implementations. It acts as factory 31 * for {@code SSLSocketFactory}'s and {@code SSLEngine}s. 32 */ 33public class SSLContext { 34 // StoreSSLContext service name 35 private static final String SERVICE = "SSLContext"; 36 37 // Used to access common engine functionality 38 private static final Engine ENGINE = new Engine(SERVICE); 39 40 /** 41 * Default SSLContext that can be replaced with SSLContext.setDefault() 42 */ 43 private static SSLContext DEFAULT; 44 45 /** 46 * Returns the default SSLContext. 47 * 48 * The default SSL context can be set with {@link #setDefault}. If 49 * not, one will be created with {@code 50 * SSLContext.getInstance("Default")}, which will already be 51 * initialized. 52 * 53 * @throws NoSuchAlgorithmException if there is a problem creating 54 * the default instance. 55 * @since 1.6 56 */ 57 public static SSLContext getDefault() throws NoSuchAlgorithmException { 58 synchronized (ENGINE) { 59 if (DEFAULT == null) { 60 DEFAULT = SSLContext.getInstance("Default"); 61 } 62 return DEFAULT; 63 } 64 } 65 66 /** 67 * Sets the default SSLContext instance as returned by {@link 68 * #getDefault()} to a non-null initialized value. 69 * 70 * @throws NullPointerException on a null argument 71 * @since 1.6 72 */ 73 public static void setDefault(SSLContext sslContext) { 74 if (sslContext == null) { 75 throw new NullPointerException("sslContext == null"); 76 } 77 synchronized (ENGINE) { 78 DEFAULT = sslContext; 79 } 80 } 81 82 /** 83 * Creates a new {@code SSLContext} instance for the specified protocol. 84 * 85 * @param protocol 86 * the requested protocol to create a context for. 87 * @return the created {@code SSLContext} instance. 88 * @throws NoSuchAlgorithmException 89 * if no installed provider can provide the requested protocol 90 * @throws NullPointerException 91 * if {@code protocol} is {@code null} (instead of 92 * NoSuchAlgorithmException as in 1.4 release) 93 */ 94 public static SSLContext getInstance(String protocol) throws NoSuchAlgorithmException { 95 if (protocol == null) { 96 throw new NullPointerException("protocol == null"); 97 } 98 Engine.SpiAndProvider sap = ENGINE.getInstance(protocol, null); 99 return new SSLContext((SSLContextSpi) sap.spi, sap.provider, protocol); 100 } 101 102 /** 103 * Creates a new {@code SSLContext} instance for the specified protocol from 104 * the specified provider. 105 * 106 * @param protocol 107 * the requested protocol to create a context for. 108 * @param provider 109 * the name of the provider that provides the requested protocol. 110 * @return an {@code SSLContext} for the requested protocol. 111 * @throws NoSuchAlgorithmException 112 * if the specified provider cannot provider the requested 113 * protocol. 114 * @throws NoSuchProviderException 115 * if the specified provider does not exits. 116 * @throws NullPointerException 117 * if {@code protocol} is {@code null} (instead of 118 * NoSuchAlgorithmException as in 1.4 release) 119 */ 120 public static SSLContext getInstance(String protocol, String provider) 121 throws NoSuchAlgorithmException, NoSuchProviderException { 122 if (provider == null) { 123 throw new IllegalArgumentException("Provider is null"); 124 } 125 if (provider.length() == 0) { 126 throw new IllegalArgumentException("Provider is empty"); 127 } 128 Provider impProvider = Security.getProvider(provider); 129 if (impProvider == null) { 130 throw new NoSuchProviderException(provider); 131 } 132 return getInstance(protocol, impProvider); 133 } 134 135 /** 136 * Creates a new {@code SSLContext} instance for the specified protocol from 137 * the specified provider. 138 * 139 * @param protocol 140 * the requested protocol to create a context for 141 * @param provider 142 * the provider that provides the requested protocol. 143 * @return an {@code SSLContext} for the requested protocol. 144 * @throws NoSuchAlgorithmException 145 * if the specified provider cannot provide the requested 146 * protocol. 147 * @throws NullPointerException 148 * if {@code protocol} is {@code null} (instead of 149 * NoSuchAlgorithmException as in 1.4 release) 150 */ 151 public static SSLContext getInstance(String protocol, Provider provider) 152 throws NoSuchAlgorithmException { 153 if (provider == null) { 154 throw new IllegalArgumentException("provider is null"); 155 } 156 if (protocol == null) { 157 throw new NullPointerException("protocol == null"); 158 } 159 Object spi = ENGINE.getInstance(protocol, provider, null); 160 return new SSLContext((SSLContextSpi) spi, provider, protocol); 161 } 162 163 private final Provider provider; 164 165 private final SSLContextSpi spiImpl; 166 167 private final String protocol; 168 169 /** 170 * Creates a new {@code SSLContext}. 171 * 172 * @param contextSpi 173 * the implementation delegate. 174 * @param provider 175 * the provider. 176 * @param protocol 177 * the protocol name. 178 */ 179 protected SSLContext(SSLContextSpi contextSpi, Provider provider, String protocol) { 180 this.provider = provider; 181 this.protocol = protocol; 182 this.spiImpl = contextSpi; 183 } 184 185 /** 186 * Returns the name of the secure socket protocol of this instance. 187 * 188 * @return the name of the secure socket protocol of this instance. 189 */ 190 public final String getProtocol() { 191 return protocol; 192 } 193 194 /** 195 * Returns the provider of this {@code SSLContext} instance. 196 * 197 * @return the provider of this {@code SSLContext} instance. 198 */ 199 public final Provider getProvider() { 200 return provider; 201 } 202 203 /** 204 * Initializes this {@code SSLContext} instance. All of the arguments are 205 * optional, and the security providers will be searched for the required 206 * implementations of the needed algorithms. 207 * 208 * @param km 209 * the key sources or {@code null}. 210 * @param tm 211 * the trust decision sources or {@code null}. 212 * @param sr 213 * the randomness source or {@code null.} 214 * @throws KeyManagementException 215 * if initializing this instance fails. 216 */ 217 public final void init(KeyManager[] km, TrustManager[] tm, SecureRandom sr) 218 throws KeyManagementException { 219 spiImpl.engineInit(km, tm, sr); 220 } 221 222 /** 223 * Returns a socket factory for this instance. 224 * 225 * @return a socket factory for this instance. 226 */ 227 public final SSLSocketFactory getSocketFactory() { 228 return spiImpl.engineGetSocketFactory(); 229 } 230 231 /** 232 * Returns a server socket factory for this instance. 233 * 234 * @return a server socket factory for this instance. 235 */ 236 public final SSLServerSocketFactory getServerSocketFactory() { 237 return spiImpl.engineGetServerSocketFactory(); 238 } 239 240 /** 241 * Creates an {@code SSLEngine} instance from this context. 242 * 243 * @return an {@code SSLEngine} instance from this context. 244 * @throws UnsupportedOperationException 245 * if the provider does not support the operation. 246 */ 247 public final SSLEngine createSSLEngine() { 248 return spiImpl.engineCreateSSLEngine(); 249 } 250 251 /** 252 * Creates an {@code SSLEngine} instance from this context with the 253 * specified hostname and port. 254 * 255 * @param peerHost 256 * the name of the host 257 * @param peerPort 258 * the port 259 * @return an {@code SSLEngine} instance from this context. 260 * @throws UnsupportedOperationException 261 * if the provider does not support the operation. 262 */ 263 public final SSLEngine createSSLEngine(String peerHost, int peerPort) { 264 return spiImpl.engineCreateSSLEngine(peerHost, peerPort); 265 } 266 267 /** 268 * Returns the SSL session context that encapsulates the set of SSL sessions 269 * that can be used for handshake of server-side SSL sockets. 270 * 271 * @return the SSL server session context for this context or {@code null} 272 * if the underlying provider does not provide an implementation of 273 * the {@code SSLSessionContext} interface. 274 */ 275 public final SSLSessionContext getServerSessionContext() { 276 return spiImpl.engineGetServerSessionContext(); 277 } 278 279 /** 280 * Returns the SSL session context that encapsulates the set of SSL sessions 281 * that can be used for handshake of client-side SSL sockets. 282 * 283 * @return the SSL client session context for this context or {@code null} 284 * if the underlying provider does not provide an implementation of 285 * the {@code SSLSessionContext} interface. 286 */ 287 public final SSLSessionContext getClientSessionContext() { 288 return spiImpl.engineGetClientSessionContext(); 289 } 290 291 /** 292 * Returns the default SSL handshake parameters for SSLSockets 293 * created by this SSLContext. 294 * 295 * @throws UnsupportedOperationException 296 * @since 1.6 297 */ 298 public final SSLParameters getDefaultSSLParameters() { 299 return spiImpl.engineGetDefaultSSLParameters(); 300 } 301 302 /** 303 * Returns SSL handshake parameters for SSLSockets that includes 304 * all supported cipher suites and protocols. 305 * 306 * @throws UnsupportedOperationException 307 * @since 1.6 308 */ 309 public final SSLParameters getSupportedSSLParameters() { 310 return spiImpl.engineGetSupportedSSLParameters(); 311 } 312} 313