Source for gnu.javax.net.ssl.provider.SSLContextImpl

   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: }