001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.mina.example.tcp.perf;
021
022import java.io.IOException;
023import java.io.InputStream;
024import java.security.GeneralSecurityException;
025import java.security.KeyStore;
026import java.security.Security;
027
028import javax.net.ssl.KeyManagerFactory;
029import javax.net.ssl.SSLContext;
030
031/**
032 * Factory to create a bogus SSLContext.
033 *
034 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
035 */
036public class BogusSslContextFactory {
037
038    /**
039     * Protocol to use.
040     */
041    private static final String PROTOCOL = "TLS";
042
043    private static final String KEY_MANAGER_FACTORY_ALGORITHM;
044
045    static {
046        String algorithm = Security
047                .getProperty("ssl.KeyManagerFactory.algorithm");
048        if (algorithm == null) {
049            algorithm = KeyManagerFactory.getDefaultAlgorithm();
050        }
051
052        KEY_MANAGER_FACTORY_ALGORITHM = algorithm;
053    }
054
055    /**
056     * Bougus Server certificate keystore file name.
057     */
058    private static final String BOGUS_KEYSTORE = "bogus.cert";
059
060    // NOTE: The keystore was generated using keytool:
061    //   keytool -genkey -alias bogus -keysize 512 -validity 3650
062    //           -keyalg RSA -dname "CN=bogus.com, OU=XXX CA,
063    //               O=Bogus Inc, L=Stockholm, S=Stockholm, C=SE"
064    //           -keypass boguspw -storepass boguspw -keystore bogus.cert
065
066    /**
067     * Bougus keystore password.
068     */
069    private static final char[] BOGUS_PW = { 'b', 'o', 'g', 'u', 's', 'p', 'w' };
070
071    private static SSLContext serverInstance = null;
072    
073    private static SSLContext clientInstance = null;
074
075    /**
076     * Get SSLContext singleton.
077     *
078     * @param server A flag to tell if this is a Client or Server instance we want to create
079     * @return SSLContext The created SSLContext 
080     * @throws GeneralSecurityException If we had an issue creating the SSLContext
081     */
082    public static SSLContext getInstance(boolean server)
083            throws GeneralSecurityException {
084        SSLContext retInstance = null;
085        if (server) {
086            synchronized(BogusSslContextFactory.class) {
087                if (serverInstance == null) {
088                    try {
089                        serverInstance = createBougusServerSslContext();
090                    } catch (Exception ioe) {
091                        throw new GeneralSecurityException(
092                                "Can't create Server SSLContext:" + ioe);
093                    }
094                }
095            }
096            retInstance = serverInstance;
097        } else {
098            synchronized (BogusSslContextFactory.class) {
099                if (clientInstance == null) {
100                    clientInstance = createBougusClientSslContext();
101                }
102            }
103            retInstance = clientInstance;
104        }
105        return retInstance;
106    }
107
108    private static SSLContext createBougusServerSslContext()
109            throws GeneralSecurityException, IOException {
110        // Create keystore
111        KeyStore ks = KeyStore.getInstance("JKS");
112        InputStream in = null;
113        try {
114            in = BogusSslContextFactory.class
115                    .getResourceAsStream(BOGUS_KEYSTORE);
116            ks.load(in, BOGUS_PW);
117        } finally {
118            if (in != null) {
119                try {
120                    in.close();
121                } catch (IOException ignored) {
122                }
123            }
124        }
125
126        // Set up key manager factory to use our key store
127        KeyManagerFactory kmf = KeyManagerFactory
128                .getInstance(KEY_MANAGER_FACTORY_ALGORITHM);
129        kmf.init(ks, BOGUS_PW);
130
131        // Initialize the SSLContext to work with our key managers.
132        SSLContext sslContext = SSLContext.getInstance(PROTOCOL);
133        sslContext.init(kmf.getKeyManagers(),
134                BogusTrustManagerFactory.X509_MANAGERS, null);
135
136        return sslContext;
137    }
138
139    private static SSLContext createBougusClientSslContext()
140            throws GeneralSecurityException {
141        SSLContext context = SSLContext.getInstance(PROTOCOL);
142        context.init(null, BogusTrustManagerFactory.X509_MANAGERS, null);
143        return context;
144    }
145
146}