Author: markt Date: Fri Aug 1 19:01:49 2014 New Revision: 1615205 URL: http://svn.apache.org/r1615205 Log: Fix the parsing of the SSLv2 alias This required changes to how the ciphers were read from OpenSSL in the unit tests to differentiate those ciphers with the same name but different protocol level support.
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/Cipher.java tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java tomcat/trunk/test/org/apache/tomcat/util/net/jsse/openssl/TestOpenSSLCipherConfigurationParser.java tomcat/trunk/test/org/apache/tomcat/util/net/jsse/openssl/TesterOpenSSL.java Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/Cipher.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/Cipher.java?rev=1615205&r1=1615204&r2=1615205&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/Cipher.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/Cipher.java Fri Aug 1 19:01:49 2014 @@ -2415,9 +2415,6 @@ enum Cipher { 256 ), // RC4_128_WITH_MD5 - /* - * Same as Cipher 04 and name isn't recognised by JSSE so ignore this as it - * adds no value and complicates the unit tests. SSL_CK_RC4_128_WITH_MD5( "RC4-MD5", null, @@ -2431,7 +2428,7 @@ enum Cipher { false, 128, 128 - ),*/ + ), // RC2_128_CBC_WITH_MD5 SSL_CK_RC2_128_CBC_WITH_MD5( "RC2-MD5", Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java?rev=1615205&r1=1615204&r2=1615205&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java Fri Aug 1 19:01:49 2014 @@ -523,6 +523,8 @@ public class OpenSSLCipherConfigurationP /* Temporarily enable everything else for sorting */ result.addAll(ciphers); + /* Low priority for SSLv2 */ + moveToEnd(result, filterByProtocol(result, Collections.singleton(Protocol.SSLv2))); /* Low priority for MD5 */ moveToEnd(result, filterByMessageDigest(result, Collections.singleton(MessageDigest.MD5))); Modified: tomcat/trunk/test/org/apache/tomcat/util/net/jsse/openssl/TestOpenSSLCipherConfigurationParser.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/net/jsse/openssl/TestOpenSSLCipherConfigurationParser.java?rev=1615205&r1=1615204&r2=1615205&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/util/net/jsse/openssl/TestOpenSSLCipherConfigurationParser.java (original) +++ tomcat/trunk/test/org/apache/tomcat/util/net/jsse/openssl/TestOpenSSLCipherConfigurationParser.java Fri Aug 1 19:01:49 2014 @@ -285,9 +285,7 @@ public class TestOpenSSLCipherConfigurat } - // TODO @Test - @Ignore("Currently fails - needs investigation") public void testSSLv2() throws Exception { testSpecification("SSLv2"); } @@ -469,12 +467,11 @@ public class TestOpenSSLCipherConfigurat private void testSpecification(String specification) throws Exception { // Filter out cipher suites that OpenSSL does not implement - String parserSpecification = "" + specification; String openSSLCipherList = TesterOpenSSL.getOpenSSLCiphersAsExpression(specification); List<String> jsseCipherListFromOpenSSL = OpenSSLCipherConfigurationParser.parseExpression(openSSLCipherList); List<String> jsseCipherListFromParser = - OpenSSLCipherConfigurationParser.parseExpression(parserSpecification); + OpenSSLCipherConfigurationParser.parseExpression(specification); TesterOpenSSL.removeUnimplementedCiphersJsse(jsseCipherListFromParser); Modified: tomcat/trunk/test/org/apache/tomcat/util/net/jsse/openssl/TesterOpenSSL.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/net/jsse/openssl/TesterOpenSSL.java?rev=1615205&r1=1615204&r2=1615205&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/util/net/jsse/openssl/TesterOpenSSL.java (original) +++ tomcat/trunk/test/org/apache/tomcat/util/net/jsse/openssl/TesterOpenSSL.java Fri Aug 1 19:01:49 2014 @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.TimeUnit; import org.apache.catalina.util.IOTools; import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream; @@ -100,11 +101,43 @@ public class TesterOpenSSL { public static String getOpenSSLCiphersAsExpression(String specification) throws Exception { + String stdout; if (specification == null) { - return executeOpenSSLCommand("ciphers"); + stdout = executeOpenSSLCommand("ciphers", "-v"); } else { - return executeOpenSSLCommand("ciphers", specification); + stdout = executeOpenSSLCommand("ciphers", "-v", specification); } + + if (stdout.length() == 0) { + return stdout; + } + + StringBuilder output = new StringBuilder(); + boolean first = true; + + // OpenSSL should have returned one cipher per line + String ciphers[] = stdout.split("\n"); + for (String cipher : ciphers) { + if (first) { + first = false; + } else { + output.append(':'); + } + // Name is first part + int i = cipher.indexOf(' '); + output.append(cipher.substring(0, i)); + + // Advance i past the space + while (Character.isWhitespace(cipher.charAt(i))) { + i++; + } + + // Protocol is the second + int j = cipher.indexOf(' ', i); + output.append('+'); + output.append(cipher.substring(i, j)); + } + return output.toString(); } @@ -132,19 +165,54 @@ public class TesterOpenSSL { cmd.add(arg); } - Process process = Runtime.getRuntime().exec(cmd.toArray(new String[cmd.size()])); - InputStream stderr = process.getErrorStream(); - InputStream stdout = process.getInputStream(); - - ByteArrayOutputStream stderrBytes = new ByteArrayOutputStream(); - IOTools.flow(stderr, stderrBytes); - String errorText = stderrBytes.toString(); + ProcessBuilder pb = new ProcessBuilder(cmd.toArray(new String[cmd.size()])); + Process p = pb.start(); + + InputStreamToText stdout = new InputStreamToText(p.getInputStream()); + InputStreamToText stderr = new InputStreamToText(p.getErrorStream()); + + Thread t1 = new Thread(stdout); + t1.setName("OpenSSL stdout reader"); + t1.start(); + + Thread t2 = new Thread(stderr); + t2.setName("OpenSSL stderr reader"); + t2.start(); + + try { + p.waitFor(2, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new IOException(e); + } + + String errorText = stderr.getText(); if (errorText.length() > 0) { System.err.println(errorText); } - ByteArrayOutputStream stdoutBytes = new ByteArrayOutputStream(); - IOTools.flow(stdout, stdoutBytes); - return stdoutBytes.toString().trim(); + return stdout.getText().trim(); + } + + private static class InputStreamToText implements Runnable { + + private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + private final InputStream is; + + InputStreamToText(InputStream is) { + this.is = is; + } + + @Override + public void run() { + try { + IOTools.flow(is, baos); + } catch (IOException e) { + // Ignore + } + } + + public String getText() { + return baos.toString(); + } } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org