Author: jerenkrantz
Date: Sat Jun 25 17:23:28 2011
New Revision: 1139573
URL: http://svn.apache.org/viewvc?rev=1139573&view=rev
Log:
Serf issue 59: Allow subjectAltName fields to match our host.
(And, minor fixup for SNI capability check in prior revision.)
* subversion/libsvn_ra_serf/util.c
(ssl_server_cert): Fetch subjectAltName from certificate and try to validate
against that.
(conn_setup): Make check for SNI based on serf version.
Modified:
subversion/trunk/subversion/libsvn_ra_serf/util.c
Modified: subversion/trunk/subversion/libsvn_ra_serf/util.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/util.c?rev=1139573&r1=1139572&r2=1139573&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/util.c Sat Jun 25 17:23:28 2011
@@ -197,7 +197,9 @@ ssl_server_cert(void *baton, int failure
const char *realmstring;
apr_uint32_t svn_failures;
apr_hash_t *issuer, *subject, *serf_cert;
+ apr_array_header_t *san;
void *creds;
+ int found_matching_hostname = 0;
/* Implicitly approve any non-server certs. */
if (serf_ssl_cert_depth(cert) > 0)
@@ -211,6 +213,7 @@ ssl_server_cert(void *baton, int failure
serf_cert = serf_ssl_cert_certificate(cert, scratch_pool);
cert_info.hostname = apr_hash_get(subject, "CN", APR_HASH_KEY_STRING);
+ san = apr_hash_get(serf_cert, "subjectAltName", APR_HASH_KEY_STRING);
cert_info.fingerprint = apr_hash_get(serf_cert, "sha1", APR_HASH_KEY_STRING);
if (! cert_info.fingerprint)
cert_info.fingerprint = apr_pstrdup(scratch_pool, "<unknown>");
@@ -227,8 +230,22 @@ ssl_server_cert(void *baton, int failure
svn_failures = ssl_convert_serf_failures(failures);
+ /* Try to find matching server name via subjectAltName first... */
+ if (san) {
+ int i;
+ for (i = 0; i < san->nelts; i++) {
+ char *s = APR_ARRAY_IDX(san, i, char*);
+ if (apr_fnmatch(s, conn->hostinfo,
+ APR_FNM_PERIOD) == APR_SUCCESS) {
+ found_matching_hostname = 1;
+ cert_info.hostname = s;
+ break;
+ }
+ }
+ }
+
/* Match server certificate CN with the hostname of the server */
- if (cert_info.hostname)
+ if (!found_matching_hostname && cert_info.hostname)
{
if (apr_fnmatch(cert_info.hostname, conn->hostinfo,
APR_FNM_PERIOD) == APR_FNM_NOMATCH)
@@ -343,7 +360,7 @@ conn_setup(apr_socket_t *sock,
{
conn->ssl_context = serf_bucket_ssl_encrypt_context_get(*read_bkt);
-#ifdef serf_ssl_set_hostname
+#if SERF_VERSION_AT_LEAST(1,0,0)
serf_ssl_set_hostname(conn->ssl_context, conn->hostinfo);
#endif