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