• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * coap_dtls_internal.h -- (Datagram) Transport Layer Support for libcoap
3  *
4  * Copyright (C) 2016 Olaf Bergmann <bergmann@tzi.org>
5  * Copyright (C) 2017 Jean-Claude Michelou <jcm@spinetix.com>
6  *
7  * SPDX-License-Identifier: BSD-2-Clause
8  *
9  * This file is part of the CoAP library libcoap. Please see README for terms
10  * of use.
11  */
12 
13 /**
14  * @file coap_dtls_internal.h
15  * @brief Internal CoAP DTLS support
16  */
17 
18 #ifndef COAP_DTLS_INTERNAL_H_
19 #define COAP_DTLS_INTERNAL_H_
20 
21 #include "coap_internal.h"
22 
23 /**
24  * @ingroup internal_api
25  * @defgroup dtls_internal DTLS Support
26  * Internal API for DTLS Support
27  * @{
28  */
29 
30 /* https://rfc-editor.org/rfc/rfc6347#section-4.2.4.1 */
31 #ifndef COAP_DTLS_RETRANSMIT_MS
32 #define COAP_DTLS_RETRANSMIT_MS 1000
33 #endif
34 #ifndef COAP_DTLS_RETRANSMIT_TOTAL_MS
35 #define COAP_DTLS_RETRANSMIT_TOTAL_MS 60000
36 #endif
37 
38 #define COAP_DTLS_RETRANSMIT_COAP_TICKS (COAP_DTLS_RETRANSMIT_MS * COAP_TICKS_PER_SECOND / 1000)
39 
40 /* For RFC9146 Connection ID support */
41 #ifndef COAP_DTLS_CID_LENGTH
42 #define COAP_DTLS_CID_LENGTH 6
43 #endif
44 
45 /**
46  * Creates a new DTLS context for the given @p coap_context. This function
47  * returns a pointer to a new DTLS context object or @c NULL on error.
48  *
49  * @param coap_context The CoAP context where the DTLS object shall be used.
50  *
51  * @return A DTLS context object or @c NULL on error.
52  */
53 void *coap_dtls_new_context(coap_context_t *coap_context);
54 
55 #if COAP_SERVER_SUPPORT
56 /**
57  * Set the DTLS context's default server PSK information.
58  * This does the PSK specifics following coap_dtls_new_context().
59  *
60  * @param coap_context The CoAP context.
61  * @param setup_data A structure containing setup data originally passed into
62  *                   coap_context_set_psk2().
63  *
64  * @return @c 1 if successful, else @c 0.
65  */
66 
67 int coap_dtls_context_set_spsk(coap_context_t *coap_context,
68                                coap_dtls_spsk_t *setup_data);
69 #endif /* COAP_SERVER_SUPPORT */
70 
71 #if COAP_CLIENT_SUPPORT
72 /**
73  * Set the DTLS context's default client PSK information.
74  * This does the PSK specifics following coap_dtls_new_context().
75  *
76  * @param coap_context The CoAP context.
77  * @param setup_data A structure containing setup data originally passed into
78  *                   coap_new_client_session_psk2().
79  *
80  * @return @c 1 if successful, else @c 0.
81  */
82 
83 int coap_dtls_context_set_cpsk(coap_context_t *coap_context,
84                                coap_dtls_cpsk_t *setup_data);
85 #endif /* COAP_CLIENT_SUPPORT */
86 
87 /**
88  * Set the DTLS context's default server PKI information.
89  * This does the PKI specifics following coap_dtls_new_context().
90  * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the
91  * TLS library's context (from which sessions are derived).
92  * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the
93  * TLS library's session.
94  *
95  * @param coap_context The CoAP context.
96  * @param setup_data     Setup information defining how PKI is to be setup.
97  *                       Required parameter.  If @p NULL, PKI will not be
98  *                       set up.
99  * @param role  One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER
100  *
101  * @return @c 1 if successful, else @c 0.
102  */
103 
104 int coap_dtls_context_set_pki(coap_context_t *coap_context,
105                               const coap_dtls_pki_t *setup_data,
106                               const coap_dtls_role_t role);
107 
108 /**
109  * Set the dtls context's default Root CA information for a client or server.
110  *
111  * @param coap_context   The current coap_context_t object.
112  * @param ca_file        If not @p NULL, is the full path name of a PEM encoded
113  *                       file containing all the Root CAs to be used.
114  * @param ca_dir         If not @p NULL, points to a directory containing PEM
115  *                       encoded files containing all the Root CAs to be used.
116  *
117  * @return @c 1 if successful, else @c 0.
118  */
119 
120 int coap_dtls_context_set_pki_root_cas(coap_context_t *coap_context,
121                                        const char *ca_file,
122                                        const char *ca_dir);
123 
124 /**
125  * Check whether one of the coap_dtls_context_set_{psk|pki}() functions have
126  * been called.
127  *
128  * @param coap_context The current coap_context_t object.
129  *
130  * @return @c 1 if coap_dtls_context_set_{psk|pki}() called, else @c 0.
131  */
132 
133 int coap_dtls_context_check_keys_enabled(coap_context_t *coap_context);
134 
135 /**
136  * Releases the storage allocated for @p dtls_context.
137  *
138  * @param dtls_context The DTLS context as returned by coap_dtls_new_context().
139  */
140 void coap_dtls_free_context(void *dtls_context);
141 
142 #if COAP_CLIENT_SUPPORT
143 /**
144  * Create a new client-side session. This should send a HELLO to the server.
145  *
146  * @param coap_session   The CoAP session.
147  *
148  * @return Opaque handle to underlying TLS library object containing security
149  *         parameters for the session.
150 */
151 void *coap_dtls_new_client_session(coap_session_t *coap_session);
152 #endif /* COAP_CLIENT_SUPPORT */
153 
154 #if COAP_SERVER_SUPPORT
155 /**
156  * Create a new DTLS server-side session.
157  * Called after coap_dtls_hello() has returned @c 1, signalling that a validated
158  * HELLO was received from a client.
159  * This should send a HELLO to the server.
160  *
161  * @param coap_session   The CoAP session.
162  *
163  * @return Opaque handle to underlying TLS library object containing security
164  *         parameters for the DTLS session.
165  */
166 void *coap_dtls_new_server_session(coap_session_t *coap_session);
167 #endif /* COAP_SERVER_SUPPORT */
168 
169 /**
170  * Terminates the DTLS session (may send an ALERT if necessary) then frees the
171  * underlying TLS library object containing security parameters for the session.
172  *
173  * @param coap_session   The CoAP session.
174  */
175 void coap_dtls_free_session(coap_session_t *coap_session);
176 
177 /**
178  * Notify of a change in the CoAP session's MTU, for example after
179  * a PMTU update.
180  *
181  * @param coap_session   The CoAP session.
182  */
183 void coap_dtls_session_update_mtu(coap_session_t *coap_session);
184 
185 /**
186  * Send data to a DTLS peer.
187  *
188  * @param coap_session The CoAP session.
189  * @param data      pointer to data.
190  * @param data_len  Number of bytes to send.
191  *
192  * @return @c 0 if this would be blocking, @c -1 if there is an error or the
193  *         number of cleartext bytes sent.
194  */
195 ssize_t coap_dtls_send(coap_session_t *coap_session,
196                        const uint8_t *data,
197                        size_t data_len);
198 
199 /**
200  * Check if timeout is handled per CoAP session or per CoAP context.
201  *
202  * @return @c 1 of timeout and retransmit is per context, @c 0 if it is
203  *         per session.
204  */
205 int coap_dtls_is_context_timeout(void);
206 
207 /**
208  * Do all pending retransmits and get next timeout
209  *
210  * @param dtls_context The DTLS context.
211  *
212  * @return @c 0 if no event is pending or date of the next retransmit.
213  */
214 coap_tick_t coap_dtls_get_context_timeout(void *dtls_context);
215 
216 /**
217  * Get next timeout for this session.
218  *
219  * @param coap_session The CoAP session.
220  * @param now The current time in ticks.
221  *
222  * @return @c 0 If no event is pending or ticks time of the next retransmit.
223  */
224 coap_tick_t coap_dtls_get_timeout(coap_session_t *coap_session,
225                                   coap_tick_t now);
226 
227 /**
228  * Handle a DTLS timeout expiration.
229  *
230  * @param coap_session The CoAP session.
231  *
232  * @return @c 1 timed out or @c 0 still timing out
233  */
234 int coap_dtls_handle_timeout(coap_session_t *coap_session);
235 
236 /**
237  * Handling incoming data from a DTLS peer.
238  *
239  * @param coap_session The CoAP session.
240  * @param data      Encrypted datagram.
241  * @param data_len  Encrypted datagram size.
242  *
243  * @return Result of coap_handle_dgram on the decrypted CoAP PDU
244  *         or @c -1 for error.
245  */
246 int coap_dtls_receive(coap_session_t *coap_session,
247                       const uint8_t *data,
248                       size_t data_len);
249 
250 #if COAP_SERVER_SUPPORT
251 /**
252  * Handling client HELLO messages from a new candiate peer.
253  * Note that session->tls is empty.
254  *
255  * @param coap_session The CoAP session.
256  * @param data      Encrypted datagram.
257  * @param data_len  Encrypted datagram size.
258  *
259  * @return @c 0 if a cookie verification message has been sent, @c 1 if the
260  *        HELLO contains a valid cookie and a server session should be created,
261  *        @c -1 if the message is invalid.
262  */
263 int coap_dtls_hello(coap_session_t *coap_session,
264                     const uint8_t *data,
265                     size_t data_len);
266 #endif /* COAP_SERVER_SUPPORT */
267 
268 /**
269  * Layer function interface for layer below DTLS connect being
270  * established.
271  *
272  * If this layer is properly established on invocation, then the next layer
273  * must get called by calling
274  *   session->lfunc[COAP_LAYER_TLS].establish(session)
275  * (or done at any point when DTLS is established).
276  *
277  * @param session Session that the lower layer connect was done on.
278  *
279  */
280 void coap_dtls_establish(coap_session_t *session);
281 
282 /**
283  * Layer function interface for DTLS close for a session.
284  *
285  * @param session  Session to do the DTLS close on.
286  */
287 void coap_dtls_close(coap_session_t *session);
288 
289 /**
290  * Get DTLS overhead over cleartext PDUs.
291  *
292  * @param coap_session The CoAP session.
293  *
294  * @return Maximum number of bytes added by DTLS layer.
295  */
296 unsigned int coap_dtls_get_overhead(coap_session_t *coap_session);
297 
298 #if COAP_CLIENT_SUPPORT
299 /**
300  * Create a new TLS client-side session.
301  *
302  * @param coap_session The CoAP session.
303  *
304  * @return Opaque handle to underlying TLS library object containing security
305  *         parameters for the session.
306 */
307 void *coap_tls_new_client_session(coap_session_t *coap_session);
308 #endif /* COAP_CLIENT_SUPPORT */
309 
310 #if COAP_SERVER_SUPPORT
311 /**
312  * Create a TLS new server-side session.
313  *
314  * @param coap_session The CoAP session.
315  *
316  * @return Opaque handle to underlying TLS library object containing security
317  *         parameters for the session.
318  */
319 void *coap_tls_new_server_session(coap_session_t *coap_session);
320 #endif /* COAP_SERVER_SUPPORT */
321 
322 /**
323  * Terminates the TLS session (may send an ALERT if necessary) then frees the
324  * underlying TLS library object containing security parameters for the session.
325  *
326  * @param coap_session The CoAP session.
327  */
328 void coap_tls_free_session(coap_session_t *coap_session);
329 
330 /**
331  * Send data to a TLS peer, with implicit flush.
332  *
333  * @param coap_session The CoAP session.
334  * @param data      Pointer to data.
335  * @param data_len  Number of bytes to send.
336  *
337  * @return          @c 0 if this should be retried, @c -1 if there is an error
338  *                  or the number of cleartext bytes sent.
339  */
340 ssize_t coap_tls_write(coap_session_t *coap_session,
341                        const uint8_t *data,
342                        size_t data_len
343                       );
344 
345 /**
346  * Read some data from a TLS peer.
347  *
348  * @param coap_session The CoAP session.
349  * @param data      Pointer to data.
350  * @param data_len  Maximum number of bytes to read.
351  *
352  * @return          @c 0 if this should be retried, @c -1 if there is an error
353  *                  or the number of cleartext bytes read.
354  */
355 ssize_t coap_tls_read(coap_session_t *coap_session,
356                       uint8_t *data,
357                       size_t data_len
358                      );
359 
360 /**
361  * Layer function interface for layer below TLS accept/connect being
362  *  established. This function initiates an accept/connect at the TLS layer.
363  *
364  * If this layer is properly established on invocation, then the next layer
365  * must get called by calling
366  *   session->lfunc[COAP_LAYER_TLS].establish(session)
367  * (or done at any point when TLS is established).
368  *
369  * @param session Session that the lower layer accept/connect was done on.
370  *
371  */
372 void coap_tls_establish(coap_session_t *session);
373 
374 /**
375  * Layer function interface for TLS close for a session.
376  *
377  * @param session  Session to do the TLS close on.
378  */
379 void coap_tls_close(coap_session_t *session);
380 
381 /**
382  * Get the current client's PSK key.
383  *
384  * @param coap_session The CoAP session.
385  *
386  * @return          @c NULL if no key, else a pointer the current key.
387  */
388 const coap_bin_const_t *coap_get_session_client_psk_key(
389     const coap_session_t *coap_session);
390 
391 /**
392  * Get the current client's PSK identity.
393  *
394  * @param coap_session The CoAP session.
395  *
396  * @return          @c NULL if no identity, else a pointer the current identity.
397  */
398 const coap_bin_const_t *coap_get_session_client_psk_identity(
399     const coap_session_t *coap_session);
400 
401 /**
402  * Get the current server's PSK key.
403  *
404  * @param coap_session The CoAP session.
405  *
406  * @return          @c NULL if no key, else a pointer the current key.
407  */
408 const coap_bin_const_t *coap_get_session_server_psk_key(
409     const coap_session_t *coap_session);
410 
411 /**
412  * Get the current server's PSK identity hint.
413  *
414  * @param coap_session The CoAP session.
415  *
416  * @return          @c NULL if no hint, else a pointer the current hint.
417  */
418 const coap_bin_const_t *coap_get_session_server_psk_hint(
419     const coap_session_t *coap_session);
420 
421 /**
422  * Initialize the underlying (D)TLS Library layer.
423  *
424  */
425 void coap_dtls_startup(void);
426 
427 /**
428  * Close down the underlying (D)TLS Library layer.
429  *
430  */
431 void coap_dtls_shutdown(void);
432 
433 /**
434  * Get the actual (D)TLS object for the session.
435  *
436  * @param session The session.
437  * @param tls_lib Updated with the library type.
438  *
439  * @return The TLS information.
440  */
441 void *coap_dtls_get_tls(const coap_session_t *session,
442                         coap_tls_library_t *tls_lib);
443 
444 /** @} */
445 
446 #endif /* COAP_DTLS_INTERNAL_H */
447