001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.tomcat.util.net.jsse;
018:
019: import java.io.ByteArrayInputStream;
020: import java.io.IOException;
021: import java.security.cert.CertificateFactory;
022:
023: import javax.net.ssl.SSLSession;
024: import javax.net.ssl.SSLSocket;
025: import javax.security.cert.X509Certificate;
026:
027: import org.apache.tomcat.util.net.SSLSupport;
028:
029: /* JSSESupport
030:
031: Concrete implementation class for JSSE
032: Support classes.
033:
034: This will only work with JDK 1.2 and up since it
035: depends on JDK 1.2's certificate support
036:
037: @author EKR
038: @author Craig R. McClanahan
039: Parts cribbed from JSSECertCompat
040: Parts cribbed from CertificatesValve
041: */
042:
043: class JSSESupport implements SSLSupport {
044: private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
045: .getLog(JSSESupport.class);
046:
047: protected SSLSocket ssl;
048:
049: JSSESupport(SSLSocket sock) {
050: ssl = sock;
051: }
052:
053: public String getCipherSuite() throws IOException {
054: // Look up the current SSLSession
055: SSLSession session = ssl.getSession();
056: if (session == null)
057: return null;
058: return session.getCipherSuite();
059: }
060:
061: public Object[] getPeerCertificateChain() throws IOException {
062: return getPeerCertificateChain(false);
063: }
064:
065: protected java.security.cert.X509Certificate[] getX509Certificates(
066: SSLSession session) throws IOException {
067: X509Certificate jsseCerts[] = null;
068: try {
069: jsseCerts = session.getPeerCertificateChain();
070: } catch (Throwable ex) {
071: // Get rid of the warning in the logs when no Client-Cert is
072: // available
073: }
074:
075: if (jsseCerts == null)
076: jsseCerts = new X509Certificate[0];
077: java.security.cert.X509Certificate[] x509Certs = new java.security.cert.X509Certificate[jsseCerts.length];
078: for (int i = 0; i < x509Certs.length; i++) {
079: try {
080: byte buffer[] = jsseCerts[i].getEncoded();
081: CertificateFactory cf = CertificateFactory
082: .getInstance("X.509");
083: ByteArrayInputStream stream = new ByteArrayInputStream(
084: buffer);
085: x509Certs[i] = (java.security.cert.X509Certificate) cf
086: .generateCertificate(stream);
087: if (log.isTraceEnabled())
088: log.trace("Cert #" + i + " = " + x509Certs[i]);
089: } catch (Exception ex) {
090: log.info("Error translating " + jsseCerts[i], ex);
091: return null;
092: }
093: }
094:
095: if (x509Certs.length < 1)
096: return null;
097: return x509Certs;
098: }
099:
100: public Object[] getPeerCertificateChain(boolean force)
101: throws IOException {
102: // Look up the current SSLSession
103: SSLSession session = ssl.getSession();
104: if (session == null)
105: return null;
106:
107: // Convert JSSE's certificate format to the ones we need
108: X509Certificate[] jsseCerts = null;
109: try {
110: jsseCerts = session.getPeerCertificateChain();
111: } catch (Exception bex) {
112: // ignore.
113: }
114: if (jsseCerts == null)
115: jsseCerts = new X509Certificate[0];
116: if (jsseCerts.length <= 0 && force) {
117: session.invalidate();
118: handShake();
119: session = ssl.getSession();
120: }
121: return getX509Certificates(session);
122: }
123:
124: protected void handShake() throws IOException {
125: ssl.setNeedClientAuth(true);
126: ssl.startHandshake();
127: }
128:
129: /**
130: * Copied from <code>org.apache.catalina.valves.CertificateValve</code>
131: */
132: public Integer getKeySize() throws IOException {
133: // Look up the current SSLSession
134: SSLSession session = ssl.getSession();
135: SSLSupport.CipherData c_aux[] = ciphers;
136: if (session == null)
137: return null;
138: Integer keySize = (Integer) session.getValue(KEY_SIZE_KEY);
139: if (keySize == null) {
140: int size = 0;
141: String cipherSuite = session.getCipherSuite();
142: for (int i = 0; i < c_aux.length; i++) {
143: if (cipherSuite.indexOf(c_aux[i].phrase) >= 0) {
144: size = c_aux[i].keySize;
145: break;
146: }
147: }
148: keySize = new Integer(size);
149: session.putValue(KEY_SIZE_KEY, keySize);
150: }
151: return keySize;
152: }
153:
154: public String getSessionId() throws IOException {
155: // Look up the current SSLSession
156: SSLSession session = ssl.getSession();
157: if (session == null)
158: return null;
159: // Expose ssl_session (getId)
160: byte[] ssl_session = session.getId();
161: if (ssl_session == null)
162: return null;
163: StringBuffer buf = new StringBuffer("");
164: for (int x = 0; x < ssl_session.length; x++) {
165: String digit = Integer.toHexString((int) ssl_session[x]);
166: if (digit.length() < 2)
167: buf.append('0');
168: if (digit.length() > 2)
169: digit = digit.substring(digit.length() - 2);
170: buf.append(digit);
171: }
172: return buf.toString();
173: }
174:
175: }
|