subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bre...@apache.org
Subject svn commit: r1617311 - in /subversion/site/publish: doap.rdf docs/release-notes/release-history.html download/download.html index.html news.html security/CVE-2014-3522-advisory.txt security/CVE-2014-3528-advisory.txt security/index.html
Date Mon, 11 Aug 2014 16:01:26 GMT
Author: breser
Date: Mon Aug 11 16:01:25 2014
New Revision: 1617311

URL: http://svn.apache.org/r1617311
Log:
Update website for 1.7.18 and 1.8.9 releases.

Added:
    subversion/site/publish/security/CVE-2014-3522-advisory.txt   (with props)
    subversion/site/publish/security/CVE-2014-3528-advisory.txt   (with props)
Modified:
    subversion/site/publish/doap.rdf
    subversion/site/publish/docs/release-notes/release-history.html
    subversion/site/publish/download/download.html
    subversion/site/publish/index.html
    subversion/site/publish/news.html
    subversion/site/publish/security/index.html

Modified: subversion/site/publish/doap.rdf
URL: http://svn.apache.org/viewvc/subversion/site/publish/doap.rdf?rev=1617311&r1=1617310&r2=1617311&view=diff
==============================================================================
--- subversion/site/publish/doap.rdf (original)
+++ subversion/site/publish/doap.rdf Mon Aug 11 16:01:25 2014
@@ -37,15 +37,15 @@
     <release>
       <Version>
         <name>Recommended current 1.8 release</name>
-        <created>2014-05-14</created>
-        <revision>1.8.9</revision>
+        <created>2014-08-11</created>
+        <revision>1.8.10</revision>
       </Version>
     </release>
     <release>
       <Version>
         <name>Current 1.7 release</name>
-        <created>2014-05-19</created>
-        <revision>1.7.17</revision>
+        <created>2014-08-11</created>
+        <revision>1.7.18</revision>
       </Version>
     </release>
     <repository>

Modified: subversion/site/publish/docs/release-notes/release-history.html
URL: http://svn.apache.org/viewvc/subversion/site/publish/docs/release-notes/release-history.html?rev=1617311&r1=1617310&r2=1617311&view=diff
==============================================================================
--- subversion/site/publish/docs/release-notes/release-history.html (original)
+++ subversion/site/publish/docs/release-notes/release-history.html Mon Aug 11 16:01:25 2014
@@ -31,6 +31,12 @@ Subversion 2.0.</p>
 
 <ul>
   <li>
+    <b>Subversion 1.8.10</b> (Monday, 11 August 2014): Bugfix/security release.
+  </li>
+  <li>
+    <b>Subversion 1.7.18</b> (Monday, 11 August 2014): Bugfix/security release.
+  </li>
+  <li>
     <b>Subversion 1.7.17</b> (Monday, 19 May 2014): Bugfix release.
   </li>
   <li>

Modified: subversion/site/publish/download/download.html
URL: http://svn.apache.org/viewvc/subversion/site/publish/download/download.html?rev=1617311&r1=1617310&r2=1617311&view=diff
==============================================================================
--- subversion/site/publish/download/download.html (original)
+++ subversion/site/publish/download/download.html Mon Aug 11 16:01:25 2014
@@ -1,7 +1,7 @@
 <h1>Download Source Code</h1>
 
-[define version]1.8.9[end]
-[define supported]1.7.17[end]
+[define version]1.8.10[end]
+[define supported]1.7.18[end]
 [define prerelease]1.9.0-alpha2[end]
 
 <div class="bigpoint">
@@ -91,17 +91,17 @@ Other mirrors:
 </tr>
 <tr>
   <td><a href="[preferred]subversion/subversion-[version].tar.bz2">subversion-[version].tar.bz2</a></td>
-  <td class="checksum">424ee12708f39a126efd905886666083dcc4eeaf</td>
+  <td class="checksum">d6896d94bb53c1b4c6e9c5bb1a5c466477b19b2b</td>
   <td>[<a href="https://www.apache.org/dist/subversion/subversion-[version].tar.bz2.asc">PGP</a>]</td>
 </tr>
 <tr>
   <td><a href="[preferred]subversion/subversion-[version].tar.gz">subversion-[version].tar.gz</a></td>
-  <td class="checksum">c9cb166654862ee0eb6b363a2de71d72514c69ca</td>
+  <td class="checksum">8e1e1e5fd97c3f575a81d66232c62dc902257a17</td>
   <td>[<a href="https://www.apache.org/dist/subversion/subversion-[version].tar.gz.asc">PGP</a>]</td>
 </tr>
 <tr>
   <td><a href="[preferred]subversion/subversion-[version].zip">subversion-[version].zip</a></td>
-  <td class="checksum">3f8d0621794befd1ad2917dc83ea9782b50b6426</td>
+  <td class="checksum">963637c9aac7f50b1b8d10a8918c57a88fb6844d</td>
   <td>[<a href="https://www.apache.org/dist/subversion/subversion-[version].zip.asc">PGP</a>]</td>
 </tr>
 </table>
@@ -129,17 +129,17 @@ Other mirrors:
 </tr>
 <tr>
   <td><a href="[preferred]subversion/subversion-[supported].tar.bz2">subversion-[supported].tar.bz2</a></td>
-  <td class="checksum">6950f6cae83992f9df440d828835646051106d15</td>
+  <td class="checksum">56bd2b413950c916642bb4c280690da875d3c745</td>
   <td>[<a href="https://www.apache.org/dist/subversion/subversion-[supported].tar.bz2.asc">PGP</a>]</td>
 </tr>
 <tr>
   <td><a href="[preferred]subversion/subversion-[supported].tar.gz">subversion-[supported].tar.gz</a></td>
-  <td class="checksum">f8e8df7439266eee425cf9f2efb18dfe9e6f5dd0</td>
+  <td class="checksum">96873512eeb196e5ba6435fbffb24ba284bfcf84</td>
   <td>[<a href="https://www.apache.org/dist/subversion/subversion-[supported].tar.gz.asc">PGP</a>]</td>
 </tr>
 <tr>
   <td><a href="[preferred]subversion/subversion-[supported].zip">subversion-[supported].zip</a></td>
-  <td class="checksum">14d344948efd2822366c8fc886250262f9141e15</td>
+  <td class="checksum">09fa636f2c59a5a4bc965def814645a2841e1b91</td>
   <td>[<a href="https://www.apache.org/dist/subversion/subversion-[supported].zip.asc">PGP</a>]</td>
 </tr>
 </table>

Modified: subversion/site/publish/index.html
URL: http://svn.apache.org/viewvc/subversion/site/publish/index.html?rev=1617311&r1=1617310&r2=1617311&view=diff
==============================================================================
--- subversion/site/publish/index.html (original)
+++ subversion/site/publish/index.html Mon Aug 11 16:01:25 2014
@@ -64,44 +64,44 @@
 
 <!-- In general, we'll keep only the most recent 3 or 4 news items here. -->
 
-<div class="h3" id="news-20140519"> 
-<h3>2014-05-19 &mdash; Apache Subversion 1.7.17 Released
- <a class="sectionlink" href="#news-20140519"
+<div class="h3" id="news-20140811-1"> 
+<h3>2014-08-11 &mdash; Apache Subversion 1.8.10 Released
+ <a class="sectionlink" href="#news-20140811-1"
  title="Link to this section">&para;</a> 
 </h3> 
  
-<p>We are pleased to announce the release of Apache Subversion 1.7.17.
- This is the most complete Subversion release in the 1.7 series to date,
- and we encourage users of Subversion to upgrade as soon as reasonable.
- Please see the
- <a href="https://mail-archives.apache.org/mod_mbox/subversion-dev/201405.mbox/%3C537A29BA.2020102@apache.org%3E"
+<p>We are pleased to announce the release of Apache Subversion 1.8.10.
+ This is the most complete Subversion release to date, and we encourage
+ users of Subversion to upgrade as soon as reasonable. Please see the
+ <a href="https://mail-archives.apache.org/mod_mbox/subversion-dev/201408.mbox/%3C53E8E6BA.5030100@apache.org%3E"
  >release announcement</a> and the
- <a href="http://svn.apache.org/repos/asf/subversion/tags/1.7.17/CHANGES"
+ <a href="http://svn.apache.org/repos/asf/subversion/tags/1.8.10/CHANGES"
  >change log</a> for more information about this release.</p> 
  
 <p>To get this release from the nearest mirror, please visit our
- <a href="/download/#supported-releases">download page</a>.</p> 
+ <a href="/download/#recommended-release">download page</a>.</p> 
  
-</div> <!-- #news-20140519 -->
+</div> <!-- #news-20140811-1 --> 
 
-<div class="h3" id="news-20140514"> 
-<h3>2014-05-14 &mdash; Apache Subversion 1.8.9 Released
- <a class="sectionlink" href="#news-20140514"
+<div class="h3" id="news-20140811-2"> 
+<h3>2014-08-11 &mdash; Apache Subversion 1.7.18 Released
+ <a class="sectionlink" href="#news-20140811-2"
  title="Link to this section">&para;</a> 
 </h3> 
  
-<p>We are pleased to announce the release of Apache Subversion 1.8.9.
- This is the most complete Subversion release to date, and we encourage
- users of Subversion to upgrade as soon as reasonable. Please see the
- <a href="https://mail-archives.apache.org/mod_mbox/subversion-dev/201405.mbox/%3C5373888E.1030901@apache.org%3E"
+<p>We are pleased to announce the release of Apache Subversion 1.7.18.
+ This is the most complete Subversion release in the 1.7 series to date,
+ and we encourage users of Subversion to upgrade as soon as reasonable.
+ Please see the
+ <a href="https://mail-archives.apache.org/mod_mbox/subversion-dev/201408.mbox/%3C53E8E6B7.3010503@apache.org%3E"
  >release announcement</a> and the
- <a href="http://svn.apache.org/repos/asf/subversion/tags/1.8.9/CHANGES"
+ <a href="http://svn.apache.org/repos/asf/subversion/tags/1.7.18/CHANGES"
  >change log</a> for more information about this release.</p> 
  
 <p>To get this release from the nearest mirror, please visit our
- <a href="/download/#recommended-release">download page</a>.</p> 
+ <a href="/download/#supported-releases">download page</a>.</p> 
  
-</div> <!-- #news-20140514 --> 
+</div> <!-- #news-20140811-2 -->
 
 <div class="h3" id="news-20140414"> 
 <h3>2014-04-14 &mdash; Apache Subversion 1.9.0-alpha2 Released

Modified: subversion/site/publish/news.html
URL: http://svn.apache.org/viewvc/subversion/site/publish/news.html?rev=1617311&r1=1617310&r2=1617311&view=diff
==============================================================================
--- subversion/site/publish/news.html (original)
+++ subversion/site/publish/news.html Mon Aug 11 16:01:25 2014
@@ -22,6 +22,45 @@
 <!-- Maybe we could insert H2's to split up the news items by  -->
 <!-- calendar year if we felt the need to do so.               -->
 
+<div class="h3" id="news-20140811-1"> 
+<h3>2014-08-11 &mdash; Apache Subversion 1.8.10 Released
+ <a class="sectionlink" href="#news-20140811-1"
+ title="Link to this section">&para;</a> 
+</h3> 
+ 
+<p>We are pleased to announce the release of Apache Subversion 1.8.10.
+ This is the most complete Subversion release to date, and we encourage
+ users of Subversion to upgrade as soon as reasonable. Please see the
+ <a href="https://mail-archives.apache.org/mod_mbox/subversion-dev/201408.mbox/%3C53E8E6BA.5030100@apache.org%3E"
+ >release announcement</a> and the
+ <a href="http://svn.apache.org/repos/asf/subversion/tags/1.8.10/CHANGES"
+ >change log</a> for more information about this release.</p> 
+ 
+<p>To get this release from the nearest mirror, please visit our
+ <a href="/download/#recommended-release">download page</a>.</p> 
+ 
+</div> <!-- #news-20140811-1 --> 
+
+<div class="h3" id="news-20140811-2"> 
+<h3>2014-08-11 &mdash; Apache Subversion 1.7.18 Released
+ <a class="sectionlink" href="#news-20140811-2"
+ title="Link to this section">&para;</a> 
+</h3> 
+ 
+<p>We are pleased to announce the release of Apache Subversion 1.7.18.
+ This is the most complete Subversion release in the 1.7 series to date,
+ and we encourage users of Subversion to upgrade as soon as reasonable.
+ Please see the
+ <a href="https://mail-archives.apache.org/mod_mbox/subversion-dev/201408.mbox/%3C53E8E6B7.3010503@apache.org%3E"
+ >release announcement</a> and the
+ <a href="http://svn.apache.org/repos/asf/subversion/tags/1.7.18/CHANGES"
+ >change log</a> for more information about this release.</p> 
+ 
+<p>To get this release from the nearest mirror, please visit our
+ <a href="/download/#supported-releases">download page</a>.</p> 
+ 
+</div> <!-- #news-20140811-2 -->
+
 <div class="h3" id="news-20140519"> 
 <h3>2014-05-19 &mdash; Apache Subversion 1.7.17 Released
  <a class="sectionlink" href="#news-20140519"

Added: subversion/site/publish/security/CVE-2014-3522-advisory.txt
URL: http://svn.apache.org/viewvc/subversion/site/publish/security/CVE-2014-3522-advisory.txt?rev=1617311&view=auto
==============================================================================
--- subversion/site/publish/security/CVE-2014-3522-advisory.txt (added)
+++ subversion/site/publish/security/CVE-2014-3522-advisory.txt Mon Aug 11 16:01:25 2014
@@ -0,0 +1,1005 @@
+  Subversion's Serf RA layer does not correctly validate certificates
+  with wildcards in them for HTTPS.
+
+Summary:
+========
+
+  Subversion's Serf RA layer improperly evaluates wildcards for HTTPS.  This
+  means it will accept certificates that it should not accept as matching the
+  hostname the client is using to make the request.
+
+  This can lead to a man-in-the-middle attack.  There are no known instances
+  of this problem being exploited in the wild and in practice it should be
+  difficult to actually exploit this vulnerability.
+
+Known vulnerable:
+=================
+
+  Subversion clients using Serf 1.4.0 through 1.7.17 (inclusive)
+  Subversion clients using Serf 1.8.0 through 1.8.9 (inclusive)
+
+Known fixed:
+============
+
+  Subversion 1.7.18
+  Subversion 1.8.10
+  Subversion clients not using HTTPS or using Neon.
+
+Details:
+========
+
+  Using the Serf RA layer of Subversion for HTTPS uses the apr_fnmatch
+  API to handle matching wildcards in certificate Common Names and Subject
+  Alternate Names.  However, apr_fnmatch is not designed for this purpose.
+  Instead it is designed to behave like common shell globbing.  In particular
+  this means that '*' is not limited to a single label within a hostname (i.e.
+  it will match '.').  But even further apr_fnmatch supports '?' and character
+  classes (neither of which are part of the RFCs defining how certificate
+  validation works).
+
+  For HTTPS URLs Subversion has historically been able to use one of two
+  HTTP libraries, Serf or Neon.  Serf support was first added as a build time
+  option in Subversion 1.4.0, which meant only Serf or Neon was available in
+  a given build of Subversion.  Starting with 1.5.0 Subversion supported
+  building support for both Serf and Neon and choosing which one to use based
+  on a run-time configuration option.  Subversion 1.8.0 removed support for
+  Neon.  Clients using Neon are not vulnerable to this issue, since the Neon
+  library itself implements the name validation and does so correctly.
+
+  Users can see if their client supports serf by running `svn --version` and
+  looking to see if the ra_serf repository access module is available.
+
+Severity:
+=========
+
+  CVSSv2 Base Score: 4.0
+  CVSSv2 Base Vector: AV:N/AC:H/Au:N/C:P/I:P/A:N
+
+  We consider this to be a medium risk vulnerability.  Taking advantage of
+  this vulnerability to execute a man in the middle attack requires access
+  to the network or DNS of the client in order to redirect it to the attackers
+  server.  Additionally, the attacker needs a certificate signed by an
+  issuer that the client trusts.
+
+  The most concerning aspect of this vulnerability is the '*' wildcard
+  matching across hostname labels.  This for instance could allow a
+  certificate with the Common Name set to only "*" to be matched against
+  any hostname.  Another possibility would be for an attacker to try and
+  get a certificate signed for a domain they control that is a suffix for
+  the domain they wish to attack.  For example if attacking "example.com"
+  the attacker could try registering "ample.com" and then request a
+  certificate for "*ample.com" (note the lack of a '.' between the '*' and
+  'a').  However, issuers should not be signing such certificates.
+
+  This issue when combined with the Serf vulnerability CVE-2014-3504, does
+  however, make things slightly worse.  CVE-2014-3504 means that serf does
+  not properly handle certificates with embedded NUL bytes in their Common
+  Names or Subject Alternate Names.  So an attacker could request a
+  certificate with the Common Name of "*\0.example.com" where "\0" is
+  a NUL byte and ".example.com" is a domain the attacker owns.  Such a
+  certificate would be matched for any hostname.  Again issuers should not
+  be signing such certificates.
+
+  There is of course no requirement that the attacker use certificates
+  signed by a Certifying Authority.  However, if an end user is going to accept
+  the certificate (without fingerprint verification) despite an error telling
+  them it is not certified by a trusted authority then this vulnerability is
+  not needed to man-in-the-middle that user.  Since the attacker can simply
+  generate a certificate with the expected values.  As such, useful exploitation
+  of this vulnerability comes from getting a trusted Certifying Authority to
+  sign a certificate the client will accept.
+
+  A successful man-in-the-middle attack would give the attacker access to
+  the plaintext of the encrypted communications between the client and the
+  server.  This would expose any information from the repository the client
+  has requested.  It may expose authentication credentials which can be used
+  by the attacker to impersonate the user of the attacked client and thus
+  gain access to more information or even be able to modify the repository.
+  In all cases the attacker would still be subject to any authorization rules
+  configured on the repository.
+
+Recommendations:
+================
+
+  We recommend all users to upgrade to Subversion 1.8.10.  Users of
+  Subversion 1.7.x or 1.8.x who are unable to upgrade may apply the
+  included patch.  We also recommend that all users upgrade to Serf 1.3.7
+  or newer to resolve CVE-2014-3504.
+
+  New Subversion packages can be found at:
+  http://subversion.apache.org/packages.html
+
+  There are no workarounds available.  However, some of the risk can be
+  mitigated by users taking some care.  Users should not accept certificates
+  that are not signed by a trusted certifying authority, without verifying
+  their authenticity via the fingerprint.  Users may also configure their
+  clients not to trust certifying authorities (or decrease the number of
+  certifying authorities they trust).  Unfortunately, these mitigating steps
+  require a great deal of care on the part of users, so upgrading the client
+  immediately is the best course of action.
+
+References:
+===========
+
+  CVE-2014-3522  (Subversion)
+  CVE-2014-3504  (Serf - different but related vulnerability)
+
+Reported by:
+============
+
+  Ben Reser, WANdisco
+
+Patches:
+========
+
+  Patch against 1.7.17:
+
+[[[
+Index: subversion/include/private/svn_cert.h
+===================================================================
+--- subversion/include/private/svn_cert.h	(nonexistent)
++++ subversion/include/private/svn_cert.h	(working copy)
+@@ -0,0 +1,68 @@
++/**
++ * @copyright
++ * ====================================================================
++ *    Licensed to the Apache Software Foundation (ASF) under one
++ *    or more contributor license agreements.  See the NOTICE file
++ *    distributed with this work for additional information
++ *    regarding copyright ownership.  The ASF licenses this file
++ *    to you under the Apache License, Version 2.0 (the
++ *    "License"); you may not use this file except in compliance
++ *    with the License.  You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ *    Unless required by applicable law or agreed to in writing,
++ *    software distributed under the License is distributed on an
++ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ *    KIND, either express or implied.  See the License for the
++ *    specific language governing permissions and limitations
++ *    under the License.
++ * ====================================================================
++ * @endcopyright
++ *
++ * @file svn_cert.h
++ * @brief Implementation of certificate validation functions
++ */
++
++#ifndef SVN_CERT_H
++#define SVN_CERT_H
++
++#include <apr.h>
++
++#include "svn_types.h"
++#include "svn_string.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++
++/* Return TRUE iff @a pattern matches @a hostname as defined
++ * by the matching rules of RFC 6125.  In the context of RFC
++ * 6125 the pattern is the domain name portion of the presented
++ * identifier (which comes from the Common Name or a DNSName
++ * portion of the subjectAltName of an X.509 certificate) and
++ * the hostname is the source domain (i.e. the host portion
++ * of the URI the user entered).
++ *
++ * @note With respect to wildcards we only support matching
++ * wildcards in the left-most label and as the only character
++ * in the left-most label (i.e. we support RFC 6125 s. 6.4.3
++ * Rule 1 and 2 but not the optional Rule 3).  This may change
++ * in the future.
++ *
++ * @note Subversion does not at current support internationalized
++ * domain names.  Both values are presumed to be in NR-LDH label
++ * or A-label form (see RFC 5890 for the definition).
++ *
++ * @since New in 1.9.
++ */
++svn_boolean_t
++svn_cert__match_dns_identity(svn_string_t *pattern, svn_string_t *hostname);
++
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* SVN_CERT_H */
+Index: subversion/libsvn_ra_serf/util.c
+===================================================================
+--- subversion/libsvn_ra_serf/util.c	(revision 1615128)
++++ subversion/libsvn_ra_serf/util.c	(working copy)
+@@ -28,7 +28,6 @@
+ #define APR_WANT_STRFUNC
+ #include <apr.h>
+ #include <apr_want.h>
+-#include <apr_fnmatch.h>
+ 
+ #include <serf.h>
+ #include <serf_bucket_types.h>
+@@ -40,6 +39,7 @@
+ #include "svn_xml.h"
+ #include "private/svn_dep_compat.h"
+ #include "private/svn_fspath.h"
++#include "private/svn_cert.h"
+ 
+ #include "ra_serf.h"
+ 
+@@ -202,7 +202,10 @@ ssl_server_cert(void *baton, int failures,
+   apr_hash_t *issuer, *subject, *serf_cert;
+   apr_array_header_t *san;
+   void *creds;
+-  int found_matching_hostname = 0;
++  svn_boolean_t found_matching_hostname = FALSE;
++  svn_boolean_t found_san_entry = FALSE;
++  svn_string_t *actual_hostname =
++      svn_string_create(conn->hostname, scratch_pool);
+ 
+   /* Implicitly approve any non-server certs. */
+   if (serf_ssl_cert_depth(cert) > 0)
+@@ -237,30 +240,42 @@ ssl_server_cert(void *baton, int failures,
+                   | conn->server_cert_failures);
+ 
+   /* Try to find matching server name via subjectAltName first... */
+-  if (san) {
++  if (san)
++    {
+       int i;
+-      for (i = 0; i < san->nelts; i++) {
++      found_san_entry = san->nelts > 0;
++      for (i = 0; i < san->nelts; i++)
++        {
+           char *s = APR_ARRAY_IDX(san, i, char*);
+-          if (apr_fnmatch(s, conn->hostname,
+-                          APR_FNM_PERIOD | APR_FNM_CASE_BLIND) == APR_SUCCESS)
++          svn_string_t *cert_hostname = svn_string_create(s, scratch_pool);
++
++          if (svn_cert__match_dns_identity(cert_hostname, actual_hostname))
+             {
+-              found_matching_hostname = 1;
++              found_matching_hostname = TRUE;
+               cert_info.hostname = s;
+               break;
+             }
+-      }
+-  }
++        }
++    }
+ 
+-  /* Match server certificate CN with the hostname of the server */
+-  if (!found_matching_hostname && cert_info.hostname)
++  /* Match server certificate CN with the hostname of the server iff
++   * we didn't find any subjectAltName fields and try to match them.
++   * Per RFC 2818 they are authoritative if present and CommonName
++   * should be ignored. */
++  if (!found_matching_hostname && !found_san_entry && cert_info.hostname)
+     {
+-      if (apr_fnmatch(cert_info.hostname, conn->hostname,
+-                      APR_FNM_PERIOD | APR_FNM_CASE_BLIND) == APR_FNM_NOMATCH)
++      svn_string_t *cert_hostname = svn_string_create(cert_info.hostname,
++                                                      scratch_pool);
++
++      if (svn_cert__match_dns_identity(cert_hostname, actual_hostname))
+         {
+-          svn_failures |= SVN_AUTH_SSL_CNMISMATCH;
++          found_matching_hostname = TRUE;
+         }
+     }
+ 
++  if (!found_matching_hostname)
++    svn_failures |= SVN_AUTH_SSL_CNMISMATCH;
++
+   svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+                          SVN_AUTH_PARAM_SSL_SERVER_FAILURES,
+                          &svn_failures);
+Index: subversion/libsvn_subr/dirent_uri.c
+===================================================================
+--- subversion/libsvn_subr/dirent_uri.c	(revision 1615128)
++++ subversion/libsvn_subr/dirent_uri.c	(working copy)
+@@ -38,6 +38,7 @@
+ 
+ #include "dirent_uri.h"
+ #include "private/svn_fspath.h"
++#include "private/svn_cert.h"
+ 
+ /* The canonical empty path.  Can this be changed?  Well, change the empty
+    test below and the path library will work, not so sure about the fs/wc
+@@ -2631,3 +2632,81 @@ svn_urlpath__canonicalize(const char *uri,
+     }
+   return uri;
+ }
++
++
++/* -------------- The cert API (see private/svn_cert.h) ------------- */
++
++svn_boolean_t
++svn_cert__match_dns_identity(svn_string_t *pattern, svn_string_t *hostname)
++{
++  apr_size_t pattern_pos = 0, hostname_pos = 0;
++
++  /* support leading wildcards that composed of the only character in the
++   * left-most label. */
++  if (pattern->len >= 2 &&
++      pattern->data[pattern_pos] == '*' &&
++      pattern->data[pattern_pos + 1] == '.')
++    {
++      while (hostname_pos < hostname->len &&
++             hostname->data[hostname_pos] != '.')
++        {
++          hostname_pos++;
++        }
++      /* Assume that the wildcard must match something.  Rule 2 says
++       * that *.example.com should not match example.com.  If the wildcard
++       * ends up not matching anything then it matches .example.com which
++       * seems to be essentially the same as just example.com */
++      if (hostname_pos == 0)
++        return FALSE;
++
++      pattern_pos++;
++    }
++
++  while (pattern_pos < pattern->len && hostname_pos < hostname->len)
++    {
++      char pattern_c = pattern->data[pattern_pos];
++      char hostname_c = hostname->data[hostname_pos];
++
++      /* fold case as described in RFC 4343.
++       * Note: We actually convert to lowercase, since our URI
++       * canonicalization code converts to lowercase and generally
++       * most certs are issued with lowercase DNS names, meaning
++       * this avoids the fold operation in most cases.  The RFC
++       * suggests the opposite transformation, but doesn't require
++       * any specific implementation in any case.  It is critical
++       * that this folding be locale independent so you can't use
++       * tolower(). */
++      pattern_c = canonicalize_to_lower(pattern_c);
++      hostname_c = canonicalize_to_lower(hostname_c);
++
++      if (pattern_c != hostname_c)
++        {
++          /* doesn't match */
++          return FALSE;
++        }
++      else
++        {
++          /* characters match so skip both */
++          pattern_pos++;
++          hostname_pos++;
++        }
++    }
++
++  /* ignore a trailing period on the hostname since this has no effect on the
++   * security of the matching.  See the following for the long explanation as
++   * to why:
++   * https://bugzilla.mozilla.org/show_bug.cgi?id=134402#c28
++   */
++  if (pattern_pos == pattern->len &&
++      hostname_pos == hostname->len - 1 &&
++      hostname->data[hostname_pos] == '.')
++    hostname_pos++;
++
++  if (pattern_pos != pattern->len || hostname_pos != hostname->len)
++    {
++      /* end didn't match */
++      return FALSE;
++    }
++
++  return TRUE;
++}
+Index: subversion/tests/libsvn_subr/dirent_uri-test.c
+===================================================================
+--- subversion/tests/libsvn_subr/dirent_uri-test.c	(revision 1615128)
++++ subversion/tests/libsvn_subr/dirent_uri-test.c	(working copy)
+@@ -37,6 +37,7 @@
+ #include "svn_pools.h"
+ #include "svn_dirent_uri.h"
+ #include "private/svn_fspath.h"
++#include "private/svn_cert.h"
+ 
+ #include "../svn_test.h"
+ 
+@@ -2821,6 +2822,145 @@ test_fspath_get_longest_ancestor(apr_pool_t *pool)
+   return SVN_NO_ERROR;
+ }
+ 
++struct cert_match_dns_test {
++  const char *pattern;
++  const char *hostname;
++  svn_boolean_t expected;
++};
++
++static svn_error_t *
++run_cert_match_dns_tests(struct cert_match_dns_test *tests, apr_pool_t *pool)
++{
++  struct cert_match_dns_test *ct;
++  apr_pool_t *iterpool = svn_pool_create(pool);
++
++  for (ct = tests; ct->pattern; ct++)
++    {
++      svn_boolean_t result;
++      svn_string_t *pattern, *hostname;
++
++      svn_pool_clear(iterpool);
++
++      pattern = svn_string_create(ct->pattern, iterpool);
++      hostname = svn_string_create(ct->hostname, iterpool);
++
++      result = svn_cert__match_dns_identity(pattern, hostname);
++      if (result != ct->expected)
++        return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
++                                 "Expected %s but got %s for pattern '%s' on "
++                                 "hostname '%s'",
++                                 ct->expected ? "match" : "no match",
++                                 result ? "match" : "no match",
++                                 pattern->data, hostname->data);
++
++    }
++
++  svn_pool_destroy(iterpool);
++
++  return SVN_NO_ERROR;
++}
++
++static struct cert_match_dns_test cert_match_dns_tests[] = {
++  { "foo.example.com", "foo.example.com", TRUE }, /* exact match */
++  { "foo.example.com", "FOO.EXAMPLE.COM", TRUE }, /* case differences */
++  { "FOO.EXAMPLE.COM", "foo.example.com", TRUE },
++  { "*.example.com", "FoO.ExAmPlE.CoM", TRUE },
++  { "*.ExAmPlE.CoM", "foo.example.com", TRUE },
++  { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", TRUE },
++  { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", TRUE },
++  { "foo.example.com", "bar.example.com", FALSE }, /* difference at start */
++  { "foo.example.com", "foo.example.net", FALSE }, /* difference at end */
++  { "foo.example.com", "foo.example.commercial", FALSE }, /* hostname longer */
++  { "foo.example.commercial", "foo.example.com", FALSE }, /* pattern longer */
++  { "foo.example.comcom", "foo.example.com", FALSE }, /* repeated suffix */
++  { "foo.example.com", "foo.example.comcom", FALSE },
++  { "foo.example.com.com", "foo.example.com", FALSE },
++  { "foo.example.com", "foo.example.com.com", FALSE },
++  { "foofoo.example.com", "foo.example.com", FALSE }, /* repeated prefix */
++  { "foo.example.com", "foofoo.example.com", FALSE },
++  { "foo.foo.example.com", "foo.example.com", FALSE },
++  { "foo.example.com", "foo.foo.example.com", FALSE },
++  { "foo.*.example.com", "foo.bar.example.com", FALSE }, /* RFC 6125 s. 6.4.3
++                                                            Rule 1 */
++  { "*.example.com", "foo.example.com", TRUE }, /* RFC 6125 s. 6.4.3 Rule 2 */
++  { "*.example.com", "bar.foo.example.com", FALSE }, /* Rule 2 */
++  { "*.example.com", "example.com", FALSE }, /* Rule 2 */
++  { "*.example.com", ".example.com", FALSE }, /* RFC doesn't say what to do
++                                                 here and a leading period on
++                                                 a hostname doesn't make sense
++                                                 so we'll just reject this. */
++  { "*", "foo.example.com", FALSE }, /* wildcard must be left-most label,
++                                        implies that there must be more than
++                                        one label. */
++  { "*", "example.com", FALSE },
++  { "*", "com", FALSE },
++  { "*.example.com", "foo.example.net", FALSE }, /* difference in literal text
++                                                    with a wildcard. */
++  { "*.com", "example.com", TRUE }, /* See Errata ID 3090 for RFC 6125,
++                                       probably shouldn't allow this but
++                                       we do for now. */
++  { "*.", "example.com", FALSE }, /* test some dubious 2 character wildcard
++                                     patterns */
++  { "*.", "example.", TRUE }, /* This one feels questionable */
++  { "*.", "example", FALSE },
++  { "*.", ".", FALSE },
++  { "a", "a", TRUE }, /* check that single letter exact matches work */
++  { "a", "b", FALSE }, /* and single letter not matches shouldn't */
++  { "*.*.com", "foo.example.com", FALSE }, /* unsupported wildcards */
++  { "*.*.com", "example.com", FALSE },
++  { "**.example.com", "foo.example.com", FALSE },
++  { "**.example.com", "example.com", FALSE },
++  { "f*.example.com", "foo.example.com", FALSE },
++  { "f*.example.com", "bar.example.com", FALSE },
++  { "*o.example.com", "foo.example.com", FALSE },
++  { "*o.example.com", "bar.example.com", FALSE },
++  { "f*o.example.com", "foo.example.com", FALSE },
++  { "f*o.example.com", "bar.example.com", FALSE },
++  { "foo.e*.com", "foo.example.com", FALSE },
++  { "foo.*e.com", "foo.example.com", FALSE },
++  { "foo.e*e.com", "foo.example.com", FALSE },
++  { "foo.example.com", "foo.example.com.", TRUE }, /* trailing dot */
++  { "*.example.com", "foo.example.com.", TRUE },
++  { "foo", "foo.", TRUE },
++  { "foo.example.com.", "foo.example.com", FALSE },
++  { "*.example.com.", "foo.example.com", FALSE },
++  { "foo.", "foo", FALSE },
++  { "foo.example.com", "foo.example.com..", FALSE },
++  { "*.example.com", "foo.example.com..", FALSE },
++  { "foo", "foo..", FALSE },
++  { "foo.example.com..", "foo.example.com", FALSE },
++  { "*.example.com..", "foo.example.com", FALSE },
++  { "foo..", "foo", FALSE },
++  { NULL }
++};
++
++static svn_error_t *
++test_cert_match_dns_identity(apr_pool_t *pool)
++{
++  return run_cert_match_dns_tests(cert_match_dns_tests, pool);
++}
++
++/* This test table implements results that should happen if we supported
++ * RFC 6125 s. 6.4.3 Rule 3.  We don't so it's expected to fail for now. */
++static struct cert_match_dns_test rule3_tests[] = {
++  { "baz*.example.net", "baz1.example.net", TRUE },
++  { "*baz.example.net", "foobaz.example.net", TRUE },
++  { "b*z.example.net", "buuz.example.net", TRUE },
++  { "b*z.example.net", "bz.example.net", FALSE }, /* presume wildcard can't
++                                                     match nothing */
++  { "baz*.example.net", "baz.example.net", FALSE },
++  { "*baz.example.net", "baz.example.net", FALSE },
++  { "b*z.example.net", "buuzuuz.example.net", TRUE }, /* presume wildcard
++                                                         should be greedy */
++  { NULL }
++};
++
++static svn_error_t *
++test_rule3(apr_pool_t *pool)
++{
++  return run_cert_match_dns_tests(rule3_tests, pool);
++}
++
+ 
+ /* The test table.  */
+ 
+@@ -2925,5 +3065,9 @@ struct svn_test_descriptor_t test_funcs[] =
+                    "test svn_fspath__dirname/basename/split"),
+     SVN_TEST_PASS2(test_fspath_get_longest_ancestor,
+                    "test svn_fspath__get_longest_ancestor"),
++    SVN_TEST_PASS2(test_cert_match_dns_identity,
++                   "test svn_cert__match_dns_identity"),
++    SVN_TEST_XFAIL2(test_rule3,
++                    "test match with RFC 6125 s. 6.4.3 Rule 3"),
+     SVN_TEST_NULL
+   };
+]]]
+
+  Patch against 1.8.9:
+
+[[[
+Index: subversion/include/private/svn_cert.h
+===================================================================
+--- subversion/include/private/svn_cert.h	(nonexistent)
++++ subversion/include/private/svn_cert.h	(working copy)
+@@ -0,0 +1,68 @@
++/**
++ * @copyright
++ * ====================================================================
++ *    Licensed to the Apache Software Foundation (ASF) under one
++ *    or more contributor license agreements.  See the NOTICE file
++ *    distributed with this work for additional information
++ *    regarding copyright ownership.  The ASF licenses this file
++ *    to you under the Apache License, Version 2.0 (the
++ *    "License"); you may not use this file except in compliance
++ *    with the License.  You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ *    Unless required by applicable law or agreed to in writing,
++ *    software distributed under the License is distributed on an
++ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ *    KIND, either express or implied.  See the License for the
++ *    specific language governing permissions and limitations
++ *    under the License.
++ * ====================================================================
++ * @endcopyright
++ *
++ * @file svn_cert.h
++ * @brief Implementation of certificate validation functions
++ */
++
++#ifndef SVN_CERT_H
++#define SVN_CERT_H
++
++#include <apr.h>
++
++#include "svn_types.h"
++#include "svn_string.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++
++/* Return TRUE iff @a pattern matches @a hostname as defined
++ * by the matching rules of RFC 6125.  In the context of RFC
++ * 6125 the pattern is the domain name portion of the presented
++ * identifier (which comes from the Common Name or a DNSName
++ * portion of the subjectAltName of an X.509 certificate) and
++ * the hostname is the source domain (i.e. the host portion
++ * of the URI the user entered).
++ *
++ * @note With respect to wildcards we only support matching
++ * wildcards in the left-most label and as the only character
++ * in the left-most label (i.e. we support RFC 6125 s. 6.4.3
++ * Rule 1 and 2 but not the optional Rule 3).  This may change
++ * in the future.
++ *
++ * @note Subversion does not at current support internationalized
++ * domain names.  Both values are presumed to be in NR-LDH label
++ * or A-label form (see RFC 5890 for the definition).
++ *
++ * @since New in 1.9.
++ */
++svn_boolean_t
++svn_cert__match_dns_identity(svn_string_t *pattern, svn_string_t *hostname);
++
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* SVN_CERT_H */
+Index: subversion/libsvn_ra_serf/util.c
+===================================================================
+--- subversion/libsvn_ra_serf/util.c	(revision 1615128)
++++ subversion/libsvn_ra_serf/util.c	(working copy)
+@@ -28,7 +28,6 @@
+ #define APR_WANT_STRFUNC
+ #include <apr.h>
+ #include <apr_want.h>
+-#include <apr_fnmatch.h>
+ 
+ #include <serf.h>
+ #include <serf_bucket_types.h>
+@@ -49,6 +48,7 @@
+ #include "private/svn_fspath.h"
+ #include "private/svn_subr_private.h"
+ #include "private/svn_auth_private.h"
++#include "private/svn_cert.h"
+ 
+ #include "ra_serf.h"
+ 
+@@ -274,7 +274,6 @@ ssl_server_cert(void *baton, int failures,
+   apr_hash_t *subject = NULL;
+   apr_hash_t *serf_cert = NULL;
+   void *creds;
+-  int found_matching_hostname = 0;
+ 
+   svn_failures = (ssl_convert_serf_failures(failures)
+       | conn->server_cert_failures);
+@@ -286,26 +285,37 @@ ssl_server_cert(void *baton, int failures,
+       ### This should really be handled by serf, which should pass an error
+           for this case, but that has backwards compatibility issues. */
+       apr_array_header_t *san;
++      svn_boolean_t found_san_entry = FALSE;
++      svn_boolean_t found_matching_hostname = FALSE;
++      svn_string_t *actual_hostname =
++          svn_string_create(conn->session->session_url.hostname, scratch_pool);
+ 
+       serf_cert = serf_ssl_cert_certificate(cert, scratch_pool);
+ 
+       san = svn_hash_gets(serf_cert, "subjectAltName");
+       /* Try to find matching server name via subjectAltName first... */
+-      if (san) {
++      if (san)
++        {
+           int i;
+-          for (i = 0; i < san->nelts; i++) {
++          found_san_entry = san->nelts > 0;
++          for (i = 0; i < san->nelts; i++)
++            {
+               const char *s = APR_ARRAY_IDX(san, i, const char*);
+-              if (apr_fnmatch(s, conn->session->session_url.hostname,
+-                  APR_FNM_PERIOD | APR_FNM_CASE_BLIND) == APR_SUCCESS)
+-              {
+-                  found_matching_hostname = 1;
++              svn_string_t *cert_hostname = svn_string_create(s, scratch_pool);
++
++              if (svn_cert__match_dns_identity(cert_hostname, actual_hostname))
++                {
++                  found_matching_hostname = TRUE;
+                   break;
+-              }
+-          }
+-      }
++                }
++            }
++        }
+ 
+-      /* Match server certificate CN with the hostname of the server */
+-      if (!found_matching_hostname)
++      /* Match server certificate CN with the hostname of the server iff
++       * we didn't find any subjectAltName fields and try to match them.
++       * Per RFC 2818 they are authoritative if present and CommonName
++       * should be ignored. */
++      if (!found_matching_hostname && !found_san_entry)
+         {
+           const char *hostname = NULL;
+ 
+@@ -314,13 +324,20 @@ ssl_server_cert(void *baton, int failures,
+           if (subject)
+             hostname = svn_hash_gets(subject, "CN");
+ 
+-          if (!hostname
+-              || apr_fnmatch(hostname, conn->session->session_url.hostname,
+-                             APR_FNM_PERIOD | APR_FNM_CASE_BLIND) != APR_SUCCESS)
+-          {
+-              svn_failures |= SVN_AUTH_SSL_CNMISMATCH;
+-          }
+-      }
++          if (hostname)
++            {
++              svn_string_t *cert_hostname = svn_string_create(hostname,
++                                                              scratch_pool);
++
++              if (svn_cert__match_dns_identity(cert_hostname, actual_hostname))
++                {
++                  found_matching_hostname = TRUE;
++                }
++            }
++        }
++
++      if (!found_matching_hostname)
++        svn_failures |= SVN_AUTH_SSL_CNMISMATCH;
+     }
+ 
+   if (!svn_failures)
+Index: subversion/libsvn_subr/dirent_uri.c
+===================================================================
+--- subversion/libsvn_subr/dirent_uri.c	(revision 1615128)
++++ subversion/libsvn_subr/dirent_uri.c	(working copy)
+@@ -38,6 +38,7 @@
+ 
+ #include "dirent_uri.h"
+ #include "private/svn_fspath.h"
++#include "private/svn_cert.h"
+ 
+ /* The canonical empty path.  Can this be changed?  Well, change the empty
+    test below and the path library will work, not so sure about the fs/wc
+@@ -2597,3 +2598,81 @@ svn_urlpath__canonicalize(const char *uri,
+     }
+   return uri;
+ }
++
++
++/* -------------- The cert API (see private/svn_cert.h) ------------- */
++
++svn_boolean_t
++svn_cert__match_dns_identity(svn_string_t *pattern, svn_string_t *hostname)
++{
++  apr_size_t pattern_pos = 0, hostname_pos = 0;
++
++  /* support leading wildcards that composed of the only character in the
++   * left-most label. */
++  if (pattern->len >= 2 &&
++      pattern->data[pattern_pos] == '*' &&
++      pattern->data[pattern_pos + 1] == '.')
++    {
++      while (hostname_pos < hostname->len &&
++             hostname->data[hostname_pos] != '.')
++        {
++          hostname_pos++;
++        }
++      /* Assume that the wildcard must match something.  Rule 2 says
++       * that *.example.com should not match example.com.  If the wildcard
++       * ends up not matching anything then it matches .example.com which
++       * seems to be essentially the same as just example.com */
++      if (hostname_pos == 0)
++        return FALSE;
++
++      pattern_pos++;
++    }
++
++  while (pattern_pos < pattern->len && hostname_pos < hostname->len)
++    {
++      char pattern_c = pattern->data[pattern_pos];
++      char hostname_c = hostname->data[hostname_pos];
++
++      /* fold case as described in RFC 4343.
++       * Note: We actually convert to lowercase, since our URI
++       * canonicalization code converts to lowercase and generally
++       * most certs are issued with lowercase DNS names, meaning
++       * this avoids the fold operation in most cases.  The RFC
++       * suggests the opposite transformation, but doesn't require
++       * any specific implementation in any case.  It is critical
++       * that this folding be locale independent so you can't use
++       * tolower(). */
++      pattern_c = canonicalize_to_lower(pattern_c);
++      hostname_c = canonicalize_to_lower(hostname_c);
++
++      if (pattern_c != hostname_c)
++        {
++          /* doesn't match */
++          return FALSE;
++        }
++      else
++        {
++          /* characters match so skip both */
++          pattern_pos++;
++          hostname_pos++;
++        }
++    }
++
++  /* ignore a trailing period on the hostname since this has no effect on the
++   * security of the matching.  See the following for the long explanation as
++   * to why:
++   * https://bugzilla.mozilla.org/show_bug.cgi?id=134402#c28
++   */
++  if (pattern_pos == pattern->len &&
++      hostname_pos == hostname->len - 1 &&
++      hostname->data[hostname_pos] == '.')
++    hostname_pos++;
++
++  if (pattern_pos != pattern->len || hostname_pos != hostname->len)
++    {
++      /* end didn't match */
++      return FALSE;
++    }
++
++  return TRUE;
++}
+Index: subversion/tests/libsvn_subr/dirent_uri-test.c
+===================================================================
+--- subversion/tests/libsvn_subr/dirent_uri-test.c	(revision 1615128)
++++ subversion/tests/libsvn_subr/dirent_uri-test.c	(working copy)
+@@ -37,6 +37,7 @@
+ #include "svn_pools.h"
+ #include "svn_dirent_uri.h"
+ #include "private/svn_fspath.h"
++#include "private/svn_cert.h"
+ 
+ #include "../svn_test.h"
+ 
+@@ -2714,6 +2715,145 @@ test_fspath_get_longest_ancestor(apr_pool_t *pool)
+   return SVN_NO_ERROR;
+ }
+ 
++struct cert_match_dns_test {
++  const char *pattern;
++  const char *hostname;
++  svn_boolean_t expected;
++};
++
++static svn_error_t *
++run_cert_match_dns_tests(struct cert_match_dns_test *tests, apr_pool_t *pool)
++{
++  struct cert_match_dns_test *ct;
++  apr_pool_t *iterpool = svn_pool_create(pool);
++
++  for (ct = tests; ct->pattern; ct++)
++    {
++      svn_boolean_t result;
++      svn_string_t *pattern, *hostname;
++
++      svn_pool_clear(iterpool);
++
++      pattern = svn_string_create(ct->pattern, iterpool);
++      hostname = svn_string_create(ct->hostname, iterpool);
++
++      result = svn_cert__match_dns_identity(pattern, hostname);
++      if (result != ct->expected)
++        return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
++                                 "Expected %s but got %s for pattern '%s' on "
++                                 "hostname '%s'",
++                                 ct->expected ? "match" : "no match",
++                                 result ? "match" : "no match",
++                                 pattern->data, hostname->data);
++
++    }
++
++  svn_pool_destroy(iterpool);
++
++  return SVN_NO_ERROR;
++}
++
++static struct cert_match_dns_test cert_match_dns_tests[] = {
++  { "foo.example.com", "foo.example.com", TRUE }, /* exact match */
++  { "foo.example.com", "FOO.EXAMPLE.COM", TRUE }, /* case differences */
++  { "FOO.EXAMPLE.COM", "foo.example.com", TRUE },
++  { "*.example.com", "FoO.ExAmPlE.CoM", TRUE },
++  { "*.ExAmPlE.CoM", "foo.example.com", TRUE },
++  { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", TRUE },
++  { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", TRUE },
++  { "foo.example.com", "bar.example.com", FALSE }, /* difference at start */
++  { "foo.example.com", "foo.example.net", FALSE }, /* difference at end */
++  { "foo.example.com", "foo.example.commercial", FALSE }, /* hostname longer */
++  { "foo.example.commercial", "foo.example.com", FALSE }, /* pattern longer */
++  { "foo.example.comcom", "foo.example.com", FALSE }, /* repeated suffix */
++  { "foo.example.com", "foo.example.comcom", FALSE },
++  { "foo.example.com.com", "foo.example.com", FALSE },
++  { "foo.example.com", "foo.example.com.com", FALSE },
++  { "foofoo.example.com", "foo.example.com", FALSE }, /* repeated prefix */
++  { "foo.example.com", "foofoo.example.com", FALSE },
++  { "foo.foo.example.com", "foo.example.com", FALSE },
++  { "foo.example.com", "foo.foo.example.com", FALSE },
++  { "foo.*.example.com", "foo.bar.example.com", FALSE }, /* RFC 6125 s. 6.4.3
++                                                            Rule 1 */
++  { "*.example.com", "foo.example.com", TRUE }, /* RFC 6125 s. 6.4.3 Rule 2 */
++  { "*.example.com", "bar.foo.example.com", FALSE }, /* Rule 2 */
++  { "*.example.com", "example.com", FALSE }, /* Rule 2 */
++  { "*.example.com", ".example.com", FALSE }, /* RFC doesn't say what to do
++                                                 here and a leading period on
++                                                 a hostname doesn't make sense
++                                                 so we'll just reject this. */
++  { "*", "foo.example.com", FALSE }, /* wildcard must be left-most label,
++                                        implies that there must be more than
++                                        one label. */
++  { "*", "example.com", FALSE },
++  { "*", "com", FALSE },
++  { "*.example.com", "foo.example.net", FALSE }, /* difference in literal text
++                                                    with a wildcard. */
++  { "*.com", "example.com", TRUE }, /* See Errata ID 3090 for RFC 6125,
++                                       probably shouldn't allow this but
++                                       we do for now. */
++  { "*.", "example.com", FALSE }, /* test some dubious 2 character wildcard
++                                     patterns */
++  { "*.", "example.", TRUE }, /* This one feels questionable */
++  { "*.", "example", FALSE },
++  { "*.", ".", FALSE },
++  { "a", "a", TRUE }, /* check that single letter exact matches work */
++  { "a", "b", FALSE }, /* and single letter not matches shouldn't */
++  { "*.*.com", "foo.example.com", FALSE }, /* unsupported wildcards */
++  { "*.*.com", "example.com", FALSE },
++  { "**.example.com", "foo.example.com", FALSE },
++  { "**.example.com", "example.com", FALSE },
++  { "f*.example.com", "foo.example.com", FALSE },
++  { "f*.example.com", "bar.example.com", FALSE },
++  { "*o.example.com", "foo.example.com", FALSE },
++  { "*o.example.com", "bar.example.com", FALSE },
++  { "f*o.example.com", "foo.example.com", FALSE },
++  { "f*o.example.com", "bar.example.com", FALSE },
++  { "foo.e*.com", "foo.example.com", FALSE },
++  { "foo.*e.com", "foo.example.com", FALSE },
++  { "foo.e*e.com", "foo.example.com", FALSE },
++  { "foo.example.com", "foo.example.com.", TRUE }, /* trailing dot */
++  { "*.example.com", "foo.example.com.", TRUE },
++  { "foo", "foo.", TRUE },
++  { "foo.example.com.", "foo.example.com", FALSE },
++  { "*.example.com.", "foo.example.com", FALSE },
++  { "foo.", "foo", FALSE },
++  { "foo.example.com", "foo.example.com..", FALSE },
++  { "*.example.com", "foo.example.com..", FALSE },
++  { "foo", "foo..", FALSE },
++  { "foo.example.com..", "foo.example.com", FALSE },
++  { "*.example.com..", "foo.example.com", FALSE },
++  { "foo..", "foo", FALSE },
++  { NULL }
++};
++
++static svn_error_t *
++test_cert_match_dns_identity(apr_pool_t *pool)
++{
++  return run_cert_match_dns_tests(cert_match_dns_tests, pool);
++}
++
++/* This test table implements results that should happen if we supported
++ * RFC 6125 s. 6.4.3 Rule 3.  We don't so it's expected to fail for now. */
++static struct cert_match_dns_test rule3_tests[] = {
++  { "baz*.example.net", "baz1.example.net", TRUE },
++  { "*baz.example.net", "foobaz.example.net", TRUE },
++  { "b*z.example.net", "buuz.example.net", TRUE },
++  { "b*z.example.net", "bz.example.net", FALSE }, /* presume wildcard can't
++                                                     match nothing */
++  { "baz*.example.net", "baz.example.net", FALSE },
++  { "*baz.example.net", "baz.example.net", FALSE },
++  { "b*z.example.net", "buuzuuz.example.net", TRUE }, /* presume wildcard
++                                                         should be greedy */
++  { NULL }
++};
++
++static svn_error_t *
++test_rule3(apr_pool_t *pool)
++{
++  return run_cert_match_dns_tests(rule3_tests, pool);
++}
++
+ 
+ /* The test table.  */
+ 
+@@ -2812,5 +2952,9 @@ struct svn_test_descriptor_t test_funcs[] =
+                    "test svn_fspath__dirname/basename/split"),
+     SVN_TEST_PASS2(test_fspath_get_longest_ancestor,
+                    "test svn_fspath__get_longest_ancestor"),
++    SVN_TEST_PASS2(test_cert_match_dns_identity,
++                   "test svn_cert__match_dns_identity"),
++    SVN_TEST_XFAIL2(test_rule3,
++                    "test match with RFC 6125 s. 6.4.3 Rule 3"),
+     SVN_TEST_NULL
+   };
+]]]

Propchange: subversion/site/publish/security/CVE-2014-3522-advisory.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/site/publish/security/CVE-2014-3522-advisory.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: subversion/site/publish/security/CVE-2014-3528-advisory.txt
URL: http://svn.apache.org/viewvc/subversion/site/publish/security/CVE-2014-3528-advisory.txt?rev=1617311&view=auto
==============================================================================
--- subversion/site/publish/security/CVE-2014-3528-advisory.txt (added)
+++ subversion/site/publish/security/CVE-2014-3528-advisory.txt Mon Aug 11 16:01:25 2014
@@ -0,0 +1,151 @@
+  Credentials cached with Subversion may be sent to the wrong server.
+
+Summary:
+========
+
+  Subversion's credentials cache uses a MD5 hash in order to index and then
+  lookup cached credentials.  MD5 is subject to hash collisions and as such
+  it may be possible to engineer a server to get Subversion to send it
+  credentials that have been cached for a different server.  This can lead to
+  the leaking of these credentials to a 3rd party.
+
+Known vulnerable:
+=================
+
+  Subversion clients 1.0.0 through 1.7.17 (inclusive)
+  Subversion clients 1.8.0 through 1.8.9 (inclusive)
+
+Known fixed:
+============
+
+  Subversion 1.7.18
+  Subversion 1.8.10
+
+Details:
+========
+
+  Subversion stores cached credentials by an MD5 hash based on the URL and
+  the authentication realm of the server the credentials are cached for.  MD5
+  has been shown to be subject to chosen plaintext hash collisions.  This
+  means it may be possible to generate an authentication realm which results
+  in the same MD5 hash for a different URL.
+
+  Subversion supports storage of the credentials in a variety of ways (e.g.
+  Windows Crypto API, KWallet, Gnome-Keyring, and the OS X Keychain) as well
+  as its own built in storage.  This vulnerability applies to all of them
+  since the same hash key is used to store the credentials in all of them.
+
+Severity:
+=========
+
+  CVSSv2 Base Score: 4.0
+  CVSSv2 Base Vector: AV:N/AC:H/Au:N/C:P/I:P/A:N
+
+  We consider this to be a very low risk vulnerability.  Exploiting this
+  vulnerability in practice will be very difficult.  Calculating such a
+  collision with the current public known techniques for producing an MD5
+  collision (e.g chosen prefix attacks) requires control of the authentication
+  realm on the real server the credentials are for.  Typically if you have
+  access to modify the authentication realm you already have more access than
+  the credentials can gain you or can log credentials in other less visible
+  ways.
+
+  However, it is possible that other techniques are unknown to the public or
+  will become known in the future that allow MD5 pre-image attacks such that
+  the attacker does not need to change the authentication realm on the real
+  server.
+
+  Even once an attacker has calculated an authentication realm for the server
+  they wish to steal credentials for they have to get the Subversion client
+  to connect to their server with this configuration in place.  This would
+  likely require some social engineering to get a user to do this.  However,
+  there would be nothing to indicate to the user that such a situation
+  was occurring.
+
+Recommendations:
+================
+
+  We recommend all users to upgrade to Subversion 1.8.10.  Users of
+  Subversion 1.7.x or 1.8.x who are unable to upgrade may apply the
+  included patch.
+
+  New Subversion packages can be found at:
+  http://subversion.apache.org/packages.html
+
+  Users can avoid this problem by disabling authentication credential
+  storage via the 'store-auth-creds' setting in the '[global]' section
+  of the Subversion servers configuration file.  See the SVN Book for
+  details on where to find these configuration files:
+    http://svnbook.red-bean.com/en/1.7/svn.advanced.confarea.html
+
+References:
+===========
+
+  CVE-2014-3528  (Subversion)
+
+Reported by:
+============
+
+  Bert Huijben, CollabNet
+
+Patches:
+========
+
+  Patch against 1.7.17:
+
+[[[
+Index: subversion/libsvn_subr/config_auth.c
+===================================================================
+--- subversion/libsvn_subr/config_auth.c        (revision 1615184)
++++ subversion/libsvn_subr/config_auth.c        (working copy)
+@@ -90,6 +90,7 @@ svn_config_read_auth_data(apr_hash_t **hash,
+   if (kind == svn_node_file)
+     {
+       svn_stream_t *stream;
++      svn_string_t *stored_realm;
+
+       SVN_ERR_W(svn_stream_open_readonly(&stream, auth_path, pool, pool),
+                 _("Unable to open auth file for reading"));
+@@ -100,6 +101,12 @@ svn_config_read_auth_data(apr_hash_t **hash,
+                 apr_psprintf(pool, _("Error parsing '%s'"),
+                              svn_dirent_local_style(auth_path, pool)));
+
++      stored_realm = apr_hash_get(*hash, SVN_CONFIG_REALMSTRING_KEY,
++                                  APR_HASH_KEY_STRING);
++
++      if (!stored_realm || strcmp(stored_realm->data, realmstring) != 0)
++        *hash = NULL; /* Hash collision, or somebody tampering with storage */
++
+       SVN_ERR(svn_stream_close(stream));
+     }
+
+]]]
+
+  Patch against 1.8.9:
+
+[[[
+Index: subversion/libsvn_subr/config_auth.c
+===================================================================
+--- subversion/libsvn_subr/config_auth.c        (revision 1605943)
++++ subversion/libsvn_subr/config_auth.c        (revision 1605944)
+@@ -94,6 +94,7 @@ svn_config_read_auth_data(apr_hash_t **hash,
+   if (kind == svn_node_file)
+     {
+       svn_stream_t *stream;
++      svn_string_t *stored_realm;
+
+       SVN_ERR_W(svn_stream_open_readonly(&stream, auth_path, pool, pool),
+                 _("Unable to open auth file for reading"));
+@@ -104,6 +105,11 @@ svn_config_read_auth_data(apr_hash_t **hash,
+                 apr_psprintf(pool, _("Error parsing '%s'"),
+                              svn_dirent_local_style(auth_path, pool)));
+
++      stored_realm = svn_hash_gets(*hash, SVN_CONFIG_REALMSTRING_KEY);
++
++      if (!stored_realm || strcmp(stored_realm->data, realmstring) != 0)
++        *hash = NULL; /* Hash collision, or somebody tampering with storage */
++
+       SVN_ERR(svn_stream_close(stream));
+     }
+
+]]]

Propchange: subversion/site/publish/security/CVE-2014-3528-advisory.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/site/publish/security/CVE-2014-3528-advisory.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: subversion/site/publish/security/index.html
URL: http://svn.apache.org/viewvc/subversion/site/publish/security/index.html?rev=1617311&r1=1617310&r2=1617311&view=diff
==============================================================================
--- subversion/site/publish/security/index.html (original)
+++ subversion/site/publish/security/index.html Mon Aug 11 16:01:25 2014
@@ -195,6 +195,16 @@ Subversion project.</p>
 <td>1.3.0-1.7.14 and 1.8.0-1.8.5</td>
 <td>mod_dav_svn DoS vulnerability with SVNListParentPath</td>
 </tr>
+<tr>
+<td><a href="CVE-2014-3522-advisory.txt">CVE-2014-3522-advisory.txt</a></td>
+<td>1.4.0-1.7.17 and 1.8.0-1.8.9</td>
+<td>ra_serf improper validation of wildcards in SSL certs</td>
+</tr>
+<tr>
+<td><a href="CVE-2014-3528-advisory.txt">CVE-2014-3528-advisory.txt</a></td>
+<td>1.0.0-1.7.17 and 1.8.0-1.8.9</td>
+<td>credentials cached with svn may be sent to wrong server</td>
+</tr>
 </tbody>
 </table>
 



Mime
View raw message