VLC  4.0.0-dev
vlc_tls.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * vlc_tls.h:
3  *****************************************************************************
4  * Copyright (C) 2004-2016 RĂ©mi Denis-Courmont
5  * Copyright (C) 2005-2006 VLC authors and VideoLAN
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
20  *****************************************************************************/
21 
22 #ifndef VLC_TLS_H
23 # define VLC_TLS_H
24 
25 /**
26  * \ingroup net
27  * \defgroup transport Transport layer sockets
28  * Network stream abstraction
29  *
30  * Originally intended for the TLS protocol (Transport Layer Security),
31  * the Transport Layer Sockets now provides a generic abstraction
32  * for connection-oriented full-duplex I/O byte streams, such as TCP/IP sockets
33  * and TLS protocol sessions.
34  *
35  * @{
36  * \file
37  * Transport layer functions
38  */
39 
40 # include <vlc_network.h>
41 
42 /**
43  * Transport layer socket.
44  *
45  * Transport layer sockets are full-duplex, meaning data can be sent and
46  * received at the same time. As such, it is permitted for two threads to
47  * use the same TLS simultaneously, if one thread is receiving data while the
48  * other is sending data. However receiving or sending data from two threads
49  * concurrently is undefined behaviour.
50  *
51  * The following functions are treated as sending data:
52  * - vlc_tls_Write(),
53  * - vlc_tls_Shutdown(),
54  * - callback vlc_tls_operations.writev,
55  * - callback vlc_tls_operations.shutdown.
56  *
57  * The following functions are treated as receiving data:
58  * - vlc_tls_Read(),
59  * - vlc_tls_GetLine(),
60  * - callback vlc_tls_operations.readv,
61  * - vlc_tls_Shutdown() if the duplex flag is true,
62  * - callback vlc_tls_operations.shutdown if the duplex flag is true.
63  */
64 typedef struct vlc_tls
65 {
66  /** Callbacks to operate on the stream. */
67  const struct vlc_tls_operations *ops;
68  /** Reserved. Pointer to the underlying stream, or NULL if none. */
69  struct vlc_tls *p;
71 
72 struct vlc_tls_operations
73 {
74  /** Callback for events polling.
75  *
76  * See \ref vlc_tls_GetPollFD().
77  */
78  int (*get_fd)(struct vlc_tls *, short *events);
79 
80  /** Callback for receiving data.
81  *
82  * This callback receives/reads data into an I/O vector
83  * in non-blocking mode.
84  *
85  * @param iov I/O vector to read data into
86  * @param len number of entries of the I/O vector
87  * @return the number of bytes received or -1 on error
88  *
89  * If no data is available without blocking, the function returns -1 and
90  * sets @c errno to @c EAGAIN .
91  */
92  ssize_t (*readv)(struct vlc_tls *, struct iovec *iov, unsigned len);
93 
94  /** Callback for sending data.
95  *
96  * This callback sends/writes data from an I/O vector
97  * in non-blocking mode.
98  *
99  * @param iov I/O vector to write data from
100  * @param len number of entries of the I/O vector
101  * @return the number of bytes sent or -1 on error
102  *
103  * If no data can be sent without blocking, the function returns -1 and
104  * sets @c errno to @c EAGAIN .
105  */
106  ssize_t (*writev)(struct vlc_tls *, const struct iovec *iov, unsigned len);
108  /** Callback for shutting down.
109  *
110  * This callback marks the end of the output (send/write) half of the
111  * stream. If the duplex flag is set, it also marks the end of the input
112  * (receive/read) half. See also \ref vlc_tls_Shutdown().
113  */
114  int (*shutdown)(struct vlc_tls *, bool duplex);
116  /** Callback for closing.
117  *
118  * This callback terminates the stream and releases any associated
119  * resources. However, it does <b>not</b> destroy the underlying stream
120  * if there is one. See also \ref vlc_tls_SessionDelete().
121  */
122  void (*close)(struct vlc_tls *);
123 };
124 
125 /**
126  * \defgroup tls Transport Layer Security
127  * @{
128  * \defgroup tls_client TLS client
129  * @{
130  */
131 
132 /**
133  * TLS client-side credentials
134  *
135  * This structure contains the credentials for establishing TLS sessions
136  * on client side, essentially the set of trusted root Certificate Authorities
137  * with which to validate certificate chains presented by servers.
138  */
139 typedef struct vlc_tls_client
140 {
141  struct vlc_object_t obj;
143  void *sys;
145 
147 {
148  vlc_tls_t *(*open)(struct vlc_tls_client *, vlc_tls_t *sock,
149  const char *host, const char *const *alpn);
150  int (*handshake)(vlc_tls_t *session,
151  const char *hostname, const char *service,
152  char ** /*restrict*/ alp);
153  void (*destroy)(struct vlc_tls_client *);
154 };
155 
156 /**
157  * Allocates TLS client-side credentials.
158  *
159  * Credentials can be cached and reused across multiple TLS sessions.
160  *
161  * @return TLS credentials object, or NULL on error.
162  **/
164 
165 /**
166  * Releases TLS client-side credentials.
167  *
168  * Releases data allocated with vlc_tls_ClientCreate().
169  */
171 
172 /**
173  * Initiates a client TLS session.
174  *
175  * Initiates a Transport Layer Security (TLS) session as the client side, using
176  * trusted root CAs previously loaded with vlc_tls_ClientCreate().
177  *
178  * This is a blocking network operation and may be a thread cancellation point.
179  *
180  * @param creds X.509 credentials, i.e. set of root certificates of trusted
181  * certificate authorities
182  * @param sock socket through which to establish the secure channel
183  * @param hostname expected server name, used both as Server Name Indication
184  * and as expected Common Name of the peer certificate [IN]
185  * @param service unique identifier for the service to connect to
186  * (only used locally for certificates database) [IN]
187  * @param alpn NULL-terminated list of Application Layer Protocols
188  * to negotiate, or NULL to not negotiate protocols [IN]
189  * @param alp storage space for the negotiated Application Layer
190  * Protocol or NULL if negotiation was not performed [OUT]
191  *
192  * @note The credentials must remain valid until the session is finished.
193  *
194  * @return TLS session, or NULL on error.
195  **/
197  vlc_tls_t *sock,
198  const char *host,
199  const char *service,
200  const char *const *alpn,
201  char **alp);
202 
203 /**
204  * @}
205  * \defgroup tls_server TLS server
206  * @{
207  */
208 
209 /**
210  * TLS server-side credentials
211  *
212  * This structure contains the credentials for establishing TLS sessions.
213  * This includes root Certificate Authorities (on client side),
214  * trust and cryptographic parameters,
215  * public certificates and private keys.
216  */
217 typedef struct vlc_tls_server
218 {
219  struct vlc_object_t obj;
221  void *sys;
224 
226 {
227  vlc_tls_t *(*open)(struct vlc_tls_server *, vlc_tls_t *sock,
228  const char *const *alpn);
229  int (*handshake)(vlc_tls_t *session, char ** /*restrict*/ alp);
230  void (*destroy)(struct vlc_tls_server *);
231 };
232 
233 /**
234  * Allocates server TLS credentials.
235  *
236  * @param cert path to an x509 certificate (required)
237  * @param key path to the PKCS private key for the certificate,
238  * or NULL to use cert path
239  *
240  * @return TLS credentials object, or NULL on error.
241  */
243  const char *cert,
244  const char *key);
245 
246 static inline int vlc_tls_SessionHandshake(vlc_tls_server_t *crd,
247  vlc_tls_t *tls)
248 {
249  return crd->ops->handshake(tls, NULL);
250 }
251 
252 /**
253  * Creates a TLS server session.
254  *
255  * Allocates a Transport Layer Security (TLS) session as the server side, using
256  * cryptographic keys pair and X.509 certificates chain already loaded with
257  * vlc_tls_ServerCreate().
258  *
259  * Unlike vlc_tls_ClientSessionCreate(), this function does not perform any
260  * actual network I/O. vlc_tls_SessionHandshake() must be used to perform the
261  * TLS handshake before sending and receiving data through the TLS session.
262  *
263  * This function is non-blocking and is not a cancellation point.
264  *
265  * @param creds server credentials, i.e. keys pair and X.509 certificates chain
266  * @param alpn NULL-terminated list of Application Layer Protocols
267  * to negotiate, or NULL to not negotiate protocols
268  *
269  * @return TLS session, or NULL on error.
270  */
272  vlc_tls_t *sock,
273  const char *const *alpn);
274 
275 /**
276  * Releases server-side TLS credentials.
277  *
278  * Releases data allocated with vlc_tls_ServerCreate().
279  */
281 
282 /** @} */
283 
284 /** @} */
285 
286 /**
287  * Destroys a TLS session.
288  *
289  * All resources associated with the TLS session are released.
290  *
291  * If the session was established successfully, then shutdown cleanly, the
292  * underlying socket can be reused. Otherwise, it must be closed. Either way,
293  * this function does not close the underlying socket: Use vlc_tls_Close()
294  * instead to close it at the same.
295  *
296  * This function is non-blocking and is not a cancellation point.
297  */
299 
300 /**
301  * Generates an event polling description.
302  *
303  * This function provides the necessary informations to make an event polling
304  * description for use with poll() or similar event multiplexing functions.
305  *
306  * This function is necessary both for receiving and sending data, therefore
307  * it is reentrant. It is not a cancellation point.
308  *
309  * @param events a pointer to a mask of poll events (e.g. POLLIN, POLLOUT)
310  * [IN/OUT]
311  * @return the file descriptor to poll
312  */
313 static inline int vlc_tls_GetPollFD(vlc_tls_t *tls, short *events)
314 {
315  return tls->ops->get_fd(tls, events);
316 }
317 
318 /**
319  * Returns the underlying file descriptor.
320  *
321  * This function returns the file descriptor underlying the transport layer
322  * stream object. This function is reentrant and is not a cancellation point.
323  */
324 static inline int vlc_tls_GetFD(vlc_tls_t *tls)
325 {
326  short events = 0;
327 
328  return vlc_tls_GetPollFD(tls, &events);
329 }
330 
331 /**
332  * Receives data through a socket.
333  *
334  * This dequeues incoming data from a transport layer socket.
335  *
336  * @param buf received buffer start address [OUT]
337  * @param len buffer length (in bytes)
338  * @param waitall whether to wait for the exact buffer length (true),
339  * or for any amount of data (false)
340  *
341  * @note At end of stream, the number of bytes returned may be shorter than
342  * requested regardless of the "waitall" flag.
343  *
344  * @return the number of bytes actually dequeued, or -1 on error.
345  */
346 VLC_API ssize_t vlc_tls_Read(vlc_tls_t *, void *buf, size_t len, bool waitall);
347 
348 /**
349  * Receives a text line through a socket.
350  *
351  * This dequeues one line of text from a transport layer socket.
352  * @return a heap-allocated nul-terminated string, or NULL on error
353  */
355 
356 /**
357  * Sends data through a socket.
358  */
359 VLC_API ssize_t vlc_tls_Write(vlc_tls_t *, const void *buf, size_t len);
360 
361 /**
362  * Shuts a connection down.
363  *
364  * This sends the connection close notification.
365  *
366  * If the TLS protocol is used, this provides a secure indication to the other
367  * end that no further data will be sent. If using plain TCP/IP, this sets the
368  * FIN flag.
369  *
370  * Data can still be received until a close notification is received from the
371  * other end.
372  *
373  * @param duplex whether to stop receiving data as well
374  * @retval 0 the session was terminated securely and cleanly
375  * (the underlying socket can be reused for other purposes)
376  * @return -1 the session was terminated locally, but either a notification
377  * could not be sent or received (the underlying socket cannot be
378  * reused and must be closed)
379  */
380 static inline int vlc_tls_Shutdown(vlc_tls_t *tls, bool duplex)
381 {
382  return tls->ops->shutdown(tls, duplex);
383 }
384 
385 /**
386  * Closes a connection and its underlying resources.
387  *
388  * This function closes the transport layer socket, and terminates any
389  * underlying connection. For instance, if the TLS protocol is used over a TCP
390  * stream, this function terminates both the TLS session, and then underlying
391  * TCP/IP connection.
392  *
393  * To close a connection but retain any underlying resources, use
394  * vlc_tls_SessionDelete() instead.
395  */
396 static inline void vlc_tls_Close(vlc_tls_t *session)
397 {
398  do
399  {
400  vlc_tls_t *p = session->p;
401 
402  vlc_tls_SessionDelete(session);
403  session = p;
404  }
405  while (session != NULL);
406 }
407 
408 /**
409  * Creates a transport-layer stream from a socket.
410  *
411  * Creates a transport-layer I/O stream from a socket file descriptor.
412  * Data will be sent and received directly through the socket. This can be used
413  * either to share common code between non-TLS and TLS cases, or for testing
414  * purposes.
415  *
416  * This function is not a cancellation point.
417  *
418  * @deprecated This function is transitional. Do not use it directly.
419  */
421 
422 /**
423  * Creates a connected pair of transport-layer sockets.
424  */
425 VLC_API int vlc_tls_SocketPair(int family, int protocol, vlc_tls_t *[2]);
426 
427 struct addrinfo;
428 
429 /**
430  * Creates a transport-layer stream from a struct addrinfo.
431  *
432  * This function tries to allocate a socket using the specified addrinfo
433  * structure. Normally, the vlc_tls_SocketOpenTCP() function takes care of
434  * this. But in some cases, it cannot be used, notably:
435  * - if the remote destination is not resolved (directly) from getaddrinfo(),
436  * - if the socket type is not SOCK_STREAM,
437  * - if the transport protocol is not TCP (IPPROTO_TCP), or
438  * - if TCP Fast Open should be attempted.
439  *
440  * @note If the @c defer_connect flag is @c true , data must be sent with a
441  * data sending function (other than vlc_tls_Shutdown()) before data can be
442  * received.
443  * Notwithstanding the thread-safety and reentrancy promises of \ref vlc_tls_t,
444  * the owner of the stream object is responsible for ensuring that data will be
445  * sent at least once before any attempt to receive data.
446  * Otherwise @c defer_connect must be @c false .
447  *
448  * @param ai a filled addrinfo structure (the ai_next member is ignored)
449  * @param defer_connect whether to attempt a TCP Fast Open connection or not
450  */
451 VLC_API vlc_tls_t *vlc_tls_SocketOpenAddrInfo(const struct addrinfo *ai,
452  bool defer_connect);
453 
454 /**
455  * Creates a transport-layer TCP stream from a name and port.
456  *
457  * This function resolves a hostname, and attempts to establish a TCP/IP
458  * connection to the specified host and port number.
459  *
460  * @note The function currently iterates through the addrinfo linked list.
461  * Future versions may implement different behaviour (e.g. RFC6555).
462  *
463  * @return a transport layer socket on success or NULL on error
464  */
466  const char *hostname, unsigned port);
467 
468 /**
469  * Initiates a TLS session over TCP.
470  *
471  * This function resolves a hostname, attempts to establish a TCP/IP
472  * connection to the specified host and port number, and finally attempts to
473  * establish a TLS session over the TCP/IP stream.
474  *
475  * See also vlc_tls_SocketOpenTCP() and vlc_tls_ClientSessionCreate().
476  */
478  const char *hostname, unsigned port,
479  const char *service,
480  const char *const *alpn, char **alp);
481 
482 /** @} */
483 
484 #endif
vlc_tls_client_t * vlc_tls_ClientCreate(vlc_object_t *)
Allocates TLS client-side credentials.
Definition: tls.c:108
vlc_tls_t * vlc_tls_SocketOpenAddrInfo(const struct addrinfo *ai, bool defer_connect)
Creates a transport-layer stream from a struct addrinfo.
vlc_tls_server_t * vlc_tls_ServerCreate(vlc_object_t *, const char *cert, const char *key)
Allocates server TLS credentials.
Definition: tls.c:76
void vlc_tls_SessionDelete(vlc_tls_t *)
Destroys a TLS session.
Definition: tls.c:139
struct vlc_tls_client vlc_tls_client_t
TLS client-side credentials.
struct vlc_tls * p
Reserved.
Definition: vlc_tls.h:70
const struct vlc_tls_operations * ops
Callbacks to operate on the stream.
Definition: vlc_tls.h:68
int(* shutdown)(struct vlc_tls *, bool duplex)
Callback for shutting down.
Definition: vlc_tls.h:115
TLS client-side credentials.
Definition: vlc_tls.h:140
vlc_tls_t * vlc_tls_ClientSessionCreate(vlc_tls_client_t *creds, vlc_tls_t *sock, const char *host, const char *service, const char *const *alpn, char **alp)
Initiates a client TLS session.
Definition: tls.c:153
ssize_t vlc_tls_Read(vlc_tls_t *, void *buf, size_t len, bool waitall)
Receives data through a socket.
Definition: stream.c:53
Definition: vlc_tls.h:226
struct vlc_tls_server vlc_tls_server_t
TLS server-side credentials.
const struct vlc_tls_server_operations * ops
Definition: vlc_tls.h:221
static int vlc_tls_GetFD(vlc_tls_t *tls)
Returns the underlying file descriptor.
Definition: vlc_tls.h:325
void vlc_tls_ServerDelete(vlc_tls_server_t *)
Releases server-side TLS credentials.
Definition: tls.c:98
char * vlc_tls_GetLine(vlc_tls_t *)
Receives a text line through a socket.
Definition: stream.c:133
Transport layer socket.
Definition: vlc_tls.h:65
int vlc_tls_SocketPair(int family, int protocol, vlc_tls_t *[2])
Creates a connected pair of transport-layer sockets.
Definition: stream.c:255
static int vlc_tls_GetPollFD(vlc_tls_t *tls, short *events)
Generates an event polling description.
Definition: vlc_tls.h:314
vlc_tls_t * vlc_tls_SocketOpenTLS(vlc_tls_client_t *crd, const char *hostname, unsigned port, const char *service, const char *const *alpn, char **alp)
Initiates a TLS session over TCP.
Definition: tls.c:221
static void vlc_tls_Close(vlc_tls_t *session)
Closes a connection and its underlying resources.
Definition: vlc_tls.h:397
vlc_tls_t * vlc_tls_ServerSessionCreate(vlc_tls_server_t *creds, vlc_tls_t *sock, const char *const *alpn)
Creates a TLS server session.
Definition: tls.c:209
Definitions for sockets and low-level networking.
int(* get_fd)(struct vlc_tls *, short *events)
Callback for events polling.
Definition: vlc_tls.h:79
TLS server-side credentials.
Definition: vlc_tls.h:218
#define VLC_API
Definition: fourcc_gen.c:31
static int vlc_tls_Shutdown(vlc_tls_t *tls, bool duplex)
Shuts a connection down.
Definition: vlc_tls.h:381
ssize_t vlc_tls_Write(vlc_tls_t *, const void *buf, size_t len)
Sends data through a socket.
Definition: stream.c:94
vlc_tls_t * vlc_tls_SocketOpen(int fd)
Creates a transport-layer stream from a socket.
Definition: stream.c:250
Definition: vlc_tls.h:147
vlc_tls_t * vlc_tls_SocketOpenTCP(vlc_object_t *obj, const char *hostname, unsigned port)
Creates a transport-layer TCP stream from a name and port.
Definition: stream.c:429
Definition: vlc_tls.h:73
struct vlc_tls vlc_tls_t
Transport layer socket.
VLC object common members.
Definition: vlc_objects.h:43
void vlc_tls_ClientDelete(vlc_tls_client_t *)
Releases TLS client-side credentials.
Definition: tls.c:126
int(* handshake)(vlc_tls_t *session, char **alp)
Definition: vlc_tls.h:230
static int vlc_tls_SessionHandshake(vlc_tls_server_t *crd, vlc_tls_t *tls)
Definition: vlc_tls.h:247