View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the License. You may obtain a copy of the License at:
    7    *
    8    *   http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    13   * License for the specific language governing permissions and limitations
    14   * under the License.
    15   */
    16  package org.jboss.netty.example.securechat;
    17
    18  import java.security.KeyStore;
    19  import java.security.SecureRandom;
    20  import java.security.Security;
    21
    22  import javax.net.ssl.KeyManager;
    23  import javax.net.ssl.KeyManagerFactory;
    24  import javax.net.ssl.SSLContext;
    25  import javax.net.ssl.SSLEngine;
    26  import javax.net.ssl.TrustManager;
    27
    28  import org.jboss.netty.handler.ssl.SslHandler;
    29
    30  /**
    31   * Creates a bogus {@link SSLContext}.  A client-side context created by this
    32   * factory accepts any certificate even if it is invalid.  A server-side context
    33   * created by this factory sends a bogus certificate defined in {@link SecureChatKeyStore}.
    34   * <p>
    35   * You will have to create your context differently in a real world application.
    36   *
    37   * <h3>Client Certificate Authentication</h3>
    38   *
    39   * To enable client certificate authentication:
    40   * <ul>
    41   * <li>Enable client authentication on the server side by calling
    42   *     {@link SSLEngine#setNeedClientAuth(boolean)} before creating
    43   *     {@link SslHandler}.</li>
    44   * <li>When initializing an {@link SSLContext} on the client side,
    45   *     specify the {@link KeyManager} that contains the client certificate as
    46   *     the first argument of {@link SSLContext#init(KeyManager[], TrustManager[], SecureRandom)}.</li>
    47   * <li>When initializing an {@link SSLContext} on the server side,
    48   *     specify the proper {@link TrustManager} as the second argument of
    49   *     {@link SSLContext#init(KeyManager[], TrustManager[], SecureRandom)}
    50   *     to validate the client certificate.</li>
    51   * </ul>
    52   */
    53  public final class SecureChatSslContextFactory {
    54
    55      private static final String PROTOCOL = "TLS";
    56      private static final SSLContext SERVER_CONTEXT;
    57      private static final SSLContext CLIENT_CONTEXT;
    58
    59      static {
    60          String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm");
    61          if (algorithm == null) {
    62              algorithm = "SunX509";
    63          }
    64
    65          SSLContext serverContext = null;
    66          SSLContext clientContext = null;
    67          try {
    68              KeyStore ks = KeyStore.getInstance("JKS");
    69              ks.load(SecureChatKeyStore.asInputStream(),
    70                      SecureChatKeyStore.getKeyStorePassword());
    71
    72              // Set up key manager factory to use our key store
    73              KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
    74              kmf.init(ks, SecureChatKeyStore.getCertificatePassword());
    75
    76              // Initialize the SSLContext to work with our key managers.
    77              serverContext = SSLContext.getInstance(PROTOCOL);
    78              serverContext.init(kmf.getKeyManagers(), null, null);
    79          } catch (Exception e) {
    80              throw new Error(
    81                      "Failed to initialize the server-side SSLContext", e);
    82          }
    83
    84          try {
    85              clientContext = SSLContext.getInstance(PROTOCOL);
    86              clientContext.init(null, SecureChatTrustManagerFactory.getTrustManagers(), null);
    87          } catch (Exception e) {
    88              throw new Error(
    89                      "Failed to initialize the client-side SSLContext", e);
    90          }
    91
    92          SERVER_CONTEXT = serverContext;
    93          CLIENT_CONTEXT = clientContext;
    94      }
    95
    96      public static SSLContext getServerContext() {
    97          return SERVER_CONTEXT;
    98      }
    99
    100     public static SSLContext getClientContext() {
    101         return CLIENT_CONTEXT;
    102     }
    103
    104     private SecureChatSslContextFactory() {
    105         // Unused
    106     }
    107 }