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