On 02.10.2014 23:18, Adam D. Barratt wrote: > On Thu, 2014-10-02 at 22:42 +0200, Markus Koschany wrote: > >> I have prepared a new point release of axis which addresses the >> security vulnerability CVE-2014-3596 "Insecure certificate >> validation". [1] > [...] >> [1] https://bugs.debian.org/762444 > > At the risk of being a bit of a pain... would it be possible to have a > diff between the current and new patches, please? > Well, I'm in a good mood today. Sure. :) Regards, Markus
diff -Nru axis-1.4/debian/changelog axis-1.4/debian/changelog --- axis-1.4/debian/changelog 2012-12-06 14:41:46.000000000 +0100 +++ axis-1.4/debian/changelog 2014-10-02 23:26:11.000000000 +0200 @@ -1,3 +1,19 @@ +axis (1.4-16.2+deb7u1) stable; urgency=high + + * Team upload. + * Fix CVE-2014-3596. + - Replace 06-fix-CVE-2012-5784.patch with CVE-2014-3596.patch which fixes + both CVE issues. Thanks to Raphael Hertzog for the report. + - The getCN function in Apache Axis 1.4 and earlier does not properly + verify that the server hostname matches a domain name in the subject's + Common Name (CN) or subjectAltName field of the X.509 certificate, + which allows man-in-the-middle attackers to spoof SSL servers via a + certificate with a subject that specifies a common name in a field + that is not the CN field. NOTE: this issue exists because of an + incomplete fix for CVE-2012-5784. + + -- Markus Koschany <apo@gambaru.de> Thu, 02 Oct 2014 22:13:16 +0200 + axis (1.4-16.2) unstable; urgency=low * Non-maintainer upload. diff -Nru axis-1.4/debian/patches/06-fix-CVE-2012-5784.patch axis-1.4/debian/patches/06-fix-CVE-2012-5784.patch --- axis-1.4/debian/patches/06-fix-CVE-2012-5784.patch 2012-12-06 13:45:17.000000000 +0100 +++ axis-1.4/debian/patches/06-fix-CVE-2012-5784.patch 2014-10-02 23:26:11.000000000 +0200 @@ -1,19 +1,25 @@ -Description: Fixed CN extraction from DN of X500 principal and wildcard validation +From: David Jorm and Arun Neelicattu (Red Hat Product Security) +Date: Thu, 25 Sep 2014 19:38:17 +0000 +Subject: CVE-2014-3596 - axis (1.4-16.2) unstable; urgency=low +The getCN function in Apache Axis 1.4 and earlier does not properly +verify that the server hostname matches a domain name in the subject's +Common Name (CN) or subjectAltName field of the X.509 certificate, +which allows man-in-the-middle attackers to spoof SSL servers via a +certificate with a subject that specifies a common name in a field +that is not the CN field. NOTE: this issue exists because of an +incomplete fix for CVE-2012-5784. - * Fixed CN extraction from DN of X500 principal and wildcard validation +Forwarded: no +Bug: https://bugs.debian.org/762444 +--- + .../axis/components/net/JSSESocketFactory.java | 309 ++++++++++++++++++++- + 1 file changed, 303 insertions(+), 6 deletions(-) -Author: Alberto Fernández Martínez <infjaf@gmail.com> - - -Origin: other -Bug-Debian: http://bugs.debian.org/692650 -Forwarded: https://issues.apache.org/jira/browse/AXIS-2883 -Last-Update: <2012-12-06> - ---- axis-1.4.orig/src/org/apache/axis/components/net/JSSESocketFactory.java -+++ axis-1.4/src/org/apache/axis/components/net/JSSESocketFactory.java +diff --git a/src/org/apache/axis/components/net/JSSESocketFactory.java b/src/org/apache/axis/components/net/JSSESocketFactory.java +index dd3f991..abffcdd 100644 +--- a/src/org/apache/axis/components/net/JSSESocketFactory.java ++++ b/src/org/apache/axis/components/net/JSSESocketFactory.java @@ -15,12 +15,6 @@ */ package org.apache.axis.components.net; @@ -27,13 +33,14 @@ import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; -@@ -28,7 +22,27 @@ import java.io.OutputStream; +@@ -28,7 +22,33 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; +import java.security.cert.Certificate; +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; ++import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Hashtable; @@ -41,9 +48,14 @@ +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; -+import java.util.StringTokenizer; +import java.util.regex.Pattern; + ++import javax.naming.InvalidNameException; ++import javax.naming.NamingException; ++import javax.naming.directory.Attribute; ++import javax.naming.directory.Attributes; ++import javax.naming.ldap.LdapName; ++import javax.naming.ldap.Rdn; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; @@ -55,7 +67,7 @@ /** -@@ -41,6 +55,10 @@ import java.util.Hashtable; +@@ -41,6 +61,10 @@ import java.util.Hashtable; */ public class JSSESocketFactory extends DefaultSocketFactory implements SecureSocketFactory { @@ -66,7 +78,7 @@ /** Field sslFactory */ protected SSLSocketFactory sslFactory = null; -@@ -187,6 +205,260 @@ public class JSSESocketFactory extends D +@@ -187,6 +211,279 @@ public class JSSESocketFactory extends DefaultSocketFactory implements SecureSoc if (log.isDebugEnabled()) { log.debug(Messages.getMessage("createdSSL00")); } @@ -74,8 +86,8 @@ return sslSocket; } + /** -+ * Verifies that the given hostname in certicifate is the hostname we are trying to connect to -+ * http://www.cvedetails.com/cve/CVE-2012-5783/ ++ * Verifies that the given hostname in certicifate is the hostname we are trying to connect to. ++ * This resolves CVE-2012-5784 and CVE-2014-3596 + * @param host + * @param ssl + * @throws IOException @@ -139,9 +151,9 @@ + // to establish the socket to the hostname in the certificate. + // Don't trim the CN, though. + -+ String cn = getCN(cert); ++ String[] cns = getCNs(cert); + String[] subjectAlts = getDNSSubjectAlts(cert); -+ verifyHostName(host, cn.toLowerCase(Locale.US), subjectAlts); ++ verifyHostName(host, cns, subjectAlts); + + } + @@ -188,7 +200,7 @@ + * @throws SSLException + */ + -+ private static void verifyHostName(final String host, String cn, String[] subjectAlts)throws SSLException{ ++ private static void verifyHostName(final String host, String[] cns, String[] subjectAlts)throws SSLException{ + StringBuffer cnTested = new StringBuffer(); + + for (int i = 0; i < subjectAlts.length; i++){ @@ -201,13 +213,18 @@ + cnTested.append("/").append(name); + } + } -+ if (cn != null && verifyHostName(host, cn)){ -+ return; -+ } -+ cnTested.append("/").append(cn); ++ for (int i = 0; i < cns.length; i++) { ++ String cn = cns[i]; ++ if (cn != null) { ++ cn = cn.toLowerCase(Locale.US); ++ if (verifyHostName(host, cn)) { ++ return; ++ } ++ cnTested.append("/").append(cn); ++ } ++ } + throw new SSLException("hostname in certificate didn't match: <" + + host + "> != <" + cnTested + ">"); -+ + } + + private static boolean verifyHostName(final String host, final String cn){ @@ -270,7 +287,7 @@ + boolean match = false; + String firstpart = parts[0]; + if (firstpart.length() > 1) { -+ // server∗ ++ // server∗ + // e.g. server + String prefix = firstpart.substring(0, firstpart.length() - 1); + // skipwildcard part from cn @@ -282,8 +299,8 @@ + match = hostName.endsWith(cn.substring(1)); + } + if (match) { -+ // I f we ’ r e i n s t r i c t mode , -+ // [ ∗.foo.com] is not allowed to match [a.b.foo.com] ++ // I f we ’ r e i n s t r i c t mode , ++ // [ ∗.foo.com] is not allowed to match [a.b.foo.com] + match = countDots(hostName) == countDots(cn); + } + return match; @@ -300,7 +317,7 @@ + } + + -+ private static String getCN(X509Certificate cert) { ++ private static String[] getCNs(X509Certificate cert) { + // Note: toString() seems to do a better job than getName() + // + // For example, getName() gives me this: @@ -310,20 +327,34 @@ + // EMAILADDRESS=juliusdavies@cucbc.com + String subjectPrincipal = cert.getSubjectX500Principal().toString(); + -+ return getCN(subjectPrincipal); ++ return getCNs(subjectPrincipal); + + } -+ private static String getCN(String subjectPrincipal) { -+ StringTokenizer st = new StringTokenizer(subjectPrincipal, ","); -+ while(st.hasMoreTokens()) { -+ String tok = st.nextToken().trim(); -+ if (tok.length() > 3) { -+ if (tok.substring(0, 3).equalsIgnoreCase("CN=")) { -+ return tok.substring(3); -+ } -+ } -+ } -+ return null; ++ private static String[] getCNs(String subjectPrincipal) { ++ if (subjectPrincipal == null) { ++ return null; ++ } ++ final List cns = new ArrayList(); ++ try { ++ final LdapName subjectDN = new LdapName(subjectPrincipal); ++ final List rdns = subjectDN.getRdns(); ++ for (int i = rdns.size() - 1; i >= 0; i--) { ++ final Rdn rds = (Rdn) rdns.get(i); ++ final Attributes attributes = rds.toAttributes(); ++ final Attribute cn = attributes.get("cn"); ++ if (cn != null) { ++ try { ++ final Object value = cn.get(); ++ if (value != null) { ++ cns.add(value.toString()); ++ } ++ } ++ catch (NamingException ignore) {} ++ } ++ } ++ } ++ catch (InvalidNameException ignore) { } ++ return cns.isEmpty() ? null : (String[]) cns.toArray(new String[ cns.size() ]); + } + }
Attachment:
signature.asc
Description: OpenPGP digital signature