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