int (*handshake) (struct vlc_tls *);
};
-VLC_API vlc_tls_t *vlc_tls_ClientCreate (vlc_object_t *, int fd,
- const char *hostname);
-VLC_API void vlc_tls_ClientDelete (vlc_tls_t *);
+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_ServerSessionHandshake (vlc_tls_t *);
+VLC_API void vlc_tls_SessionDelete (vlc_tls_t *);
+#define vlc_tls_ServerSessionDelete vlc_tls_SessionDelete
/* NOTE: It is assumed that a->sock.p_sys = a */
# define tls_Send( a, b, c ) (((vlc_tls_t *)a)->sock.pf_send (a, b, c))
void (*close) (vlc_tls_creds_t *, vlc_tls_t *);
};
+VLC_API vlc_tls_creds_t *vlc_tls_ClientCreate (vlc_object_t *);
vlc_tls_creds_t *vlc_tls_ServerCreate (vlc_object_t *,
const char *cert, const char *key);
-void vlc_tls_Delete (vlc_tls_creds_t *);
+VLC_API void vlc_tls_Delete (vlc_tls_creds_t *);
#define vlc_tls_ServerDelete vlc_tls_Delete
int vlc_tls_ServerAddCA (vlc_tls_creds_t *srv, const char *path);
int vlc_tls_ServerAddCRL (vlc_tls_creds_t *srv, const char *path);
-vlc_tls_t *vlc_tls_ServerSessionCreate (vlc_tls_creds_t *, int fd);
-int vlc_tls_ServerSessionHandshake (vlc_tls_t *);
-void vlc_tls_SessionDelete (vlc_tls_t *);
-#define vlc_tls_ServerSessionDelete vlc_tls_SessionDelete
-
#endif
{
int fd;
bool b_error;
- vlc_tls_t *p_tls;
+ vlc_tls_creds_t *p_creds;
+ vlc_tls_t *p_tls;
v_socket_t *p_vs;
/* From uri */
char *psz_location;
bool b_mms;
bool b_icecast;
- bool b_ssl;
#ifdef HAVE_ZLIB_H
bool b_compressed;
struct
p_sys->psz_user_agent = NULL;
p_sys->psz_referrer = NULL;
p_sys->b_pace_control = true;
- p_sys->b_ssl = false;
#ifdef HAVE_ZLIB_H
p_sys->b_compressed = false;
/* 15 is the max windowBits, +32 to enable optional gzip decoding */
if( !strncmp( psz_access, "https", 5 ) )
{
/* HTTP over SSL */
- p_sys->b_ssl = true;
+ p_sys->p_creds = vlc_tls_ClientCreate( p_this );
+ if( p_sys->p_creds == NULL )
+ goto error;
if( p_sys->url.i_port <= 0 )
p_sys->url.i_port = 443;
}
free( p_sys->psz_referrer );
Disconnect( p_access );
+ vlc_tls_Delete( p_sys->p_creds );
cookies = p_sys->cookies;
#ifdef HAVE_ZLIB_H
inflateEnd( &p_sys->inflate.stream );
free( p_sys->psz_referrer );
Disconnect( p_access );
+ vlc_tls_Delete( p_sys->p_creds );
if( p_sys->cookies )
{
free( p_sys->psz_referrer );
Disconnect( p_access );
+ vlc_tls_Delete( p_sys->p_creds );
if( p_sys->cookies )
{
setsockopt (p_sys->fd, SOL_SOCKET, SO_KEEPALIVE, &(int){ 1 }, sizeof (int));
/* Initialize TLS/SSL session */
- if( p_sys->b_ssl )
+ if( p_sys->p_creds != NULL )
{
/* CONNECT to establish TLS tunnel through HTTP proxy */
if( p_sys->b_proxy )
}
/* TLS/SSL handshake */
- p_sys->p_tls = vlc_tls_ClientCreate( VLC_OBJECT(p_access), p_sys->fd,
- p_sys->url.psz_host );
+ p_sys->p_tls = vlc_tls_ClientSessionCreate( p_sys->p_creds, p_sys->fd,
+ p_sys->url.psz_host );
if( p_sys->p_tls == NULL )
{
msg_Err( p_access, "cannot establish HTTP/TLS session" );
* handle it as everyone does. */
if( p[0] == '/' )
{
- const char *psz_http_ext = p_sys->b_ssl ? "s" : "" ;
+ const char *psz_http_ext = p_sys->p_tls ? "s" : "" ;
- if( p_sys->url.i_port == ( p_sys->b_ssl ? 443 : 80 ) )
+ if( p_sys->url.i_port == ( p_sys->p_tls ? 443 : 80 ) )
{
if( asprintf(&psz_new_loc, "http%s://%s%s", psz_http_ext,
p_sys->url.psz_host, p) < 0 )
if( p_sys->p_tls != NULL)
{
- vlc_tls_ClientDelete( p_sys->p_tls );
+ vlc_tls_SessionDelete( p_sys->p_tls );
p_sys->p_tls = NULL;
p_sys->p_vs = NULL;
}
subpicture_region_Delete
subpicture_region_New
vlc_tls_ClientCreate
-vlc_tls_ClientDelete
+vlc_tls_Delete
+vlc_tls_ClientSessionCreate
+vlc_tls_SessionDelete
ToCharset
update_Check
update_Delete
return NULL;
}
- msg_Dbg (srv, "TLS server plugin initialized");
return srv;
}
+/**
+ * Allocates TLS credentials for a client.
+ * Credentials can be cached and reused across multiple TLS sessions.
+ *
+ * @return TLS credentials object, or NULL on error.
+ **/
+vlc_tls_creds_t *vlc_tls_ClientCreate (vlc_object_t *obj)
+{
+ vlc_tls_creds_t *crd = vlc_custom_create (obj, sizeof (*crd),
+ "tls client");
+ if (unlikely(crd == NULL))
+ return NULL;
+
+ crd->module = vlc_module_load (crd, "tls client", NULL, false,
+ tls_client_load, crd);
+ if (crd->module == NULL)
+ {
+ msg_Err (crd, "TLS client plugin not available");
+ vlc_object_release (crd);
+ return NULL;
+ }
+
+ return crd;
+}
/**
- * Releases data allocated with vlc_tls_ServerCreate().
+ * Releases data allocated with vlc_tls_ClientCreate() or
+ * vlc_tls_ServerCreate().
* @param srv TLS server object to be destroyed, or NULL
*/
void vlc_tls_Delete (vlc_tls_creds_t *crd)
}
/**
- * Allocates a client's TLS credentials and shakes hands through the network.
- * This is a blocking network operation.
+ * 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 psz_hostname Server Name Indication to pass to the server, or NULL.
+ * @param hostname expected server name, used both as Server Name Indication
+ * and as expected Common Name of the peer's certificate.
*
* @return NULL on error.
**/
-vlc_tls_t *
-vlc_tls_ClientCreate (vlc_object_t *obj, int fd, const char *hostname)
+vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
+ const char *hostname)
{
- vlc_tls_creds_t *crd = vlc_custom_create (obj, sizeof (*crd),
- "tls client");
- if (unlikely(crd == NULL))
- return NULL;
-
- crd->module = vlc_module_load (crd, "tls client", NULL, false,
- tls_client_load, crd);
- if (crd->module == NULL)
- {
- msg_Err (crd, "TLS client plugin not available");
- vlc_object_release (crd);
- return NULL;
- }
-
- /* TODO: separate credentials and sessions, so we do not reload the
- * credentials every time the HTTP access seeks... */
vlc_tls_t *session = vlc_tls_SessionCreate (crd, fd, hostname);
if (session == NULL)
- goto error;
+ return NULL;
/* TODO: do this directly in the TLS plugin */
int val;
{
msg_Err (session, "TLS client session handshake error");
vlc_tls_SessionDelete (session);
- goto error;
+ session = NULL;
}
- msg_Dbg (session, "TLS client session initialized");
return session;
-error:
- vlc_tls_Delete (crd);
- return NULL;
-}
-
-
-/**
- * Releases data allocated with vlc_tls_ClientCreate().
- * It is your job to close the underlying socket.
- */
-void vlc_tls_ClientDelete (vlc_tls_t *session)
-{
- if (session == NULL)
- return;
-
- vlc_tls_creds_t *cl = (vlc_tls_creds_t *)(session->p_parent);
-
- vlc_tls_SessionDelete (session);
- vlc_tls_Delete (cl);
}