[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#763815: wheezy-pu: package axis/1.4-16.2+deb7u1



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


Reply to: