Package pygmy.core

Source Code of pygmy.core.SSLServerSocketEndPoint$AliasForcingKeyManager

package pygmy.core;

import javax.net.ssl.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.ServerSocket;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.logging.Logger;
import java.util.logging.Level;
/**
* This EndPoint provides SSL sockets for http protocol.  This extends the ServerSocket to create SSLSockets for http.
*
* <table class="inner">
* <tr class="header"><td>Parameter Name</td><td>Explanation</td><td>Default Value</td><td>Required</td></tr>
* <tr class="row"><td>keystore</td><td>The keystore of the certificates used by this socket.  This contains both the certificate used to authenticate the server as well as authenticate clients.</td><td>None</td><td>Yes</td></tr>
* <tr class="altrow"><td>storepass</td><td>Password for the keystore.</td><td>None</td><td>Yes</td></tr>
* <tr class="row"><td>keypass</td><td>Password for the key with the given alias.</td><td>Defaults to storepass</td><td>No, but its a good idea</td></tr>
* <tr class="altrow"><td>alias</td><td>The name of the certificate in the keystore used for server authentication.</td><td>sslkey</td><td>No</td></tr>
* <tr class="row"><td>ciphers</td><td>A comma seperated list of cipher suites to use to encrypt the SSL socket.</td><td></td><td>No</td></tr>
* <tr class="atlrow"><td>protocols</td><td>A comma seperated list of protocols to use in negotiating the SSL socket.</td><td></td><td>No</td></tr>
* <tr class="row"><td>clientauth</td><td>Setting this to true will require clients authenticate to the server.</td><td>false</td><td>No</td></tr>
* </table>
*/
public class SSLServerSocketEndPoint extends ServerSocketEndPoint {

    private static final Logger log = Logger.getLogger( ServerSocketEndPoint.class.getName() );

    private static final ConfigOption KEYSTORE_OPTION = new ConfigOption( "keystore", true, "The keystore used by the SSL server." );
    private static final ConfigOption STOREPASS_OPTION = new ConfigOption( "storepass", true, "The keystore password." );
    private static final ConfigOption KEYPASS_OPTION = new ConfigOption( "keypass", false, "The password for the key in the keystore." );
    private static final ConfigOption ALIAS_OPTION = new ConfigOption( "alias", "sslkey", "The alias to the key used by the SSL server." );
    private static final ConfigOption CIPHERS_OPTION = new ConfigOption( "ciphers", false, "Comma seperated list of ciphers to use for the SSL server.");
    private static final ConfigOption PROTOCOLS_OPTION = new ConfigOption( "protocols", false, "Comma seperated list of protocols for SSL server.");
    private static final ConfigOption CLIENT_AUTH_OPTION = new ConfigOption( "clientauth", "false", "Require client authentication during SSL handshake." );


    public void initialize(String name, Server server) throws IOException {
        super.initialize( name, server );
        try {
            File keystoreFile = new File(KEYSTORE_OPTION.getProperty(server,endpointName));
            String storepass = STOREPASS_OPTION.getProperty(server,endpointName);
            String keypass = KEYPASS_OPTION.getProperty(server, endpointName );
            keypass = keypass == null ? storepass : keypass;
            KeyStore keystore = loadKeystoreFromFile(keystoreFile, storepass.toCharArray());

            SSLContext context = SSLContext.getInstance("SSL");
            context.init(getKeyManagers(keystore, keypass.toCharArray(), ALIAS_OPTION.getProperty( server, endpointName ) ), getTrustManagers(keystore), null);
            factory = context.getServerSocketFactory();
        } catch (GeneralSecurityException e) {
            log.log( Level.SEVERE, "Security Exception while initializing.", e );
            throw (IOException) new IOException().initCause(e);
        }
    }

    protected String getProtocol() {
        return "https";
    }

    protected ServerSocket createSocket(int port) throws IOException {
        ServerSocket serverSocket = super.createSocket(port);
        String cipherSuites = CIPHERS_OPTION.getProperty( server, getName() );
        if( cipherSuites != null ) {
            ((SSLServerSocket)serverSocket).setEnabledCipherSuites( cipherSuites.split(",") );
        }

        String protocols = PROTOCOLS_OPTION.getProperty( server, getName() );
        if( protocols != null ) {
            ((SSLServerSocket)serverSocket).setEnabledProtocols( protocols.split(",") );
        }

        boolean clientAuth = CLIENT_AUTH_OPTION.getBoolean( server, getName() ).booleanValue();
        if( clientAuth ) {
            ((SSLServerSocket)serverSocket).setNeedClientAuth( true );
        }
        return serverSocket;
    }

    private KeyStore loadKeystoreFromFile(File file, char[] password) throws IOException, GeneralSecurityException {
        KeyStore keystore = KeyStore.getInstance("JKS");
        InputStream stream = new FileInputStream(file);
        keystore.load(stream, password);
        stream.close();

        return keystore;
    }

    private TrustManager[] getTrustManagers(KeyStore keystore) throws GeneralSecurityException {
        TrustManagerFactory factory = TrustManagerFactory.getInstance("SunX509");
        factory.init(keystore);

        return factory.getTrustManagers();
    }

    private KeyManager[] getKeyManagers(KeyStore keystore, char[] pwd, String alias) throws GeneralSecurityException {
        KeyManagerFactory factory = KeyManagerFactory.getInstance("SunX509");
        factory.init(keystore, pwd);
        KeyManager[] kms = factory.getKeyManagers();
        if (alias != null) {
            for (int i = 0; i < kms.length; i++) {
                if (kms[i] instanceof X509KeyManager)
                    kms[i] = new AliasForcingKeyManager((X509KeyManager) kms[i], alias);
            }
        }

        return kms;
    }

    private class AliasForcingKeyManager implements X509KeyManager {
        X509KeyManager baseKM = null;
        String alias = null;

        public AliasForcingKeyManager(X509KeyManager keyManager, String alias) {
            baseKM = keyManager;
            this.alias = alias;
        }

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

        public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
            String[] validAliases = baseKM.getServerAliases(keyType, issuers);
            if (validAliases != null) {
                for (int j = 0; j < validAliases.length; j++) {
                    if (validAliases[j].equals(alias)) return alias;
                }
            }
            return baseKM.chooseServerAlias( keyType, issuers, socket )// use default if we can't find the alias.
        }

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

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

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

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

Related Classes of pygmy.core.SSLServerSocketEndPoint$AliasForcingKeyManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.