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 */
struct vlc_tls_sys
{
gnutls_session_t session;
- char *hostname; /* XXX: client only */
bool handshaked;
};
* 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;
}
sys->handshaked = true;
+ (void) host;
return 0;
}
};
-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;
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:
{
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 */
};
gnutls_bye (sys->session, GNUTLS_SHUT_WR);
gnutls_deinit (sys->session);
- free (sys->hostname);
free (sys);
(void) crd;
}
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)
/* 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;
}
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;
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;
/*** 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);
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)