]> git.sesse.net Git - vlc/blob - src/network/tls.c
Fix TLS session cleanup
[vlc] / src / network / tls.c
1 /*****************************************************************************
2  * tls.c
3  *****************************************************************************
4  * Copyright © 2004-2007 Rémi Denis-Courmont
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 <vlc/vlc.h>
30 #include "libvlc.h"
31
32 #include <vlc_tls.h>
33
34 /**
35  * Allocates a whole server's TLS credentials.
36  *
37  * @param cert_path required (Unicode) path to an x509 certificate,
38  *                  if NULL, anonymous key exchange will be used.
39  * @param key_path (UTF-8) path to the PKCS private key for the certificate,
40  *                 if NULL; cert_path will be used.
41  *
42  * @return NULL on error.
43  */
44 tls_server_t *
45 tls_ServerCreate (vlc_object_t *obj, const char *cert_path,
46                   const char *key_path)
47 {
48     tls_server_t *srv;
49
50     srv = (tls_server_t *)vlc_custom_create (obj, sizeof (*srv),
51                                              VLC_OBJECT_GENERIC,
52                                              "tls server");
53     if (srv == NULL)
54         return NULL;
55
56     var_Create (srv, "tls-x509-cert", VLC_VAR_STRING);
57     var_Create (srv, "tls-x509-key", VLC_VAR_STRING);
58
59     if (cert_path != NULL)
60     {
61         var_SetString (srv, "tls-x509-cert", cert_path);
62
63         if (key_path == NULL)
64             key_path = cert_path;
65         var_SetString (srv, "tls-x509-key", key_path);
66     }
67
68     srv->p_module = module_Need (srv, "tls server", 0, 0);
69     if (srv->p_module == NULL)
70     {
71         msg_Err (srv, "TLS server plugin not available");
72         vlc_object_destroy (srv);
73         return NULL;
74     }
75
76     vlc_object_attach (srv, obj);
77     msg_Dbg (srv, "TLS server plugin initialized");
78     return srv;
79 }
80
81
82 /**
83  * Releases data allocated with tls_ServerCreate.
84  * @param srv TLS server object to be destroyed, or NULL
85  */
86 void tls_ServerDelete (tls_server_t *srv)
87 {
88     if (srv == NULL)
89         return;
90
91     module_Unneed (srv, srv->p_module);
92     vlc_object_detach (srv);
93     vlc_object_destroy (srv);
94 }
95
96
97 /**
98  * Adds one or more certificate authorities from a file.
99  * @return -1 on error, 0 on success.
100  */
101 int tls_ServerAddCA (tls_server_t *srv, const char *path)
102 {
103     return srv->pf_add_CA (srv, path);
104 }
105
106
107 /**
108  * Adds one or more certificate revocation list from a file.
109  * @return -1 on error, 0 on success.
110  */
111 int tls_ServerAddCRL (tls_server_t *srv, const char *path)
112 {
113     return srv->pf_add_CRL (srv, path);
114 }
115
116
117 tls_session_t *tls_ServerSessionPrepare (tls_server_t *srv)
118 {
119     tls_session_t *ses;
120
121     ses = srv->pf_open (srv);
122     if (ses == NULL)
123         return NULL;
124
125     vlc_object_attach (ses, srv);
126     return ses;
127 }
128
129
130 void tls_ServerSessionClose (tls_session_t *ses)
131 {
132     tls_server_t *srv = (tls_server_t *)(ses->p_parent);
133     srv->pf_close (srv, ses);
134 }
135
136
137 int tls_ServerSessionHandshake (tls_session_t *ses, int fd)
138 {
139     ses->pf_set_fd (ses, fd);
140     return 2;
141 }
142
143
144 int tls_SessionContinueHandshake (tls_session_t *ses)
145 {
146     int val = ses->pf_handshake (ses);
147     if (val < 0)
148         tls_ServerSessionClose (ses);
149     return val;
150 }
151
152
153 /**
154  * Allocates a client's TLS credentials and shakes hands through the network.
155  * This is a blocking network operation.
156  *
157  * @param fd stream socket through which to establish the secure communication
158  * layer.
159  * @param psz_hostname Server Name Indication to pass to the server, or NULL.
160  *
161  * @return NULL on error.
162  **/
163 tls_session_t *
164 tls_ClientCreate (vlc_object_t *obj, int fd, const char *psz_hostname)
165 {
166     tls_session_t *cl;
167     int val;
168
169     cl = (tls_session_t *)vlc_custom_create (obj, sizeof (*cl),
170                                              VLC_OBJECT_GENERIC,
171                                              "tls client");
172     if (cl == NULL)
173         return NULL;
174
175     var_Create (cl, "tls-server-name", VLC_VAR_STRING);
176     if (psz_hostname != NULL)
177     {
178         msg_Dbg (cl, "requested server name: %s", psz_hostname);
179         var_SetString (cl, "tls-server-name", psz_hostname);
180     }
181     else
182         msg_Dbg (cl, "requested anonymous server");
183
184     cl->p_module = module_Need (cl, "tls client", 0, 0);
185     if (cl->p_module == NULL)
186     {
187         msg_Err (cl, "TLS client plugin not available");
188         vlc_object_destroy (cl);
189         return NULL;
190     }
191
192     cl->pf_set_fd (cl, fd);
193
194     do
195         val = cl->pf_handshake (cl);
196     while (val > 0);
197
198     if (val == 0)
199     {
200         msg_Dbg (cl, "TLS client session initialized");
201         vlc_object_attach (cl, obj);
202         return cl;
203     }
204     msg_Err (cl, "TLS client session handshake error");
205
206     module_Unneed (cl, cl->p_module);
207     vlc_object_destroy (cl);
208     return NULL;
209 }
210
211
212 /**
213  * Releases data allocated with tls_ClientCreate.
214  * It is your job to close the underlying socket.
215  */
216 void tls_ClientDelete (tls_session_t *cl)
217 {
218     if (cl == NULL)
219         return;
220
221     module_Unneed (cl, cl->p_module);
222     vlc_object_detach (cl);
223     vlc_object_destroy (cl);
224 }