Commit c6acfbb3 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont
Browse files

tls: pass host name to handshake function, simplify

parent 75ffd9ea
......@@ -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 */
......
......@@ -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;
......@@ -322,15 +322,13 @@ static int gnutls_HandshakeAndValidate (vlc_tls_t *session)
goto error;
}
if (sys->hostname != NULL
&& !gnutls_x509_crt_check_hostname (cert, sys->hostname))
if (host != NULL && !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 +365,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 +381,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 +402,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 +459,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;
}
......
......@@ -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;
......
......@@ -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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment