1 /* SSLContext.java -- an SSL protocol context. 2 Copyright (C) 2004 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package javax.net.ssl; 40 41 import gnu.java.security.Engine; 42 43 import java.lang.reflect.InvocationTargetException; 44 import java.security.KeyManagementException; 45 import java.security.NoSuchAlgorithmException; 46 import java.security.NoSuchProviderException; 47 import java.security.Provider; 48 import java.security.SecureRandom; 49 import java.security.Security; 50 51 /** 52 * A "meta-factory" for protocol-specific socket and server socket 53 * factories. This class serves as a clearinghouse for socket 54 * factories and cached session contexts for a particular protocol, 55 * such as SSLv3. 56 * 57 * @author Casey Marshall (rsdio@metastatic.org) 58 */ 59 public class SSLContext 60 { 61 // Constants and fields. 62 // ------------------------------------------------------------------ 63 64 /** Service name for SSL contexts. */ 65 private static final String SSL_CONTEXT = "SSLContext"; 66 67 /** The underlying engine. */ 68 private final SSLContextSpi ctxSpi; 69 70 /** The provider of the engine class. */ 71 private final Provider provider; 72 73 /** The protocal name. */ 74 private final String protocol; 75 76 // Constructor. 77 // ------------------------------------------------------------------ 78 79 /** 80 * Create a new SSL context. 81 * 82 * @param ctxSpi The context engine. 83 * @param provider The provider of the implementation. 84 * @param protocol The name of the SSL protocol. 85 */ SSLContext(SSLContextSpi ctxSpi, Provider provider, String protocol)86 protected SSLContext(SSLContextSpi ctxSpi, Provider provider, 87 String protocol) 88 { 89 this.ctxSpi = ctxSpi; 90 this.provider = provider; 91 this.protocol = protocol; 92 } 93 94 /** 95 * Get an instance of a context for the specified protocol from the first 96 * provider that implements it. 97 * 98 * @param protocol The name of the protocol to get a context for. 99 * @return The new context. 100 * @throws NoSuchAlgorithmException If no provider implements the given 101 * protocol. 102 * @throws IllegalArgumentException if <code>protocol</code> is 103 * <code>null</code> or is an empty string. 104 */ getInstance(String protocol)105 public static final SSLContext getInstance(String protocol) 106 throws NoSuchAlgorithmException 107 { 108 Provider[] p = Security.getProviders(); 109 NoSuchAlgorithmException lastException = null; 110 for (int i = 0; i < p.length; i++) 111 try 112 { 113 return getInstance(protocol, p[i]); 114 } 115 catch (NoSuchAlgorithmException x) 116 { 117 lastException = x; 118 } 119 if (lastException != null) 120 throw lastException; 121 throw new NoSuchAlgorithmException(protocol); 122 } 123 124 /** 125 * Get an instance of a context for the specified protocol from the named 126 * provider. 127 * 128 * @param protocol The name of the protocol to get a context for. 129 * @param provider The name of the provider to get the implementation from. 130 * @return The new context. 131 * @throws NoSuchAlgorithmException If the provider does not implement the 132 * given protocol. 133 * @throws NoSuchProviderException If the named provider does not exist. 134 * @throws IllegalArgumentException if either <code>protocol</code> or 135 * <code>provider</code> is <code>null</code>, or if 136 * <code>protocol</code> is an empty string. 137 */ getInstance(String protocol, String provider)138 public static final SSLContext getInstance(String protocol, String provider) 139 throws NoSuchAlgorithmException, NoSuchProviderException 140 { 141 if (provider == null) 142 throw new IllegalArgumentException("provider MUST NOT be null"); 143 Provider p = Security.getProvider(provider); 144 if (p == null) 145 throw new NoSuchProviderException(provider); 146 return getInstance(protocol, p); 147 } 148 149 /** 150 * Get an instance of a context for the specified protocol from the specified 151 * provider. 152 * 153 * @param protocol The name of the protocol to get a context for. 154 * @param provider The name of the provider to get the implementation from. 155 * @return The new context. 156 * @throws NoSuchAlgorithmException If the provider does not implement the 157 * given protocol. 158 * @throws IllegalArgumentException if either <code>protocol</code> or 159 * <code>provider</code> is <code>null</code>, or if 160 * <code>protocol</code> is an empty string. 161 */ getInstance(String protocol, Provider provider)162 public static final SSLContext getInstance(String protocol, Provider provider) 163 throws NoSuchAlgorithmException 164 { 165 StringBuilder sb = new StringBuilder("SSLContext for protocol [") 166 .append(protocol).append("] from provider[") 167 .append(provider).append("] could not be created"); 168 Throwable cause; 169 try 170 { 171 Object spi = Engine.getInstance(SSL_CONTEXT, protocol, provider); 172 return new SSLContext((SSLContextSpi) spi, provider, protocol); 173 } 174 catch (InvocationTargetException x) 175 { 176 cause = x.getCause(); 177 if (cause instanceof NoSuchAlgorithmException) 178 throw (NoSuchAlgorithmException) cause; 179 if (cause == null) 180 cause = x; 181 } 182 catch (ClassCastException x) 183 { 184 cause = x; 185 } 186 NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString()); 187 x.initCause(cause); 188 throw x; 189 } 190 191 /** 192 * Creates a new {@link SSLEngine} for this context. 193 * 194 * @return The new SSLEngine. 195 * @since 1.5 196 */ createSSLEngine()197 public final SSLEngine createSSLEngine () 198 { 199 return ctxSpi.engineCreateSSLEngine (); 200 } 201 202 /** 203 * Creates a new {@link SSLEngine} for this context, with a given 204 * host name and port number. 205 * 206 * @param host The local host name. 207 * @param port The local port number. 208 * @return The new SSLEngine. 209 * @since 1.5 210 */ createSSLEngine(final String host, final int port)211 public final SSLEngine createSSLEngine (final String host, final int port) 212 { 213 return ctxSpi.engineCreateSSLEngine (host, port); 214 } 215 216 /** 217 * Returns the set of SSL contexts available for client connections. 218 * 219 * @return The set of SSL contexts available for client connections. 220 */ getClientSessionContext()221 public final SSLSessionContext getClientSessionContext() 222 { 223 return ctxSpi.engineGetClientSessionContext(); 224 } 225 226 /** 227 * Returns the protocol name of this context. 228 * 229 * @return The protocol name of this context. 230 */ getProtocol()231 public final String getProtocol() 232 { 233 return protocol; 234 } 235 236 /** 237 * Returns the provider of this implementation. 238 * 239 * @return The provider of this implementation. 240 */ getProvider()241 public final Provider getProvider() 242 { 243 return provider; 244 } 245 246 /** 247 * Returns the set of SSL contexts available for server connections. 248 * 249 * @return The set of SSL contexts available for server connections. 250 */ getServerSessionContext()251 public final SSLSessionContext getServerSessionContext() 252 { 253 return ctxSpi.engineGetServerSessionContext(); 254 } 255 256 /** 257 * Returns the factory for server SSL sockets. 258 * 259 * @return The factory for server SSL sockets. 260 */ getServerSocketFactory()261 public final SSLServerSocketFactory getServerSocketFactory() 262 { 263 return ctxSpi.engineGetServerSocketFactory(); 264 } 265 266 /** 267 * Returns the factory for client SSL sockets. 268 * 269 * @return The factory for client SSL sockets. 270 */ getSocketFactory()271 public final SSLSocketFactory getSocketFactory() 272 { 273 return ctxSpi.engineGetSocketFactory(); 274 } 275 276 /** 277 * Initializes this context and prepares it for producing socket 278 * factories. All of the parameters are optional; default values are 279 * used if left unspecified. 280 * 281 * @param keyManagers The set of key managers to use. 282 * @param trustManagers The set of trust managers to use. 283 * @param random A source of random bits to use. 284 * @throws KeyManagementException If initialization fails. 285 */ init(KeyManager[] keyManagers, TrustManager[] trustManagers, SecureRandom random)286 public final void init(KeyManager[] keyManagers, 287 TrustManager[] trustManagers, 288 SecureRandom random) 289 throws KeyManagementException 290 { 291 ctxSpi.engineInit(keyManagers, trustManagers, random); 292 } 293 } 294