[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