KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tomcat > util > net > jsse > JSSESupport


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.tomcat.util.net.jsse;
19
20 import java.io.ByteArrayInputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.net.SocketException JavaDoc;
24 import java.security.cert.Certificate JavaDoc;
25 import java.security.cert.CertificateFactory JavaDoc;
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 /** JSSESupport
37
38    Concrete implementation class for JSSE
39    Support classes.
40
41    This will only work with JDK 1.2 and up since it
42    depends on JDK 1.2's certificate support
43
44    @author EKR
45    @author Craig R. McClanahan
46    @author Filip Hanik
47    Parts cribbed from JSSECertCompat
48    Parts cribbed from CertificatesValve
49 */

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 JavaDoc getCipherSuite() throws IOException JavaDoc {
72         // Look up the current SSLSession
73
if (session == null)
74             return null;
75         return session.getCipherSuite();
76     }
77
78     public Object JavaDoc[] getPeerCertificateChain()
79         throws IOException JavaDoc {
80         return getPeerCertificateChain(false);
81     }
82
83     protected java.security.cert.X509Certificate JavaDoc [] getX509Certificates(SSLSession session)
84         throws IOException JavaDoc {
85         Certificate JavaDoc [] certs=null;
86         try {
87             certs = session.getPeerCertificates();
88         } catch( Throwable JavaDoc 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 JavaDoc [] x509Certs =
95             new java.security.cert.X509Certificate JavaDoc[certs.length];
96         for(int i=0; i < certs.length; i++) {
97             if (certs[i] instanceof java.security.cert.X509Certificate JavaDoc ) {
98                 // always currently true with the JSSE 1.1.x
99
x509Certs[i] = (java.security.cert.X509Certificate JavaDoc) certs[i];
100             } else {
101                 try {
102                     byte [] buffer = certs[i].getEncoded();
103                     CertificateFactory JavaDoc cf =
104                         CertificateFactory.getInstance("X.509");
105                     ByteArrayInputStream JavaDoc stream =
106                         new ByteArrayInputStream JavaDoc(buffer);
107                     x509Certs[i] = (java.security.cert.X509Certificate JavaDoc) cf.generateCertificate(stream);
108                 } catch(Exception JavaDoc 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 JavaDoc[] getPeerCertificateChain(boolean force)
122         throws IOException JavaDoc {
123         // Look up the current SSLSession
124
if (session == null)
125             return null;
126
127         // Convert JSSE's certificate format to the ones we need
128
X509Certificate [] jsseCerts = null;
129     try {
130         jsseCerts = session.getPeerCertificateChain();
131     } catch(Exception JavaDoc bex) {
132         // ignore.
133
}
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 JavaDoc {
145         if( ssl.getWantClientAuth() ) {
146             log.debug("No client cert sent for want");
147         } else {
148             ssl.setNeedClientAuth(true);
149         }
150
151         InputStream JavaDoc 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; // 60 * 1000 = example 1 minute time out
158
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 JavaDoc e) {
167                 // ignore - presumably the timeout
168
}
169             if (listener.completed) {
170                 break;
171             }
172         }
173         ssl.setSoTimeout(oldTimeout);
174         if (listener.completed == false) {
175             throw new SocketException JavaDoc("SSL Cert handshake timeout");
176         }
177
178     }
179
180     /**
181      * Copied from <code>org.apache.catalina.valves.CertificateValve</code>
182      */

183     public Integer JavaDoc getKeySize()
184         throws IOException JavaDoc {
185         // Look up the current SSLSession
186
SSLSupport.CipherData c_aux[]=ciphers;
187         if (session == null)
188             return null;
189         Integer JavaDoc keySize = (Integer JavaDoc) session.getValue(KEY_SIZE_KEY);
190         if (keySize == null) {
191             int size = 0;
192             String JavaDoc 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 JavaDoc(size);
200             session.putValue(KEY_SIZE_KEY, keySize);
201         }
202         return keySize;
203     }
204
205     public String JavaDoc getSessionId()
206         throws IOException JavaDoc {
207         // Look up the current SSLSession
208
if (session == null)
209             return null;
210         // Expose ssl_session (getId)
211
byte [] ssl_session = session.getId();
212         if ( ssl_session == null)
213             return null;
214         StringBuffer JavaDoc buf=new StringBuffer JavaDoc("");
215         for(int x=0; x<ssl_session.length; x++) {
216             String JavaDoc 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