1 /* 2 * Copyright 2009 Red Hat, Inc. 3 * 4 * Red Hat licenses this file to you under the Apache License, version 2.0 5 * (the "License"); you may not use this file except in compliance with the 6 * 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.Security; 20 21 import javax.net.ssl.KeyManager; 22 import javax.net.ssl.KeyManagerFactory; 23 import javax.net.ssl.SSLContext; 24 import javax.net.ssl.SSLEngine; 25 import javax.net.ssl.TrustManager; 26 27 import org.jboss.netty.handler.ssl.SslHandler; 28 29 /** 30 * Creates a bogus {@link SSLContext}. A client-side context created by this 31 * factory accepts any certificate even if it is invalid. A server-side context 32 * created by this factory sends a bogus certificate defined in {@link SecureChatKeyStore}. 33 * <p> 34 * You will have to create your context differently in a real world application. 35 * 36 * <h3>Client Certificate Authentication</h3> 37 * 38 * To enable client certificate authentication: 39 * <ul> 40 * <li>Enable client authentication on the server side by calling 41 * {@link SSLEngine#setNeedClientAuth(boolean)} before creating 42 * {@link SslHandler}.</li> 43 * <li>When initializing an {@link SSLContext} on the client side, 44 * specify the {@link KeyManager} that contains the client certificate as 45 * the first argument of {@link SSLContext#init(KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom)}.</li> 46 * <li>When initializing an {@link SSLContext} on the server side, 47 * specify the proper {@link TrustManager} as the second argument of 48 * {@link SSLContext#init(KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom)} 49 * to validate the client certificate.</li> 50 * </ul> 51 * 52 * @author <a href="http://www.jboss.org/netty/">The Netty Project</a> 53 * @author <a href="http://gleamynode.net/">Trustin Lee</a> 54 * 55 * @version $Rev: 2080 $, $Date: 2010-01-26 18:04:19 +0900 (Tue, 26 Jan 2010) $ 56 */ 57 public class SecureChatSslContextFactory { 58 59 private static final String PROTOCOL = "TLS"; 60 private static final SSLContext SERVER_CONTEXT; 61 private static final SSLContext CLIENT_CONTEXT; 62 63 static { 64 String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm"); 65 if (algorithm == null) { 66 algorithm = "SunX509"; 67 } 68 69 SSLContext serverContext = null; 70 SSLContext clientContext = null; 71 try { 72 KeyStore ks = KeyStore.getInstance("JKS"); 73 ks.load(SecureChatKeyStore.asInputStream(), 74 SecureChatKeyStore.getKeyStorePassword()); 75 76 // Set up key manager factory to use our key store 77 KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); 78 kmf.init(ks, SecureChatKeyStore.getCertificatePassword()); 79 80 // Initialize the SSLContext to work with our key managers. 81 serverContext = SSLContext.getInstance(PROTOCOL); 82 serverContext.init(kmf.getKeyManagers(), null, null); 83 } catch (Exception e) { 84 throw new Error( 85 "Failed to initialize the server-side SSLContext", e); 86 } 87 88 try { 89 clientContext = SSLContext.getInstance(PROTOCOL); 90 clientContext.init(null, SecureChatTrustManagerFactory.getTrustManagers(), null); 91 } catch (Exception e) { 92 throw new Error( 93 "Failed to initialize the client-side SSLContext", e); 94 } 95 96 SERVER_CONTEXT = serverContext; 97 CLIENT_CONTEXT = clientContext; 98 } 99 100 public static SSLContext getServerContext() { 101 return SERVER_CONTEXT; 102 } 103 104 public static SSLContext getClientContext() { 105 return CLIENT_CONTEXT; 106 } 107 }