001/* 002 * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Java13.java $ 003 * $Revision: 121 $ 004 * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $ 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 032package org.apache.commons.ssl; 033 034import com.sun.net.ssl.KeyManager; 035import com.sun.net.ssl.KeyManagerFactory; 036import com.sun.net.ssl.SSLContext; 037import com.sun.net.ssl.TrustManager; 038import com.sun.net.ssl.TrustManagerFactory; 039import com.sun.net.ssl.X509KeyManager; 040import com.sun.net.ssl.X509TrustManager; 041 042import javax.net.SocketFactory; 043import javax.net.ssl.SSLPeerUnverifiedException; 044import javax.net.ssl.SSLServerSocket; 045import javax.net.ssl.SSLServerSocketFactory; 046import javax.net.ssl.SSLSession; 047import javax.net.ssl.SSLSocket; 048import javax.net.ssl.SSLSocketFactory; 049import java.io.ByteArrayInputStream; 050import java.io.ByteArrayOutputStream; 051import java.io.IOException; 052import java.io.PrintStream; 053import java.lang.reflect.Method; 054import java.net.InetAddress; 055import java.net.Socket; 056import java.net.URL; 057import java.security.KeyManagementException; 058import java.security.KeyStore; 059import java.security.KeyStoreException; 060import java.security.NoSuchAlgorithmException; 061import java.security.Provider; 062import java.security.Security; 063import java.security.UnrecoverableKeyException; 064import java.security.cert.Certificate; 065import java.security.cert.CertificateException; 066import 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 */ 074public 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, 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 // overwrite password 154 for (int i = 0; i < password.length; i++) { 155 password[i] = '*'; 156 } 157 return kmf; 158 } 159 160 protected final Object buildTrustManagerFactory(KeyStore ks) 161 throws NoSuchAlgorithmException, KeyStoreException { 162 String alg = TrustManagerFactory.getDefaultAlgorithm(); 163 TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg); 164 tmf.init(ks); 165 return tmf; 166 } 167 168 169 protected final Object[] retrieveKeyManagers(Object keyManagerFactory) { 170 KeyManagerFactory kmf = (KeyManagerFactory) keyManagerFactory; 171 return kmf.getKeyManagers(); 172 } 173 174 protected final Object[] retrieveTrustManagers(Object trustManagerFactory) { 175 TrustManagerFactory tmf = (TrustManagerFactory) trustManagerFactory; 176 return tmf.getTrustManagers(); 177 } 178 179 protected final SSLSocketFactory buildSSLSocketFactory(Object ssl) { 180 return ((SSLContext) ssl).getSocketFactory(); 181 } 182 183 protected final SSLServerSocketFactory buildSSLServerSocketFactory(Object ssl) { 184 return ((SSLContext) ssl).getServerSocketFactory(); 185 } 186 187 protected final RuntimeException buildRuntimeException(Exception cause) { 188 ByteArrayOutputStream byteOut = new ByteArrayOutputStream(512); 189 PrintStream ps = new PrintStream(byteOut); 190 ps.println(cause.toString()); 191 cause.printStackTrace(ps); 192 ps.flush(); 193 String originalCause = byteOut.toString(); 194 return new RuntimeException(originalCause); 195 } 196 197 protected final SSLSocket buildSocket(SSL ssl) { 198 // Not supported in Java 1.3. 199 throw new UnsupportedOperationException(); 200 } 201 202 protected final SSLSocket buildSocket(SSL ssl, String remoteHost, 203 int remotePort, InetAddress localHost, 204 int localPort, int connectTimeout) 205 throws IOException { 206 // Connect Timeout ignored for Java 1.3 207 SSLSocketFactory sf = ssl.getSSLSocketFactory(); 208 SSLSocket s = (SSLSocket) connectSocket(null, sf, remoteHost, 209 remotePort, localHost, 210 localPort, -1); 211 ssl.doPreConnectSocketStuff(s); 212 ssl.doPostConnectSocketStuff(s, remoteHost); 213 return s; 214 } 215 216 protected final Socket connectSocket(Socket s, SocketFactory sf, 217 String remoteHost, int remotePort, 218 InetAddress localHost, int localPort, 219 int timeout) 220 throws IOException { 221 // Connect Timeout ignored for Java 1.3 222 if (s == null) { 223 if (sf == null) { 224 s = new Socket(remoteHost, remotePort, localHost, localPort); 225 } else { 226 s = sf.createSocket(remoteHost, remotePort, localHost, localPort); 227 } 228 } 229 return s; 230 } 231 232 233 protected final SSLServerSocket buildServerSocket(SSL ssl) { 234 // Not supported in Java 1.3. 235 throw new UnsupportedOperationException(); 236 } 237 238 protected final void wantClientAuth(Object o, boolean wantClientAuth) { 239 // Not supported in Java 1.3. 240 } 241 242 protected final void enabledProtocols(Object o, String[] enabledProtocols) { 243 // Not supported in Java 1.3. 244 } 245 246 protected void checkTrusted(Object trustManager, X509Certificate[] chain, 247 String authType) 248 throws CertificateException { 249 X509TrustManager tm = (X509TrustManager) trustManager; 250 boolean result = tm.isServerTrusted(chain); 251 if (!result) { 252 throw new CertificateException("commons-ssl java13 mode: certificate chain not trusted"); 253 } 254 } 255 256 257 protected final Object initSSL(SSL ssl, TrustChain tc, KeyMaterial k) 258 throws NoSuchAlgorithmException, KeyStoreException, 259 CertificateException, KeyManagementException, IOException { 260 SSLContext context = SSLContext.getInstance(ssl.getDefaultProtocol()); 261 TrustManager[] trustManagers = null; 262 KeyManager[] keyManagers = null; 263 if (tc != null) { 264 trustManagers = (TrustManager[]) tc.getTrustManagers(); 265 } 266 if (k != null) { 267 keyManagers = (KeyManager[]) k.getKeyManagers(); 268 } 269 if (keyManagers != null) { 270 for (int i = 0; i < keyManagers.length; i++) { 271 if (keyManagers[i] instanceof X509KeyManager) { 272 X509KeyManager km = (X509KeyManager) keyManagers[i]; 273 keyManagers[i] = new Java13KeyManagerWrapper(km, k, ssl); 274 } 275 } 276 } 277 if (trustManagers != null) { 278 for (int i = 0; i < trustManagers.length; i++) { 279 if (trustManagers[i] instanceof X509TrustManager) { 280 X509TrustManager tm = (X509TrustManager) trustManagers[i]; 281 trustManagers[i] = new Java13TrustManagerWrapper(tm, tc, ssl); 282 } 283 } 284 } 285 context.init(keyManagers, trustManagers, null); 286 return context; 287 } 288 289 290}