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