1 17 18 package org.apache.tomcat.util.net.jsse; 19 20 import java.io.ByteArrayInputStream ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.net.SocketException ; 24 import java.security.cert.Certificate ; 25 import java.security.cert.CertificateFactory ; 26 27 import javax.net.ssl.HandshakeCompletedEvent; 28 import javax.net.ssl.HandshakeCompletedListener; 29 import javax.net.ssl.SSLException; 30 import javax.net.ssl.SSLSession; 31 import javax.net.ssl.SSLSocket; 32 import javax.security.cert.X509Certificate; 33 34 import org.apache.tomcat.util.net.SSLSupport; 35 36 50 51 class JSSESupport implements SSLSupport { 52 53 private static org.apache.commons.logging.Log log = 54 org.apache.commons.logging.LogFactory.getLog(JSSESupport.class); 55 56 protected SSLSocket ssl; 57 protected SSLSession session; 58 59 Listener listener = new Listener(); 60 61 JSSESupport(SSLSocket sock){ 62 ssl=sock; 63 session = sock.getSession(); 64 sock.addHandshakeCompletedListener(listener); 65 } 66 67 JSSESupport(SSLSession session) { 68 this.session = session; 69 } 70 71 public String getCipherSuite() throws IOException { 72 if (session == null) 74 return null; 75 return session.getCipherSuite(); 76 } 77 78 public Object [] getPeerCertificateChain() 79 throws IOException { 80 return getPeerCertificateChain(false); 81 } 82 83 protected java.security.cert.X509Certificate [] getX509Certificates(SSLSession session) 84 throws IOException { 85 Certificate [] certs=null; 86 try { 87 certs = session.getPeerCertificates(); 88 } catch( Throwable t ) { 89 log.debug("Error getting client certs",t); 90 return null; 91 } 92 if( certs==null ) return null; 93 94 java.security.cert.X509Certificate [] x509Certs = 95 new java.security.cert.X509Certificate [certs.length]; 96 for(int i=0; i < certs.length; i++) { 97 if (certs[i] instanceof java.security.cert.X509Certificate ) { 98 x509Certs[i] = (java.security.cert.X509Certificate ) certs[i]; 100 } else { 101 try { 102 byte [] buffer = certs[i].getEncoded(); 103 CertificateFactory cf = 104 CertificateFactory.getInstance("X.509"); 105 ByteArrayInputStream stream = 106 new ByteArrayInputStream (buffer); 107 x509Certs[i] = (java.security.cert.X509Certificate ) cf.generateCertificate(stream); 108 } catch(Exception ex) { 109 log.info("Error translating cert " + certs[i], ex); 110 return null; 111 } 112 } 113 if(log.isTraceEnabled()) 114 log.trace("Cert #" + i + " = " + x509Certs[i]); 115 } 116 if(x509Certs.length < 1) 117 return null; 118 return x509Certs; 119 } 120 121 public Object [] getPeerCertificateChain(boolean force) 122 throws IOException { 123 if (session == null) 125 return null; 126 127 X509Certificate [] jsseCerts = null; 129 try { 130 jsseCerts = session.getPeerCertificateChain(); 131 } catch(Exception bex) { 132 } 134 if (jsseCerts == null) 135 jsseCerts = new X509Certificate[0]; 136 if(jsseCerts.length <= 0 && force) { 137 session.invalidate(); 138 handShake(); 139 session = ssl.getSession(); 140 } 141 return getX509Certificates(session); 142 } 143 144 protected void handShake() throws IOException { 145 if( ssl.getWantClientAuth() ) { 146 log.debug("No client cert sent for want"); 147 } else { 148 ssl.setNeedClientAuth(true); 149 } 150 151 InputStream in = ssl.getInputStream(); 152 int oldTimeout = ssl.getSoTimeout(); 153 ssl.setSoTimeout(1000); 154 byte[] b = new byte[0]; 155 listener.reset(); 156 ssl.startHandshake(); 157 int maxTries = 60; for (int i = 0; i < maxTries; i++) { 159 if(log.isTraceEnabled()) 160 log.trace("Reading for try #" +i); 161 try { 162 int x = in.read(b); 163 } catch(SSLException sslex) { 164 log.info("SSL Error getting client Certs",sslex); 165 throw sslex; 166 } catch (IOException e) { 167 } 169 if (listener.completed) { 170 break; 171 } 172 } 173 ssl.setSoTimeout(oldTimeout); 174 if (listener.completed == false) { 175 throw new SocketException ("SSL Cert handshake timeout"); 176 } 177 178 } 179 180 183 public Integer getKeySize() 184 throws IOException { 185 SSLSupport.CipherData c_aux[]=ciphers; 187 if (session == null) 188 return null; 189 Integer keySize = (Integer ) session.getValue(KEY_SIZE_KEY); 190 if (keySize == null) { 191 int size = 0; 192 String cipherSuite = session.getCipherSuite(); 193 for (int i = 0; i < c_aux.length; i++) { 194 if (cipherSuite.indexOf(c_aux[i].phrase) >= 0) { 195 size = c_aux[i].keySize; 196 break; 197 } 198 } 199 keySize = new Integer (size); 200 session.putValue(KEY_SIZE_KEY, keySize); 201 } 202 return keySize; 203 } 204 205 public String getSessionId() 206 throws IOException { 207 if (session == null) 209 return null; 210 byte [] ssl_session = session.getId(); 212 if ( ssl_session == null) 213 return null; 214 StringBuffer buf=new StringBuffer (""); 215 for(int x=0; x<ssl_session.length; x++) { 216 String digit=Integer.toHexString((int)ssl_session[x]); 217 if (digit.length()<2) buf.append('0'); 218 if (digit.length()>2) digit=digit.substring(digit.length()-2); 219 buf.append(digit); 220 } 221 return buf.toString(); 222 } 223 224 225 private static class Listener implements HandshakeCompletedListener { 226 volatile boolean completed = false; 227 public void handshakeCompleted(HandshakeCompletedEvent event) { 228 completed = true; 229 } 230 void reset() { 231 completed = false; 232 } 233 } 234 235 } 236 237 | Popular Tags |