KickJava   Java API By Example, From Geeks To Geeks.

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


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

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

47
48 class JSSE14Support extends JSSESupport {
49
50     private static org.apache.commons.logging.Log logger =
51         org.apache.commons.logging.LogFactory.getLog(JSSE14Support.class);
52
53     Listener listener = new Listener();
54
55     public JSSE14Support(SSLSocket sock){
56         super(sock);
57         sock.addHandshakeCompletedListener(listener);
58     }
59
60     protected void handShake() throws IOException JavaDoc {
61         if( ssl.getWantClientAuth() ) {
62             logger.debug("No client cert sent for want");
63         } else {
64             ssl.setNeedClientAuth(true);
65         }
66         synchronousHandshake(ssl);
67     }
68
69     /**
70      * JSSE in JDK 1.4 has an issue/feature that requires us to do a
71      * read() to get the client-cert. As suggested by Andreas
72      * Sterbenz
73      */

74     private void synchronousHandshake(SSLSocket socket)
75         throws IOException JavaDoc {
76         InputStream JavaDoc in = socket.getInputStream();
77         int oldTimeout = socket.getSoTimeout();
78         socket.setSoTimeout(1000);
79         byte[] b = new byte[0];
80         listener.reset();
81         socket.startHandshake();
82         int maxTries = 60; // 60 * 1000 = example 1 minute time out
83
for (int i = 0; i < maxTries; i++) {
84         if(logger.isTraceEnabled())
85         logger.trace("Reading for try #" +i);
86             try {
87                 int x = in.read(b);
88             } catch(SSLException sslex) {
89                 logger.info("SSL Error getting client Certs",sslex);
90                 throw sslex;
91             } catch (IOException JavaDoc e) {
92                 // ignore - presumably the timeout
93
}
94             if (listener.completed) {
95                 break;
96             }
97         }
98         socket.setSoTimeout(oldTimeout);
99         if (listener.completed == false) {
100             throw new SocketException JavaDoc("SSL Cert handshake timeout");
101         }
102     }
103
104     /** Return the X509certificates or null if we can't get them.
105      * XXX We should allow unverified certificates
106      */

107     protected X509Certificate JavaDoc [] getX509Certificates(SSLSession session)
108     throws IOException JavaDoc
109     {
110         Certificate JavaDoc [] certs=null;
111         try {
112         certs = session.getPeerCertificates();
113         } catch( Throwable JavaDoc t ) {
114             logger.debug("Error getting client certs",t);
115             return null;
116         }
117         if( certs==null ) return null;
118         
119         X509Certificate JavaDoc [] x509Certs = new X509Certificate JavaDoc[certs.length];
120     for(int i=0; i < certs.length; i++) {
121         if( certs[i] instanceof X509Certificate JavaDoc ) {
122         // always currently true with the JSSE 1.1.x
123
x509Certs[i] = (X509Certificate JavaDoc)certs[i];
124         } else {
125         try {
126             byte [] buffer = certs[i].getEncoded();
127             CertificateFactory JavaDoc cf =
128             CertificateFactory.getInstance("X.509");
129             ByteArrayInputStream JavaDoc stream =
130             new ByteArrayInputStream JavaDoc(buffer);
131             x509Certs[i] = (X509Certificate JavaDoc)
132             cf.generateCertificate(stream);
133         } catch(Exception JavaDoc ex) {
134             logger.info("Error translating cert " + certs[i], ex);
135             return null;
136         }
137         }
138         if(logger.isTraceEnabled())
139         logger.trace("Cert #" + i + " = " + x509Certs[i]);
140     }
141     if(x509Certs.length < 1)
142         return null;
143     return x509Certs;
144     }
145
146
147     private static class Listener implements HandshakeCompletedListener {
148         volatile boolean completed = false;
149         public void handshakeCompleted(HandshakeCompletedEvent event) {
150             completed = true;
151         }
152         void reset() {
153             completed = false;
154         }
155     }
156
157 }
158
159
Popular Tags