Use Tree Navigation
public class

SSLContextImpl

extends SSLContextSpi
/*
 * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


package sun.security.ssl;

import java.net.Socket;

import java.security.*;
import java.security.cert.*;

import javax.net.ssl.*;

public class SSLContextImpl extends SSLContextSpi {

   
private static final Debug debug = Debug.getInstance("ssl");

   
private final EphemeralKeyManager ephemeralKeyManager;
   
private final SSLSessionContextImpl clientCache;
   
private final SSLSessionContextImpl serverCache;

   
private boolean isInitialized;

   
private X509ExtendedKeyManager keyManager;
   
private X509TrustManager trustManager;
   
private SecureRandom secureRandom;

   
public SSLContextImpl() {
       
this(null);
   
}

   
SSLContextImpl(SSLContextImpl other) {
       
if (other == null) {
            ephemeralKeyManager
= new EphemeralKeyManager();
            clientCache
= new SSLSessionContextImpl();
            serverCache
= new SSLSessionContextImpl();
       
} else {
            ephemeralKeyManager
= other.ephemeralKeyManager;
            clientCache
= other.clientCache;
            serverCache
= other.serverCache;
       
}
   
}

   
protected void engineInit(KeyManager[] km, TrustManager[] tm,
                               
SecureRandom sr) throws KeyManagementException {
        isInitialized
= false;
        keyManager
= chooseKeyManager(km);

       
if (tm == null) {
           
try {
               
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
                       
TrustManagerFactory.getDefaultAlgorithm());
                tmf
.init((KeyStore)null);
                tm
= tmf.getTrustManagers();
           
} catch (Exception e) {
               
// eat
           
}
       
}
        trustManager
= chooseTrustManager(tm);

       
if (sr == null) {
            secureRandom
= JsseJce.getSecureRandom();
       
} else {
           
if (SunJSSE.isFIPS() && (sr.getProvider() != SunJSSE.cryptoProvider)) {
               
throw new KeyManagementException
                   
("FIPS mode: SecureRandom must be from provider "
                   
+ SunJSSE.cryptoProvider.getName());
           
}
            secureRandom
= sr;
       
}

       
/*
         * The initial delay of seeding the random number generator
         * could be long enough to cause the initial handshake on our
         * first connection to timeout and fail. Make sure it is
         * primed and ready by getting some initial output from it.
         */

       
if (debug != null && Debug.isOn("sslctx")) {
           
System.out.println("trigger seeding of SecureRandom");
       
}
        secureRandom
.nextInt();
       
if (debug != null && Debug.isOn("sslctx")) {
           
System.out.println("done seeding SecureRandom");
       
}
        isInitialized
= true;
   
}

   
private X509TrustManager chooseTrustManager(TrustManager[] tm)
           
throws KeyManagementException {
       
// We only use the first instance of X509TrustManager passed to us.
       
for (int i = 0; tm != null && i < tm.length; i++) {
           
if (tm[i] instanceof X509TrustManager) {
               
if (SunJSSE.isFIPS() && !(tm[i] instanceof X509TrustManagerImpl)) {
                   
throw new KeyManagementException
                       
("FIPS mode: only SunJSSE TrustManagers may be used");
               
}
               
return (X509TrustManager)tm[i];
           
}
       
}

       
// nothing found, return a dummy X509TrustManager.
       
return DummyX509TrustManager.INSTANCE;
   
}

   
private X509ExtendedKeyManager chooseKeyManager(KeyManager[] kms)
           
throws KeyManagementException {
       
for (int i = 0; kms != null && i < kms.length; i++) {
           
KeyManager km = kms[i];
           
if (km instanceof X509KeyManager == false) {
               
continue;
           
}
           
if (SunJSSE.isFIPS()) {
               
// In FIPS mode, require that one of SunJSSE's own keymanagers
               
// is used. Otherwise, we cannot be sure that only keys from
               
// the FIPS token are used.
               
if ((km instanceof X509KeyManagerImpl)
                           
|| (km instanceof SunX509KeyManagerImpl)) {
                   
return (X509ExtendedKeyManager)km;
               
} else {
                   
// throw exception, we don't want to silently use the
                   
// dummy keymanager without telling the user.
                   
throw new KeyManagementException
                       
("FIPS mode: only SunJSSE KeyManagers may be used");
               
}
           
}
           
if (km instanceof X509ExtendedKeyManager) {
               
return (X509ExtendedKeyManager)km;
           
}
           
if (debug != null && Debug.isOn("sslctx")) {
               
System.out.println(
                   
"X509KeyManager passed to " +
                   
"SSLContext.init():  need an " +
                   
"X509ExtendedKeyManager for SSLEngine use");
           
}
           
return new AbstractWrapper((X509KeyManager)km);
       
}

       
// nothing found, return a dummy X509ExtendedKeyManager
       
return DummyX509KeyManager.INSTANCE;
   
}

   
protected SSLSocketFactory engineGetSocketFactory() {
       
if (!isInitialized) {
           
throw new IllegalStateException(
               
"SSLContextImpl is not initialized");
       
}
       
return new SSLSocketFactoryImpl(this);
   
}

   
protected SSLServerSocketFactory engineGetServerSocketFactory() {
       
if (!isInitialized) {
           
throw new IllegalStateException("SSLContext is not initialized");
       
}
       
return new SSLServerSocketFactoryImpl(this);
   
}

   
protected SSLEngine engineCreateSSLEngine() {
       
if (!isInitialized) {
           
throw new IllegalStateException(
               
"SSLContextImpl is not initialized");
       
}
       
return new SSLEngineImpl(this);
   
}

   
protected SSLEngine engineCreateSSLEngine(String host, int port) {
       
if (!isInitialized) {
           
throw new IllegalStateException(
               
"SSLContextImpl is not initialized");
       
}
       
return new SSLEngineImpl(this, host, port);
   
}

   
protected SSLSessionContext engineGetClientSessionContext() {
       
return clientCache;
   
}

   
protected SSLSessionContext engineGetServerSessionContext() {
       
return serverCache;
   
}

   
SecureRandom getSecureRandom() {
       
return secureRandom;
   
}

    X509ExtendedKeyManager getX509KeyManager
() {
       
return keyManager;
   
}

    X509TrustManager getX509TrustManager
() {
       
return trustManager;
   
}

   
EphemeralKeyManager getEphemeralKeyManager() {
       
return ephemeralKeyManager;
   
}

}

// Dummy X509TrustManager implementation, rejects all peer certificates.
// Used if the application did not specify a proper X509TrustManager.
final class DummyX509TrustManager implements X509TrustManager {

   
static final X509TrustManager INSTANCE = new DummyX509TrustManager();

   
private DummyX509TrustManager() {
       
// empty
   
}

   
/*
     * Given the partial or complete certificate chain
     * provided by the peer, build a certificate path
     * to a trusted root and return if it can be
     * validated and is trusted for client SSL authentication.
     * If not, it throws an exception.
     */

   
public void checkClientTrusted(X509Certificate[] chain, String authType)
       
throws CertificateException {
       
throw new CertificateException(
           
"No X509TrustManager implementation avaiable");
   
}

   
/*
     * Given the partial or complete certificate chain
     * provided by the peer, build a certificate path
     * to a trusted root and return if it can be
     * validated and is trusted for server SSL authentication.
     * If not, it throws an exception.
     */

   
public void checkServerTrusted(X509Certificate[] chain, String authType)
       
throws CertificateException {
       
throw new CertificateException(
           
"No X509TrustManager implementation available");
   
}

   
/*
     * Return an array of issuer certificates which are trusted
     * for authenticating peers.
     */

   
public X509Certificate[] getAcceptedIssuers() {
       
return new X509Certificate[0];
   
}
}

/*
 * A wrapper class to turn a X509KeyManager into an X509ExtendedKeyManager
 */

final class AbstractWrapper extends X509ExtendedKeyManager {

   
private final X509KeyManager km;

   
AbstractWrapper(X509KeyManager km) {
       
this.km = km;
   
}

   
public String[] getClientAliases(String keyType, Principal[] issuers) {
       
return km.getClientAliases(keyType, issuers);
   
}

   
public String chooseClientAlias(String[] keyType, Principal[] issuers,
           
Socket socket) {
       
return km.chooseClientAlias(keyType, issuers, socket);
   
}

   
public String[] getServerAliases(String keyType, Principal[] issuers) {
       
return km.getServerAliases(keyType, issuers);
   
}

   
public String chooseServerAlias(String keyType, Principal[] issuers,
           
Socket socket) {
       
return km.chooseServerAlias(keyType, issuers, socket);
   
}

   
public X509Certificate[] getCertificateChain(String alias) {
       
return km.getCertificateChain(alias);
   
}

   
public PrivateKey getPrivateKey(String alias) {
       
return km.getPrivateKey(alias);
   
}

   
// Inherit chooseEngineClientAlias() and chooseEngineServerAlias() from
   
// X509ExtendedKeymanager. It defines them to return null;
}


// Dummy X509KeyManager implementation, never returns any certificates/keys.
// Used if the application did not specify a proper X509TrustManager.
final class DummyX509KeyManager extends X509ExtendedKeyManager {

   
static final X509ExtendedKeyManager INSTANCE = new DummyX509KeyManager();

   
private DummyX509KeyManager() {
       
// empty
   
}

   
/*
     * Get the matching aliases for authenticating the client side of a secure
     * socket given the public key type and the list of
     * certificate issuer authorities recognized by the peer (if any).
     */

   
public String[] getClientAliases(String keyType, Principal[] issuers) {
       
return null;
   
}

   
/*
     * Choose an alias to authenticate the client side of a secure
     * socket given the public key type and the list of
     * certificate issuer authorities recognized by the peer (if any).
     */

   
public String chooseClientAlias(String[] keyTypes, Principal[] issuers,
           
Socket socket) {
       
return null;
   
}

   
/*
     * Choose an alias to authenticate the client side of an
     * engine given the public key type and the list of
     * certificate issuer authorities recognized by the peer (if any).
     */

   
public String chooseEngineClientAlias(
           
String[] keyTypes, Principal[] issuers, SSLEngine engine) {
       
return null;
   
}

   
/*
     * Get the matching aliases for authenticating the server side of a secure
     * socket given the public key type and the list of
     * certificate issuer authorities recognized by the peer (if any).
     */

   
public String[] getServerAliases(String keyType, Principal[] issuers) {
       
return null;
   
}

   
/*
     * Choose an alias to authenticate the server side of a secure
     * socket given the public key type and the list of
     * certificate issuer authorities recognized by the peer (if any).
     */

   
public String chooseServerAlias(String keyType, Principal[] issuers,
           
Socket socket) {
       
return null;
   
}

   
/*
     * Choose an alias to authenticate the server side of an engine
     * given the public key type and the list of
     * certificate issuer authorities recognized by the peer (if any).
     */

   
public String chooseEngineServerAlias(
           
String keyType, Principal[] issuers, SSLEngine engine) {
       
return null;
   
}

   
/**
     * Returns the certificate chain associated with the given alias.
     *
     * @param alias the alias name
     *
     * @return the certificate chain (ordered with the user's certificate first
     * and the root certificate authority last)
     */

   
public X509Certificate[] getCertificateChain(String alias) {
       
return null;
   
}

   
/*
     * Returns the key associated with the given alias, using the given
     * password to recover it.
     *
     * @param alias the alias name
     *
     * @return the requested key
     */

   
public PrivateKey getPrivateKey(String alias) {
       
return null;
   
}
}