KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > security > SecureSocketFactory


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.security;
6
7 import java.io.IOException JavaDoc;
8 import java.net.InetAddress JavaDoc;
9 import java.net.ServerSocket JavaDoc;
10 import java.net.Socket JavaDoc;
11 import java.sql.SQLException JavaDoc;
12
13 //#ifdef JDK14
14
import java.io.ByteArrayInputStream JavaDoc;
15 import java.io.ByteArrayOutputStream JavaDoc;
16 import java.io.File JavaDoc;
17 import java.io.FileInputStream JavaDoc;
18 import java.io.FileOutputStream JavaDoc;
19 import java.security.Key JavaDoc;
20 import java.security.KeyFactory JavaDoc;
21 import java.security.KeyStore JavaDoc;
22 import java.security.KeyStoreException JavaDoc;
23 import java.security.NoSuchAlgorithmException JavaDoc;
24 import java.security.PrivateKey JavaDoc;
25 import java.security.UnrecoverableKeyException JavaDoc;
26 import java.security.cert.Certificate JavaDoc;
27 import java.security.cert.CertificateEncodingException JavaDoc;
28 import java.security.cert.CertificateFactory JavaDoc;
29 import java.security.spec.PKCS8EncodedKeySpec JavaDoc;
30 import java.util.Enumeration JavaDoc;
31 import java.util.Properties JavaDoc;
32 import javax.net.ServerSocketFactory;
33 import javax.net.ssl.SSLServerSocket;
34 import javax.net.ssl.SSLServerSocketFactory;
35 import javax.net.ssl.SSLSocket;
36 import javax.net.ssl.SSLSocketFactory;
37 import org.h2.message.Message;
38 import org.h2.util.ByteUtils;
39 import org.h2.util.FileUtils;
40 import org.h2.util.IOUtils;
41 //#endif
42

43 /**
44  *
45  * keytool -genkey -alias h2 -keyalg RSA -dname "cn=H2" -validity 25000 -keypass h2pass -keystore h2.keystore -storepass h2pass
46  *
47  *
48  *
49  * @author Thomas
50  */

51 public class SecureSocketFactory {
52
53     private static final String JavaDoc KEYSTORE = ".h2.keystore";
54     private static final String JavaDoc KEYSTORE_KEY = "javax.net.ssl.keyStore";
55     private static final String JavaDoc KEYSTORE_PASSWORD_KEY = "javax.net.ssl.keyStorePassword";
56     private static final String JavaDoc KEYSTORE_PASSWORD = "h2pass";
57     
58     // TODO security / SSL: need a way to disable anonymous ssl
59
private static final boolean ENABLE_ANONYMOUS_SSL = true;
60     private static SecureSocketFactory factory;
61     private static final String JavaDoc ANONYMOUS_CIPHER_SUITE = "SSL_DH_anon_WITH_RC4_128_MD5";
62
63     private static void setFactory(SecureSocketFactory f) {
64         factory = f;
65     }
66
67     public static SecureSocketFactory getInstance() {
68         if (factory == null) {
69             setFactory(new SecureSocketFactory());
70         }
71         return factory;
72     }
73     
74     public Socket JavaDoc createSocket(InetAddress JavaDoc address, int port) throws SQLException JavaDoc, IOException JavaDoc {
75         Socket JavaDoc socket = null;
76 //#ifdef JDK14
77
setKeystore();
78         SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
79         SSLSocket secureSocket = (SSLSocket) f.createSocket(address, port);
80         if (ENABLE_ANONYMOUS_SSL) {
81             String JavaDoc[] list = secureSocket.getEnabledCipherSuites();
82             list = addAnonymous(list);
83             secureSocket.setEnabledCipherSuites(list);
84         }
85         socket = secureSocket;
86 //#endif
87
return socket;
88     }
89
90     public ServerSocket JavaDoc createServerSocket(int port) throws IOException JavaDoc, SQLException JavaDoc {
91         ServerSocket JavaDoc socket = null;
92 //#ifdef JDK14
93
setKeystore();
94         ServerSocketFactory f = SSLServerSocketFactory.getDefault();
95         SSLServerSocket secureSocket = (SSLServerSocket) f.createServerSocket(port);
96         if (ENABLE_ANONYMOUS_SSL) {
97             String JavaDoc[] list = secureSocket.getEnabledCipherSuites();
98             list = addAnonymous(list);
99             secureSocket.setEnabledCipherSuites(list);
100         }
101         socket = secureSocket;
102 //#endif
103
return socket;
104     }
105
106 //#ifdef JDK14
107
private static byte[] getBytes(String JavaDoc hex) throws SQLException JavaDoc {
108         return ByteUtils.convertStringToBytes(hex);
109     }
110     
111     private byte[] getKeyStoreBytes(KeyStore JavaDoc store, String JavaDoc password) throws SQLException JavaDoc {
112         try {
113             ByteArrayOutputStream JavaDoc bout = new ByteArrayOutputStream JavaDoc();
114             store.store(bout, KEYSTORE_PASSWORD.toCharArray());
115             return bout.toByteArray();
116         } catch(Exception JavaDoc e) {
117             throw Message.convert(e);
118         }
119     }
120     
121     public static void main(String JavaDoc[] a) throws Exception JavaDoc {
122         // first, create a keystore using:
123
// keytool -genkey -alias h2 -keyalg RSA -dname "cn=H2" -validity 25000 -keypass h2pass -keystore h2.keystore -storepass h2pass
124
// then run this application to generate the source code
125
// then replace the code in the function getKeyStore as specified
126
KeyStore JavaDoc store = getKeyStore(KEYSTORE_PASSWORD);
127         printKeystore(store, KEYSTORE_PASSWORD);
128     }
129         
130     private static KeyStore JavaDoc getKeyStore(String JavaDoc password) throws SQLException JavaDoc {
131         try {
132             // The following source code can be re-generated when you have a keystore file.
133
// This code is (hopefully) more Java version independent than using keystores directly.
134
// See also: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4887561 (1.4.2 cannot read keystore written with 1.4.1)
135
// --- generated code start ---
136

137             // GCJ hack
138
//KeyStore store = KeyStore.getInstance("JKS");
139
KeyStore JavaDoc store = KeyStore.getInstance(KeyStore.getDefaultType());
140             
141             store.load(null, password.toCharArray());
142             KeyFactory JavaDoc keyFactory = KeyFactory.getInstance("RSA");
143             store.load(null, password.toCharArray());
144             PKCS8EncodedKeySpec JavaDoc keySpec = new PKCS8EncodedKeySpec JavaDoc(getBytes("30820277020100300d06092a864886f70d0101010500048202613082025d02010002818100dc0a13c602b7141110eade2f051b54777b060d0f74e6a110f9cce81159f271ebc88d8e8aa1f743b505fc2e7dfe38d33b8d3f64d1b363d1af4d877833897954cbaec2fa384c22a415498cf306bb07ac09b76b001cd68bf77ea0a628f5101959cf2993a9c23dbee79b19305977f8715ae78d023471194cc900b231eecb0aaea98d02030100010281810099aa4ff4d0a09a5af0bd953cb10c4d08c3d98df565664ac5582e494314d5c3c92dddedd5d316a32a206be4ec084616fe57be15e27cad111aa3c21fa79e32258c6ca8430afc69eddd52d3b751b37da6b6860910b94653192c0db1d02abcfd6ce14c01f238eec7c20bd3bb750940004bacba2880349a9494d10e139ecb2355d101024100ffdc3defd9c05a2d377ef6019fa62b3fbd5b0020a04cc8533bca730e1f6fcf5dfceea1b044fbe17d9eababfbc7d955edad6bc60f9be826ad2c22ba77d19a9f65024100dc28d43fdbbc93852cc3567093157702bc16f156f709fb7db0d9eec028f41fd0edcd17224c866e66be1744141fb724a10fd741c8a96afdd9141b36d67fff6309024077b1cddbde0f69604bdcfe33263fb36ddf24aa3b9922327915b890f8a36648295d0139ecdf68c245652c4489c6257b58744fbdd961834a4cab201801a3b1e52d024100b17142e8991d1b350a0802624759d48ae2b8071a158ff91fabeb6a8f7c328e762143dc726b8529f42b1fab6220d1c676fdc27ba5d44e847c72c52064afd351a902407c6e23fe35bcfcd1a662aa82a2aa725fcece311644d5b6e3894853fd4ce9fe78218c957b1ff03fc9e5ef8ffeb6bd58235f6a215c97d354fdace7e781e4a63e8b"));
145             PrivateKey JavaDoc privateKey = keyFactory.generatePrivate(keySpec);
146             Certificate JavaDoc[] certs = new Certificate JavaDoc[]{
147               CertificateFactory.getInstance("X.509").
148                     generateCertificate(new ByteArrayInputStream JavaDoc(getBytes("3082018b3081f502044295ce6b300d06092a864886f70d0101040500300d310b3009060355040313024832301e170d3035303532363133323630335a170d3337303933303036353734375a300d310b300906035504031302483230819f300d06092a864886f70d010101050003818d0030818902818100dc0a13c602b7141110eade2f051b54777b060d0f74e6a110f9cce81159f271ebc88d8e8aa1f743b505fc2e7dfe38d33b8d3f64d1b363d1af4d877833897954cbaec2fa384c22a415498cf306bb07ac09b76b001cd68bf77ea0a628f5101959cf2993a9c23dbee79b19305977f8715ae78d023471194cc900b231eecb0aaea98d0203010001300d06092a864886f70d01010405000381810083f4401a279453701bef9a7681a5b8b24f153f7d18c7c892133d97bd5f13736be7505290a445a7d5ceb75522403e5097515cd966ded6351ff60d5193de34cd36e5cb04d380398e66286f99923fd92296645fd4ada45844d194dfd815e6cd57f385c117be982809028bba1116c85740b3d27a55b1a0948bf291ddba44bed337b9"))),
149             };
150             store.setKeyEntry("h2", privateKey, password.toCharArray(), certs);
151             // --- generated code end ---
152
return store;
153         } catch(Exception JavaDoc e) {
154             throw Message.convert(e);
155         }
156     }
157             
158     private static void printKeystore(KeyStore JavaDoc store, String JavaDoc password) throws KeyStoreException JavaDoc, NoSuchAlgorithmException JavaDoc, UnrecoverableKeyException JavaDoc, CertificateEncodingException JavaDoc {
159         System.out.println("KeyStore store = KeyStore.getInstance(\""+store.getType()+"\");");
160         System.out.println("store.load(null, password.toCharArray());");
161         //System.out.println("keystore provider="+store.getProvider().getName());
162
Enumeration JavaDoc en = store.aliases();
163         while(en.hasMoreElements()) {
164             String JavaDoc alias = (String JavaDoc) en.nextElement();
165             Key JavaDoc key = store.getKey(alias, password.toCharArray());
166             System.out.println("KeyFactory keyFactory = KeyFactory.getInstance(\""+key.getAlgorithm()+"\");");
167             System.out.println("store.load(null, password.toCharArray());");
168             String JavaDoc pkFormat = key.getFormat();
169             String JavaDoc encoded = ByteUtils.convertBytesToString(key.getEncoded());
170             System.out.println(pkFormat+"EncodedKeySpec keySpec = new "+pkFormat+"EncodedKeySpec(getBytes(\"" +encoded+ "\"));");
171             System.out.println("PrivateKey privateKey = keyFactory.generatePrivate(keySpec);");
172             System.out.println("Certificate[] certs = new Certificate[]{");
173             Certificate JavaDoc[] certs = store.getCertificateChain(alias);
174             for(int i=0; i<certs.length; i++) {
175                 Certificate JavaDoc cert = certs[i];
176                 System.out.println(" CertificateFactory.getInstance(\""+cert.getType()+"\").");
177                 String JavaDoc enc = ByteUtils.convertBytesToString(cert.getEncoded());
178                 System.out.println(" generateCertificate(new ByteArrayInputStream(getBytes(\""+enc+"\"))),");
179                 // PublicKey pubKey = cert.getPublicKey();
180
// System.out.println(" publicKey algorithm="+pubKey.getAlgorithm());
181
// System.out.println(" publicKey format="+pubKey.getFormat());
182
// System.out.println(" publicKey format="+ByteUtils.convertBytesToString(pubKey.getEncoded()));
183
}
184             System.out.println("};");
185             System.out.println("store.setKeyEntry(\""+alias+"\", privateKey, password.toCharArray(), certs);");
186         }
187     }
188
189     private void setKeystore() throws IOException JavaDoc, SQLException JavaDoc {
190         Properties JavaDoc p = System.getProperties();
191         if (p.getProperty(KEYSTORE_KEY) == null) {
192             File JavaDoc file = FileUtils.getFileInUserHome(KEYSTORE);
193             byte[] data = getKeyStoreBytes(getKeyStore(KEYSTORE_PASSWORD), KEYSTORE_PASSWORD);
194             boolean needWrite = true;
195             if (file.exists() && file.length() == data.length) {
196                 // don't need to overwrite the file if it did not change
197
FileInputStream JavaDoc fin = new FileInputStream JavaDoc(file);
198                 byte[] now = IOUtils.readBytesAndClose(fin, 0);
199                 if (now != null && ByteUtils.compareNotNull(data, now) == 0) {
200                     needWrite = false;
201                 }
202             }
203             if (needWrite) {
204                 FileOutputStream JavaDoc out = new FileOutputStream JavaDoc(file);
205                 out.write(data);
206                 out.close();
207             }
208             System.setProperty(KEYSTORE_KEY, file.getAbsolutePath());
209         }
210         if (p.getProperty(KEYSTORE_PASSWORD_KEY) == null) {
211             System.setProperty(KEYSTORE_PASSWORD_KEY, KEYSTORE_PASSWORD);
212         }
213     }
214
215     private String JavaDoc[] addAnonymous(String JavaDoc[] list) {
216         String JavaDoc[] newList = new String JavaDoc[list.length + 1];
217         System.arraycopy(list, 0, newList, 1, list.length);
218         newList[0] = ANONYMOUS_CIPHER_SUITE;
219         return newList;
220     }
221
222     // private void listCipherSuites(SSLServerSocketFactory f) {
223
// String[] def = f.getDefaultCipherSuites();
224
// for(int i=0; i<def.length; i++) {
225
// System.out.println("default = " + def[i]);
226
// }
227
// String[] sup = f.getSupportedCipherSuites();
228
// for(int i=0; i<sup.length; i++) {
229
// System.out.println("supported = " + sup[i]);
230
// }
231
// }
232
//#endif
233

234 }
235
Popular Tags