[vlc-commits] tls: pass host name to handshake function, simplify

Rémi Denis-Courmont git at videolan.org
Sun Sep 30 14:28:34 CEST 2012


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Sep 30 14:28:03 2012 +0300| [9a2909130565db414550adbf6820407b11bcfb4c] | committer: Rémi Denis-Courmont

tls: pass host name to handshake function, simplify

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=9a2909130565db414550adbf6820407b11bcfb4c
---

 include/vlc_tls.h     |    6 +++---
 modules/misc/gnutls.c |   31 ++++++++++---------------------
 src/network/httpd.c   |    4 ++--
 src/network/tls.c     |   27 ++++++++++-----------------
 4 files changed, 25 insertions(+), 43 deletions(-)

diff --git a/include/vlc_tls.h b/include/vlc_tls.h
index 7c7720c..e3f9e32 100644
--- a/include/vlc_tls.h
+++ b/include/vlc_tls.h
@@ -42,13 +42,13 @@ struct vlc_tls
     vlc_tls_sys_t *sys;
 
     struct virtual_socket_t sock;
-    int  (*handshake) (struct vlc_tls *);
+    int  (*handshake) (vlc_tls_t *, const char *host);
 };
 
 VLC_API vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *, int fd,
                                                 const char *host);
-vlc_tls_t *vlc_tls_ServerSessionCreate (vlc_tls_creds_t *, int fd);
-int vlc_tls_SessionHandshake (vlc_tls_t *);
+vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *, int fd, const char *host);
+int vlc_tls_SessionHandshake (vlc_tls_t *, const char *host);
 VLC_API void vlc_tls_SessionDelete (vlc_tls_t *);
 
 /* NOTE: It is assumed that a->sock.p_sys = a */
diff --git a/modules/misc/gnutls.c b/modules/misc/gnutls.c
index 3587307..a1169be 100644
--- a/modules/misc/gnutls.c
+++ b/modules/misc/gnutls.c
@@ -176,7 +176,6 @@ static int gnutls_Error (vlc_object_t *obj, int val)
 struct vlc_tls_sys
 {
     gnutls_session_t session;
-    char *hostname; /* XXX: client only */
     bool handshaked;
 };
 
@@ -214,7 +213,7 @@ static int gnutls_Recv (void *opaque, void *buf, size_t length)
  * 1 if more would-be blocking recv is needed,
  * 2 if more would-be blocking send is required.
  */
-static int gnutls_ContinueHandshake (vlc_tls_t *session)
+static int gnutls_ContinueHandshake (vlc_tls_t *session, const char *host)
 {
     vlc_tls_sys_t *sys = session->sys;
     int val;
@@ -236,6 +235,7 @@ static int gnutls_ContinueHandshake (vlc_tls_t *session)
     }
 
     sys->handshaked = true;
+    (void) host;
     return 0;
 }
 
@@ -263,11 +263,11 @@ static struct
 };
 
 
-static int gnutls_HandshakeAndValidate (vlc_tls_t *session)
+static int gnutls_HandshakeAndValidate (vlc_tls_t *session, const char *host)
 {
     vlc_tls_sys_t *sys = session->sys;
 
-    int val = gnutls_ContinueHandshake (session);
+    int val = gnutls_ContinueHandshake (session, host);
     if (val)
         return val;
 
@@ -298,6 +298,9 @@ static int gnutls_HandshakeAndValidate (vlc_tls_t *session)
     }
 
     /* certificate (host)name verification */
+    if (host == NULL)
+        return 0; // shortcut
+
     const gnutls_datum_t *data;
     data = gnutls_certificate_get_peers (sys->session, &(unsigned){0});
     if (data == NULL)
@@ -322,15 +325,13 @@ static int gnutls_HandshakeAndValidate (vlc_tls_t *session)
         goto error;
     }
 
-    if (sys->hostname != NULL
-     && !gnutls_x509_crt_check_hostname (cert, sys->hostname))
+    if (!gnutls_x509_crt_check_hostname (cert, host))
     {
-        msg_Err (session, "Certificate does not match \"%s\"", sys->hostname);
+        msg_Err (session, "Certificate does not match \"%s\"", host);
         goto error;
     }
 
     gnutls_x509_crt_deinit (cert);
-    msg_Dbg (session, "TLS/X.509 certificate verified");
     return 0;
 
 error:
@@ -367,7 +368,7 @@ struct vlc_tls_creds_sys
 {
     gnutls_certificate_credentials_t x509_cred;
     gnutls_dh_params_t dh_params; /* XXX: used for server only */
-    int (*handshake) (vlc_tls_t *); /* XXX: useful for server only */
+    int (*handshake) (vlc_tls_t *, const char *); /* XXX: useful for server only */
 };
 
 
@@ -383,7 +384,6 @@ static void gnutls_SessionClose (vlc_tls_creds_t *crd, vlc_tls_t *session)
         gnutls_bye (sys->session, GNUTLS_SHUT_WR);
     gnutls_deinit (sys->session);
 
-    free (sys->hostname);
     free (sys);
     (void) crd;
 }
@@ -405,7 +405,6 @@ static int gnutls_SessionOpen (vlc_tls_creds_t *crd, vlc_tls_t *session,
     session->sock.pf_recv = gnutls_Recv;
     session->handshake = crd->sys->handshake;
     sys->handshaked = false;
-    sys->hostname = NULL;
 
     int val = gnutls_init (&sys->session, type);
     if (val != 0)
@@ -463,22 +462,12 @@ static int gnutls_ClientSessionOpen (vlc_tls_creds_t *crd, vlc_tls_t *session,
     /* minimum DH prime bits */
     gnutls_dh_set_prime_bits (sys->session, 1024);
 
-    /* server name */
     if (likely(hostname != NULL))
-    {
         /* fill Server Name Indication */
         gnutls_server_name_set (sys->session, GNUTLS_NAME_DNS,
                                 hostname, strlen (hostname));
-        /* keep hostname to match CNAME after handshake */
-        sys->hostname = strdup (hostname);
-        if (unlikely(sys->hostname == NULL))
-            goto error;
-    }
 
     return VLC_SUCCESS;
-error:
-    gnutls_SessionClose (crd, session);
-    return VLC_EGENERIC;
 }
 
 
diff --git a/src/network/httpd.c b/src/network/httpd.c
index e90dc98..5b97ea9 100644
--- a/src/network/httpd.c
+++ b/src/network/httpd.c
@@ -1880,7 +1880,7 @@ static void httpd_ClientSend( httpd_client_t *cl )
 
 static void httpd_ClientTlsHandshake( httpd_client_t *cl )
 {
-    switch( vlc_tls_SessionHandshake( cl->p_tls ) )
+    switch( vlc_tls_SessionHandshake( cl->p_tls, NULL ) )
     {
         case 0:
             cl->i_state = HTTPD_CLIENT_RECEIVING;
@@ -2312,7 +2312,7 @@ static void* httpd_HostThread( void *data )
             vlc_tls_t *p_tls;
 
             if( host->p_tls != NULL )
-                p_tls = vlc_tls_ServerSessionCreate( host->p_tls, fd );
+                p_tls = vlc_tls_SessionCreate( host->p_tls, fd, NULL );
             else
                 p_tls = NULL;
 
diff --git a/src/network/tls.c b/src/network/tls.c
index 1ffc465..97e5556 100644
--- a/src/network/tls.c
+++ b/src/network/tls.c
@@ -160,12 +160,12 @@ int vlc_tls_ServerAddCRL (vlc_tls_creds_t *srv, const char *path)
 
 /*** TLS  session ***/
 
-static vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *crd, int fd,
-                                         const char *hostname)
+vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *crd, int fd,
+                                  const char *host)
 {
     vlc_tls_t *session = vlc_custom_create (crd, sizeof (*session),
                                             "tls session");
-    int val = crd->open (crd, session, fd, hostname);
+    int val = crd->open (crd, session, fd, host);
     if (val == VLC_SUCCESS)
         return session;
     vlc_object_release (session);
@@ -180,38 +180,31 @@ void vlc_tls_SessionDelete (vlc_tls_t *session)
     vlc_object_release (session);
 }
 
-vlc_tls_t *vlc_tls_ServerSessionCreate (vlc_tls_creds_t *crd, int fd)
+int vlc_tls_SessionHandshake (vlc_tls_t *session, const char *host)
 {
-    return vlc_tls_SessionCreate (crd, fd, NULL);
-}
-
-int vlc_tls_SessionHandshake (vlc_tls_t *session)
-{
-    return session->handshake (session);
+    return session->handshake (session, host);
 }
 
 /**
  * Performs client side of TLS handshake through a connected socket, and
  * establishes a secure channel. This is a blocking network operation.
  *
- * @param fd stream socket through which to establish the secure communication
- * layer.
+ * @param fd socket through which to establish the secure channel
  * @param hostname expected server name, used both as Server Name Indication
- *                 and as expected Common Name of the peer's certificate.
+ *                 and as expected Common Name of the peer certificate
  *
  * @return NULL on error.
  **/
 vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
-                                        const char *hostname)
+                                        const char *host)
 {
-    vlc_tls_t *session = vlc_tls_SessionCreate (crd, fd, hostname);
+    vlc_tls_t *session = vlc_tls_SessionCreate (crd, fd, host);
     if (session == NULL)
         return NULL;
 
-    /* TODO: do this directly in the TLS plugin */
     int val;
     do
-        val = session->handshake (session);
+        val = vlc_tls_SessionHandshake (session, host);
     while (val > 0);
 
     if (val != 0)



More information about the vlc-commits mailing list