VLC  3.0.15
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 /** Transport layer socket */
43 typedef struct vlc_tls
44 {
45  int (*get_fd)(struct vlc_tls *);
46  ssize_t (*readv)(struct vlc_tls *, struct iovec *, unsigned);
47  ssize_t (*writev)(struct vlc_tls *, const struct iovec *, unsigned);
48  int (*shutdown)(struct vlc_tls *, bool duplex);
49  void (*close)(struct vlc_tls *);
50 
51  struct vlc_tls *p;
52 } vlc_tls_t;
53 
54 /**
55  * \defgroup tls Transport Layer Security
56  * @{
57  */
58 
59 /**
60  * TLS credentials
61  *
62  * This structure contains the credentials for establishing TLS sessions.
63  * This includes root Certificate Authorities (on client side),
64  * trust and cryptographic parameters,
65  * public certificates and private keys.
66  */
67 typedef struct vlc_tls_creds
68 {
70 
72  void *sys;
73 
74  vlc_tls_t *(*open)(struct vlc_tls_creds *, vlc_tls_t *sock,
75  const char *host, const char *const *alpn);
76  int (*handshake)(struct vlc_tls_creds *, vlc_tls_t *session,
77  const char *hostname, const char *service,
78  char ** /*restrict*/ alp);
80 
81 /**
82  * Allocates TLS credentials for a client.
83  * Credentials can be cached and reused across multiple TLS sessions.
84  *
85  * @return TLS credentials object, or NULL on error.
86  **/
88 
89 /**
90  * Allocates server TLS credentials.
91  *
92  * @param cert path to an x509 certificate (required)
93  * @param key path to the PKCS private key for the certificate,
94  * or NULL to use cert path
95  *
96  * @return TLS credentials object, or NULL on error.
97  */
99  const char *key);
100 
102  vlc_tls_t *tls)
103 {
104  return crd->handshake(crd, tls, NULL, NULL, NULL);
105 }
106 
107 /**
108  * Releases TLS credentials.
109  *
110  * Releases data allocated with vlc_tls_ClientCreate() or
111  * vlc_tls_ServerCreate().
112  *
113  * @param srv object to be destroyed (or NULL)
114  */
116 
117 /**
118  * Initiates a client TLS session.
119  *
120  * Initiates a Transport Layer Security (TLS) session as the client side, using
121  * trusted root CAs previously loaded with vlc_tls_ClientCreate().
122  *
123  * This is a blocking network operation and may be a thread cancellation point.
124  *
125  * @param creds X.509 credentials, i.e. set of root certificates of trusted
126  * certificate authorities
127  * @param sock socket through which to establish the secure channel
128  * @param hostname expected server name, used both as Server Name Indication
129  * and as expected Common Name of the peer certificate [IN]
130  * @param service unique identifier for the service to connect to
131  * (only used locally for certificates database) [IN]
132  * @param alpn NULL-terminated list of Application Layer Protocols
133  * to negotiate, or NULL to not negotiate protocols [IN]
134  * @param alp storage space for the negotiated Application Layer
135  * Protocol or NULL if negotiation was not performed [OUT]
136  *
137  * @note The credentials must remain valid until the session is finished.
138  *
139  * @return TLS session, or NULL on error.
140  **/
142  vlc_tls_t *sock,
143  const char *host,
144  const char *service,
145  const char *const *alpn,
146  char **alp);
147 
148 /**
149  * Creates a TLS server session.
150  *
151  * Allocates a Transport Layer Security (TLS) session as the server side, using
152  * cryptographic keys pair and X.509 certificates chain already loaded with
153  * vlc_tls_ServerCreate().
154  *
155  * Unlike vlc_tls_ClientSessionCreate(), this function does not perform any
156  * actual network I/O. vlc_tls_SessionHandshake() must be used to perform the
157  * TLS handshake before sending and receiving data through the TLS session.
158  *
159  * This function is non-blocking and is not a cancellation point.
160  *
161  * @param creds server credentials, i.e. keys pair and X.509 certificates chain
162  * @param alpn NULL-terminated list of Application Layer Protocols
163  * to negotiate, or NULL to not negotiate protocols
164  *
165  * @return TLS session, or NULL on error.
166  */
168  vlc_tls_t *sock,
169  const char *const *alpn);
170 
171 /** @} */
172 
173 /**
174  * Destroys a TLS session down.
175  *
176  * All resources associated with the TLS session are released.
177  *
178  * If the session was established successfully, then shutdown cleanly, the
179  * underlying socket can be reused. Otherwise, it must be closed. Either way,
180  * this function does not close the underlying socket: Use vlc_tls_Close()
181  * instead to close it at the same.
182  *
183  * This function is non-blocking and is not a cancellation point.
184  */
186 
187 static inline int vlc_tls_GetFD(vlc_tls_t *tls)
188 {
189  return tls->get_fd(tls);
190 }
191 
192 /**
193  * Receives data through a socket.
194  *
195  * This dequeues incoming data from a transport layer socket.
196  *
197  * @param buf received buffer start address [OUT]
198  * @param len buffer length (in bytes)
199  * @param waitall whether to wait for the exact buffer length (true),
200  * or for any amount of data (false)
201  *
202  * @note At end of stream, the number of bytes returned may be shorter than
203  * requested regardless of the "waitall" flag.
204  *
205  * @return the number of bytes actually dequeued, or -1 on error.
206  */
207 VLC_API ssize_t vlc_tls_Read(vlc_tls_t *, void *buf, size_t len, bool waitall);
208 
209 /**
210  * Receives a text line through a socket.
211  *
212  * This dequeues one line of text from a transport layer socket.
213  * @return a heap-allocated nul-terminated string, or NULL on error
214  */
216 
217 /**
218  * Sends data through a socket.
219  */
220 VLC_API ssize_t vlc_tls_Write(vlc_tls_t *, const void *buf, size_t len);
221 
222 /**
223  * Shuts a connection down.
224  *
225  * This sends the connection close notification.
226  *
227  * If the TLS protocol is used, this provides a secure indication to the other
228  * end that no further data will be sent. If using plain TCP/IP, this sets the
229  * FIN flag.
230  *
231  * Data can still be received until a close notification is received from the
232  * other end.
233  *
234  * @param duplex whether to stop receiving data as well
235  * @retval 0 the session was terminated securely and cleanly
236  * (the underlying socket can be reused for other purposes)
237  * @return -1 the session was terminated locally, but either a notification
238  * could not be sent or received (the underlying socket cannot be
239  * reused and must be closed)
240  */
241 static inline int vlc_tls_Shutdown(vlc_tls_t *tls, bool duplex)
242 {
243  return tls->shutdown(tls, duplex);
244 }
245 
246 /**
247  * Closes a connection and its underlying resources.
248  *
249  * This function closes the transport layer socket, and terminates any
250  * underlying connection. For instance, if the TLS protocol is used over a TCP
251  * stream, this function terminates both the TLS session, and then underlying
252  * TCP/IP connection.
253  *
254  * To close a connection but retain any underlying resources, use
255  * vlc_tls_SessionDelete() instead.
256  */
257 static inline void vlc_tls_Close(vlc_tls_t *session)
258 {
259  do
260  {
261  vlc_tls_t *p = session->p;
262 
263  vlc_tls_SessionDelete(session);
264  session = p;
265  }
266  while (session != NULL);
267 }
268 
269 /**
270  * Creates a transport-layer stream from a socket.
271  *
272  * Creates a transport-layer I/O stream from a socket file descriptor.
273  * Data will be sent and received directly through the socket. This can be used
274  * either to share common code between non-TLS and TLS cases, or for testing
275  * purposes.
276  *
277  * This function is not a cancellation point.
278  *
279  * @deprecated This function is transitional. Do not use it directly.
280  */
282 
283 /**
284  * Creates a connected pair of transport-layer sockets.
285  */
286 VLC_API int vlc_tls_SocketPair(int family, int protocol, vlc_tls_t *[2]);
287 
288 struct addrinfo;
289 
290 /**
291  * Creates a transport-layer stream from a struct addrinfo.
292  *
293  * This function tries to allocate a socket using the specified addrinfo
294  * structure. Normally, the vlc_tls_SocketOpenTCP() function takes care of
295  * this. But in some cases, it cannot be used, notably:
296  * - if the remote destination is not resolved (directly) from getaddrinfo(),
297  * - if the socket type is not SOCK_STREAM,
298  * - if the transport protocol is not TCP (IPPROTO_TCP), or
299  * - if TCP Fast Open should be attempted.
300  *
301  * @param ai a filled addrinfo structure (the ai_next member is ignored)
302  * @param defer_connect whether to attempt a TCP Fast Open connection or not
303  */
304 VLC_API vlc_tls_t *vlc_tls_SocketOpenAddrInfo(const struct addrinfo *ai,
305  bool defer_connect);
306 
307 /**
308  * Creates a transport-layer TCP stream from a name and port.
309  *
310  * This function resolves a hostname, and attempts to establish a TCP/IP
311  * connection to the specified host and port number.
312  *
313  * @note The function currently iterates through the addrinfo linked list.
314  * Future versions may implement different behaviour (e.g. RFC6555).
315  *
316  * @return a transport layer socket on success or NULL on error
317  */
319  const char *hostname, unsigned port);
320 
321 /**
322  * Initiates a TLS session over TCP.
323  *
324  * This function resolves a hostname, attempts to establish a TCP/IP
325  * connection to the specified host and port number, and finally attempts to
326  * establish a TLS session over the TCP/IP stream.
327  *
328  * See also vlc_tls_SocketOpenTCP() and vlc_tls_SessionCreate().
329  */
331  const char *hostname, unsigned port,
332  const char *service,
333  const char *const *alpn, char **alp);
334 
336 static inline vlc_tls_t *
337 vlc_tls_ClientSessionCreateFD(vlc_tls_creds_t *crd, int fd, const char *host,
338  const char *srv, const char *const *lp, char **p)
339 {
340  vlc_tls_t *sock = vlc_tls_SocketOpen(fd);
341  if (unlikely(sock == NULL))
342  return NULL;
343 
344  vlc_tls_t *tls = vlc_tls_ClientSessionCreate(crd, sock, host, srv, lp, p);
345  if (unlikely(tls == NULL))
346  free(sock);
347  return tls;
348 }
349 
350 /** @} */
351 
352 #endif
VLC_API
#define VLC_API
Definition: fourcc_gen.c:30
VLC_COMMON_MEMBERS
#define VLC_COMMON_MEMBERS
Backward compatibility macro.
Definition: vlc_common.h:453
VLC_DEPRECATED
#define VLC_DEPRECATED
Definition: vlc_common.h:98
vlc_tls::writev
ssize_t(* writev)(struct vlc_tls *, const struct iovec *, unsigned)
Definition: vlc_tls.h:47
vlc_tls_Write
ssize_t vlc_tls_Write(vlc_tls_t *, const void *buf, size_t len)
Sends data through a socket.
Definition: tls.c:268
vlc_tls_GetLine
char * vlc_tls_GetLine(vlc_tls_t *)
Receives a text line through a socket.
Definition: tls.c:307
vlc_tls_creds
TLS credentials.
Definition: vlc_tls.h:67
vlc_common.h
vlc_tls_Read
ssize_t vlc_tls_Read(vlc_tls_t *, void *buf, size_t len, bool waitall)
Receives data through a socket.
Definition: tls.c:227
vlc_network.h
vlc_tls
Transport layer socket.
Definition: vlc_tls.h:43
vlc_tls::p
struct vlc_tls * p
Definition: vlc_tls.h:51
vlc_tls::close
void(* close)(struct vlc_tls *)
Definition: vlc_tls.h:49
vlc_tls_Delete
void vlc_tls_Delete(vlc_tls_creds_t *)
Releases TLS credentials.
Definition: tls.c:128
vlc_tls_SocketPair
int vlc_tls_SocketPair(int family, int protocol, vlc_tls_t *[2])
Creates a connected pair of transport-layer sockets.
Definition: tls.c:419
module_t
Internal module descriptor.
Definition: modules.h:79
vlc_tls::shutdown
int(* shutdown)(struct vlc_tls *, bool duplex)
Definition: vlc_tls.h:48
vlc_tls::readv
ssize_t(* readv)(struct vlc_tls *, struct iovec *, unsigned)
Definition: vlc_tls.h:46
vlc_tls_GetFD
static int vlc_tls_GetFD(vlc_tls_t *tls)
Definition: vlc_tls.h:187
vlc_tls_creds::sys
void * sys
Definition: vlc_tls.h:72
vlc_tls_t
struct vlc_tls vlc_tls_t
Transport layer socket.
vlc_tls_creds::module
module_t * module
Definition: vlc_tls.h:71
vlc_tls_Close
static void vlc_tls_Close(vlc_tls_t *session)
Closes a connection and its underlying resources.
Definition: vlc_tls.h:257
vlc_tls_ServerSessionCreate
vlc_tls_t * vlc_tls_ServerSessionCreate(vlc_tls_creds_t *creds, vlc_tls_t *sock, const char *const *alpn)
Creates a TLS server session.
Definition: tls.c:220
vlc_tls_SocketOpenTCP
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: tls.c:586
vlc_object_t
The main vlc_object_t structure.
Definition: vlc_objects.h:39
vlc_tls_SocketOpen
vlc_tls_t * vlc_tls_SocketOpen(int fd)
Creates a transport-layer stream from a socket.
Definition: tls.c:414
vlc_tls_SocketOpenAddrInfo
vlc_tls_t * vlc_tls_SocketOpenAddrInfo(const struct addrinfo *ai, bool defer_connect)
Creates a transport-layer stream from a struct addrinfo.
vlc_tls_ClientSessionCreate
vlc_tls_t * vlc_tls_ClientSessionCreate(vlc_tls_creds_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:169
unlikely
#define unlikely(p)
Definition: vlc_common.h:114
vlc_tls_ClientCreate
vlc_tls_creds_t * vlc_tls_ClientCreate(vlc_object_t *)
Allocates TLS credentials for a client.
Definition: tls.c:109
vlc_tls_SessionHandshake
static int vlc_tls_SessionHandshake(vlc_tls_creds_t *crd, vlc_tls_t *tls)
Definition: vlc_tls.h:101
vlc_tls::get_fd
int(* get_fd)(struct vlc_tls *)
Definition: vlc_tls.h:45
vlc_tls_SessionDelete
void vlc_tls_SessionDelete(vlc_tls_t *)
Destroys a TLS session down.
Definition: tls.c:154
vlc_tls_ClientSessionCreateFD
static vlc_tls_t * vlc_tls_ClientSessionCreateFD(vlc_tls_creds_t *crd, int fd, const char *host, const char *srv, const char *const *lp, char **p)
Definition: vlc_tls.h:337
vlc_tls_ServerCreate
vlc_tls_creds_t * vlc_tls_ServerCreate(vlc_object_t *, const char *cert, const char *key)
Allocates server TLS credentials.
Definition: tls.c:86
vlc_tls_creds::handshake
int(* handshake)(struct vlc_tls_creds *, vlc_tls_t *session, const char *hostname, const char *service, char **alp)
Definition: vlc_tls.h:76
vlc_tls_SocketOpenTLS
vlc_tls_t * vlc_tls_SocketOpenTLS(vlc_tls_creds_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:626
vlc_tls_Shutdown
static int vlc_tls_Shutdown(vlc_tls_t *tls, bool duplex)
Shuts a connection down.
Definition: vlc_tls.h:241
vlc_tls_creds_t
struct vlc_tls_creds vlc_tls_creds_t
TLS credentials.
p
#define p(t)