]> git.sesse.net Git - vlc/blob - src/network/tls.c
Doxygenization
[vlc] / src / network / tls.c
1 /*****************************************************************************
2  * tls.c
3  *****************************************************************************
4  * Copyright (C) 2004-2005 the VideoLAN team
5  * $Id$
6  *
7  * Authors: RĂ©mi Denis-Courmont <rem # videolan.org>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 /**
25  * @file
26  * libvlc interface to the Transport Layer Security (TLS) plugins.
27  */
28
29 #include <stdlib.h>
30 #include <vlc/vlc.h>
31
32 #include "vlc_tls.h"
33
34 static tls_t *
35 tls_Init( vlc_object_t *p_this )
36 {
37     tls_t *p_tls;
38     vlc_value_t lockval;
39
40     var_Create( p_this->p_libvlc, "tls_mutex", VLC_VAR_MUTEX );
41     var_Get( p_this->p_libvlc, "tls_mutex", &lockval );
42     vlc_mutex_lock( lockval.p_address );
43
44     p_tls = vlc_object_find( p_this, VLC_OBJECT_TLS, FIND_ANYWHERE );
45
46     if( p_tls == NULL )
47     {
48         p_tls = vlc_object_create( p_this, VLC_OBJECT_TLS );
49         if( p_tls == NULL )
50         {
51             vlc_mutex_unlock( lockval.p_address );
52             return NULL;
53         }
54
55         p_tls->p_module = module_Need( p_tls, "tls", 0, 0 );
56         if( p_tls->p_module == NULL )
57         {
58             msg_Err( p_tls, "TLS/SSL provider not found" );
59             vlc_mutex_unlock( lockval.p_address );
60             vlc_object_destroy( p_tls );
61             return NULL;
62         }
63
64         vlc_object_attach( p_tls, p_this->p_vlc );
65         vlc_object_yield( p_tls );
66         msg_Dbg( p_tls, "TLS/SSL provider initialized" );
67     }
68     vlc_mutex_unlock( lockval.p_address );
69
70     return p_tls;
71 }
72
73 static void
74 tls_Deinit( tls_t *p_tls )
75 {
76     int i;
77     vlc_value_t lockval;
78
79     var_Get( p_tls->p_libvlc, "tls_mutex", &lockval );
80     vlc_mutex_lock( lockval.p_address );
81
82     vlc_object_release( p_tls );
83     
84     i = p_tls->i_refcount;
85     if( i == 0 )
86         vlc_object_detach( p_tls );
87
88     vlc_mutex_unlock( lockval.p_address );
89
90     if( i == 0 )
91     {
92         module_Unneed( p_tls, p_tls->p_module );
93         msg_Dbg( p_tls, "TLS/SSL provider deinitialized" );
94         vlc_object_destroy( p_tls );
95     }
96 }
97
98 /**
99  * Allocates a whole server's TLS credentials.
100  *
101  * @param psz_cert required (Unicode) path to an x509 certificate.
102  * @param psz_key required (Unicode) path to the PKCS private key for
103  * the certificate.
104  *
105  * @return NULL on error.
106  */
107 tls_server_t *
108 tls_ServerCreate( vlc_object_t *p_this, const char *psz_cert,
109                   const char *psz_key )
110 {
111     tls_t *p_tls;
112     tls_server_t *p_server;
113
114     p_tls = tls_Init( p_this );
115     if( p_tls == NULL )
116         return NULL;
117
118     if( psz_key == NULL )
119         psz_key = psz_cert;
120
121     p_server = p_tls->pf_server_create( p_tls, psz_cert, psz_key );
122     if( p_server != NULL )
123     {
124         msg_Dbg( p_tls, "TLS/SSL server initialized" );
125         return p_server;
126     }
127     else
128         msg_Err( p_tls, "TLS/SSL server error" );
129
130     tls_Deinit( p_tls );
131     return NULL;
132 }
133
134
135 /**
136  * Releases data allocated with tls_ServerCreate.
137  */
138 void
139 tls_ServerDelete( tls_server_t *p_server )
140 {
141     tls_t *p_tls = (tls_t *)p_server->p_parent;
142
143     p_server->pf_delete( p_server );
144
145     tls_Deinit( p_tls );
146 }
147
148
149 /**
150  * Allocates a client's TLS credentials and shakes hands through the network.
151  * This is a blocking network operation.
152  *
153  * @param fd stream socket through which to establish the secure communication
154  * layer.
155  * @param psz_hostname Server Name Indication to pass to the server, or NULL.
156  *
157  * @return NULL on error.
158  **/
159 tls_session_t *
160 tls_ClientCreate( vlc_object_t *p_this, int fd, const char *psz_hostname )
161 {
162     tls_t *p_tls;
163     tls_session_t *p_session;
164
165     p_tls = tls_Init( p_this );
166     if( p_tls == NULL )
167         return NULL;
168         
169     p_session = p_tls->pf_client_create( p_tls );
170     if( p_session != NULL )
171     {
172         int i_val;
173
174         for( i_val = tls_ClientSessionHandshake( p_session, fd,
175                                                  psz_hostname );
176              i_val > 0;
177              i_val = tls_SessionContinueHandshake( p_session ) );
178
179         if( i_val == 0 )
180         {
181             msg_Dbg( p_this, "TLS/SSL client initialized" );
182             return p_session;
183         }
184         msg_Err( p_this, "TLS/SSL session handshake error" );
185     }
186     else
187         msg_Err( p_this, "TLS/SSL client error" );
188
189     tls_Deinit( p_tls );
190     return NULL;
191 }
192
193
194 /**
195  * Releases data allocated with tls_ClientCreate.
196  * It is your job to close the underlying socket.
197  */
198 void
199 tls_ClientDelete( tls_session_t *p_session )
200 {
201     tls_t *p_tls = (tls_t *)p_session->p_parent;
202
203     p_session->pf_close( p_session );
204
205     tls_Deinit( p_tls );
206 }