001/* 002 * $HeadURL: file:///opt/dev/not-yet-commons-ssl-SVN-repo/tags/commons-ssl-0.3.17/src/java/org/apache/commons/ssl/Java14.java $ 003 * $Revision: 187 $ 004 * $Date: 2015-03-16 14:27:25 -0700 (Mon, 16 Mar 2015) $ 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 java.io.IOException; 035import java.lang.reflect.InvocationTargetException; 036import java.lang.reflect.Method; 037import java.net.InetAddress; 038import java.net.InetSocketAddress; 039import java.net.ServerSocket; 040import java.net.Socket; 041import java.security.KeyManagementException; 042import java.security.KeyStore; 043import java.security.KeyStoreException; 044import java.security.NoSuchAlgorithmException; 045import java.security.UnrecoverableKeyException; 046import java.security.cert.Certificate; 047import java.security.cert.CertificateException; 048import java.security.cert.X509Certificate; 049 050import javax.net.SocketFactory; 051import javax.net.ssl.KeyManager; 052import javax.net.ssl.KeyManagerFactory; 053import javax.net.ssl.SSLContext; 054import javax.net.ssl.SSLPeerUnverifiedException; 055import javax.net.ssl.SSLServerSocket; 056import javax.net.ssl.SSLServerSocketFactory; 057import javax.net.ssl.SSLSession; 058import javax.net.ssl.SSLSocket; 059import javax.net.ssl.SSLSocketFactory; 060import javax.net.ssl.TrustManager; 061import javax.net.ssl.TrustManagerFactory; 062import javax.net.ssl.X509KeyManager; 063import javax.net.ssl.X509TrustManager; 064 065 066/** 067 * @author Credit Union Central of British Columbia 068 * @author <a href="http://www.cucbc.com/">www.cucbc.com</a> 069 * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a> 070 * @since 30-Jun-2006 071 */ 072public final class Java14 extends JavaImpl { 073 private static Java14 instance = new Java14(); 074 075 private Java14() { 076 try { 077 SSLSocketFactory.getDefault().createSocket(); 078 } 079 catch (IOException ioe) { 080 ioe.hashCode(); 081 } 082 } 083 084 public static Java14 getInstance() { 085 return instance; 086 } 087 088 public final String getVersion() { 089 return "Java14"; 090 } 091 092 protected final String retrieveSubjectX500(X509Certificate cert) { 093 return cert.getSubjectX500Principal().toString(); 094 } 095 096 protected final String retrieveIssuerX500(X509Certificate cert) { 097 return cert.getIssuerX500Principal().toString(); 098 } 099 100 protected final Certificate[] retrievePeerCerts(SSLSession sslSession) 101 throws SSLPeerUnverifiedException { 102 return sslSession.getPeerCertificates(); 103 } 104 105 protected final Object buildKeyManagerFactory(KeyStore ks, char[] password) 106 throws NoSuchAlgorithmException, KeyStoreException, 107 UnrecoverableKeyException { 108 String alg = KeyManagerFactory.getDefaultAlgorithm(); 109 KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg); 110 kmf.init(ks, password); 111 return kmf; 112 } 113 114 protected final Object buildTrustManagerFactory(KeyStore ks) 115 throws NoSuchAlgorithmException, KeyStoreException { 116 String alg = TrustManagerFactory.getDefaultAlgorithm(); 117 TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg); 118 tmf.init(ks); 119 return tmf; 120 } 121 122 protected final Object[] retrieveKeyManagers(Object keyManagerFactory) { 123 KeyManagerFactory kmf = (KeyManagerFactory) keyManagerFactory; 124 return kmf.getKeyManagers(); 125 } 126 127 protected final Object[] retrieveTrustManagers(Object trustManagerFactory) { 128 TrustManagerFactory tmf = (TrustManagerFactory) trustManagerFactory; 129 return tmf.getTrustManagers(); 130 } 131 132 protected final SSLSocketFactory buildSSLSocketFactory(Object ssl) { 133 return ((SSLContext) ssl).getSocketFactory(); 134 } 135 136 protected final SSLServerSocketFactory buildSSLServerSocketFactory(Object ssl) { 137 return ((SSLContext) ssl).getServerSocketFactory(); 138 } 139 140 protected final RuntimeException buildRuntimeException(Exception cause) { 141 return new RuntimeException(cause); 142 } 143 144 protected final SSLSocket buildSocket(SSL ssl) throws IOException { 145 SSLSocketFactory sf = ssl.getSSLSocketFactory(); 146 SSLSocket s = (SSLSocket) sf.createSocket(); 147 ssl.doPreConnectSocketStuff(s); 148 return s; 149 } 150 151 protected final SSLSocket buildSocket(SSL ssl, String remoteHost, 152 int remotePort, InetAddress localHost, 153 int localPort, int timeout) 154 throws IOException { 155 SSLSocket s = buildSocket(ssl); 156 s = (SSLSocket) connectSocket(s, null, remoteHost, remotePort, 157 localHost, localPort, timeout, ssl); 158 ssl.doPostConnectSocketStuff(s, remoteHost); 159 return s; 160 } 161 162 163 protected final Socket buildPlainSocket( 164 SSL ssl, String remoteHost, int remotePort, InetAddress localHost, int localPort, int timeout 165 ) throws IOException { 166 Socket s = SocketFactory.getDefault().createSocket(); 167 ssl.doPreConnectSocketStuff(s); 168 s = connectSocket( 169 s, null, remoteHost, remotePort, localHost, localPort, timeout, ssl 170 ); 171 ssl.doPostConnectSocketStuff(s, remoteHost); 172 return s; 173 } 174 175 protected final Socket connectSocket(Socket s, SocketFactory sf, 176 String host, int remotePort, 177 InetAddress localHost, int localPort, 178 int timeout, SSL ssl) 179 throws IOException { 180 if (s == null) { 181 if (sf == null) { 182 s = new Socket(); 183 } else { 184 s = sf.createSocket(); 185 } 186 } 187 host = ssl.dnsOverride(host); 188 InetAddress remoteHost = Util.toInetAddress(host); 189 InetSocketAddress dest = new InetSocketAddress(remoteHost, remotePort); 190 InetSocketAddress src = new InetSocketAddress(localHost, localPort); 191 if (s instanceof SSLSocket) { 192 setHostForSNI((SSLSocket) s, host); 193 } 194 s.bind(src); 195 s.connect(dest, timeout); 196 return s; 197 } 198 199 private static boolean returnsVoidTakesOneString(Method m) { 200 Class<?>[] params = m.getParameterTypes(); 201 return Void.TYPE.equals(m.getReturnType()) 202 && params != null && params.length == 1 && String.class.equals(params[0]); 203 } 204 205 public static void setHostForSNI(SSLSocket s, String host) throws IOException { 206 // Tries to call a "setHost()" method on the supplied SSLSocket via reflection if one exists. 207 Method[] methods = s.getClass().getMethods(); 208 for (int i = 0; i < methods.length; i++) { 209 Method m = methods[i]; 210 if (returnsVoidTakesOneString(m) && "setHost".equals(m.getName())) { 211 try { 212 213 m.invoke(s, host); 214 return; 215 216 } catch (IllegalAccessException iae) { 217 218 // oh well, nevermind 219 220 } catch (InvocationTargetException ite) { 221 Throwable t = ite.getCause(); 222 if (t instanceof IOException) { 223 throw (IOException) t; 224 } else if (t instanceof RuntimeException) { 225 throw (RuntimeException) t; 226 } else if (t instanceof Error) { 227 throw (Error) t; 228 } else { 229 throw new IOException("setHost() via reflection failed: " + t); 230 } 231 } 232 } 233 } 234 } 235 236 protected final SSLServerSocket buildServerSocket(SSL ssl) 237 throws IOException { 238 ServerSocket s = ssl.getSSLServerSocketFactory().createServerSocket(); 239 SSLServerSocket ss = (SSLServerSocket) s; 240 ssl.doPreConnectServerSocketStuff(ss); 241 return ss; 242 } 243 244 protected final void wantClientAuth(Object o, boolean wantClientAuth) { 245 SSLSocket s; 246 SSLServerSocket ss; 247 if (o instanceof SSLSocket) { 248 s = (SSLSocket) o; 249 s.setWantClientAuth(wantClientAuth); 250 } else if (o instanceof SSLServerSocket) { 251 ss = (SSLServerSocket) o; 252 ss.setWantClientAuth(wantClientAuth); 253 } else { 254 throw new ClassCastException("need SSLSocket or SSLServerSocket"); 255 } 256 } 257 258 protected final void enabledProtocols(Object o, String[] enabledProtocols) { 259 SSLSocket s; 260 SSLServerSocket ss; 261 if (o instanceof SSLSocket) { 262 s = (SSLSocket) o; 263 s.setEnabledProtocols(enabledProtocols); 264 } else if (o instanceof SSLServerSocket) { 265 ss = (SSLServerSocket) o; 266 ss.setEnabledProtocols(enabledProtocols); 267 } else { 268 throw new ClassCastException("need SSLSocket or SSLServerSocket"); 269 } 270 } 271 272 protected void checkTrusted(Object trustManager, X509Certificate[] chain, 273 String authType) 274 throws CertificateException { 275 X509TrustManager tm = (X509TrustManager) trustManager; 276 tm.checkServerTrusted(chain, authType); 277 } 278 279 protected final Object initSSL(SSL ssl, TrustChain tc, KeyMaterial k) 280 throws NoSuchAlgorithmException, KeyStoreException, 281 CertificateException, KeyManagementException, IOException { 282 SSLContext context = SSLContext.getInstance(ssl.getDefaultProtocol()); 283 TrustManager[] trustManagers = null; 284 KeyManager[] keyManagers = null; 285 if (tc != null) { 286 trustManagers = (TrustManager[]) tc.getTrustManagers(); 287 } 288 if (k != null) { 289 keyManagers = (KeyManager[]) k.getKeyManagers(); 290 } 291 if (keyManagers != null) { 292 for (int i = 0; i < keyManagers.length; i++) { 293 if (keyManagers[i] instanceof X509KeyManager) { 294 X509KeyManager km = (X509KeyManager) keyManagers[i]; 295 keyManagers[i] = new Java14KeyManagerWrapper(km, k, ssl); 296 } 297 } 298 } 299 if (trustManagers != null) { 300 for (int i = 0; i < trustManagers.length; i++) { 301 if (trustManagers[i] instanceof X509TrustManager) { 302 X509TrustManager tm = (X509TrustManager) trustManagers[i]; 303 trustManagers[i] = new Java14TrustManagerWrapper(tm, tc, ssl); 304 } 305 } 306 } 307 context.init(keyManagers, trustManagers, null); 308 return context; 309 } 310 311 312}