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 it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
26 * libvlc interface to the Transport Layer Security (TLS) plugins.
33 #include <vlc_common.h>
37 #include <vlc_modules.h>
39 /*** TLS credentials ***/
41 static int tls_server_load(void *func, va_list ap)
43 int (*activate) (vlc_tls_creds_t *, const char *, const char *) = func;
44 vlc_tls_creds_t *crd = va_arg (ap, vlc_tls_creds_t *);
45 const char *cert = va_arg (ap, const char *);
46 const char *key = va_arg (ap, const char *);
48 return activate (crd, cert, key);
51 static int tls_client_load(void *func, va_list ap)
53 int (*activate) (vlc_tls_creds_t *) = func;
54 vlc_tls_creds_t *crd = va_arg (ap, vlc_tls_creds_t *);
56 return activate (crd);
59 static void tls_unload(void *func, va_list ap)
61 void (*deactivate) (vlc_tls_creds_t *) = func;
62 vlc_tls_creds_t *crd = va_arg (ap, vlc_tls_creds_t *);
68 * Allocates a whole server's TLS credentials.
70 * @param cert_path required (Unicode) path to an x509 certificate,
71 * if NULL, anonymous key exchange will be used.
72 * @param key_path (UTF-8) path to the PKCS private key for the certificate,
73 * if NULL; cert_path will be used.
75 * @return NULL on error.
78 vlc_tls_ServerCreate (vlc_object_t *obj, const char *cert_path,
81 vlc_tls_creds_t *srv = vlc_custom_create (obj, sizeof (*srv),
83 if (unlikely(srv == NULL))
89 srv->module = vlc_module_load (srv, "tls server", NULL, false,
90 tls_server_load, srv, cert_path, key_path);
91 if (srv->module == NULL)
93 msg_Err (srv, "TLS server plugin not available");
94 vlc_object_release (srv);
102 * Allocates TLS credentials for a client.
103 * Credentials can be cached and reused across multiple TLS sessions.
105 * @return TLS credentials object, or NULL on error.
107 vlc_tls_creds_t *vlc_tls_ClientCreate (vlc_object_t *obj)
109 vlc_tls_creds_t *crd = vlc_custom_create (obj, sizeof (*crd),
111 if (unlikely(crd == NULL))
114 crd->module = vlc_module_load (crd, "tls client", NULL, false,
115 tls_client_load, crd);
116 if (crd->module == NULL)
118 msg_Err (crd, "TLS client plugin not available");
119 vlc_object_release (crd);
127 * Releases data allocated with vlc_tls_ClientCreate() or
128 * vlc_tls_ServerCreate().
129 * @param srv TLS server object to be destroyed, or NULL
131 void vlc_tls_Delete (vlc_tls_creds_t *crd)
136 vlc_module_unload (crd->module, tls_unload, crd);
137 vlc_object_release (crd);
142 * Adds one or more certificate authorities from a file.
143 * @return -1 on error, 0 on success.
145 int vlc_tls_ServerAddCA (vlc_tls_creds_t *srv, const char *path)
147 return srv->add_CA (srv, path);
152 * Adds one or more certificate revocation list from a file.
153 * @return -1 on error, 0 on success.
155 int vlc_tls_ServerAddCRL (vlc_tls_creds_t *srv, const char *path)
157 return srv->add_CRL (srv, path);
161 /*** TLS session ***/
163 static vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *crd, int fd,
164 const char *hostname)
166 vlc_tls_t *session = vlc_custom_create (crd, sizeof (*session),
168 int val = crd->open (crd, session, fd, hostname);
169 if (val == VLC_SUCCESS)
171 vlc_object_release (session);
175 void vlc_tls_SessionDelete (vlc_tls_t *session)
177 vlc_tls_creds_t *crd = (vlc_tls_creds_t *)(session->p_parent);
179 crd->close (crd, session);
180 vlc_object_release (session);
183 vlc_tls_t *vlc_tls_ServerSessionCreate (vlc_tls_creds_t *crd, int fd)
185 return vlc_tls_SessionCreate (crd, fd, NULL);
188 int vlc_tls_ServerSessionHandshake (vlc_tls_t *ses)
190 int val = ses->handshake (ses);
192 vlc_tls_ServerSessionDelete (ses);
197 * Performs client side of TLS handshake through a connected socket, and
198 * establishes a secure channel. This is a blocking network operation.
200 * @param fd stream socket through which to establish the secure communication
202 * @param hostname expected server name, used both as Server Name Indication
203 * and as expected Common Name of the peer's certificate.
205 * @return NULL on error.
207 vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
208 const char *hostname)
210 vlc_tls_t *session = vlc_tls_SessionCreate (crd, fd, hostname);
214 /* TODO: do this directly in the TLS plugin */
217 val = session->handshake (session);
222 msg_Err (session, "TLS client session handshake error");
223 vlc_tls_SessionDelete (session);