From f7aa397425d4b3b2782c7461ad5a60b9e5fea917 Mon Sep 17 00:00:00 2001 From: costin Date: Tue, 25 May 2010 06:42:26 +0000 Subject: [PATCH] Moved the JSSE code to separate package. Added a bunch of workarounds to support harmony/android, there seems to be a problem with the ciphers. Probably the code will go away after I add APR support - too many problems, in particular SPDY can't be implemented as it relies on SSL protocol negotiation. For now it mostly works on android. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@947935 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/tomcat/lite/io/SslProvider.java | 24 +++ .../JsseSslProvider.java} | 189 +++++++++++----- .../tomcat/lite/io/{ => jsse}/SslChannel.java | 239 +++++++++++++++------ 3 files changed, 335 insertions(+), 117 deletions(-) create mode 100644 modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslProvider.java rename modules/tomcat-lite/java/org/apache/tomcat/lite/io/{SslConnector.java => jsse/JsseSslProvider.java} (66%) rename modules/tomcat-lite/java/org/apache/tomcat/lite/io/{ => jsse}/SslChannel.java (69%) diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslProvider.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslProvider.java new file mode 100644 index 000000000..94e86ae4a --- /dev/null +++ b/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslProvider.java @@ -0,0 +1,24 @@ +/* + */ +package org.apache.tomcat.lite.io; + +import java.io.IOException; + +public interface SslProvider { + + public static final String ATT_SSL_CERT = "SslCert"; + public static final String ATT_SSL_CIPHER = "SslCipher"; + public static final String ATT_SSL_KEY_SIZE = "SslKeySize"; + public static final String ATT_SSL_SESSION_ID = "SslSessionId"; + + /** + * Wrap channel with SSL. + * + * The result will start a handshake + */ + public IOChannel channel(IOChannel net, String host, int port) + throws IOException; + + public IOChannel serverChannel(IOChannel net) throws IOException; + +} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslConnector.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/io/jsse/JsseSslProvider.java similarity index 66% rename from modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslConnector.java rename to modules/tomcat-lite/java/org/apache/tomcat/lite/io/jsse/JsseSslProvider.java index cdb4acef9..7d72db5c8 100644 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslConnector.java +++ b/modules/tomcat-lite/java/org/apache/tomcat/lite/io/jsse/JsseSslProvider.java @@ -1,6 +1,6 @@ /* */ -package org.apache.tomcat.lite.io; +package org.apache.tomcat.lite.io.jsse; import java.io.ByteArrayInputStream; import java.io.FileInputStream; @@ -8,7 +8,6 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.Socket; -import java.security.GeneralSecurityException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyManagementException; @@ -24,23 +23,34 @@ import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAKeyGenParameterSpec; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509ExtendedKeyManager; import javax.net.ssl.X509TrustManager; +import org.apache.tomcat.lite.io.BBuffer; +import org.apache.tomcat.lite.io.DumpChannel; +import org.apache.tomcat.lite.io.IOChannel; +import org.apache.tomcat.lite.io.IOConnector; +import org.apache.tomcat.lite.io.SocketConnector; +import org.apache.tomcat.lite.io.SslProvider; +import org.apache.tomcat.lite.io.WrappedException; +import org.apache.tomcat.lite.io.IOConnector.ConnectedCallback; -public class SslConnector extends IOConnector { + +public class JsseSslProvider implements SslProvider { /** * TODO: option to require validation. @@ -70,6 +80,7 @@ public class SslConnector extends IOConnector { public static TrustManager[] trustAllCerts = new TrustManager[] { new BasicTrustManager() }; + static String[] enabledCiphers; static final boolean debug = false; @@ -87,14 +98,18 @@ public class SslConnector extends IOConnector { Executor handshakeExecutor = Executors.newCachedThreadPool(); static int id = 0; - public SslConnector() { + public JsseSslProvider() { + } + + public static void setEnabledCiphers(String[] enabled) { + enabledCiphers = enabled; } public void start() { } - public SSLContext getSSLContext() { + SSLContext getSSLContext() { if (sslCtx == null) { try { sslCtx = SSLContext.getInstance("TLS"); @@ -122,20 +137,30 @@ public class SslConnector extends IOConnector { return net; } - public SslChannel channel(String host, int port) { - return new SslChannel() + @Override + public IOChannel channel(IOChannel net, String host, int port) throws IOException { + if (debug) { + DumpChannel dch = new DumpChannel("S-ENC-" + id, net); + net.setHead(dch); + net = dch; + } + SslChannel ch = new SslChannel() .setTarget(host, port) .setSslContext(getSSLContext()) - .setSslConnector(this); + .setSslProvider(this); + net.setHead(ch); + return ch; } - public SslChannel serverChannel() { - return new SslChannel() + @Override + public SslChannel serverChannel(IOChannel net) throws IOException { + SslChannel ch = new SslChannel() .setSslContext(getSSLContext()) - .setSslConnector(this).withServer(); + .setSslProvider(this).withServer(); + ch.setSink(net); + return ch; } - @Override public void acceptor(final ConnectedCallback sc, CharSequence port, Object extra) throws IOException { getNet().acceptor(new ConnectedCallback() { @@ -143,18 +168,18 @@ public class SslConnector extends IOConnector { public void handleConnected(IOChannel ch) throws IOException { IOChannel first = ch; if (debug) { - DumpChannel dch = new DumpChannel("S-ENC-" + id ); - ch.addFilterAfter(dch); + DumpChannel dch = new DumpChannel("S-ENC-" + id, ch); + ch.setHead(dch); first = dch; } - IOChannel sslch = serverChannel(); + IOChannel sslch = serverChannel(first); sslch.setSink(first); - first.addFilterAfter(sslch); + first.setHead(sslch); if (debug) { - DumpChannel dch2 = new DumpChannel("S-CLR-" + id); - sslch.addFilterAfter(dch2); + DumpChannel dch2 = new DumpChannel("S-CLR-" + id, sslch); + sslch.setHead(dch2); sslch = dch2; id++; } @@ -164,7 +189,6 @@ public class SslConnector extends IOConnector { }, port, extra); } - @Override public void connect(final String host, final int port, final ConnectedCallback sc) throws IOException { getNet().connect(host, port, new ConnectedCallback() { @@ -174,17 +198,16 @@ public class SslConnector extends IOConnector { IOChannel first = ch; if (debug) { DumpChannel dch = new DumpChannel("ENC-" + id); - ch.addFilterAfter(dch); + ch.setHead(dch); first = dch; } - IOChannel sslch = channel(host, port); - sslch.setSink(first); - first.addFilterAfter(sslch); + IOChannel sslch = channel(first, host, port); +// first.setHead(sslch); if (debug) { DumpChannel dch2 = new DumpChannel("CLR-" + id); - sslch.addFilterAfter(dch2); + sslch.setHead(dch2); sslch = dch2; id++; } @@ -195,25 +218,29 @@ public class SslConnector extends IOConnector { }); } - public SslConnector withKeyManager(KeyManager[] kms) { + public JsseSslProvider withKeyManager(KeyManager[] kms) { this.keyManager = kms; return this; } - public SslConnector setKeysFile(String file, String pass) throws IOException { - return setKeys(new FileInputStream(file), pass); + public JsseSslProvider setKeystoreFile(String file, String pass) throws IOException { + return setKeystore(new FileInputStream(file), pass); } - public SslConnector setKeysResource(String res, String pass) throws IOException { - return setKeys(this.getClass().getClassLoader().getResourceAsStream(res), + public JsseSslProvider setKeystoreResource(String res, String pass) throws IOException { + return setKeystore(this.getClass().getClassLoader().getResourceAsStream(res), pass); } - public SslConnector setKeys(InputStream file, String pass) { + public JsseSslProvider setKeystore(InputStream file, String pass) { char[] passphrase = pass.toCharArray(); KeyStore ks; try { - ks = KeyStore.getInstance("JKS"); + String type = KeyStore.getDefaultType(); + System.err.println("Keystore: " + type); + // Java: JKS + // Android: BKS + ks = KeyStore.getInstance(type); ks.load(file, passphrase); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); @@ -226,6 +253,7 @@ public class SslConnector extends IOConnector { keyManager = kmf.getKeyManagers(); trustManagers = tmf.getTrustManagers(); } catch (KeyStoreException e) { + // No JKS keystore ? // TODO Auto-generated catch block }catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block @@ -247,41 +275,67 @@ public class SslConnector extends IOConnector { return this; } - public SslConnector setKeys(X509Certificate cert, PrivateKey privKey) { + public JsseSslProvider setKeys(X509Certificate cert, PrivateKey privKey) { keyManager = new KeyManager[] { new TestKeyManager(cert, privKey) }; return this; } + public JsseSslProvider setKeyFiles(String certPem, String keyFile) + throws IOException { + + + return this; + } + + public JsseSslProvider setKeyRes(String certPem, String keyFile) + throws IOException { + setKeys(this.getClass().getClassLoader().getResourceAsStream(certPem), + this.getClass().getClassLoader().getResourceAsStream(keyFile)); + return this; + } + + private void setKeys(InputStream certPem, + InputStream keyDer) throws IOException { + BBuffer keyB = BBuffer.allocate(2048); + keyB.readAll(keyDer); + byte[] key = new byte[keyB.remaining()]; + keyB.getByteBuffer().get(key); + + setKeys(certPem, key); + } + + public JsseSslProvider setKeys(String certPem, byte[] keyBytes) throws IOException{ + InputStream is = new ByteArrayInputStream(certPem.getBytes()); + return setKeys(is, keyBytes); + } + /** * Initialize using a PEM certificate and key bytes. * ( TODO: base64 dep to set the key as PEM ) * - * - * Key was generated with - * keytool -genkey -alias server -keyalg RSA -storepass changeit - * keytool -selfcert -storepass changeit -alias server - * - * Then the bytes printed with printPrivateKey() - * - * I found no way to generate the self-signed keys from jsse - * except CLI. + * openssl genrsa 1024 > host.key + * openssl pkcs8 -topk8 -nocrypt -in host.key -inform PEM + * -out host.der -outform DER + * openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert * */ - public SslConnector setKeys(String certPem, byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException, GeneralSecurityException { + public JsseSslProvider setKeys(InputStream certPem, byte[] keyBytes) throws IOException{ // convert key - KeyFactory kf = KeyFactory.getInstance("RSA"); - PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec(keyBytes); - PrivateKey priv = kf.generatePrivate (keysp); + try { + KeyFactory kf = KeyFactory.getInstance("RSA"); + PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec(keyBytes); + PrivateKey priv = kf.generatePrivate (keysp); - // Convert cert pem to certificate - InputStream is = new ByteArrayInputStream(certPem.getBytes()); - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - final X509Certificate cert = (X509Certificate) cf.generateCertificate(is); - - setKeys(cert, priv); - + // Convert cert pem to certificate + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + final X509Certificate cert = (X509Certificate) cf.generateCertificate(certPem); + + setKeys(cert, priv); + } catch (Throwable t) { + throw new WrappedException(t); + } return this; } @@ -332,12 +386,37 @@ public class SslConnector extends IOConnector { } } - public static void fixUrlConnection() { + // TODO: add a mode that trust a defined list of certs, like SSH + + /** + * Make URLConnection accept all certificates. + * Use only for testing ! + */ + public static void testModeURLConnection() { try { SSLContext sc = SSLContext.getInstance("TLS"); - sc.init(null, SslConnector.trustAllCerts, null); + sc.init(null, JsseSslProvider.trustAllCerts, null); + javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory( sc.getSocketFactory()); + javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier( + new HostnameVerifier() { + + @Override + public boolean verify(String hostname, + SSLSession session) { + try { + Certificate[] certs = session.getPeerCertificates(); + // TODO... + // see org/apache/http/conn/ssl/AbstractVerifier + } catch (SSLPeerUnverifiedException e) { + e.printStackTrace(); + } + return true; + } + + }); + } catch (Exception e) { e.printStackTrace(); } diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslChannel.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/io/jsse/SslChannel.java similarity index 69% rename from modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslChannel.java rename to modules/tomcat-lite/java/org/apache/tomcat/lite/io/jsse/SslChannel.java index e2ae08a29..bd9301a65 100644 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslChannel.java +++ b/modules/tomcat-lite/java/org/apache/tomcat/lite/io/jsse/SslChannel.java @@ -1,6 +1,6 @@ /* */ -package org.apache.tomcat.lite.io; +package org.apache.tomcat.lite.io.jsse; import java.io.IOException; import java.nio.ByteBuffer; @@ -13,36 +13,42 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLException; +import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLEngineResult.Status; +import org.apache.tomcat.lite.io.IOBuffer; +import org.apache.tomcat.lite.io.IOChannel; +import org.apache.tomcat.lite.io.SslProvider; -public class SslChannel extends IOChannel implements Runnable { +class SslChannel extends IOChannel implements Runnable { static Logger log = Logger.getLogger("SSL"); + static ByteBuffer EMPTY = ByteBuffer.allocate(0); + + SSLEngine sslEngine; // Last result SSLEngineResult unwrapR; boolean handshakeDone = false; boolean handshakeInProgress = false; + Object handshakeSync = new Object(); boolean flushing = false; IOBuffer in = new IOBuffer(this); IOBuffer out = new IOBuffer(this); - long handshakeTimeout = 10000; + long handshakeTimeout = 20000; // Used for session reuse String host; int port; - public SslChannel() { - } - ByteBuffer myAppOutData; ByteBuffer myNetOutData; + private static boolean debugWrap = false; /* * Special: SSL works in packet mode, and we may receive an incomplete @@ -50,7 +56,6 @@ public class SslChannel extends IOChannel implements Runnable { * limit at end ) */ ByteBuffer myNetInData; - ByteBuffer myAppInData; boolean client = true; @@ -58,6 +63,9 @@ public class SslChannel extends IOChannel implements Runnable { private boolean closeHandshake = false; + public SslChannel() { + } + /** * Setting the host/port enables clients to reuse SSL session - * less traffic and encryption overhead at startup, assuming the @@ -73,6 +81,7 @@ public class SslChannel extends IOChannel implements Runnable { private synchronized void initSsl() throws GeneralSecurityException { if (sslEngine != null) { + log.severe("Double initSsl"); return; } @@ -86,23 +95,25 @@ public class SslChannel extends IOChannel implements Runnable { } else { sslEngine = sslCtx.createSSLEngine(); sslEngine.setUseClientMode(false); - String[] cs = sslEngine.getEnabledCipherSuites(); - cs =sslEngine.getSupportedCipherSuites(); } + + // Some VMs have broken ciphers. + if (JsseSslProvider.enabledCiphers != null) { + sslEngine.setEnabledCipherSuites(JsseSslProvider.enabledCiphers); + } + SSLSession session = sslEngine.getSession(); + int packetBuffer = session.getPacketBufferSize(); myAppOutData = ByteBuffer.allocate(session.getApplicationBufferSize()); - myNetOutData = ByteBuffer.allocate(session.getPacketBufferSize()); + myNetOutData = ByteBuffer.allocate(packetBuffer); myAppInData = ByteBuffer.allocate(session.getApplicationBufferSize()); - myNetInData = ByteBuffer.allocate(session.getPacketBufferSize()); + myNetInData = ByteBuffer.allocate(packetBuffer); myNetInData.flip(); myNetOutData.flip(); myAppInData.flip(); myAppOutData.flip(); - - // TODO: enable anon suites - //sslEngine.setEnabledCipherSuites(sslEngine.getSupportedCipherSuites()); } public SslChannel withServer() { @@ -114,7 +125,9 @@ public class SslChannel extends IOChannel implements Runnable { @Override public synchronized void setSink(IOChannel net) throws IOException { try { - initSsl(); + if (sslEngine == null) { + initSsl(); + } super.setSink(net); } catch (GeneralSecurityException e) { log.log(Level.SEVERE, "Error initializing ", e); @@ -143,13 +156,15 @@ public class SslChannel extends IOChannel implements Runnable { if (log.isLoggable(Level.FINEST)) { log.info("JSSE: processInput " + handshakeInProgress + " " + netIn.getBufferCount()); } - if (!handshakeDone && !handshakeInProgress) { - handshakeInProgress = true; - handleHandshking(); - return 0; - } - if (handshakeInProgress) { - return 0; // leave it there + synchronized(handshakeSync) { + if (!handshakeDone && !handshakeInProgress) { + handshakeInProgress = true; + handleHandshking(); + return 0; + } + if (handshakeInProgress) { + return 0; // leave it there + } } return processRealInput(netIn, appIn); } @@ -201,8 +216,10 @@ public class SslChannel extends IOChannel implements Runnable { in.close(); if (unwrapR.getHandshakeStatus() == HandshakeStatus.NEED_WRAP) { // TODO: send/receive one more packet ( handshake mode ? ) - handshakeInProgress = true; - closeHandshake = true; + synchronized(handshakeSync) { + handshakeInProgress = true; + closeHandshake = true; + } handleHandshking(); startSending(); @@ -234,21 +251,24 @@ public class SslChannel extends IOChannel implements Runnable { return sslEngine.getHandshakeStatus(); } - static ByteBuffer EMPTY = ByteBuffer.allocate(0); - public void startSending() throws IOException { flushing = true; - - if (handshakeInProgress) { - return; // don't bother me. + boolean needHandshake = false; + synchronized(handshakeSync) { + if (handshakeInProgress) { + return; // don't bother me. + } + if (!handshakeDone) { + handshakeInProgress = true; + needHandshake = true; + } } - - if (!handshakeDone) { - handshakeInProgress = true; + if (needHandshake) { handleHandshking(); - return; // can't write yet. + return; // can't write yet. } + startRealSending(); } @@ -281,6 +301,8 @@ public class SslChannel extends IOChannel implements Runnable { } private Object sendLock = new Object(); + + private JsseSslProvider sslProvider; private void startRealSending() throws IOException { // Only one thread at a time @@ -342,17 +364,21 @@ public class SslChannel extends IOChannel implements Runnable { if (log.isLoggable(Level.FINEST)) { log.info("Starting handshake"); } - handshakeInProgress = true; + synchronized(handshakeSync) { + handshakeInProgress = true; + } - ((SslConnector) connector).handshakeExecutor.execute(this); + sslProvider.handshakeExecutor.execute(this); } private void endHandshake() throws IOException { if (log.isLoggable(Level.FINEST)) { log.info("Handshake done " + net.getIn().available()); } - handshakeDone = true; - handshakeInProgress = false; + synchronized(handshakeSync) { + handshakeDone = true; + handshakeInProgress = false; + } if (flushing) { flushing = false; startSending(); @@ -398,38 +424,37 @@ public class SslChannel extends IOChannel implements Runnable { // || initial - for client initial = false; synchronized(myNetOutData) { - myNetOutData.compact(); - - try { - wrap = sslEngine.wrap(myAppOutData, myNetOutData); - } catch (Throwable t) { - t.printStackTrace(); - close(); - return; - } finally { - myNetOutData.flip(); - } - - hstatus = wrap.getHandshakeStatus(); - if (myNetOutData.remaining() > 0) { - net.getOut().write(myNetOutData); + while (hstatus == HandshakeStatus.NEED_WRAP) { + myNetOutData.compact(); + try { + wrap = sslEngine.wrap(myAppOutData, myNetOutData); + } catch (Throwable t) { + log.log(Level.SEVERE, "Wrap error", t); + close(); + return; + } finally { + myNetOutData.flip(); + } + if (myNetOutData.remaining() > 0) { + net.getOut().write(myNetOutData); + } + hstatus = wrap.getHandshakeStatus(); } } net.startSending(); - - } else if (hstatus == HandshakeStatus.NEED_UNWRAP) { - while (hstatus == HandshakeStatus.NEED_UNWRAP) { // If we have few remaining bytes - process them if (myNetInData.remaining() > 0) { myAppInData.clear(); + if (debugWrap) { + log.info("UNWRAP: rem=" + myNetInData.remaining()); + } wrap = sslEngine.unwrap(myNetInData, myAppInData); hstatus = wrap.getHandshakeStatus(); - myAppInData.flip(); if (myAppInData.remaining() > 0) { - throw new IOException("Unexpected data"); + log.severe("Unexpected data after unwrap"); } if (wrap.getStatus() == Status.CLOSED) { break; @@ -444,13 +469,21 @@ public class SslChannel extends IOChannel implements Runnable { int rd; try { rd = net.getIn().read(myNetInData); + if (debugWrap) { + log.info("Read: " + rd); + } } finally { myNetInData.flip(); } if (rd == 0) { - net.getIn().waitData(handshakeTimeout - - (System.currentTimeMillis() - t0)); + if (debugWrap) { + log.info("Wait: " + handshakeTimeout); + } + net.getIn().waitData(handshakeTimeout); rd = net.getIn().read(myNetInData); + if (debugWrap) { + log.info("Read after wait: " + rd); + } } if (rd < 0) { // in closed @@ -506,13 +539,95 @@ public class SslChannel extends IOChannel implements Runnable { sendHandleReceivedCallback(); } - public SslChannel setSslContext(SSLContext sslCtx) { + SslChannel setSslContext(SSLContext sslCtx) { this.sslCtx = sslCtx; return this; } - public SslChannel setSslConnector(SslConnector con) { - this.connector = con; + SslChannel setSslProvider(JsseSslProvider con) { + this.sslProvider = con; return this; } + + public Object getAttribute(String name) { + if (SslProvider.ATT_SSL_CERT.equals(name)) { + try { + return sslEngine.getSession().getPeerCertificateChain(); + } catch (SSLPeerUnverifiedException e) { + return null; // no re-negotiation + } + } else if (SslProvider.ATT_SSL_CIPHER.equals(name)) { + return sslEngine.getSession().getCipherSuite(); + } else if (SslProvider.ATT_SSL_KEY_SIZE.equals(name)) { + // looks like we need to get it from the string cipher + CipherData c_aux[] = ciphers; + + int size = 0; + String cipherSuite = sslEngine.getSession().getCipherSuite(); + for (int i = 0; i < c_aux.length; i++) { + if (cipherSuite.indexOf(c_aux[i].phrase) >= 0) { + size = c_aux[i].keySize; + break; + } + } + return size; + } else if (SslProvider.ATT_SSL_SESSION_ID.equals(name)) { + byte [] ssl_session = sslEngine.getSession().getId(); + if ( ssl_session == null) + return null; + StringBuilder buf=new StringBuilder(); + for(int x=0; x2) digit=digit.substring(digit.length()-2); + buf.append(digit); + } + return buf.toString(); + } + + if (net != null) { + return net.getAttribute(name); + } + return null; + } + + + /** + * Simple data class that represents the cipher being used, along with the + * corresponding effective key size. The specified phrase must appear in the + * name of the cipher suite to be recognized. + */ + + static final class CipherData { + + public String phrase = null; + + public int keySize = 0; + + public CipherData(String phrase, int keySize) { + this.phrase = phrase; + this.keySize = keySize; + } + + } + + + /** + * A mapping table to determine the number of effective bits in the key + * when using a cipher suite containing the specified cipher name. The + * underlying data came from the TLS Specification (RFC 2246), Appendix C. + */ + static final CipherData ciphers[] = { + new CipherData("_WITH_NULL_", 0), + new CipherData("_WITH_IDEA_CBC_", 128), + new CipherData("_WITH_RC2_CBC_40_", 40), + new CipherData("_WITH_RC4_40_", 40), + new CipherData("_WITH_RC4_128_", 128), + new CipherData("_WITH_DES40_CBC_", 40), + new CipherData("_WITH_DES_CBC_", 56), + new CipherData("_WITH_3DES_EDE_CBC_", 168), + new CipherData("_WITH_AES_128_CBC_", 128), + new CipherData("_WITH_AES_256_CBC_", 256) + }; + } -- 2.11.0