1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright © 2004-2007 Rémi Denis-Courmont
7 * Authors: Rémi Denis-Courmont <rem # videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
26 * libvlc interface to the Transport Layer Security (TLS) plugins.
35 tls_Init( vlc_object_t *p_this )
40 var_Create( p_this->p_libvlc_global, "tls_mutex", VLC_VAR_MUTEX );
41 var_Get( p_this->p_libvlc_global, "tls_mutex", &lockval );
42 vlc_mutex_lock( lockval.p_address );
44 p_tls = vlc_object_find( p_this, VLC_OBJECT_TLS, FIND_ANYWHERE );
48 p_tls = vlc_object_create( p_this, VLC_OBJECT_TLS );
51 vlc_mutex_unlock( lockval.p_address );
55 p_tls->p_module = module_Need( p_tls, "tls", 0, 0 );
56 if( p_tls->p_module == NULL )
58 msg_Err( p_tls, "TLS/SSL provider not found" );
59 vlc_mutex_unlock( lockval.p_address );
60 vlc_object_destroy( p_tls );
64 vlc_object_attach( p_tls, p_this->p_libvlc );
65 vlc_object_yield( p_tls );
66 msg_Dbg( p_tls, "TLS/SSL provider initialized" );
68 vlc_mutex_unlock( lockval.p_address );
74 tls_Deinit( tls_t *p_tls )
79 var_Get( p_tls->p_libvlc_global, "tls_mutex", &lockval );
80 vlc_mutex_lock( lockval.p_address );
82 vlc_object_release( p_tls );
84 i = p_tls->i_refcount;
86 vlc_object_detach( p_tls );
88 vlc_mutex_unlock( lockval.p_address );
92 module_Unneed( p_tls, p_tls->p_module );
93 msg_Dbg( p_tls, "TLS/SSL provider deinitialized" );
94 vlc_object_destroy( p_tls );
99 * Allocates a whole server's TLS credentials.
101 * @param psz_cert required (Unicode) path to an x509 certificate.
102 * @param psz_key required (Unicode) path to the PKCS private key for
105 * @return NULL on error.
108 tls_ServerCreate( vlc_object_t *p_this, const char *psz_cert,
109 const char *psz_key )
112 tls_server_t *p_server;
114 p_tls = tls_Init( p_this );
118 if( psz_key == NULL )
121 p_server = p_tls->pf_server_create( p_tls, psz_cert, psz_key );
122 if( p_server != NULL )
124 msg_Dbg( p_tls, "TLS/SSL server initialized" );
128 msg_Err( p_tls, "TLS/SSL server error" );
136 * Releases data allocated with tls_ServerCreate.
139 tls_ServerDelete( tls_server_t *p_server )
141 tls_t *p_tls = (tls_t *)p_server->p_parent;
143 p_server->pf_delete( p_server );
150 * Allocates a client's TLS credentials and shakes hands through the network.
151 * This is a blocking network operation.
153 * @param fd stream socket through which to establish the secure communication
155 * @param psz_hostname Server Name Indication to pass to the server, or NULL.
157 * @return NULL on error.
160 tls_ClientCreate( vlc_object_t *p_this, int fd, const char *psz_hostname )
163 tls_session_t *p_session;
165 p_tls = tls_Init( p_this );
169 p_session = p_tls->pf_client_create( p_tls );
170 if( p_session != NULL )
174 for( i_val = tls_ClientSessionHandshake( p_session, fd,
177 i_val = tls_SessionContinueHandshake( p_session ) );
181 msg_Dbg( p_this, "TLS/SSL client initialized" );
184 msg_Err( p_this, "TLS/SSL session handshake error" );
187 msg_Err( p_this, "TLS/SSL client error" );
195 * Releases data allocated with tls_ClientCreate.
196 * It is your job to close the underlying socket.
199 tls_ClientDelete( tls_session_t *p_session )
201 tls_t *p_tls = (tls_t *)p_session->p_parent;
203 p_session->pf_close( p_session );