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