You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by jo...@apache.org on 2014/08/27 18:11:18 UTC

svn commit: r1620926 - in /httpd/httpd/trunk: CHANGES modules/ssl/ssl_engine_vars.c

Author: jorton
Date: Wed Aug 27 16:11:17 2014
New Revision: 1620926

URL: http://svn.apache.org/r1620926
Log:
Add API to support TLS channel bindings with mod_ssl.

* modules/ssl/mod_ssl.h: Define ssl_get_tls_cb.

* modules/ssl/ssl_engine_vars.c (ssl_get_tls_cb): New function.

Submitted by: Simo Sorce <simo redhat.com>

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1620926&r1=1620925&r2=1620926&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Wed Aug 27 16:11:17 2014
@@ -1,5 +1,8 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
+  
+  *) mod_ssl: Add optional function "ssl_get_tls_cb" to allow support
+     for channel bindings.  [Simo Sorce <simo redhat.com>]
 
   *) mod_cache: Avoid sending 304 responses during failed revalidations
      PR56881. [Eric Covener]

Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c?rev=1620926&r1=1620925&r2=1620926&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_vars.c Wed Aug 27 16:11:17 2014
@@ -59,6 +59,75 @@ static int ssl_is_https(conn_rec *c)
     return sslconn && sslconn->ssl;
 }
 
+/* SSLv3 uses 36 bytes for Finishd messages, TLS1.0 12 bytes,
+ * So tls-unique is max 36 bytes, however with tls-server-end-point,
+ * the CB data is the certificate signature, so we use the maximum
+ * hash size known to the library (currently 64).
+ * */
+#define TLS_CB_MAX EVP_MAX_MD_SIZE
+#define TLS_UNIQUE_PREFIX "tls-unique:"
+#define TLS_SERVER_END_POINT_PREFIX "tls-server-end-point:"
+
+static apr_status_t ssl_get_tls_cb(apr_pool_t *p, conn_rec *c, const char *type,
+                                   unsigned char **buf, apr_size_t *size)
+{
+    SSLConnRec *sslconn = myConnConfig(c);
+    const char *prefix;
+    apr_size_t preflen;
+    const unsigned char *data;
+    unsigned char cb[TLS_CB_MAX], *retbuf;
+    unsigned int l = 0;
+    X509 *x = NULL;
+
+    if (!sslconn || !sslconn->ssl) {
+        return APR_EGENERAL;
+    }
+    if (strcEQ(type, "SERVER_TLS_UNIQUE")) {
+        l = SSL_get_peer_finished(sslconn->ssl, cb, TLS_CB_MAX);
+    }
+    else if (strcEQ(type, "CLIENT_TLS_UNIQUE")) {
+        l = SSL_get_finished(sslconn->ssl, cb, TLS_CB_MAX);
+    }
+    else if (strcEQ(type, "SERVER_TLS_SERVER_END_POINT")) {
+        x = SSL_get_certificate(sslconn->ssl);
+    }
+    else if (strcEQ(type, "CLIENT_TLS_SERVER_END_POINT")) {
+        x = SSL_get_peer_certificate(sslconn->ssl);
+    }
+    if (l > 0) {
+        preflen = sizeof(TLS_UNIQUE_PREFIX) -1;
+        prefix = TLS_UNIQUE_PREFIX;
+        data = cb;
+    } 
+    else if (x != NULL) {
+        const EVP_MD *md;
+
+        md = EVP_get_digestbynid(OBJ_obj2nid(x->sig_alg->algorithm));
+        /* Override digest as specified by RFC 5929 section 4.1. */
+        if (md == NULL || md == EVP_md5() || md == EVP_sha1()) {
+            md = EVP_sha256();
+        }
+        if (!X509_digest(x, md, cb, &l)) {
+            return APR_EGENERAL;
+        }
+
+        preflen = sizeof(TLS_SERVER_END_POINT_PREFIX) - 1;
+        prefix = TLS_SERVER_END_POINT_PREFIX;
+        data = cb;
+    } 
+    else {
+        return APR_EGENERAL;
+    }
+
+    retbuf = apr_palloc(p, preflen + l);
+    memcpy(retbuf, prefix, preflen);
+    memcpy(&retbuf[preflen], data, l);
+    *size = preflen + l;
+    *buf = retbuf;
+
+    return APR_SUCCESS;
+}
+
 static const char var_interface[] = "mod_ssl/" AP_SERVER_BASEREVISION;
 static char var_library_interface[] = SSL_LIBRARY_TEXT;
 static char *var_library = NULL;
@@ -107,6 +176,7 @@ void ssl_var_register(apr_pool_t *p)
     char *cp, *cp2;
 
     APR_REGISTER_OPTIONAL_FN(ssl_is_https);
+    APR_REGISTER_OPTIONAL_FN(ssl_get_tls_cb);
     APR_REGISTER_OPTIONAL_FN(ssl_var_lookup);
     APR_REGISTER_OPTIONAL_FN(ssl_ext_list);