1// -*- mode:doc; -*- 2// vim: set syntax=asciidoc tw=0 3 4coap_encryption(3) 5=================== 6:doctype: manpage 7:man source: coap_encryption 8:man version: @PACKAGE_VERSION@ 9:man manual: libcoap Manual 10 11NAME 12---- 13coap_encryption, 14coap_dtls_cpsk_t, 15coap_dtls_spsk_t, 16coap_dtls_pki_t 17- Work with CoAP TLS/DTLS 18 19SYNOPSIS 20-------- 21*#include <coap@LIBCOAP_API_VERSION@/coap.h>* 22 23*struct coap_dtls_cpsk_t;* 24 25*struct coap_dtls_spsk_t;* 26 27*struct coap_dtls_pki_t;* 28 29For specific (D)TLS library support, link with 30*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*, 31*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls* 32or *-lcoap-@LIBCOAP_API_VERSION@-tinydtls*. Otherwise, link with 33*-lcoap-@LIBCOAP_API_VERSION@* to get the default (D)TLS library support. 34 35DESCRIPTION 36----------- 37This man page focuses on setting up CoAP to use encryption. 38 39When the libcoap library was built, it will have been compiled using a 40specific underlying TLS implementation type (e.g. https://www.openssl.org[OpenSSL], 41https://www.gnutls.org[GnuTLS], 42https://www.trustedfirmware.org/projects/mbed-tls/[Mbed TLS], 43https://github.com/eclipse/tinydtls[TinyDTLS] or noTLS). 44When the libcoap library is linked into an application, it is possible 45that the application needs to dynamically determine whether DTLS or TLS is 46supported, what type of TLS implementation libcoap was compiled with, as well 47as detect what is the version of the currently loaded TLS library. 48 49*NOTE:* If OpenSSL is being used, then the minimum supported OpenSSL library 50version is 1.1.0. 51 52*NOTE:* If GnuTLS is being used, then the minimum GnuTLS library version is 533.3.0. 54 55*NOTE:* If Mbed TLS is being used, then the minimum Mbed TLS library version is 562.7.10. 57 58*NOTE:* If GnuTLS is going to interoperate with TinyDTLS, then a minimum 59revision of GnuTLS 3.5.5 which supports CCM algorithms is required 60by TinyDTLS as TinyDTLS currently only supports CCM. 61 62*NOTE:* For Raw Public Key support, GnuTLS library version must be 3.6.6 or 63later. TinyDTLS only supports TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, curve 64secp256r1 and hash SHA-256. There currently is no OpenSSL or Mbed TLS RPK support 65(respective library limitations). 66 67Network traffic can be un-encrypted or encrypted with libcoap if there is an 68underlying TLS library. 69 70If TLS is going to be used for encrypting the network traffic, then the TLS 71information for Pre-Shared Keys (PSK), Public Key Infrastructure (PKI) or 72Raw Public Key (RPK) needs to be configured before any network traffic starts 73to flow. For Servers, this has to be done before the Endpoint is created, 74for Clients, this is done during the Client Session set up. 75 76For Servers, all the encryption information is held internally by the TLS 77Context level and the CoAP Context level as the Server is listening for new 78incoming traffic based on the Endpoint definition. The TLS and CoAP session 79will not get built until the new traffic starts, which is done by the libcoap 80library, with the session having a reference count of 1. 81 82For Clients, all the encryption information will be held internally by the TLS 83Context and/or TLS Session level and internally by the CoAP Session level. 84 85In principle the set-up sequence for CoAP Servers looks like 86---- 87coap_new_context() 88coap_context_set_pki_root_cas() - if the root CAs need to be updated and PKI 89coap_context_set_pki() and/or coap_context_set_psk2() - if encryption is required 90coap_new_endpoint() 91---- 92 93Multiple endpoints can be set up per Context, each listening for a new traffic 94flow with different TCP/UDP protocols, TLS protocols, port numbers etc. When a 95new traffic flow is started, then the CoAP library will create and start a new 96server session. 97 98In principle the set-up sequence for CoAP Clients looks like 99---- 100coap_new_context() 101coap_context_set_pki_root_cas() - if the root CAs need to be updated and PKI 102coap_new_client_session(), coap_new_client_session_pki() or coap_new_client_session_psk2() 103---- 104 105Multiple client sessions are supported per Context. 106 107Due to the nature of TLS, there are Callbacks that are invoked as the TLS 108session negotiates encryption algorithms, encryption keys etc. 109Where possible, the CoAP layer handles all this automatically based on 110different configuration options passed in by the *coap_context_set_pki*(), 111*coap_new_client_session_pki*(), *coap_context_set_psk2*() and 112*coap_new_client_session_psk2*() functions. 113 114PSK CLIENT INFORMATION 115---------------------- 116 117For Client PSK setup, the required information needs to be provided in the setup 118calls with optional application callbacks defined to update the Identity and 119PSK. Initially, the Client has to provide an Identity and a Pre-Shared Key. 120 121Libcoap will put the Identity and Pre-Shared Key as appropriate into the TLS 122environment. 123 124*SECTION: PSK Client: coap_dtls_cpsk_t* 125[source, c] 126---- 127typedef struct coap_dtls_cpsk_t { 128 uint8_t version; /** Set to COAP_DTLS_CPSK_SETUP_VERSION 129 to support the version of the struct */ 130 131 /* Options to enable different TLS functionality in libcoap */ 132 uint8_t reserved[7]; /* Reserved - must be set to 0 for 133 future compatibility */ 134 135 /** Identity Hint check callback function. 136 * If not NULL, is called when the Identity Hint (TLS1.2 or earlier) is 137 * provided by the server. 138 * The appropriate Identity and Pre-Shared Key to use can then be returned. 139 */ 140 coap_dtls_ih_callback_t validate_ih_call_back; 141 void *ih_call_back_arg; /* Passed in to the Identity Hint callback 142 function */ 143 144 char* client_sni; /* If not NULL, SNI to use in client TLS setup. 145 Owned by the client app and must remain valid 146 during the call to coap_new_client_session_pki(). 147 Note: Not supported by TinyDTLS. */ 148 149 coap_dtls_cpsk_info_t psk_info; /* Client PSK definition */ 150} coap_dtls_cpsk_t; 151---- 152 153More detailed explanation of the coap_dtls_cpsk_t structure follows. 154 155*WARNING*: For all the parameter definitions that are pointers to other 156locations, these locations must remain valid during the lifetime of all the 157underlying TLS sessions that are, or will get created based on this PSK 158definition. 159 160*SECTION: PSK Client: coap_dtls_cpsk_t: Version* 161[source, c] 162---- 163#define COAP_DTLS_CPSK_SETUP_VERSION 1 /**< Latest CPSK setup version */ 164---- 165 166*version* is set to COAP_DTLS_CPSK_SETUP_VERSION. This will then allow 167support for different versions of the coap_dtls_cpsk_t structure in the future. 168 169*SECTION: PSK Client: coap_dtls_cpsk_t: Reserved* 170 171*reserved* All must be set to 0. Future functionality updates will make use of 172these reserved definitions. 173 174*SECTION: PSK Client: coap_dtls_cpsk_t: Identity Hint Callback* 175[source, c] 176---- 177/** 178 * Identity Hint Validation callback that can be set up by 179 * coap_new_client_session_psk2(). 180 * Invoked when libcoap has done the validation checks at the TLS level, 181 * but the application needs to check that the Identity Hint is allowed, and 182 * needs to use the appropriate PSK information for the (D)TLS session. 183 * Note: Identity Hint is not supported in (D)TLS1.3. 184 * 185 * @param hint The server provided Identity Hint 186 * @param coap_session The CoAP session associated with the Identity Hint 187 * @param arg The same as was passed into coap_new_client_session_psk2() 188 * in setup_data->ih_call_back_arg 189 * 190 * @return New coap_dtls_cpsk_info_t object or @c NULL on error. 191 */ 192typedef const coap_dtls_cpsk_info_t *(*coap_dtls_ih_callback_t)( 193 coap_str_const_t *hint, 194 coap_session_t *coap_session, 195 void *arg); 196---- 197 198*validate_ih_call_back* points to an application provided Identity Hint callback 199function or NULL. The application can make use of this Identity Hint information 200to decide what Identity and Pre-Shared Key should be used for this session. 201The Callback returns the new coap_dtls_cpsk_info_t on success, 202or NULL if the Identity Hint is unacceptable. 203 204*NOTE:* The Server may not provide a hint, or a zero length hint to indicate 205there is no hint. In this case the initially provided Identity and 206Pre-Shared Key should be used. 207 208*ih_call_back_arg* points to a user defined set of data that will get passed 209in to the validate_ih_call_back() function's arg parameter and can be used by 210that function. An example would be a set of Identity Hints that map into new 211Identity / Pre-Shared Key to use. 212 213*SECTION: PSK Client: coap_dtls_cpsk_t: Subject Name Indicator (SNI) Definition* 214 215*client_sni* points to the SNI name that will be added in as a TLS extension, 216if not NULL. This typically is the DNS name of the server that the client is 217trying to contact. The server is then able to decide, based on the name in the 218SNI extension, whether, for example, a different Hint and/or Pre-Shared Key is 219to be used. 220 221*NOTE:* Not supported by TinyDTLS. 222 223*SECTION: PSK Client: coap_dtls_cpsk_t: PSK Client Definitions* 224[source, c] 225---- 226typedef struct coap_dtls_cpsk_info_t { 227 coap_bin_const_t identity; /* The Identity */ 228 coap_bin_const_t key; /* The Pre-Shared Key */ 229} coap_dtls_cpsk_info_t; 230---- 231 232*identity* defines the Identity to use. 233 234*key* defines the Pre-Shared Key to use 235 236PSK SERVER INFORMATION 237---------------------- 238 239For PSK setup, the required information needs to be provided in the setup 240calls with optional application Callbacks defined to update the Identity Hint 241and Pre-SHared Key. Initially, the Server has to provided with an (optional) 242Identity Hint and a (required) Pre-Shared Key. 243 244Libcoap will put the Hint and Pre-Shared Key as appropriate into the TLS 245environment. 246 247*SECTION: PSK Server: coap_dtls_spsk_t* 248[source, c] 249---- 250typedef struct coap_dtls_spsk_t { 251 uint8_t version; /** Set to COAP_DTLS_SPSK_SETUP_VERSION 252 to support the version of the struct */ 253 254 /* Options to enable different TLS functionality in libcoap */ 255 uint8_t reserved[7]; /* Reserved - must be set to 0 for 256 future compatibility */ 257 258 /** Identity check callback function. 259 * If not @p NULL, is called when the Identity is provided by the client. 260 * The appropriate Pre-Shared Key to use can then be returned. 261 */ 262 coap_dtls_id_callback_t validate_id_call_back; 263 void *id_call_back_arg; /* Passed in to the Identity callback function */ 264 265 /** SNI check callback function. 266 * If not @p NULL, called if the SNI is not previously seen and exexuted 267 * prior to sending an Identity Hint back to the client so that the 268 * appropriate PSK information can be used based on the requesting SNI. 269 */ 270 coap_dtls_psk_sni_callback_t validate_sni_call_back; 271 void *sni_call_back_arg; /* Passed in to the SNI callback function */ 272 273 coap_dtls_spsk_info_t psk_info; /* Server PSK definition */ 274} coap_dtls_spsk_t; 275---- 276 277More detailed explanation of the coap_dtls_spsk_t structure follows. 278 279*WARNING*: For all the parameter definitions that are pointers to other 280locations, these locations must remain valid during the lifetime of all the 281underlying TLS sessions that are, or will get created based on this PSK 282definition. 283 284*SECTION: PSK Server: coap_dtls_spsk_t: Version* 285[source, c] 286---- 287#define COAP_DTLS_SPSK_SETUP_VERSION 1 /**< Latest SPSK setup version */ 288---- 289 290*version* is set to COAP_DTLS_SPSK_SETUP_VERSION. This will then allow 291support for different versions of the coap_dtls_spsk_t structure in the future. 292 293*SECTION: PSK Server: coap_dtls_spsk_t: Reserved* 294 295*reserved* All must be set to 0. Future functionality updates will make use of 296these reserved definitions. 297 298*SECTION: PSK Server: coap_dtls_spsk_t: Identity Validation Callback* 299[source, c] 300---- 301/** 302 * Identity Validation callback that can be set up by 303 * coap_context_set_psk2(). 304 * Invoked when libcoap has done the validation checks at the TLS level, 305 * but the application needs to check that the Identity is allowed, and 306 * needs to use the appropriate Pre-Shared Key for the (D)TLS session. 307 * 308 * @param identity The client provided Identity (should be NULL terminated) 309 * @param coap_session The CoAP session associated with the Identity Hint 310 * @param arg The same as was passed into coap_context_set_psk2() 311 * in setup_data->id_call_back_arg 312 * 313 * @return New coap_bin_const_t Pre-Shared Key object or @c NULL on error. 314 */ 315typedef const coap_bin_const_t *(*coap_dtls_id_callback_t)( 316 coap_bin_const_t *identity, 317 coap_session_t *coap_session, 318 void *arg); 319---- 320 321*WARNING:* If both *validate_id_call_back* and *validate_sni_call_back* are 322defined, validate_id_call_back() is invoked after validate_sni_call_back(), 323and so if the Pre-Shared Key is changed in validate_sni_call_back(), 324validate_id_call_back() needs to be sure that the appropriate Pre-Shared Key 325is provided. 326 327*validate_id_call_back* points to an application provided Identity callback 328function or NULL. The application can make use of this Identity information 329to decide what PSK should be used for this session. 330The Callback returns the new coap_bin_const_t Pre-Shared Key on success, 331or NULL if the Identity is unacceptable. 332 333*NOTE:* The Client may be using a binary Identity that contains an embedded 334zero. However OpenSSL and GnuTLS do not currently support this. 335 336*id_call_back_arg* points to a user defined set of data that will get passed 337in to the validate_id_call_back() function and can be used by that function. 338An example would be a set of Identities that map into new Pre-Shared Keys 339to use. 340 341*SECTION: PSK Server: coap_dtls_spsk_t: Subject Name Identifier (SNI) Callback* 342[source, c] 343---- 344/** 345 * PSK SNI callback that can be set up by coap_context_set_psk2(). 346 * Invoked when libcoap has done the validation checks at the TLS level, 347 * but the application needs to check that the SNI is allowed, and needs 348 * to use the appropriate PSK information for the (D)TLS session. 349 * 350 * @param sni The client provided SNI 351 * @param coap_session The CoAP session associated with the SNI 352 * @param arg The same as was passed into coap_new_client_session_psk2() 353 * in setup_data->sni_call_back_arg 354 * 355 * @return New coap_dtls_spsk_info_t object or @c NULL on error. 356 */ 357typedef const coap_dtls_spsk_info_t *(*coap_dtls_psk_sni_callback_t)( 358 const char *sni, 359 coap_session_t *coap_session, 360 void *arg); 361---- 362 363*validate_sni_call_back* points to an application provided SNI callback 364checking function or NULL. The application can make use of this SNI information 365to decide whether the SNI is valid, and hence what new Hint and Pre-Shared Key 366to use. 367Thus it is possible for the coap server to host multiple domains with 368different Hints and PSKs allocated to each SNI domain. 369The Callback returns a coap_dtls_spsk_info_t pointer to the Hint and 370Pre-Shared Key to use for this SNI, or NULL if the connection is to get 371rejected. Libcoap remembers the association between a specific SNI and Hint + 372Pre-Shared Key set and will only invoke this callback if the SNI is unknown. 373 374*NOTE:* Not supported by TinyDTLS. 375 376*sni_call_back_arg* points to a user defined set of data that will get passed 377in to the validate_sni_call_back() function and can be used by that function. 378An example would be a set of SNIs that are allowed with their matching 379Hint + Pre-Shared Key sets. 380 381*SECTION: PSK Server: coap_dtls_spsk_t: PSK Information Definitions* 382[source, c] 383---- 384typedef struct coap_dtls_spsk_info_t { 385 coap_bin_const_t hint; /* The identity hint to use */ 386 coap_bin_const_t key; /* The Pre-Shared Key to use */ 387} coap_dtls_spsk_info_t; 388---- 389 390*identity* defines the Identity Hint to use. 391 392*key* defines the Pre-Shared Key to use 393 394PKI/RPK CLIENT AND SERVER INFORMATION 395------------------------------------- 396 397For PKI or RPK setup, if the libcoap PKI/RPK configuration options do not 398handle a specific requirement as defined by the available options, then an 399application defined Callback can called to do the additional specific checks. 400 401The information passed to this Application Callback will be the 402TLS session (as well the configuration information), but the structures 403containing this information will be different as they will be based on the 404underlying TLS library type. coap_get_tls_library_version() is provided to help 405here. 406 407Libcoap will add in the defined Certificate (or Public Key), Private Key and 408CA Certificate into the TLS environment. The CA Certificate is also added 409in to the list of valid CAs for Certificate checking. 410 411The internal Callbacks (and optionally the Application Callback) will then 412check the required information as defined in the coap_dtls_pki_t described 413below. 414 415*SECTION: PKI/RPK: coap_dtls_pki_t* 416[source, c] 417---- 418typedef struct coap_dtls_pki_t { 419 uint8_t version; /* COAP_DTLS_PKI_SETUP_VERSION */ 420 421 /* Options to enable different TLS functionality in libcoap */ 422 uint8_t verify_peer_cert; /* 1 if peer cert is to be verified */ 423 uint8_t check_common_ca; /* 1 if peer cert is to be signed by 424 * the same CA as the local cert */ 425 uint8_t allow_self_signed; /* 1 if self-signed certs are allowed */ 426 uint8_t allow_self_signed; /* 1 if self-signed certs are allowed. 427 * Ignored if check_common_ca set */ 428 uint8_t allow_expired_certs; /* 1 if expired certs are allowed */ 429 uint8_t cert_chain_validation; /* 1 if to check cert_chain_verify_depth */ 430 uint8_t cert_chain_verify_depth; /* recommended depth is 3 */ 431 uint8_t check_cert_revocation; /* 1 if revocation checks wanted */ 432 uint8_t allow_no_crl; /* 1 ignore if CRL not there */ 433 uint8_t allow_expired_crl; /* 1 if expired crl is allowed */ 434 uint8_t allow_bad_md_hash; /* 1 if unsupported MD hashes are allowed */ 435 uint8_t allow_short_rsa_length; /* 1 if small RSA keysizes are allowed */ 436 uint8_t is_rpk_not_cert; /* 1 is RPK instead of Public Certificate. 437 * If set, PKI key format type cannot be 438 * COAP_PKI_KEY_PEM */ 439 uint8_t reserved[3]; /* Reserved - must be set to 0 for 440 future compatibility */ 441 442 /** CN check callback function 443 * If not NULL, is called when the TLS connection has passed the configured 444 * TLS options above for the application to verify if the CN is valid. 445 */ 446 coap_dtls_cn_callback_t validate_cn_call_back; 447 void *cn_call_back_arg; /* Passed in to the CN callback function */ 448 449 /** SNI check callback function 450 * If not NULL, called if the SNI is not previously seen and prior to sending 451 * a certificate set back to the client so that the appropriate certificate 452 * set can be used based on the requesting SNI. 453 */ 454 coap_dtls_sni_callback_t validate_sni_call_back; 455 void *sni_call_back_arg; /* Passed in to the SNI callback function */ 456 457 /** Additional Security callback handler that is invoked when libcoap has 458 * done the standard, defined validation checks at the TLS level, 459 * If not NULL, called from within the TLS Client Hello connection 460 * setup. 461 */ 462 coap_dtls_security_setup_t additional_tls_setup_call_back; 463 464 char* client_sni; /* If not NULL, SNI to use in client TLS setup. 465 Owned by the client app and must remain valid 466 during the call to coap_new_client_session_pki() */ 467 468 coap_dtls_key_t pki_key; /* PKI key definition */ 469} coap_dtls_pki_t; 470---- 471 472More detailed explanation of the coap_dtls_pki_t structure follows. 473 474*WARNING*: For all the parameter definitions that are pointers to other 475locations, these locations must remain valid during the lifetime of all the 476underlying TLS sessions that are, or will get created based on this PKI/RPK 477definition. 478 479The first parameter in each subsection enables/disables the functionality, the 480remaining parameter(s) control what happens when the functionality is 481enabled. 482 483*SECTION: PKI/RPK: coap_dtls_pki_t: Version* 484[source, c] 485---- 486#define COAP_DTLS_PKI_SETUP_VERSION 1 487---- 488 489*version* is set to COAP_DTLS_PKI_SETUP_VERSION. This will then allow support 490for different versions of the coap_dtls_pki_t structure in the future. 491 492*SECTION: PKI/RPK: coap_dtls_pki_t: Peer Certificate Checking* 493 494*verify_peer_cert* Set to 1 to check that the peer's certificate is valid if 495provided, else 0. If not set, check_common_ca, allow_self_signed, 496allow_expired_certs, cert_chain_validation, cert_chain_verify_depth, 497check_cert_revocation, allow_no_crl, allow_expired_crl, allow_bad_md_hash 498and allow_short_rsa_length settings are all ignored. 499 500*check_common_ca* Set to 1 to check that the CA that signed the peer's 501certificate is the same CA that signed the local certificate 502else 0. If set to 1 and *verify_peer_cert* is set to 1, then for the server, a 503list of valid CAs are sent to client. For the client, the logic will check 504that both the client and server certificates are signed by the same CA. 505 506*allow_self_signed* Set to 1 to allow the peer (or any certificate in the 507certificate chain) to be a self-signed certificate, else 0. If 508*check_common_ca* is set, then a self-signed certificate will not be allowed. 509 510*allow_expired_certs* Set to 1 to allow certificates that have either expired, 511or are not yet valid to be allowed, else 0. 512 513*SECTION: PKI/RPK: coap_dtls_pki_t: Certificate Chain Validation* 514 515*cert_chain_validation* Set to 1 to check that the certificate chain is valid, 516else 0. 517 518*cert_chain_verify_depth* Set to the chain depth that is to be checked. This 519is the number of intermediate CAs in the chain. If set to 0, then there can be 520no intermediate CA in the chain. 521 522*SECTION: PKI/RPK: coap_dtls_pki_t: Certificate Revocation* 523 524*check_cert_revocation* Set to 1 to check whether any certificate in the chain 525has been revoked, else 0. 526 527*allow_no_crl* Set to 1 to not check any certificate that does not have a CRL, 528else 0. 529 530*allow_expired_crl* Set to 1 to allow an certificate that has an expired CRL 531definition to be valid, else 0. 532 533*SECTION: PKI/RPK: coap_dtls_pki_t: Other* 534 535*allow_bad_md_hash* Set to 1 if unsupported MD hashes are allowed, else 0. 536 537*allow_short_rsa_length* Set to 1 if small RSA keysizes are allowed, else 0. 538 539*is_rpk_not_cert* Set to 1 if the Certificate is actually a Raw Public Key. 540If set, PKI key format type cannot be COAP_PKI_KEY_PEM. If set, 541check_common_ca, allow_self_signed, allow_expired_certs, 542cert_chain_validation, cert_chain_verify_depth, check_cert_revocation, 543allow_no_crl, allow_expired_crl, allow_bad_md_hash and 544allow_short_rsa_length settings are all ignored. 545 546*SECTION: PKI/RPK: coap_dtls_pki_t: Reserved* 547 548*reserved* All must be set to 0. Future functionality updates will make use of 549these reserved definitions. 550 551*SECTION: PKI/RPK: coap_dtls_pki_t: Common Name (CN) Callback* 552[source, c] 553---- 554#define COAP_DTLS_RPK_CERT_CN "RPK" 555 556/** 557 * CN Validation callback that can be set up by coap_context_set_pki(). 558 * Invoked when libcoap has done the validation checks at the TLS level, 559 * but the application needs to check that the CN is allowed. 560 * CN is the SubjectAltName in the cert, if not present, then the leftmost 561 * Common Name (CN) component of the subject name. 562 * NOTE: If using RPK, then the Public Key does not contain a CN, but the 563 * content of COAP_DTLS_RPK_CERT_CN is presented for the @p cn parameter. 564 * 565 * @param cn The determined CN from the certificate 566 * @param asn1_public_cert The ASN.1 encoded (DER) X.509 certificate 567 * @param asn1_length The ASN.1 length 568 * @param session The coap session associated with the certificate update 569 * @param depth Depth in cert chain. If 0, then client cert, else a CA 570 * @param validated TLS can find no issues if 1 571 * @param arg The same as was passed into coap_context_set_pki() 572 * in setup_data->cn_call_back_arg 573 * 574 * @return 1 if accepted, else 0 if to be rejected 575 */ 576typedef int (*coap_dtls_cn_callback_t)(const char *cn, 577 const uint8_t *asn1_public_cert, 578 size_t asn1_length, 579 coap_session_t *session, 580 unsigned int depth, 581 int validated, 582 void *arg); 583---- 584 585*validate_cn_call_back* points to an application provided CN callback 586checking function or NULL. The application can make use of this CN information 587to decide, for example, that the CN is valid coming from a particular peer. 588The Callback returns 1 on success, 0 if the TLS connection is to be aborted. 589 590*cn_call_back_arg* points to a user defined set of data that will get passed 591in to the validate_cn_call_back() function and can be used by that function. 592An example would be a set of CNs that are allowed. 593 594*SECTION: PKI/RPK: coap_dtls_pki_t: Subject Name Identifier (SNI) Callback* 595[source, c] 596---- 597typedef struct coap_dtls_key_t { 598 coap_pki_key_t key_type; /* key format type */ 599 union { 600 coap_pki_key_pem_t pem; /* for PEM file keys */ 601 coap_pki_key_pem_buf_t pem_buf; /* for PEM memory keys */ 602 coap_pki_key_asn1_t asn1; /* for ASN.1 (DER) memory keys */ 603 coap_pki_key_pkcs11_t pkcs11; /* for PKCS11 keys */ 604 } key; 605} coap_dtls_key_t; 606 607/** 608 * SNI Validation callback that can be set up by coap_context_set_pki(). 609 * Invoked if the SNI is not previously seen and prior to sending a certificate 610 * set back to the client so that the appropriate certificate set can be used 611 * based on the requesting SNI. 612 * 613 * @param sni The requested SNI 614 * @param arg The same as was passed into coap_context_set_pki() 615 * in setup_data->sni_call_back_arg 616 * 617 * @return new set of certificates to use, or NULL if SNI is to be rejected. 618 */ 619typedef coap_dtls_key_t *(*coap_dtls_sni_callback_t)(const char *sni, 620 void* arg); 621---- 622 623*validate_sni_call_back* points to an application provided SNI callback 624checking function or NULL. The application can make use of this SNI information 625to decide whether the SNI is valid, and what set of certificates to give to the 626client. Thus it is possible for the coap server to host multiple domains with 627different certificates allocated to each domain. 628The Callback returns a pointer to the certificates to use for this SNI, or NULL 629if the connection it to get rejected. libcoap remembers the association 630between the SNI and Certificate set and will only invoke this callback if the 631SNI is unknown. 632 633*sni_call_back_arg* points to a user defined set of data that will get passed 634in to the validate_sni_call_back() function and can be used by that function. 635An example would be a set of SNIs that are allowed with their matching 636certificate sets. 637 638*SECTION: PKI/RPK: coap_dtls_pki_t: Application Additional Setup Callback* 639[source, c] 640---- 641/** 642 * Additional Security setup handler that can be set up by 643 * coap_context_set_pki(). 644 * Invoked when libcoap has done the validation checks at the TLS level, 645 * but the application needs to do some additional checks/changes/updates. 646 * 647 * @param session The security session definition - e.g. SSL * for OpenSSL. 648 * This will be dependent on the underlying TLS library 649 * - see coap_get_tls_library_version() 650 * @param setup_data A structure containing setup data originally passed into 651 * coap_context_set_pki() or coap_new_client_session_pki(). 652 * @return 1 if successful, else 0 653 */ 654typedef int (*coap_dtls_security_setup_t)(void *context, void* session, 655 coap_dtls_pki_t *setup_data); 656---- 657 658*additional_tls_setup_call_back* points to an application provided callback 659function that will do additional checking/changes/updates after libcoap has 660done all of the configured TLS setup checking, or NULL to do no additional 661checking. 662 663*SECTION: PKI/RPK: coap_dtls_pki_t: Subject Name Indicator (SNI) Definition* 664 665*client_sni* points to the SNI name that will be added in as a TLS extension, 666or set NULL. This typically is the DNS name of the server that the client is 667trying to contact. This is only used by a client application and the server 668is then able to decide, based on the name in the SNI extension, whether, for 669example, a different certificate should be provided. 670 671*SECTION: PKI/RPK: coap_dtls_pki_t: Key Type Definition* 672[source, c] 673---- 674typedef enum coap_pki_key_t { 675 COAP_PKI_KEY_PEM, /* The PKI key type is PEM file */ 676 COAP_PKI_KEY_ASN1, /* The PKI key type is ASN.1 (DER) buffer */ 677 COAP_PKI_KEY_PEM_BUF, /* The PKI key type is PEM buffer */ 678 COAP_PKI_KEY_PKCS11, /* The PKI key type is PKCS11 (DER) */ 679} coap_pki_key_t; 680---- 681 682*key_type* defines the format that the certificates / keys are provided in. 683This can be COAP_PKI_KEY_PEM, COAP_PKI_KEY_PEM_BUF, COAP_PKI_KEY_ASN1 or 684COAP_PKI_KEY_PKCS11. 685 686*SECTION: PKI: coap_dtls_pki_t: PEM Key Definitions* 687[source, c] 688---- 689typedef struct coap_pki_key_pem_t { 690 const char *ca_file; /* File location of Common CA in PEM format */ 691 const char *public_cert; /* File location of Public Cert */ 692 const char *private_key; /* File location of Private Key in PEM format */ 693} coap_pki_key_pem_t; 694---- 695 696*key.pem.ca_file* points to the CA File location on disk which will be in 697PEM format, or NULL. This file should only contain one CA (that has signed the 698public certificate) as this is passed from the server to the client when 699requesting the client's certificate. This certificate is also added into 700the valid root CAs list if not already present. 701 702*key.pem.public_cert* points to the public certificate location on disk which 703will be in PEM format. 704 705*key.pem.private_key* points to the private key location on disk which 706will be in PEM format. This file cannot be password protected. 707 708*SECTION: PKI/RPK: coap_dtls_pki_t: PEM Memory Key Definitions* 709[source, c] 710---- 711typedef struct coap_pki_key_pem_buf_t { 712 const uint8_t *ca_cert; /* PEM buffer Common CA Cert */ 713 const uint8_t *public_cert; /* PEM buffer Public Cert, or Public Key if RPK */ 714 const uint8_t *private_key; /* PEM buffer Private Key */ 715 If RPK and 'EC PRIVATE KEY' this can be used 716 for both the public_cert and private_key */ 717 size_t ca_cert_len; /* PEM buffer CA Cert length */ 718 size_t public_cert_len; /* PEM buffer Public Cert length */ 719 size_t private_key_len; /* PEM buffer Private Key length */ 720} coap_pki_key_pem_buf_t; 721---- 722 723*key.pem_buf.ca_cert* points to the CA location in memory which will be in 724PEM format, or NULL. This file should only contain one CA (that has signed the 725public certificate) as this is passed from the server to the client when 726requesting the client's certificate. This certificate is also added into 727the valid root CAs list if not already present. 728 729*key.pem_buf.ca_cert_len* is the length of the CA. 730 731*key.pem_buf.public_cert* points to the public certificate (or public key if 732RPK) location in memory which will be in PEM format. 733 734*key.pem_buf.public_cert_len* is the length of the public certificate. 735 736*key.pem_buf.private_key* points to the private key location in memory which 737will be in PEM format. This data cannot be password protected. If RPK and 738'EC PRIVATE KEY' this can be used for both the public_cert and private_key. 739 740*key.pem_buf.private_key* is the length of the private key. 741 742*NOTE:* The PEM buffer Certs and Key should be be NULL terminated strings for 743performance reasons (to save a potential buffer copy) and the length include 744this NULL terminator. It is not a requirement to have the NULL terminator 745though and the length must then reflect the actual data size. 746 747*SECTION: PKI/RPK: coap_dtls_pki_t: ASN1 Key Definitions* 748[source, c] 749---- 750typedef struct coap_pki_key_asn1_t { 751 const uint8_t *ca_cert; /* ASN1 Common CA Certificate */ 752 const uint8_t *public_cert; /* ASN1 (DER) Public Cert, or Public Key if RPK */ 753 const uint8_t *private_key; /* ASN1 Private Key */ 754 int ca_cert_len; /* ASN1 CA Certificate length */ 755 int public_cert_len; /* ASN1 Public Certificate length */ 756 int private_key_len; /* ASN1 Private Key length */ 757 coap_asn1_privatekey_type_t private_key_type; /* Private Key Type 758 COAP_ASN1_PKEY_* */ 759} coap_pki_key_asn1_t; 760 761typedef enum coap_asn1_privatekey_type_t { 762 COAP_ASN1_PKEY_NONE, 763 COAP_ASN1_PKEY_RSA, 764 COAP_ASN1_PKEY_RSA2, 765 COAP_ASN1_PKEY_DSA, 766 COAP_ASN1_PKEY_DSA1, 767 COAP_ASN1_PKEY_DSA2, 768 COAP_ASN1_PKEY_DSA3, 769 COAP_ASN1_PKEY_DSA4, 770 COAP_ASN1_PKEY_DH, 771 COAP_ASN1_PKEY_DHX, 772 COAP_ASN1_PKEY_EC, 773 COAP_ASN1_PKEY_HMAC, 774 COAP_ASN1_PKEY_CMAC, 775 COAP_ASN1_PKEY_TLS1_PRF, 776 COAP_ASN1_PKEY_HKDF 777} coap_asn1_privatekey_type_t; 778---- 779 780*key.asn1.ca_cert* points to a DER encoded ASN.1 definition of the CA 781Certificate, or NULL. This certificate is passed from the server to the client 782when requesting the client's certificate. This certificate is also added into 783the valid root CAs list if not already present. 784 785*key.asn1.public_cert* points to a DER encoded ASN.1 definition of the 786public certificate (or public key if RPK). 787 788*key.asn1.private_key* points to DER encoded ASN.1 definition of the 789private key. 790 791*key.asn1.ca_cert_len* is the length of the DER encoded ASN.1 definition of 792the CA Certificate. 793 794*key.asn1.public_cert_len* is the length of the DER encoded ASN.1 definition 795of the public certificate. 796 797*key.asn1.private_key_len* is the length of the DER encoded ASN.1 definition 798of the private key. 799 800*key.asn1.private_key_type* is the encoding type of the DER encoded ASN.1 801definition of the private key. This will be one of the COAP_ASN1_PKEY_* 802definitions. 803 804*SECTION: PKI: coap_dtls_pki_t: PKCS11 Key Definitions* 805[source, c] 806---- 807typedef struct coap_pki_key_pkcs11_t { 808 const char *ca; /* pkcs11: URI for Common CA Certificate */ 809 const char *public_cert; /* pkcs11: URI for Public Cert */ 810 const char *private_key; /* pkcs11: URI for Private Key */ 811 const char *pin; /* pin to access PKCS11. If NULL, then 812 pin-value= parameter must be set in 813 pkcs11: URI as a query. */ 814} coap_pki_key_pkcs11_t; 815---- 816 817*key.pkcs11.ca* is a pkcs11: URI for the CA certificate or NULL. This is for 818the CA (that has signed the public certificate) as this is passed from the 819server to the client when requesting the client's certificate. This certificate 820is also added into the valid root CAs list if not already present. 821An example URI is 'pkcs11:pkcs11:token=My%20Token;id=%aa%bb%cc%dd' which is 822for token 'My Token' and (hex) id of 'aabbccdd'. 823 824*key.pkcs11.public_cert* is a pkcs11: URI for the Public Certificate which 825was signed by *key.pkcs11.ca* or NULL. 826 827*key.pkcs11.private_key* is a pkcs11: URI for the Private Key for the 828public certificate defined by *key.pkcs11.public_cert* or NULL. 829 830*key.pkcs11.user_pin* is the user pin used to unlock the token or NULL. 831If NULL, the pin can be defined on the other pkcs11: URI entries by using 832pin-value=XXX as a query - e.g. 833'pkcs11:pkcs11:token=My%20Token;id=%aa%bb%cc%dd?pin-value=XXX' where XXX is 834the user pin. 835 836EXAMPLES 837-------- 838*CoAP Server DTLS PKI Setup* 839[source, c] 840---- 841#include <coap@LIBCOAP_API_VERSION@/coap.h> 842 843typedef struct valid_cns_t { 844 int count; 845 char **cn_list; 846} valid_cns_t; 847 848/** 849 * CN Validation callback that can be set up by coap_context_set_pki(). 850 * Invoked when libcoap has done the validation checks at the TLS level, 851 * but the application needs to check that the CN is allowed. 852 * CN is the SubjectAltName in the cert, if not present, then the leftmost 853 * Common Name (CN) component of the subject name. 854 * NOTE: If using RPK, then the Public Key does not contain a CN, but "RPK" 855 * is presented for the cn parameter. 856 * 857 * @param cn The determined CN from the certificate 858 * @param asn1_public_cert The ASN.1 encoded (DER) X.509 certificate 859 * @param asn1_length The ASN.1 length 860 * @param session The coap session associated with the certificate update 861 * @param depth Depth in cert chain. If 0, then client cert, else a CA 862 * @param validated TLS can find no issues if 1 863 * @param arg The same as was passed into coap_context_set_pki() 864 * in setup_data->cn_call_back_arg 865 * 866 * @return 1 if accepted, else 0 if to be rejected 867 */ 868static int 869verify_cn_callback(const char *cn, 870 const uint8_t *asn1_public_cert, 871 size_t asn1_length, 872 coap_session_t *c_session, 873 unsigned depth, 874 int validated, 875 void *arg 876) { 877 valid_cns_t *valid_cn_list = (valid_cns_t*)arg; 878 int i; 879 /* Remove (void) definition if variable is used */ 880 (void)asn1_public_cert; 881 (void)asn1_length; 882 (void)c_session; 883 (void)depth; 884 (void)validated; 885 886 /* Check that the CN is valid */ 887 for (i = 0; i < valid_cn_list->count; i++) { 888 if (!strcasecmp(cn, valid_cn_list->cn_list[i])) { 889 return 1; 890 } 891 } 892 return 0; 893} 894 895typedef struct sni_def_t { 896 char* sni; 897 coap_dtls_key_t key; 898} sni_def_t; 899 900typedef struct valid_snis_t { 901 int count; 902 sni_def_t *sni_list; 903} valid_snis_t; 904 905/** 906 * SNI Validation callback that is set up by coap_context_set_pki(). 907 * Invoked if the SNI is not previously seen and prior to sending a certificate 908 * set back to the client so that the appropriate certificate set can be used 909 * based on the requesting SNI. 910 * 911 * @param sni The requested SNI 912 * @param arg The same as was passed into coap_context_set_pki() 913 * in setup_data->sni_call_back_arg 914 * 915 * @return new set of certificates to use, or NULL if SNI is to be rejected. 916 */ 917static coap_dtls_key_t * 918verify_pki_sni_callback(const char *sni, 919 void *arg 920) { 921 valid_snis_t *valid_sni_list = (valid_snis_t *)arg; 922 int i; 923 924 /* Check that the SNI is valid */ 925 for (i = 0; i < valid_sni_list->count; i++) { 926 if (!strcasecmp(sni, valid_sni_list->sni_list[i].sni)) { 927 return &valid_sni_list->sni_list[i].key; 928 } 929 } 930 return NULL; 931} 932 933/* 934 * Set up PKI encryption information 935 */ 936static coap_context_t * 937setup_server_context_pki (const char *public_cert_file, 938 const char *private_key_file, 939 const char *ca_file, 940 valid_cns_t *valid_cn_list, 941 valid_snis_t *valid_sni_list 942) { 943 coap_endpoint_t *endpoint; 944 coap_address_t listen_addr; 945 coap_dtls_pki_t dtls_pki; 946 coap_context_t *context; 947 948 /* See coap_tls_library(3) */ 949 if (!coap_dtls_is_supported()) 950 return NULL; 951 952 /* See coap_context(3) */ 953 context = coap_new_context(NULL); 954 if (!context) 955 return NULL; 956 /* See coap_block(3) */ 957 coap_context_set_block_mode(context, 958 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 959 960 961 memset (&dtls_pki, 0, sizeof (dtls_pki)); 962 963 dtls_pki.version = COAP_DTLS_PKI_SETUP_VERSION; 964 dtls_pki.verify_peer_cert = 1; 965 dtls_pki.check_common_ca = 1; 966 dtls_pki.allow_self_signed = 1; 967 dtls_pki.allow_expired_certs = 1; 968 dtls_pki.cert_chain_validation = 1; 969 dtls_pki.cert_chain_verify_depth = 1; 970 dtls_pki.check_cert_revocation = 1; 971 dtls_pki.allow_no_crl = 1; 972 dtls_pki.allow_expired_crl = 1; 973 dtls_pki.allow_bad_md_hash = 0; 974 dtls_pki.allow_short_rsa_length = 0; 975 dtls_pki.is_rpk_not_cert = 0; /* Set to 1 if RPK */ 976 dtls_pki.validate_cn_call_back = verify_cn_callback; 977 dtls_pki.cn_call_back_arg = valid_cn_list; 978 dtls_pki.validate_sni_call_back = verify_pki_sni_callback; 979 dtls_pki.sni_call_back_arg = valid_sni_list; 980 dtls_pki.additional_tls_setup_call_back = NULL; 981 dtls_pki.client_sni = NULL; 982 dtls_pki.pki_key.key_type = COAP_PKI_KEY_PEM; 983 dtls_pki.pki_key.key.pem.ca_file = ca_file; 984 dtls_pki.pki_key.key.pem.public_cert = public_cert_file; 985 dtls_pki.pki_key.key.pem.private_key = private_key_file; 986 987 /* See coap_context(3) */ 988 if (coap_context_set_pki(context, &dtls_pki)) { 989 coap_free_context(context); 990 return NULL; 991 } 992 993 coap_address_init(&listen_addr); 994 listen_addr.addr.sa.sa_family = AF_INET; 995 listen_addr.addr.sin.sin_port = htons (5684); 996 997 /* See coap_context(3) */ 998 endpoint = coap_new_endpoint(context, &listen_addr, COAP_PROTO_DTLS); 999 if (!endpoint) { 1000 coap_free_context(context); 1001 return NULL; 1002 } 1003 1004 /* Initialize resources - See coap_resource(3) init_resources() example */ 1005 1006 return context; 1007} 1008---- 1009 1010*CoAP Server DTLS PSK Setup* 1011[source, c] 1012---- 1013#include <coap@LIBCOAP_API_VERSION@/coap.h> 1014 1015typedef struct id_def_t { 1016 char *hint_match; 1017 coap_bin_const_t id; 1018 coap_bin_const_t key; 1019} id_def_t; 1020 1021typedef struct valid_ids_t { 1022 size_t count; 1023 id_def_t *id_list; 1024} valid_ids_t; 1025 1026/* 1027 * PSK Identity Pre-Shared Key selection Callback function 1028 */ 1029static const coap_bin_const_t * 1030verify_id_callback(coap_bin_const_t *identity, 1031 coap_session_t *c_session, 1032 void *arg 1033) { 1034 valid_ids_t *valid_id_list = (valid_ids_t*)arg; 1035 const coap_bin_const_t *s_psk_hint = coap_session_get_psk_hint(c_session); 1036 size_t i; 1037 1038 /* Check that the Identity is valid */ 1039 for (i = 0; i < valid_id_list->count; i++) { 1040 if (s_psk_hint && 1041 strcmp((const char *)s_psk_hint->s, 1042 valid_id_list->id_list[i].hint_match)) { 1043 continue; 1044 } 1045 if (coap_binary_equal(identity, &valid_id_list->id_list[i].id)) { 1046 return &valid_id_list->id_list[i].key; 1047 } 1048 } 1049 return NULL; 1050} 1051 1052typedef struct sni_psk_def_t { 1053 char* sni; 1054 coap_dtls_spsk_info_t psk_info; 1055} sni_psk_def_t; 1056 1057typedef struct valid_psk_snis_t { 1058 int count; 1059 sni_psk_def_t *sni_list; 1060} valid_psk_snis_t; 1061 1062/* 1063 * PSK Subject Name Identifier (SNI) callback verifier 1064 */ 1065static const coap_dtls_spsk_info_t * 1066verify_psk_sni_callback(const char *sni, 1067 coap_session_t *c_session, 1068 void *arg 1069) { 1070 valid_psk_snis_t *valid_sni_list = (valid_psk_snis_t *)arg; 1071 int i; 1072 /* Remove (void) definition if variable is used */ 1073 (void)c_session; 1074 1075 /* Check that the SNI is valid */ 1076 for (i = 0; i < valid_sni_list->count; i++) { 1077 if (!strcasecmp(sni, valid_sni_list->sni_list[i].sni)) { 1078 return &valid_sni_list->sni_list[i].psk_info; 1079 } 1080 } 1081 return NULL; 1082} 1083 1084static coap_context_t * 1085setup_server_context_psk (const char *hint, 1086 const uint8_t *key, 1087 unsigned int key_len, 1088 valid_ids_t *valid_id_list, 1089 valid_psk_snis_t *valid_sni_list 1090) { 1091 coap_endpoint_t *endpoint; 1092 coap_address_t listen_addr; 1093 coap_context_t *context; 1094 coap_dtls_spsk_t dtls_psk; 1095 1096 /* See coap_tls_library(3) */ 1097 if (!coap_dtls_is_supported()) 1098 return NULL; 1099 1100 context = coap_new_context(NULL); 1101 if (!context) 1102 return NULL; 1103 /* See coap_block(3) */ 1104 coap_context_set_block_mode(context, 1105 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 1106 1107 1108 memset (&dtls_psk, 0, sizeof (dtls_psk)); 1109 1110 /* see coap_encryption(3) */ 1111 dtls_psk.version = COAP_DTLS_SPSK_SETUP_VERSION; 1112 dtls_psk.validate_id_call_back = verify_id_callback; 1113 dtls_psk.id_call_back_arg = valid_id_list; 1114 dtls_psk.validate_sni_call_back = verify_psk_sni_callback; 1115 dtls_psk.sni_call_back_arg = valid_sni_list; 1116 dtls_psk.psk_info.hint.s = (const uint8_t*)hint; 1117 dtls_psk.psk_info.hint.length = hint ? strlen(hint) : 0; 1118 dtls_psk.psk_info.key.s = key; 1119 dtls_psk.psk_info.key.length = key_len; 1120 1121 if (coap_context_set_psk2(context, &dtls_psk)) { 1122 coap_free_context(context); 1123 return NULL; 1124 } 1125 1126 coap_address_init(&listen_addr); 1127 listen_addr.addr.sa.sa_family = AF_INET; 1128 listen_addr.addr.sin.sin_port = htons (5684); 1129 1130 endpoint = coap_new_endpoint(context, &listen_addr, COAP_PROTO_DTLS); 1131 if (!endpoint) { 1132 coap_free_context(context); 1133 return NULL; 1134 } 1135 1136 /* Initialize resources - See coap_resource(3) init_resources() example */ 1137 1138 return context; 1139} 1140---- 1141 1142*CoAP Client DTLS PSK Setup* 1143[source, c] 1144---- 1145#include <coap@LIBCOAP_API_VERSION@/coap.h> 1146 1147#include <stdio.h> 1148 1149#ifndef min 1150#define min(a,b) ((a) < (b) ? (a) : (b)) 1151#endif 1152 1153static const coap_dtls_cpsk_info_t * 1154verify_ih_callback(coap_str_const_t *hint, 1155 coap_session_t *c_session, 1156 void *arg 1157) { 1158 coap_dtls_cpsk_info_t *psk_info = (coap_dtls_cpsk_info_t *)arg; 1159 /* Remove (void) definition if variable is used */ 1160 (void)c_session; 1161 1162 coap_log_info("Identity Hint '%.*s' provided\n", (int)hint->length, hint->s); 1163 1164 /* Just use the defined information for now as passed in by arg */ 1165 return psk_info; 1166} 1167 1168static coap_dtls_cpsk_t dtls_psk; 1169static char client_sni[256]; 1170 1171static coap_session_t * 1172setup_client_session_psk (const char *uri, 1173 struct in_addr ip_address, 1174 const uint8_t *identity, 1175 unsigned int identity_len, 1176 const uint8_t *key, 1177 unsigned int key_len 1178) { 1179 coap_session_t *session; 1180 coap_address_t server; 1181 /* See coap_context(3) */ 1182 coap_context_t *context = coap_new_context(NULL); 1183 1184 if (!context) 1185 return NULL; 1186 /* See coap_block(3) */ 1187 coap_context_set_block_mode(context, 1188 COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 1189 1190 1191 coap_address_init(&server); 1192 server.addr.sa.sa_family = AF_INET; 1193 server.addr.sin.sin_addr = ip_address; 1194 server.addr.sin.sin_port = htons (5684); 1195 1196 /* See coap_encryption(3) */ 1197 memset (&dtls_psk, 0, sizeof(dtls_psk)); 1198 dtls_psk.version = COAP_DTLS_CPSK_SETUP_VERSION; 1199 dtls_psk.validate_ih_call_back = verify_ih_callback; 1200 dtls_psk.ih_call_back_arg = &dtls_psk.psk_info; 1201 if (uri) 1202 memcpy(client_sni, uri, min(strlen(uri), sizeof(client_sni)-1)); 1203 else 1204 memcpy(client_sni, "localhost", 9); 1205 dtls_psk.client_sni = client_sni; 1206 dtls_psk.psk_info.identity.s = identity; 1207 dtls_psk.psk_info.identity.length = identity_len; 1208 dtls_psk.psk_info.key.s = key; 1209 dtls_psk.psk_info.key.length = key_len; 1210 session = coap_new_client_session_psk2(context, NULL, &server, 1211 COAP_PROTO_DTLS, &dtls_psk); 1212 if (!session) { 1213 coap_free_context(context); 1214 return NULL; 1215 } 1216 /* The context is in session->context */ 1217 return session; 1218} 1219---- 1220 1221SEE ALSO 1222-------- 1223*coap_block*(3), *coap_context*(3), *coap_resource*(3), *coap_session*(3) and 1224*coap_tls_library*(3) 1225 1226FURTHER INFORMATION 1227------------------- 1228See 1229 1230"https://rfc-editor.org/rfc/rfc7252[RFC7252: The Constrained Application Protocol (CoAP)]" 1231 1232for further information. 1233 1234BUGS 1235---- 1236Please report bugs on the mailing list for libcoap: 1237libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at 1238https://github.com/obgm/libcoap/issues 1239 1240AUTHORS 1241------- 1242The libcoap project <libcoap-developers@lists.sourceforge.net> 1243