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