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