001 /*
002 * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.11/src/java/org/apache/commons/ssl/Java13.java $
003 * $Revision: 155 $
004 * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $
005 *
006 * ====================================================================
007 * Licensed to the Apache Software Foundation (ASF) under one
008 * or more contributor license agreements. See the NOTICE file
009 * distributed with this work for additional information
010 * regarding copyright ownership. The ASF licenses this file
011 * to you under the Apache License, Version 2.0 (the
012 * "License"); you may not use this file except in compliance
013 * with the License. You may obtain a copy of the License at
014 *
015 * http://www.apache.org/licenses/LICENSE-2.0
016 *
017 * Unless required by applicable law or agreed to in writing,
018 * software distributed under the License is distributed on an
019 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
020 * KIND, either express or implied. See the License for the
021 * specific language governing permissions and limitations
022 * under the License.
023 * ====================================================================
024 *
025 * This software consists of voluntary contributions made by many
026 * individuals on behalf of the Apache Software Foundation. For more
027 * information on the Apache Software Foundation, please see
028 * <http://www.apache.org/>.
029 *
030 */
031
032 package org.apache.commons.ssl;
033
034 import com.sun.net.ssl.KeyManager;
035 import com.sun.net.ssl.KeyManagerFactory;
036 import com.sun.net.ssl.SSLContext;
037 import com.sun.net.ssl.TrustManager;
038 import com.sun.net.ssl.TrustManagerFactory;
039 import com.sun.net.ssl.X509KeyManager;
040 import com.sun.net.ssl.X509TrustManager;
041
042 import javax.net.SocketFactory;
043 import javax.net.ssl.SSLPeerUnverifiedException;
044 import javax.net.ssl.SSLServerSocket;
045 import javax.net.ssl.SSLServerSocketFactory;
046 import javax.net.ssl.SSLSession;
047 import javax.net.ssl.SSLSocket;
048 import javax.net.ssl.SSLSocketFactory;
049 import java.io.ByteArrayInputStream;
050 import java.io.ByteArrayOutputStream;
051 import java.io.IOException;
052 import java.io.PrintStream;
053 import java.lang.reflect.Method;
054 import java.net.InetAddress;
055 import java.net.Socket;
056 import java.net.URL;
057 import java.security.KeyManagementException;
058 import java.security.KeyStore;
059 import java.security.KeyStoreException;
060 import java.security.NoSuchAlgorithmException;
061 import java.security.Provider;
062 import java.security.Security;
063 import java.security.UnrecoverableKeyException;
064 import java.security.cert.Certificate;
065 import java.security.cert.CertificateException;
066 import java.security.cert.X509Certificate;
067
068 /**
069 * @author Credit Union Central of British Columbia
070 * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
071 * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
072 * @since 30-Jun-2006
073 */
074 public final class Java13 extends JavaImpl {
075 private final static Java13 instance = new Java13();
076
077 private Java13() {
078 try {
079 Class c = Class.forName("javax.crypto.Cipher");
080 Class[] sig = {String.class};
081 String[] args = {"DES/CBC/PKCS5Padding"};
082 Method m = c.getMethod("getInstance", sig);
083 m.invoke(null, (Object[]) args);
084 }
085 catch (Exception e) {
086 try {
087 Class c = Class.forName("com.sun.crypto.provider.SunJCE");
088 Security.addProvider((Provider) c.newInstance());
089 // System.out.println( "jce not loaded: " + e + " - loading SunJCE!" );
090 //e.printStackTrace( System.out );
091 }
092 catch (Exception e2) {
093 System.out.println("com.sun.crypto.provider.SunJCE unavailable: " + e2);
094 // e2.printStackTrace( System.out );
095 }
096 }
097 try {
098 URL u = new URL("https://vancity.com/");
099 u.openConnection();
100 }
101 catch (Exception e) {
102 // System.out.println( "java.net.URL support of https not loaded: " + e + " - attempting to load com.sun.net.ssl.internal.ssl.Provider!" );
103 Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
104 System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
105 }
106 // System.out.println( "old HANDLER: " + HANDLER );
107 }
108
109 public static Java13 getInstance() {
110 return instance;
111 }
112
113 public final String getVersion() {
114 return "Java13";
115 }
116
117 protected final String retrieveSubjectX500(X509Certificate cert) {
118 return cert.getSubjectDN().toString();
119 }
120
121 protected final String retrieveIssuerX500(X509Certificate cert) {
122 return cert.getIssuerDN().toString();
123 }
124
125 protected final Certificate[] retrievePeerCerts(SSLSession sslSession)
126 throws SSLPeerUnverifiedException {
127 javax.security.cert.X509Certificate[] chain;
128 chain = sslSession.getPeerCertificateChain();
129 X509Certificate[] newChain = new X509Certificate[chain.length];
130 try {
131 for (int i = 0; i < chain.length; i++) {
132 javax.security.cert.X509Certificate javaxCert = chain[i];
133 byte[] encoded = javaxCert.getEncoded();
134 ByteArrayInputStream in = new ByteArrayInputStream(encoded);
135 synchronized (Certificates.CF) {
136 Certificate c = Certificates.CF.generateCertificate(in);
137 newChain[i] = (X509Certificate) c;
138 }
139 }
140 }
141 catch (Exception e) {
142 throw buildRuntimeException(e);
143 }
144 return newChain;
145 }
146
147 protected final Object buildKeyManagerFactory(KeyStore ks, char[] password)
148 throws NoSuchAlgorithmException, KeyStoreException,
149 UnrecoverableKeyException {
150 String alg = KeyManagerFactory.getDefaultAlgorithm();
151 KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg);
152 kmf.init(ks, password);
153 return kmf;
154 }
155
156 protected final Object buildTrustManagerFactory(KeyStore ks)
157 throws NoSuchAlgorithmException, KeyStoreException {
158 String alg = TrustManagerFactory.getDefaultAlgorithm();
159 TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg);
160 tmf.init(ks);
161 return tmf;
162 }
163
164
165 protected final Object[] retrieveKeyManagers(Object keyManagerFactory) {
166 KeyManagerFactory kmf = (KeyManagerFactory) keyManagerFactory;
167 return kmf.getKeyManagers();
168 }
169
170 protected final Object[] retrieveTrustManagers(Object trustManagerFactory) {
171 TrustManagerFactory tmf = (TrustManagerFactory) trustManagerFactory;
172 return tmf.getTrustManagers();
173 }
174
175 protected final SSLSocketFactory buildSSLSocketFactory(Object ssl) {
176 return ((SSLContext) ssl).getSocketFactory();
177 }
178
179 protected final SSLServerSocketFactory buildSSLServerSocketFactory(Object ssl) {
180 return ((SSLContext) ssl).getServerSocketFactory();
181 }
182
183 protected final RuntimeException buildRuntimeException(Exception cause) {
184 ByteArrayOutputStream byteOut = new ByteArrayOutputStream(512);
185 PrintStream ps = new PrintStream(byteOut);
186 ps.println(cause.toString());
187 cause.printStackTrace(ps);
188 ps.flush();
189 String originalCause = byteOut.toString();
190 return new RuntimeException(originalCause);
191 }
192
193 protected final SSLSocket buildSocket(SSL ssl) {
194 // Not supported in Java 1.3.
195 throw new UnsupportedOperationException();
196 }
197
198 protected final SSLSocket buildSocket(SSL ssl, String remoteHost,
199 int remotePort, InetAddress localHost,
200 int localPort, int connectTimeout)
201 throws IOException {
202 // Connect Timeout ignored for Java 1.3
203 SSLSocketFactory sf = ssl.getSSLSocketFactory();
204 SSLSocket s = (SSLSocket) connectSocket(
205 null, sf, remoteHost, remotePort, localHost, localPort, -1, ssl
206 );
207 ssl.doPreConnectSocketStuff(s);
208 ssl.doPostConnectSocketStuff(s, remoteHost);
209 return s;
210 }
211
212 protected final Socket buildPlainSocket(
213 SSL ssl, String remoteHost, int remotePort, InetAddress localHost, int localPort, int connectTimeout
214 )
215 throws IOException {
216 // Connect Timeout ignored for Java 1.3
217 SocketFactory sf = SocketFactory.getDefault();
218 Socket s = connectSocket(
219 null, sf, remoteHost, remotePort, localHost, localPort, -1, ssl
220 );
221 ssl.doPreConnectSocketStuff(s);
222 ssl.doPostConnectSocketStuff(s, remoteHost);
223 return s;
224 }
225
226 protected final Socket connectSocket(Socket s, SocketFactory sf,
227 String remoteHost, int remotePort,
228 InetAddress localHost, int localPort,
229 int timeout, SSL ssl)
230 throws IOException {
231
232 remoteHost = ssl.dnsOverride(remoteHost);
233
234 // Connect Timeout ignored for Java 1.3
235 if (s == null) {
236 if (sf == null) {
237 s = new Socket(remoteHost, remotePort, localHost, localPort);
238 } else {
239 s = sf.createSocket(remoteHost, remotePort, localHost, localPort);
240 }
241 }
242 return s;
243 }
244
245
246 protected final SSLServerSocket buildServerSocket(SSL ssl) {
247 // Not supported in Java 1.3.
248 throw new UnsupportedOperationException();
249 }
250
251 protected final void wantClientAuth(Object o, boolean wantClientAuth) {
252 // Not supported in Java 1.3.
253 }
254
255 protected final void enabledProtocols(Object o, String[] enabledProtocols) {
256 // Not supported in Java 1.3.
257 }
258
259 protected void checkTrusted(Object trustManager, X509Certificate[] chain,
260 String authType)
261 throws CertificateException {
262 X509TrustManager tm = (X509TrustManager) trustManager;
263 boolean result = tm.isServerTrusted(chain);
264 if (!result) {
265 throw new CertificateException("commons-ssl java13 mode: certificate chain not trusted");
266 }
267 }
268
269
270 protected final Object initSSL(SSL ssl, TrustChain tc, KeyMaterial k)
271 throws NoSuchAlgorithmException, KeyStoreException,
272 CertificateException, KeyManagementException, IOException {
273 SSLContext context = SSLContext.getInstance(ssl.getDefaultProtocol());
274 TrustManager[] trustManagers = null;
275 KeyManager[] keyManagers = null;
276 if (tc != null) {
277 trustManagers = (TrustManager[]) tc.getTrustManagers();
278 }
279 if (k != null) {
280 keyManagers = (KeyManager[]) k.getKeyManagers();
281 }
282 if (keyManagers != null) {
283 for (int i = 0; i < keyManagers.length; i++) {
284 if (keyManagers[i] instanceof X509KeyManager) {
285 X509KeyManager km = (X509KeyManager) keyManagers[i];
286 keyManagers[i] = new Java13KeyManagerWrapper(km, k, ssl);
287 }
288 }
289 }
290 if (trustManagers != null) {
291 for (int i = 0; i < trustManagers.length; i++) {
292 if (trustManagers[i] instanceof X509TrustManager) {
293 X509TrustManager tm = (X509TrustManager) trustManagers[i];
294 trustManagers[i] = new Java13TrustManagerWrapper(tm, tc, ssl);
295 }
296 }
297 }
298 context.init(keyManagers, trustManagers, null);
299 return context;
300 }
301
302
303 }