001 /* SSLContext.java -- an SSL protocol context.
002 Copyright (C) 2004 Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038
039 package javax.net.ssl;
040
041 import gnu.java.security.Engine;
042
043 import java.lang.reflect.InvocationTargetException;
044 import java.security.KeyManagementException;
045 import java.security.NoSuchAlgorithmException;
046 import java.security.NoSuchProviderException;
047 import java.security.Provider;
048 import java.security.SecureRandom;
049 import 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 */
059 public 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 }