OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / javax / net / ssl / provider / SSLContextImpl.java
1 /* SSLContextImpl.java -- 
2    Copyright (C) 2006  Free Software Foundation, Inc.
3
4 This file is a 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 of the License, or (at
9 your option) 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; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 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 gnu.javax.net.ssl.provider;
40
41 import gnu.java.security.action.GetSecurityPropertyAction;
42 import gnu.javax.net.ssl.AbstractSessionContext;
43 import gnu.javax.net.ssl.NullManagerParameters;
44 import gnu.javax.net.ssl.PreSharedKeyManager;
45 import gnu.javax.net.ssl.SRPTrustManager;
46
47 import java.security.AccessController;
48 import java.security.KeyManagementException;
49 import java.security.KeyStore;
50 import java.security.KeyStoreException;
51 import java.security.NoSuchAlgorithmException;
52 import java.security.NoSuchProviderException;
53 import java.security.SecureRandom;
54 import java.security.UnrecoverableKeyException;
55
56 import javax.net.ssl.KeyManager;
57 import javax.net.ssl.KeyManagerFactory;
58 import javax.net.ssl.SSLContextSpi;
59 import javax.net.ssl.SSLEngine;
60 import javax.net.ssl.SSLException;
61 import javax.net.ssl.SSLServerSocketFactory;
62 import javax.net.ssl.SSLSessionContext;
63 import javax.net.ssl.SSLSocketFactory;
64 import javax.net.ssl.TrustManager;
65 import javax.net.ssl.TrustManagerFactory;
66 import javax.net.ssl.X509ExtendedKeyManager;
67 import javax.net.ssl.X509TrustManager;
68
69 /**
70  * Our implementation of {@link SSLContextSpi}.
71  * 
72  * @author Casey Marshall (csm@gnu.org)
73  */
74 public final class SSLContextImpl extends SSLContextSpi
75 {
76   AbstractSessionContext serverContext;
77   AbstractSessionContext clientContext;
78   
79   PreSharedKeyManager pskManager;
80   X509ExtendedKeyManager keyManager;
81   X509TrustManager trustManager;
82   SRPTrustManager srpTrustManager;
83   SecureRandom random;
84
85   public SSLContextImpl()
86   {
87   }
88   
89   /* (non-Javadoc)
90    * @see javax.net.ssl.SSLContextSpi#engineCreateSSLEngine()
91    */
92   protected @Override SSLEngine engineCreateSSLEngine()
93   {
94     return engineCreateSSLEngine(null, -1);
95   }
96
97   /* (non-Javadoc)
98    * @see javax.net.ssl.SSLContextSpi#engineCreateSSLEngine(java.lang.String, int)
99    */
100   protected @Override SSLEngine engineCreateSSLEngine(String host, int port)
101   {
102     return new SSLEngineImpl(this, host, port);
103   }
104
105   /* (non-Javadoc)
106    * @see javax.net.ssl.SSLContextSpi#engineGetClientSessionContext()
107    */
108   protected @Override synchronized SSLSessionContext engineGetClientSessionContext()
109   {
110     if (clientContext == null)
111       {
112         try
113           {
114             clientContext = AbstractSessionContext.newInstance();
115           }
116         catch (SSLException ssle)
117           {
118             // XXX Ignore?
119           }
120       }
121     return clientContext;
122   }
123
124   /* (non-Javadoc)
125    * @see javax.net.ssl.SSLContextSpi#engineGetServerSessionContext()
126    */
127   protected @Override synchronized SSLSessionContext engineGetServerSessionContext()
128   {
129     if (serverContext == null)
130       {
131         try
132           {
133             serverContext = AbstractSessionContext.newInstance();
134           }
135         catch (SSLException ssle)
136           {
137             // XXX Ignore?
138           }
139       }
140     return serverContext;
141   }
142
143   /* (non-Javadoc)
144    * @see javax.net.ssl.SSLContextSpi#engineGetServerSocketFactory()
145    */
146   protected @Override SSLServerSocketFactory engineGetServerSocketFactory()
147   {
148     return new SSLServerSocketFactoryImpl(this);
149   }
150
151   /* (non-Javadoc)
152    * @see javax.net.ssl.SSLContextSpi#engineGetSocketFactory()
153    */
154   protected @Override SSLSocketFactory engineGetSocketFactory()
155   {
156     return new SSLSocketFactoryImpl(this);
157   }
158
159   /* (non-Javadoc)
160    * @see javax.net.ssl.SSLContextSpi#engineInit(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom)
161    */
162   protected @Override void engineInit(KeyManager[] keyManagers,
163                                       TrustManager[] trustManagers,
164                                       SecureRandom random)
165     throws KeyManagementException
166   {
167     keyManager = null;
168     trustManager = null;
169     srpTrustManager = null;
170     if (keyManagers != null)
171       {
172         for (int i = 0; i < keyManagers.length; i++)
173           {
174             if ((keyManagers[i] instanceof X509ExtendedKeyManager)
175                 && keyManager == null)
176               keyManager = (X509ExtendedKeyManager) keyManagers[i];
177             if (keyManagers[i] instanceof PreSharedKeyManager
178                 && pskManager == null)
179               pskManager = (PreSharedKeyManager) keyManagers[i];
180           }
181       }
182     if (keyManager == null)
183       keyManager = defaultKeyManager();
184     if (trustManagers != null)
185       {
186         for (int i = 0; i < trustManagers.length; i++)
187           {
188             if (trustManagers[i] instanceof X509TrustManager)
189               {
190                 if (trustManager == null)
191                   trustManager = (X509TrustManager) trustManagers[i];
192               }
193             else if (trustManagers[i] instanceof SRPTrustManager)
194               {
195                 if (srpTrustManager == null)
196                   srpTrustManager = (SRPTrustManager) trustManagers[i];
197               }
198           }
199       }
200     if (trustManager == null && srpTrustManager == null)
201       {
202         trustManager = defaultTrustManager();
203       }
204     if (random != null)
205       {
206         this.random = random;
207       }
208     else
209       {
210         this.random = defaultRandom();
211       }
212   }
213   
214   /**
215    * Create and return a default key manager. The default is the JessieX509
216    * algorithm, loaded from either the jssecerts file, or the cacerts file.
217    * 
218    * @return The default key manager instance.
219    * @throws KeyManagementException If the instance cannot be created.
220    */
221   private X509ExtendedKeyManager defaultKeyManager() throws KeyManagementException
222   {
223     KeyManagerFactory fact = null;
224     try
225       {
226         fact = KeyManagerFactory.getInstance("JessieX509", "Jessie");
227       }
228     catch (NoSuchAlgorithmException nsae)
229       {
230         throw new KeyManagementException(nsae);
231       }
232     catch (NoSuchProviderException nspe)
233       {
234         throw new KeyManagementException(nspe);
235       }
236     try
237       {
238         fact.init(null, null);
239         return (X509ExtendedKeyManager) fact.getKeyManagers()[0];
240       }
241     catch (NoSuchAlgorithmException nsae) { }
242     catch (KeyStoreException kse) { }
243     catch (UnrecoverableKeyException uke) { }
244     catch (IllegalStateException ise) { }
245
246     try
247       {
248         fact.init(new NullManagerParameters());
249         return (X509ExtendedKeyManager) fact.getKeyManagers()[0];
250       }
251     catch (Exception shouldNotHappen)
252       {
253         throw new Error(shouldNotHappen.toString());
254       }
255   }
256
257   /**
258    * Create and return a default trust manager. The default is the JessieX509
259    * algorithm, loaded from either the jssecerts file, or the cacerts file.
260    * 
261    * @return The default trust manager instance.
262    * @throws KeyManagementException If the instance cannot be created.
263    */
264   private X509TrustManager defaultTrustManager() throws KeyManagementException
265   {
266     try
267       {
268         TrustManagerFactory fact =
269           TrustManagerFactory.getInstance("JessieX509", "Jessie");
270         fact.init((KeyStore) null);
271         return (X509TrustManager) fact.getTrustManagers()[0];
272       }
273     catch (NoSuchAlgorithmException nsae)
274       {
275         throw new KeyManagementException(nsae);
276       }
277     catch (NoSuchProviderException nspe)
278       {
279         throw new KeyManagementException(nspe);
280       }
281     catch (KeyStoreException kse)
282       {
283         throw new KeyManagementException(kse);
284       }
285   }
286
287   /**
288    * Create a default secure PRNG. This is defined as either the algorithm
289    * given in the <code>gnu.javax.net.ssl.secureRandom</code> security
290    * property, or Fortuna if that property is not set. If none of these
291    * algorithms can be found, and instance created with the SecureRandom
292    * constructor is returned.
293    * 
294    * @return The default secure PRNG instance.
295    */
296   private SecureRandom defaultRandom()
297   {
298     GetSecurityPropertyAction gspa
299       = new GetSecurityPropertyAction("gnu.javax.net.ssl.secureRandom");
300     String alg = AccessController.doPrivileged(gspa);
301     if (alg == null)
302       alg = "Fortuna";
303     SecureRandom rand = null;
304     try
305       {
306         rand = SecureRandom.getInstance(alg);
307       }
308     catch (NoSuchAlgorithmException nsae)
309       {
310         rand = new SecureRandom();
311       }
312
313     return rand;
314   }
315 }