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 * 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.h 15 * @brief CoAP DTLS support 16 */ 17 18 #ifndef COAP_DTLS_H_ 19 #define COAP_DTLS_H_ 20 21 #include "coap_time.h" 22 #include "coap_str.h" 23 24 /** 25 * @ingroup application_api 26 * @defgroup dtls DTLS Support 27 * API for interfacing with DTLS libraries. 28 * @{ 29 */ 30 31 typedef struct coap_dtls_pki_t coap_dtls_pki_t; 32 33 #ifndef COAP_DTLS_HINT_LENGTH 34 #define COAP_DTLS_HINT_LENGTH 128 35 #endif 36 #ifndef COAP_DTLS_MAX_PSK_IDENTITY 37 #define COAP_DTLS_MAX_PSK_IDENTITY 64 38 #endif 39 #ifndef COAP_DTLS_MAX_PSK 40 #define COAP_DTLS_MAX_PSK 64 41 #endif 42 43 typedef enum coap_dtls_role_t { 44 COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */ 45 COAP_DTLS_ROLE_SERVER /**< Internal function invoked for server */ 46 } coap_dtls_role_t; 47 48 #define COAP_DTLS_RPK_CERT_CN "RPK" 49 50 /** 51 * Check whether DTLS is available. 52 * 53 * @return @c 1 if support for DTLS is available, or @c 0 otherwise. 54 */ 55 int coap_dtls_is_supported(void); 56 57 /** 58 * Check whether TLS is available. 59 * 60 * @return @c 1 if support for TLS is available, or @c 0 otherwise. 61 */ 62 int coap_tls_is_supported(void); 63 64 /** 65 * Check whether (D)TLS PSK is available. 66 * 67 * @return @c 1 if support for (D)TLS PSK is available, or @c 0 otherwise. 68 */ 69 int coap_dtls_psk_is_supported(void); 70 71 /** 72 * Check whether (D)TLS PKI is available. 73 * 74 * @return @c 1 if support for (D)TLS PKI is available, or @c 0 otherwise. 75 */ 76 int coap_dtls_pki_is_supported(void); 77 78 /** 79 * Check whether (D)TLS PKCS11 is available. 80 * 81 * @return @c 1 if support for (D)TLS PKCS11 is available, or @c 0 otherwise. 82 */ 83 int coap_dtls_pkcs11_is_supported(void); 84 85 /** 86 * Check whether (D)TLS RPK is available. 87 * 88 * @return @c 1 if support for (D)TLS RPK is available, or @c 0 otherwise. 89 */ 90 int coap_dtls_rpk_is_supported(void); 91 92 typedef enum coap_tls_library_t { 93 COAP_TLS_LIBRARY_NOTLS = 0, /**< No DTLS library */ 94 COAP_TLS_LIBRARY_TINYDTLS, /**< Using TinyDTLS library */ 95 COAP_TLS_LIBRARY_OPENSSL, /**< Using OpenSSL library */ 96 COAP_TLS_LIBRARY_GNUTLS, /**< Using GnuTLS library */ 97 COAP_TLS_LIBRARY_MBEDTLS, /**< Using Mbed TLS library */ 98 } coap_tls_library_t; 99 100 /** 101 * The structure used for returning the underlying (D)TLS library 102 * information. 103 */ 104 typedef struct coap_tls_version_t { 105 uint64_t version; /**< (D)TLS runtime Library Version */ 106 coap_tls_library_t type; /**< Library type. One of COAP_TLS_LIBRARY_* */ 107 uint64_t built_version; /**< (D)TLS Built against Library Version */ 108 } coap_tls_version_t; 109 110 /** 111 * Determine the type and version of the underlying (D)TLS library. 112 * 113 * @return The version and type of library libcoap was compiled against. 114 */ 115 coap_tls_version_t *coap_get_tls_library_version(void); 116 117 /** 118 * Additional Security setup handler that can be set up by 119 * coap_context_set_pki(). 120 * Invoked when libcoap has done the validation checks at the TLS level, 121 * but the application needs to do some additional checks/changes/updates. 122 * 123 * @param tls_session The security session definition - e.g. SSL * for OpenSSL. 124 * NULL if server callback. 125 * This will be dependent on the underlying TLS library - 126 * see coap_get_tls_library_version() 127 * @param setup_data A structure containing setup data originally passed into 128 * coap_context_set_pki() or coap_new_client_session_pki(). 129 * 130 * @return @c 1 if successful, else @c 0. 131 */ 132 typedef int (*coap_dtls_security_setup_t)(void *tls_session, 133 coap_dtls_pki_t *setup_data); 134 135 /** 136 * CN Validation callback that can be set up by coap_context_set_pki(). 137 * Invoked when libcoap has done the validation checks at the TLS level, 138 * but the application needs to check that the CN is allowed. 139 * CN is the SubjectAltName in the cert, if not present, then the leftmost 140 * Common Name (CN) component of the subject name. 141 * NOTE: If using RPK, then the Public Key does not contain a CN, but the 142 * content of COAP_DTLS_RPK_CERT_CN is presented for the @p cn parameter. 143 * 144 * @param cn The determined CN from the certificate 145 * @param asn1_public_cert The ASN.1 DER encoded X.509 certificate 146 * @param asn1_length The ASN.1 length 147 * @param coap_session The CoAP session associated with the certificate update 148 * @param depth Depth in cert chain. If 0, then client cert, else a CA 149 * @param validated TLS layer can find no issues if 1 150 * @param arg The same as was passed into coap_context_set_pki() 151 * in setup_data->cn_call_back_arg 152 * 153 * @return @c 1 if accepted, else @c 0 if to be rejected. 154 */ 155 typedef int (*coap_dtls_cn_callback_t)(const char *cn, 156 const uint8_t *asn1_public_cert, 157 size_t asn1_length, 158 coap_session_t *coap_session, 159 unsigned int depth, 160 int validated, 161 void *arg); 162 163 /** 164 * The enum used for determining the provided PKI ASN.1 (DER) Private Key 165 * formats. 166 */ 167 typedef enum coap_asn1_privatekey_type_t { 168 COAP_ASN1_PKEY_NONE, /**< NONE */ 169 COAP_ASN1_PKEY_RSA, /**< RSA type */ 170 COAP_ASN1_PKEY_RSA2, /**< RSA2 type */ 171 COAP_ASN1_PKEY_DSA, /**< DSA type */ 172 COAP_ASN1_PKEY_DSA1, /**< DSA1 type */ 173 COAP_ASN1_PKEY_DSA2, /**< DSA2 type */ 174 COAP_ASN1_PKEY_DSA3, /**< DSA3 type */ 175 COAP_ASN1_PKEY_DSA4, /**< DSA4 type */ 176 COAP_ASN1_PKEY_DH, /**< DH type */ 177 COAP_ASN1_PKEY_DHX, /**< DHX type */ 178 COAP_ASN1_PKEY_EC, /**< EC type */ 179 COAP_ASN1_PKEY_HMAC, /**< HMAC type */ 180 COAP_ASN1_PKEY_CMAC, /**< CMAC type */ 181 COAP_ASN1_PKEY_TLS1_PRF, /**< TLS1_PRF type */ 182 COAP_ASN1_PKEY_HKDF /**< HKDF type */ 183 } coap_asn1_privatekey_type_t; 184 185 /** 186 * The enum used for determining the PKI key formats. 187 */ 188 typedef enum coap_pki_key_t { 189 COAP_PKI_KEY_PEM = 0, /**< The PKI key type is PEM file */ 190 COAP_PKI_KEY_ASN1, /**< The PKI key type is ASN.1 (DER) buffer */ 191 COAP_PKI_KEY_PEM_BUF, /**< The PKI key type is PEM buffer */ 192 COAP_PKI_KEY_PKCS11, /**< The PKI key type is PKCS11 (DER) */ 193 } coap_pki_key_t; 194 195 /** 196 * The structure that holds the PKI PEM definitions. 197 */ 198 typedef struct coap_pki_key_pem_t { 199 const char *ca_file; /**< File location of Common CA in PEM format */ 200 const char *public_cert; /**< File location of Public Cert */ 201 const char *private_key; /**< File location of Private Key in PEM format */ 202 } coap_pki_key_pem_t; 203 204 /** 205 * The structure that holds the PKI PEM buffer definitions. 206 * The certificates and private key data must be in PEM format. 207 * 208 * Note: The Certs and Key should be NULL terminated strings for 209 * performance reasons (to save a potential buffer copy) and the length include 210 * this NULL terminator. It is not a requirement to have the NULL terminator 211 * though and the length must then reflect the actual data size. 212 */ 213 typedef struct coap_pki_key_pem_buf_t { 214 const uint8_t *ca_cert; /**< PEM buffer Common CA Cert */ 215 const uint8_t *public_cert; /**< PEM buffer Public Cert, or Public Key if RPK */ 216 const uint8_t *private_key; /**< PEM buffer Private Key 217 If RPK and 'EC PRIVATE KEY' this can be used 218 for both the public_cert and private_key */ 219 size_t ca_cert_len; /**< PEM buffer CA Cert length */ 220 size_t public_cert_len; /**< PEM buffer Public Cert length */ 221 size_t private_key_len; /**< PEM buffer Private Key length */ 222 } coap_pki_key_pem_buf_t; 223 224 /** 225 * The structure that holds the PKI ASN.1 (DER) definitions. 226 */ 227 typedef struct coap_pki_key_asn1_t { 228 const uint8_t *ca_cert; /**< ASN1 (DER) Common CA Cert */ 229 const uint8_t *public_cert; /**< ASN1 (DER) Public Cert, or Public Key if RPK */ 230 const uint8_t *private_key; /**< ASN1 (DER) Private Key */ 231 size_t ca_cert_len; /**< ASN1 CA Cert length */ 232 size_t public_cert_len; /**< ASN1 Public Cert length */ 233 size_t private_key_len; /**< ASN1 Private Key length */ 234 coap_asn1_privatekey_type_t private_key_type; /**< Private Key Type */ 235 } coap_pki_key_asn1_t; 236 237 /** 238 * The structure that holds the PKI PKCS11 definitions. 239 */ 240 typedef struct coap_pki_key_pkcs11_t { 241 const char *ca; /**< pkcs11: URI for Common CA Certificate */ 242 const char *public_cert; /**< pkcs11: URI for Public Cert */ 243 const char *private_key; /**< pkcs11: URI for Private Key */ 244 const char *user_pin; /**< User pin to access PKCS11. If NULL, then 245 pin-value= parameter must be set in 246 pkcs11: URI as a query. */ 247 } coap_pki_key_pkcs11_t; 248 249 /** 250 * The structure that holds the PKI key information. 251 */ 252 typedef struct coap_dtls_key_t { 253 coap_pki_key_t key_type; /**< key format type */ 254 union { 255 coap_pki_key_pem_t pem; /**< for PEM file keys */ 256 coap_pki_key_pem_buf_t pem_buf; /**< for PEM memory keys */ 257 coap_pki_key_asn1_t asn1; /**< for ASN.1 (DER) memory keys */ 258 coap_pki_key_pkcs11_t pkcs11; /**< for PKCS11 keys */ 259 } key; 260 } coap_dtls_key_t; 261 262 /** 263 * Server Name Indication (SNI) Validation callback that can be set up by 264 * coap_context_set_pki(). 265 * Invoked if the SNI is not previously seen and prior to sending a certificate 266 * set back to the client so that the appropriate certificate set can be used 267 * based on the requesting SNI. 268 * 269 * @param sni The requested SNI 270 * @param arg The same as was passed into coap_context_set_pki() 271 * in setup_data->sni_call_back_arg 272 * 273 * @return New set of certificates to use, or @c NULL if SNI is to be rejected. 274 */ 275 typedef coap_dtls_key_t *(*coap_dtls_pki_sni_callback_t)(const char *sni, 276 void *arg); 277 278 279 #define COAP_DTLS_PKI_SETUP_VERSION 1 /**< Latest PKI setup version */ 280 281 /** 282 * The structure used for defining the PKI setup data to be used. 283 */ 284 struct coap_dtls_pki_t { 285 uint8_t version; /** Set to COAP_DTLS_PKI_SETUP_VERSION 286 to support this version of the struct */ 287 288 /* Options to enable different TLS functionality in libcoap */ 289 uint8_t verify_peer_cert; /**< 1 if peer cert is to be verified */ 290 uint8_t check_common_ca; /**< 1 if peer cert is to be signed by 291 * the same CA as the local cert */ 292 uint8_t allow_self_signed; /**< 1 if self-signed certs are allowed. 293 * Ignored if check_common_ca set */ 294 uint8_t allow_expired_certs; /**< 1 if expired certs are allowed */ 295 uint8_t cert_chain_validation; /**< 1 if to check cert_chain_verify_depth */ 296 uint8_t cert_chain_verify_depth; /**< recommended depth is 3 */ 297 uint8_t check_cert_revocation; /**< 1 if revocation checks wanted */ 298 uint8_t allow_no_crl; /**< 1 ignore if CRL not there */ 299 uint8_t allow_expired_crl; /**< 1 if expired crl is allowed */ 300 uint8_t allow_bad_md_hash; /**< 1 if unsupported MD hashes are allowed */ 301 uint8_t allow_short_rsa_length; /**< 1 if small RSA keysizes are allowed */ 302 uint8_t is_rpk_not_cert; /**< 1 is RPK instead of Public Certificate. 303 * If set, PKI key format type cannot be 304 * COAP_PKI_KEY_PEM */ 305 uint8_t reserved[3]; /**< Reserved - must be set to 0 for 306 future compatibility */ 307 /* Size of 3 chosen to align to next 308 * parameter, so if newly defined option 309 * it can use one of the reserved slots so 310 * no need to change 311 * COAP_DTLS_PKI_SETUP_VERSION and just 312 * decrement the reserved[] count. 313 */ 314 315 /** CN check callback function. 316 * If not NULL, is called when the TLS connection has passed the configured 317 * TLS options above for the application to verify if the CN is valid. 318 */ 319 coap_dtls_cn_callback_t validate_cn_call_back; 320 void *cn_call_back_arg; /**< Passed in to the CN callback function */ 321 322 /** SNI check callback function. 323 * If not @p NULL, called if the SNI is not previously seen and prior to 324 * sending a certificate set back to the client so that the appropriate 325 * certificate set can be used based on the requesting SNI. 326 */ 327 coap_dtls_pki_sni_callback_t validate_sni_call_back; 328 void *sni_call_back_arg; /**< Passed in to the sni callback function */ 329 330 /** Additional Security callback handler that is invoked when libcoap has 331 * done the standard, defined validation checks at the TLS level, 332 * If not @p NULL, called from within the TLS Client Hello connection 333 * setup. 334 */ 335 coap_dtls_security_setup_t additional_tls_setup_call_back; 336 337 char *client_sni; /**< If not NULL, SNI to use in client TLS setup. 338 Owned by the client app and must remain valid 339 during the call to coap_new_client_session_pki() */ 340 341 coap_dtls_key_t pki_key; /**< PKI key definition */ 342 }; 343 344 /** 345 * The structure that holds the Client PSK information. 346 */ 347 typedef struct coap_dtls_cpsk_info_t { 348 coap_bin_const_t identity; 349 coap_bin_const_t key; 350 } coap_dtls_cpsk_info_t; 351 352 /** 353 * Identity Hint Validation callback that can be set up by 354 * coap_new_client_session_psk2(). 355 * Invoked when libcoap has done the validation checks at the TLS level, 356 * but the application needs to check that the Identity Hint is allowed, 357 * and thus needs to use the appropriate PSK information for the Identity 358 * Hint for the (D)TLS session. 359 * Note: Identity Hint is not supported in (D)TLS1.3. 360 * 361 * @param hint The server provided Identity Hint 362 * @param coap_session The CoAP session associated with the Identity Hint 363 * @param arg The same as was passed into coap_new_client_session_psk2() 364 * in setup_data->ih_call_back_arg 365 * 366 * @return New coap_dtls_cpsk_info_t object or @c NULL on error. 367 */ 368 typedef const coap_dtls_cpsk_info_t *(*coap_dtls_ih_callback_t)( 369 coap_str_const_t *hint, 370 coap_session_t *coap_session, 371 void *arg); 372 373 #define COAP_DTLS_CPSK_SETUP_VERSION 1 /**< Latest CPSK setup version */ 374 375 /** 376 * The structure used for defining the Client PSK setup data to be used. 377 */ 378 typedef struct coap_dtls_cpsk_t { 379 uint8_t version; /** Set to COAP_DTLS_CPSK_SETUP_VERSION 380 to support this version of the struct */ 381 382 /* Options to enable different TLS functionality in libcoap */ 383 uint8_t reserved[7]; /**< Reserved - must be set to 0 for 384 future compatibility */ 385 /* Size of 7 chosen to align to next 386 * parameter, so if newly defined option 387 * it can use one of the reserverd slot so 388 * no need to change 389 * COAP_DTLS_CPSK_SETUP_VERSION and just 390 * decrement the reserved[] count. 391 */ 392 393 /** Identity Hint check callback function. 394 * If not NULL, is called when the Identity Hint (TLS1.2 or earlier) is 395 * provided by the server. 396 * The appropriate Identity and Pre-shared Key to use can then be returned. 397 */ 398 coap_dtls_ih_callback_t validate_ih_call_back; 399 void *ih_call_back_arg; /**< Passed in to the Identity Hint callback 400 function */ 401 402 char *client_sni; /**< If not NULL, SNI to use in client TLS setup. 403 Owned by the client app and must remain valid 404 during the call to coap_new_client_session_psk2() 405 Note: Not supported by TinyDTLS. */ 406 407 coap_dtls_cpsk_info_t psk_info; /**< Client PSK definition */ 408 } coap_dtls_cpsk_t; 409 410 /** 411 * The structure that holds the Server Pre-Shared Key and Identity 412 * Hint information. 413 */ 414 typedef struct coap_dtls_spsk_info_t { 415 coap_bin_const_t hint; 416 coap_bin_const_t key; 417 } coap_dtls_spsk_info_t; 418 419 420 /** 421 * Identity Validation callback that can be set up by 422 * coap_context_set_psk2(). 423 * Invoked when libcoap has done the validation checks at the TLS level, 424 * but the application needs to check that the Identity is allowed, 425 * and needs to use the appropriate Pre-Shared Key for the (D)TLS session. 426 * 427 * @param identity The client provided Identity 428 * @param coap_session The CoAP session associated with the Identity Hint 429 * @param arg The value as passed into coap_context_set_psk2() 430 * in setup_data->id_call_back_arg 431 * 432 * @return New coap_bin_const_t object containing the Pre-Shared Key or 433 @c NULL on error. 434 * Note: This information will be duplicated into an internal 435 * structure. 436 */ 437 typedef const coap_bin_const_t *(*coap_dtls_id_callback_t)( 438 coap_bin_const_t *identity, 439 coap_session_t *coap_session, 440 void *arg); 441 /** 442 * PSK SNI callback that can be set up by coap_context_set_psk2(). 443 * Invoked when libcoap has done the validation checks at the TLS level 444 * and the application needs to:- 445 * a) check that the SNI is allowed 446 * b) provide the appropriate PSK information for the (D)TLS session. 447 * 448 * @param sni The client provided SNI 449 * @param coap_session The CoAP session associated with the SNI 450 * @param arg The same as was passed into coap_context_set_psk2() 451 * in setup_data->sni_call_back_arg 452 * 453 * @return New coap_dtls_spsk_info_t object or @c NULL on error. 454 */ 455 typedef const coap_dtls_spsk_info_t *(*coap_dtls_psk_sni_callback_t)( 456 const char *sni, 457 coap_session_t *coap_session, 458 void *arg); 459 460 #define COAP_DTLS_SPSK_SETUP_VERSION 1 /**< Latest SPSK setup version */ 461 462 /** 463 * The structure used for defining the Server PSK setup data to be used. 464 */ 465 typedef struct coap_dtls_spsk_t { 466 uint8_t version; /** Set to COAP_DTLS_SPSK_SETUP_VERSION 467 to support this version of the struct */ 468 469 /* Options to enable different TLS functionality in libcoap */ 470 uint8_t reserved[7]; /**< Reserved - must be set to 0 for 471 future compatibility */ 472 /* Size of 7 chosen to align to next 473 * parameter, so if newly defined option 474 * it can use one of the reserverd slot so 475 * no need to change 476 * COAP_DTLS_SPSK_SETUP_VERSION and just 477 * decrement the reserved[] count. 478 */ 479 480 /** Identity check callback function. 481 * If not @p NULL, is called when the Identity is provided by the client. 482 * The appropriate Pre-Shared Key to use can then be returned. 483 */ 484 coap_dtls_id_callback_t validate_id_call_back; 485 void *id_call_back_arg; /**< Passed in to the Identity callback function */ 486 487 /** SNI check callback function. 488 * If not @p NULL, called if the SNI is not previously seen and prior to 489 * sending PSK information back to the client so that the appropriate 490 * PSK information can be used based on the requesting SNI. 491 */ 492 coap_dtls_psk_sni_callback_t validate_sni_call_back; 493 void *sni_call_back_arg; /**< Passed in to the SNI callback function */ 494 495 coap_dtls_spsk_info_t psk_info; /**< Server PSK definition */ 496 } coap_dtls_spsk_t; 497 498 499 /** @} */ 500 501 #endif /* COAP_DTLS_H */ 502