File: CVE-2014-3577.patch

package info (click to toggle)
commons-httpclient 3.1-11%2Bdeb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 19,344 kB
  • ctags: 68,956
  • sloc: java: 30,282; xml: 855; makefile: 15
file content (110 lines) | stat: -rw-r--r-- 4,189 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
From: Markus Koschany <apo@gambaru.de>
Date: Mon, 23 Mar 2015 22:45:14 +0100
Subject: CVE-2014-3577

It was found that the fix for CVE-2012-6153 was incomplete: the code added to
check that the server hostname matches the domain name in a subject's Common
Name (CN) field in X.509 certificates was flawed. A man-in-the-middle attacker
could use this flaw to spoof an SSL server using a specially crafted X.509
certificate.
The fix for CVE-2012-6153 was intended to address the incomplete patch for
CVE-2012-5783. This means the issue is now completely resolved by applying
this patch and the 06_fix_CVE-2012-5783.patch.

References:

upstream announcement:
https://mail-archives.apache.org/mod_mbox/www-announce/201408.mbox/CVE-2014-3577

Fedora-Fix:
http://pkgs.fedoraproject.org/cgit/jakarta-commons-httpclient.git/tree/jakarta-commons-httpclient-CVE-2014-3577.patch

CentOS-Fix:
https://git.centos.org/blob/rpms!jakarta-commons-httpclient/SOURCES!jakarta-commons-httpclient-CVE-2014-3577.patch

Debian-Bug: https://bugs.debian.org/758086
Forwarded: not-needed, already fixed
---
 .../protocol/SSLProtocolSocketFactory.java         | 57 ++++++++++++++--------
 1 file changed, 37 insertions(+), 20 deletions(-)

diff --git a/src/java/org/apache/commons/httpclient/protocol/SSLProtocolSocketFactory.java b/src/java/org/apache/commons/httpclient/protocol/SSLProtocolSocketFactory.java
index fa0acc7..e6ce513 100644
--- a/src/java/org/apache/commons/httpclient/protocol/SSLProtocolSocketFactory.java
+++ b/src/java/org/apache/commons/httpclient/protocol/SSLProtocolSocketFactory.java
@@ -44,9 +44,15 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
-import java.util.StringTokenizer;
+import java.util.NoSuchElementException;
 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;
@@ -424,28 +430,39 @@ public class SSLProtocolSocketFactory implements SecureProtocolSocketFactory {
 		return dots;
 	}
 
-	private static String getCN(X509Certificate cert) {
-        // Note:  toString() seems to do a better job than getName()
-        //
-        // For example, getName() gives me this:
-        // 1.2.840.113549.1.9.1=#16166a756c6975736461766965734063756362632e636f6d
-        //
-        // whereas toString() gives me this:
-        // EMAILADDRESS=juliusdavies@cucbc.com        
-		String subjectPrincipal = cert.getSubjectX500Principal().toString();
-		
-		return getCN(subjectPrincipal);
-
+	private static String getCN(final X509Certificate cert) {
+		final String subjectPrincipal = cert.getSubjectX500Principal().toString();
+		try {
+			return extractCN(subjectPrincipal);
+		} catch (SSLException ex) {
+			return null;
+		}
 	}
-	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);
+
+	private static String extractCN(final String subjectPrincipal) throws SSLException {
+		if (subjectPrincipal == null) {
+			return null;
+		}
+		try {
+			final LdapName subjectDN = new LdapName(subjectPrincipal);
+			final List<Rdn> rdns = subjectDN.getRdns();
+			for (int i = rdns.size() - 1; i >= 0; i--) {
+				final Rdn rds = 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) {
+							return value.toString();
+						}
+					} catch (NoSuchElementException ignore) {
+					} catch (NamingException ignore) {
+					}
 				}
 			}
+		} catch (InvalidNameException e) {
+			throw new SSLException(subjectPrincipal + " is not a valid X500 distinguished name");
 		}
 		return null;
 	}