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 }