001/* SSLContext.java -- an SSL protocol context. 002 Copyright (C) 2004 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package javax.net.ssl; 040 041import gnu.java.security.Engine; 042 043import java.lang.reflect.InvocationTargetException; 044import java.security.KeyManagementException; 045import java.security.NoSuchAlgorithmException; 046import java.security.NoSuchProviderException; 047import java.security.Provider; 048import java.security.SecureRandom; 049import java.security.Security; 050 051/** 052 * A "meta-factory" for protocol-specific socket and server socket 053 * factories. This class serves as a clearinghouse for socket 054 * factories and cached session contexts for a particular protocol, 055 * such as SSLv3. 056 * 057 * @author Casey Marshall (rsdio@metastatic.org) 058 */ 059public class SSLContext 060{ 061 // Constants and fields. 062 // ------------------------------------------------------------------ 063 064 /** Service name for SSL contexts. */ 065 private static final String SSL_CONTEXT = "SSLContext"; 066 067 /** The underlying engine. */ 068 private final SSLContextSpi ctxSpi; 069 070 /** The provider of the engine class. */ 071 private final Provider provider; 072 073 /** The protocal name. */ 074 private final String protocol; 075 076 // Constructor. 077 // ------------------------------------------------------------------ 078 079 /** 080 * Create a new SSL context. 081 * 082 * @param ctxSpi The context engine. 083 * @param provider The provider of the implementation. 084 * @param protocol The name of the SSL protocol. 085 */ 086 protected SSLContext(SSLContextSpi ctxSpi, Provider provider, 087 String protocol) 088 { 089 this.ctxSpi = ctxSpi; 090 this.provider = provider; 091 this.protocol = protocol; 092 } 093 094 /** 095 * Get an instance of a context for the specified protocol from the first 096 * provider that implements it. 097 * 098 * @param protocol The name of the protocol to get a context for. 099 * @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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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}