1 /* 2 * coap_dtls.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 * This file is part of the CoAP library libcoap. Please see README for terms 8 * of use. 9 */ 10 11 #ifndef COAP_DTLS_H_ 12 #define COAP_DTLS_H_ 13 14 #include "coap_time.h" 15 #include "str.h" 16 17 struct coap_context_t; 18 struct coap_session_t; 19 struct coap_dtls_pki_t; 20 21 /** 22 * @defgroup dtls DTLS Support 23 * API functions for interfacing with DTLS libraries. 24 * @{ 25 */ 26 27 /** 28 * Check whether DTLS is available. 29 * 30 * @return @c 1 if support for DTLS is enabled, or @c 0 otherwise. 31 */ 32 int coap_dtls_is_supported(void); 33 34 /** 35 * Check whether TLS is available. 36 * 37 * @return @c 1 if support for TLS is enabled, or @c 0 otherwise. 38 */ 39 int coap_tls_is_supported(void); 40 41 typedef enum coap_tls_library_t { 42 COAP_TLS_LIBRARY_NOTLS = 0, /**< No DTLS library */ 43 COAP_TLS_LIBRARY_TINYDTLS, /**< Using TinyDTLS library */ 44 COAP_TLS_LIBRARY_OPENSSL, /**< Using OpenSSL library */ 45 COAP_TLS_LIBRARY_GNUTLS, /**< Using GnuTLS library */ 46 COAP_TLS_LIBRARY_MBEDTLS, /**< Using MbedTLS library */ 47 } coap_tls_library_t; 48 49 /** 50 * The structure used for returning the underlying (D)TLS library 51 * information. 52 */ 53 typedef struct coap_tls_version_t { 54 uint64_t version; /**< (D)TLS runtime Library Version */ 55 coap_tls_library_t type; /**< Library type. One of COAP_TLS_LIBRARY_* */ 56 uint64_t built_version; /**< (D)TLS Built against Library Version */ 57 } coap_tls_version_t; 58 59 /** 60 * Determine the type and version of the underlying (D)TLS library. 61 * 62 * @return The version and type of library libcoap was compiled against. 63 */ 64 coap_tls_version_t *coap_get_tls_library_version(void); 65 66 /** 67 * Additional Security setup handler that can be set up by 68 * coap_context_set_pki(). 69 * Invoked when libcoap has done the validation checks at the TLS level, 70 * but the application needs to do some additional checks/changes/updates. 71 * 72 * @param tls_session The security session definition - e.g. SSL * for OpenSSL. 73 * NULL if server call-back. 74 * This will be dependent on the underlying TLS library - 75 * see coap_get_tls_library_version() 76 * @param setup_data A structure containing setup data originally passed into 77 * coap_context_set_pki() or coap_new_client_session_pki(). 78 * 79 * @return @c 1 if successful, else @c 0. 80 */ 81 typedef int (*coap_dtls_security_setup_t)(void* tls_session, 82 struct coap_dtls_pki_t *setup_data); 83 84 /** 85 * CN Validation call-back that can be set up by coap_context_set_pki(). 86 * Invoked when libcoap has done the validation checks at the TLS level, 87 * but the application needs to check that the CN is allowed. 88 * CN is the SubjectAltName in the cert, if not present, then the leftmost 89 * Common Name (CN) component of the subject name. 90 * 91 * @param cn The determined CN from the certificate 92 * @param asn1_public_cert The ASN.1 DER encoded X.509 certificate 93 * @param asn1_length The ASN.1 length 94 * @param coap_session The CoAP session associated with the certificate update 95 * @param depth Depth in cert chain. If 0, then client cert, else a CA 96 * @param validated TLS layer can find no issues if 1 97 * @param arg The same as was passed into coap_context_set_pki() 98 * in setup_data->cn_call_back_arg 99 * 100 * @return @c 1 if accepted, else @c 0 if to be rejected. 101 */ 102 typedef int (*coap_dtls_cn_callback_t)(const char *cn, 103 const uint8_t *asn1_public_cert, 104 size_t asn1_length, 105 struct coap_session_t *coap_session, 106 unsigned depth, 107 int validated, 108 void *arg); 109 110 /** 111 * The enum used for determining the provided PKI ASN.1 (DER) Private Key 112 * formats. 113 */ 114 typedef enum coap_asn1_privatekey_type_t { 115 COAP_ASN1_PKEY_NONE, /**< NONE */ 116 COAP_ASN1_PKEY_RSA, /**< RSA type */ 117 COAP_ASN1_PKEY_RSA2, /**< RSA2 type */ 118 COAP_ASN1_PKEY_DSA, /**< DSA type */ 119 COAP_ASN1_PKEY_DSA1, /**< DSA1 type */ 120 COAP_ASN1_PKEY_DSA2, /**< DSA2 type */ 121 COAP_ASN1_PKEY_DSA3, /**< DSA3 type */ 122 COAP_ASN1_PKEY_DSA4, /**< DSA4 type */ 123 COAP_ASN1_PKEY_DH, /**< DH type */ 124 COAP_ASN1_PKEY_DHX, /**< DHX type */ 125 COAP_ASN1_PKEY_EC, /**< EC type */ 126 COAP_ASN1_PKEY_HMAC, /**< HMAC type */ 127 COAP_ASN1_PKEY_CMAC, /**< CMAC type */ 128 COAP_ASN1_PKEY_TLS1_PRF, /**< TLS1_PRF type */ 129 COAP_ASN1_PKEY_HKDF /**< HKDF type */ 130 } coap_asn1_privatekey_type_t; 131 132 /** 133 * The enum used for determining the PKI key formats. 134 */ 135 typedef enum coap_pki_key_t { 136 COAP_PKI_KEY_PEM = 0, /**< The PKI key type is PEM file */ 137 COAP_PKI_KEY_ASN1, /**< The PKI key type is ASN.1 (DER) */ 138 COAP_PKI_KEY_PEM_BUF, /**< The PKI key type is PEM buffer */ 139 } coap_pki_key_t; 140 141 /** 142 * The structure that holds the PKI PEM definitions. 143 */ 144 typedef struct coap_pki_key_pem_t { 145 const char *ca_file; /**< File location of Common CA in PEM format */ 146 const char *public_cert; /**< File location of Public Cert in PEM format */ 147 const char *private_key; /**< File location of Private Key in PEM format */ 148 } coap_pki_key_pem_t; 149 150 /** 151 * The structure that holds the PKI PEM buffer definitions. 152 */ 153 typedef struct coap_pki_key_pem_buf_t { 154 const uint8_t *ca_cert; /**< PEM buffer Common CA Cert */ 155 const uint8_t *public_cert; /**< PEM buffer Public Cert */ 156 const uint8_t *private_key; /**< PEM buffer Private Key */ 157 size_t ca_cert_len; /**< PEM buffer CA Cert length */ 158 size_t public_cert_len; /**< PEM buffer Public Cert length */ 159 size_t private_key_len; /**< PEM buffer Private Key length */ 160 } coap_pki_key_pem_buf_t; 161 162 /** 163 * The structure that holds the PKI ASN.1 (DER) definitions. 164 */ 165 typedef struct coap_pki_key_asn1_t { 166 const uint8_t *ca_cert; /**< ASN1 (DER) Common CA Cert */ 167 const uint8_t *public_cert; /**< ASN1 (DER) Public Cert */ 168 const uint8_t *private_key; /**< ASN1 (DER) Private Key */ 169 size_t ca_cert_len; /**< ASN1 CA Cert length */ 170 size_t public_cert_len; /**< ASN1 Public Cert length */ 171 size_t private_key_len; /**< ASN1 Private Key length */ 172 coap_asn1_privatekey_type_t private_key_type; /**< Private Key Type */ 173 } coap_pki_key_asn1_t; 174 175 /** 176 * The structure that holds the PKI key information. 177 */ 178 typedef struct coap_dtls_key_t { 179 coap_pki_key_t key_type; /**< key format type */ 180 union { 181 coap_pki_key_pem_t pem; /**< for PEM file keys */ 182 coap_pki_key_pem_buf_t pem_buf; /**< for PEM memory keys */ 183 coap_pki_key_asn1_t asn1; /**< for ASN.1 (DER) file keys */ 184 } key; 185 } coap_dtls_key_t; 186 187 /** 188 * Server Name Indication (SNI) Validation call-back that can be set up by 189 * coap_context_set_pki(). 190 * Invoked if the SNI is not previously seen and prior to sending a certificate 191 * set back to the client so that the appropriate certificate set can be used 192 * based on the requesting SNI. 193 * 194 * @param sni The requested SNI 195 * @param arg The same as was passed into coap_context_set_pki() 196 * in setup_data->sni_call_back_arg 197 * 198 * @return New set of certificates to use, or @c NULL if SNI is to be rejected. 199 */ 200 typedef coap_dtls_key_t *(*coap_dtls_sni_callback_t)(const char *sni, 201 void* arg); 202 203 204 #define COAP_DTLS_PKI_SETUP_VERSION 1 /**< Latest PKI setup version */ 205 206 /** 207 * The structure used for defining the PKI setup data to be used. 208 */ 209 typedef struct coap_dtls_pki_t { 210 uint8_t version; /** Set to 1 to support this version of the struct */ 211 212 /* Options to enable different TLS functionality in libcoap */ 213 uint8_t verify_peer_cert; /**< 1 if peer cert is to be verified */ 214 uint8_t require_peer_cert; /**< 1 if peer cert is required */ 215 uint8_t allow_self_signed; /**< 1 if self signed certs are allowed */ 216 uint8_t allow_expired_certs; /**< 1 if expired certs are allowed */ 217 uint8_t cert_chain_validation; /**< 1 if to check cert_chain_verify_depth */ 218 uint8_t cert_chain_verify_depth; /**< recommended depth is 3 */ 219 uint8_t check_cert_revocation; /**< 1 if revocation checks wanted */ 220 uint8_t allow_no_crl; /**< 1 ignore if CRL not there */ 221 uint8_t allow_expired_crl; /**< 1 if expired crl is allowed */ 222 uint8_t allow_bad_md_hash; /**< 1 if expired certs are allowed */ 223 uint8_t allow_short_rsa_length; /**< 1 if expired certs are allowed */ 224 uint8_t reserved[4]; /**< Reserved - must be set to 0 for 225 future compatibility */ 226 /* Size of 4 chosen to align to next 227 * parameter, so if newly defined option 228 * it can use one of the reserverd slot so 229 * no need to change 230 * COAP_DTLS_PKI_SETUP_VERSION and just 231 * decrement the reserved[] count. 232 */ 233 234 /** CN check call-back function. 235 * If not NULL, is called when the TLS connection has passed the configured 236 * TLS options above for the application to verify if the CN is valid. 237 */ 238 coap_dtls_cn_callback_t validate_cn_call_back; 239 void *cn_call_back_arg; /**< Passed in to the CN call-back function */ 240 241 /** SNI check call-back function. 242 * If not @p NULL, called if the SNI is not previously seen and prior to 243 * sending a certificate set back to the client so that the appropriate 244 * certificate set can be used based on the requesting SNI. 245 */ 246 coap_dtls_sni_callback_t validate_sni_call_back; 247 void *sni_call_back_arg; /**< Passed in to the sni call-back function */ 248 249 /** Additional Security call-back handler that is invoked when libcoap has 250 * done the standerd, defined validation checks at the TLS level, 251 * If not @p NULL, called from within the TLS Client Hello connection 252 * setup. 253 */ 254 coap_dtls_security_setup_t additional_tls_setup_call_back; 255 256 char* client_sni; /**< If not NULL, SNI to use in client TLS setup. 257 Owned by the client app and must remain valid 258 during the call to coap_new_client_session_pki() */ 259 260 coap_dtls_key_t pki_key; /**< PKI key definition */ 261 } coap_dtls_pki_t; 262 263 /** @} */ 264 265 /** 266 * @defgroup dtls_internal DTLS Support (Internal) 267 * Internal API functions for interfacing with DTLS libraries. 268 * @{ 269 */ 270 271 /** 272 * Creates a new DTLS context for the given @p coap_context. This function 273 * returns a pointer to a new DTLS context object or @c NULL on error. 274 * 275 * Internal function. 276 * 277 * @param coap_context The CoAP context where the DTLS object shall be used. 278 * 279 * @return A DTLS context object or @c NULL on error. 280 */ 281 void * 282 coap_dtls_new_context(struct coap_context_t *coap_context); 283 284 typedef enum coap_dtls_role_t { 285 COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */ 286 COAP_DTLS_ROLE_SERVER /**< Internal function invoked for server */ 287 } coap_dtls_role_t; 288 289 /** 290 * Set the DTLS context's default PSK information. 291 * This does the PSK specifics following coap_dtls_new_context(). 292 * If @p COAP_DTLS_ROLE_SERVER, then identity hint will also get set. 293 * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the 294 * TLS library's context (from which sessions are derived). 295 * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the 296 * TLS library's session. 297 * 298 * Internal function. 299 * 300 * @param coap_context The CoAP context. 301 * @param identity_hint The default PSK server identity hint sent to a client. 302 * Required parameter. If @p NULL, will be set to "". 303 * Empty string is a valid hint. 304 * This parameter is ignored if COAP_DTLS_ROLE_CLIENT 305 * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER 306 * 307 * @return @c 1 if successful, else @c 0. 308 */ 309 310 int 311 coap_dtls_context_set_psk(struct coap_context_t *coap_context, 312 const char *identity_hint, 313 coap_dtls_role_t role); 314 315 /** 316 * Set the DTLS context's default server PKI information. 317 * This does the PKI specifics following coap_dtls_new_context(). 318 * If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the 319 * TLS library's context (from which sessions are derived). 320 * If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the 321 * TLS library's session. 322 * 323 * Internal function. 324 * 325 * @param coap_context The CoAP context. 326 * @param setup_data Setup information defining how PKI is to be setup. 327 * Required parameter. If @p NULL, PKI will not be 328 * set up. 329 * @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER 330 * 331 * @return @c 1 if successful, else @c 0. 332 */ 333 334 int 335 coap_dtls_context_set_pki(struct coap_context_t *coap_context, 336 coap_dtls_pki_t *setup_data, 337 coap_dtls_role_t role); 338 339 /** 340 * Set the dtls context's default Root CA information for a client or server. 341 * 342 * Internal function. 343 * 344 * @param coap_context The current coap_context_t object. 345 * @param ca_file If not @p NULL, is the full path name of a PEM encoded 346 * file containing all the Root CAs to be used. 347 * @param ca_dir If not @p NULL, points to a directory containing PEM 348 * encoded files containing all the Root CAs to be used. 349 * 350 * @return @c 1 if successful, else @c 0. 351 */ 352 353 int 354 coap_dtls_context_set_pki_root_cas(struct coap_context_t *coap_context, 355 const char *ca_file, 356 const char *ca_dir); 357 358 /** 359 * Check whether one of the coap_dtls_context_set_{psk|pki}() functions have 360 * been called. 361 * 362 * Internal function. 363 * 364 * @param coap_context The current coap_context_t object. 365 * 366 * @return @c 1 if coap_dtls_context_set_{psk|pki}() called, else @c 0. 367 */ 368 369 int coap_dtls_context_check_keys_enabled(struct coap_context_t *coap_context); 370 371 /** 372 * Releases the storage allocated for @p dtls_context. 373 * 374 * Internal function. 375 * 376 * @param dtls_context The DTLS context as returned by coap_dtls_new_context(). 377 */ 378 void coap_dtls_free_context(void *dtls_context); 379 380 /** 381 * Create a new client-side session. This should send a HELLO to the server. 382 * 383 * Internal function. 384 * 385 * @param coap_session The CoAP session. 386 * 387 * @return Opaque handle to underlying TLS library object containing security 388 * parameters for the session. 389 */ 390 void *coap_dtls_new_client_session(struct coap_session_t *coap_session); 391 392 /** 393 * Create a new DTLS server-side session. 394 * Called after coap_dtls_hello() has returned @c 1, signalling that a validated 395 * HELLO was received from a client. 396 * This should send a HELLO to the server. 397 * 398 * Internal function. 399 * 400 * @param coap_session The CoAP session. 401 * 402 * @return Opaque handle to underlying TLS library object containing security 403 * parameters for the DTLS session. 404 */ 405 void *coap_dtls_new_server_session(struct coap_session_t *coap_session); 406 407 /** 408 * Terminates the DTLS session (may send an ALERT if necessary) then frees the 409 * underlying TLS library object containing security parameters for the session. 410 * 411 * Internal function. 412 * 413 * @param coap_session The CoAP session. 414 */ 415 void coap_dtls_free_session(struct coap_session_t *coap_session); 416 417 /** 418 * Notify of a change in the CoAP session's MTU, for example after 419 * a PMTU update. 420 * 421 * Internal function. 422 * 423 * @param coap_session The CoAP session. 424 */ 425 void coap_dtls_session_update_mtu(struct coap_session_t *coap_session); 426 427 /** 428 * Send data to a DTLS peer. 429 * 430 * Internal function. 431 * 432 * @param coap_session The CoAP session. 433 * @param data pointer to data. 434 * @param data_len Number of bytes to send. 435 * 436 * @return @c 0 if this would be blocking, @c -1 if there is an error or the 437 * number of cleartext bytes sent. 438 */ 439 int coap_dtls_send(struct coap_session_t *coap_session, 440 const uint8_t *data, 441 size_t data_len); 442 443 /** 444 * Check if timeout is handled per CoAP session or per CoAP context. 445 * 446 * Internal function. 447 * 448 * @return @c 1 of timeout and retransmit is per context, @c 0 if it is 449 * per session. 450 */ 451 int coap_dtls_is_context_timeout(void); 452 453 /** 454 * Do all pending retransmits and get next timeout 455 * 456 * Internal function. 457 * 458 * @param dtls_context The DTLS context. 459 * 460 * @return @c 0 if no event is pending or date of the next retransmit. 461 */ 462 coap_tick_t coap_dtls_get_context_timeout(void *dtls_context); 463 464 /** 465 * Get next timeout for this session. 466 * 467 * Internal function. 468 * 469 * @param coap_session The CoAP session. 470 * @param now The current time in ticks. 471 * 472 * @return @c 0 If no event is pending or ticks time of the next retransmit. 473 */ 474 coap_tick_t coap_dtls_get_timeout(struct coap_session_t *coap_session, 475 coap_tick_t now); 476 477 /** 478 * Handle a DTLS timeout expiration. 479 * 480 * Internal function. 481 * 482 * @param coap_session The CoAP session. 483 */ 484 void coap_dtls_handle_timeout(struct coap_session_t *coap_session); 485 486 /** 487 * Handling incoming data from a DTLS peer. 488 * 489 * Internal function. 490 * 491 * @param coap_session The CoAP session. 492 * @param data Encrypted datagram. 493 * @param data_len Encrypted datagram size. 494 * 495 * @return Result of coap_handle_dgram on the decrypted CoAP PDU 496 * or @c -1 for error. 497 */ 498 int coap_dtls_receive(struct coap_session_t *coap_session, 499 const uint8_t *data, 500 size_t data_len); 501 502 /** 503 * Handling client HELLO messages from a new candiate peer. 504 * Note that session->tls is empty. 505 * 506 * Internal function. 507 * 508 * @param coap_session The CoAP session. 509 * @param data Encrypted datagram. 510 * @param data_len Encrypted datagram size. 511 * 512 * @return @c 0 if a cookie verification message has been sent, @c 1 if the 513 * HELLO contains a valid cookie and a server session should be created, 514 * @c -1 if the message is invalid. 515 */ 516 int coap_dtls_hello(struct coap_session_t *coap_session, 517 const uint8_t *data, 518 size_t data_len); 519 520 /** 521 * Get DTLS overhead over cleartext PDUs. 522 * 523 * Internal function. 524 * 525 * @param coap_session The CoAP session. 526 * 527 * @return Maximum number of bytes added by DTLS layer. 528 */ 529 unsigned int coap_dtls_get_overhead(struct coap_session_t *coap_session); 530 531 /** 532 * Create a new TLS client-side session. 533 * 534 * Internal function. 535 * 536 * @param coap_session The CoAP session. 537 * @param connected Updated with whether the connection is connected yet or not. 538 * @c 0 is not connected, @c 1 is connected. 539 * 540 * @return Opaque handle to underlying TLS library object containing security 541 * parameters for the session. 542 */ 543 void *coap_tls_new_client_session(struct coap_session_t *coap_session, int *connected); 544 545 /** 546 * Create a TLS new server-side session. 547 * 548 * Internal function. 549 * 550 * @param coap_session The CoAP session. 551 * @param connected Updated with whether the connection is connected yet or not. 552 * @c 0 is not connected, @c 1 is connected. 553 * 554 * @return Opaque handle to underlying TLS library object containing security 555 * parameters for the session. 556 */ 557 void *coap_tls_new_server_session(struct coap_session_t *coap_session, int *connected); 558 559 /** 560 * Terminates the TLS session (may send an ALERT if necessary) then frees the 561 * underlying TLS library object containing security parameters for the session. 562 * 563 * Internal function. 564 * 565 * @param coap_session The CoAP session. 566 */ 567 void coap_tls_free_session( struct coap_session_t *coap_session ); 568 569 /** 570 * Send data to a TLS peer, with implicit flush. 571 * 572 * Internal function. 573 * 574 * @param coap_session The CoAP session. 575 * @param data Pointer to data. 576 * @param data_len Number of bytes to send. 577 * 578 * @return @c 0 if this should be retried, @c -1 if there is an error 579 * or the number of cleartext bytes sent. 580 */ 581 ssize_t coap_tls_write(struct coap_session_t *coap_session, 582 const uint8_t *data, 583 size_t data_len 584 ); 585 586 /** 587 * Read some data from a TLS peer. 588 * 589 * Internal function. 590 * 591 * @param coap_session The CoAP session. 592 * @param data Pointer to data. 593 * @param data_len Maximum number of bytes to read. 594 * 595 * @return @c 0 if this should be retried, @c -1 if there is an error 596 * or the number of cleartext bytes read. 597 */ 598 ssize_t coap_tls_read(struct coap_session_t *coap_session, 599 uint8_t *data, 600 size_t data_len 601 ); 602 603 /** 604 * Initialize the underlying (D)TLS Library layer. 605 * 606 * Internal function. 607 * 608 */ 609 void coap_dtls_startup(void); 610 611 /** @} */ 612 613 /** 614 * @ingroup logging 615 * Sets the (D)TLS logging level to the specified @p level. 616 * Note: coap_log_level() will influence output if at a specified level. 617 * 618 * @param level The logging level to use - LOG_* 619 */ 620 void coap_dtls_set_log_level(int level); 621 622 /** 623 * @ingroup logging 624 * Get the current (D)TLS logging. 625 * 626 * @return The current log level (one of LOG_*). 627 */ 628 int coap_dtls_get_log_level(void); 629 630 631 #endif /* COAP_DTLS_H */ 632