1c87c5fbaSopenharmony_ci// -*- mode:doc; -*- 2c87c5fbaSopenharmony_ci// vim: set syntax=asciidoc tw=0 3c87c5fbaSopenharmony_ci 4c87c5fbaSopenharmony_cicoap_endpoint_server(3) 5c87c5fbaSopenharmony_ci======================= 6c87c5fbaSopenharmony_ci:doctype: manpage 7c87c5fbaSopenharmony_ci:man source: coap_endpoint_server 8c87c5fbaSopenharmony_ci:man version: @PACKAGE_VERSION@ 9c87c5fbaSopenharmony_ci:man manual: libcoap Manual 10c87c5fbaSopenharmony_ci 11c87c5fbaSopenharmony_ciNAME 12c87c5fbaSopenharmony_ci---- 13c87c5fbaSopenharmony_cicoap_endpoint_server, 14c87c5fbaSopenharmony_cicoap_context_set_pki, 15c87c5fbaSopenharmony_cicoap_context_set_pki_root_cas, 16c87c5fbaSopenharmony_cicoap_context_set_psk2, 17c87c5fbaSopenharmony_cicoap_new_endpoint, 18c87c5fbaSopenharmony_cicoap_free_endpoint, 19c87c5fbaSopenharmony_cicoap_endpoint_set_default_mtu, 20c87c5fbaSopenharmony_cicoap_join_mcast_group_intf, 21c87c5fbaSopenharmony_cicoap_mcast_per_resource 22c87c5fbaSopenharmony_ci- Work with CoAP server endpoints 23c87c5fbaSopenharmony_ci 24c87c5fbaSopenharmony_ciSYNOPSIS 25c87c5fbaSopenharmony_ci-------- 26c87c5fbaSopenharmony_ci*#include <coap@LIBCOAP_API_VERSION@/coap.h>* 27c87c5fbaSopenharmony_ci 28c87c5fbaSopenharmony_ci*int coap_context_set_pki(coap_context_t *_context_, 29c87c5fbaSopenharmony_ciconst coap_dtls_pki_t *_setup_data_);* 30c87c5fbaSopenharmony_ci 31c87c5fbaSopenharmony_ci*int coap_context_set_pki_root_cas(coap_context_t *_context_, 32c87c5fbaSopenharmony_ciconst char *_ca_file_, const char *_ca_dir_);* 33c87c5fbaSopenharmony_ci 34c87c5fbaSopenharmony_ci*int coap_context_set_psk2(coap_context_t *_context_, 35c87c5fbaSopenharmony_cicoap_dtls_spsk_t *setup_data);* 36c87c5fbaSopenharmony_ci 37c87c5fbaSopenharmony_ci*coap_endpoint_t *coap_new_endpoint(coap_context_t *_context_, 38c87c5fbaSopenharmony_ciconst coap_address_t *_listen_addr_, coap_proto_t _proto_);* 39c87c5fbaSopenharmony_ci 40c87c5fbaSopenharmony_ci*void coap_free_endpoint(coap_endpoint_t *_endpoint_);* 41c87c5fbaSopenharmony_ci 42c87c5fbaSopenharmony_ci*void coap_endpoint_set_default_mtu(coap_endpoint_t *_endpoint_, 43c87c5fbaSopenharmony_ciunsigned _mtu_);* 44c87c5fbaSopenharmony_ci 45c87c5fbaSopenharmony_ci*int coap_join_mcast_group_intf(coap_context_t *_context_, 46c87c5fbaSopenharmony_ciconst char *_groupname_, const char *_ifname_);* 47c87c5fbaSopenharmony_ci 48c87c5fbaSopenharmony_ci*void coap_mcast_per_resource(coap_context_t *_context_);* 49c87c5fbaSopenharmony_ci 50c87c5fbaSopenharmony_ciFor specific (D)TLS library support, link with 51c87c5fbaSopenharmony_ci*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*, 52c87c5fbaSopenharmony_ci*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls* 53c87c5fbaSopenharmony_cior *-lcoap-@LIBCOAP_API_VERSION@-tinydtls*. Otherwise, link with 54c87c5fbaSopenharmony_ci*-lcoap-@LIBCOAP_API_VERSION@* to get the default (D)TLS library support. 55c87c5fbaSopenharmony_ci 56c87c5fbaSopenharmony_ciDESCRIPTION 57c87c5fbaSopenharmony_ci----------- 58c87c5fbaSopenharmony_ciThis man page focuses on the setting up of a CoAP server endpoint. For a CoAP 59c87c5fbaSopenharmony_ciclient endpoint, see *coap_endpoint_client*(3). 60c87c5fbaSopenharmony_ci 61c87c5fbaSopenharmony_ciThe CoAP stack's global state is stored in a coap_context_t _context_ object. 62c87c5fbaSopenharmony_ciResources, Endpoints and Sessions are associated with this _context_ object. 63c87c5fbaSopenharmony_ciThere can be more than one coap_context_t object per application, it is up to 64c87c5fbaSopenharmony_cithe application to manage each one accordingly. 65c87c5fbaSopenharmony_ci 66c87c5fbaSopenharmony_ciA CoAP _session_ maintains the state of an ongoing connection between a Client 67c87c5fbaSopenharmony_ciand Server which is stored in a coap_session_t _session_ object. A CoAP 68c87c5fbaSopenharmony_ci_session_ is tracked by local port, CoAP protocol, remote IP address and 69c87c5fbaSopenharmony_ciremote port, or in the case of Unix Domain sockets, the local path and the 70c87c5fbaSopenharmony_ciremote path. 71c87c5fbaSopenharmony_ci 72c87c5fbaSopenharmony_ciThe _session_ network traffic can be encrypted or un-encrypted if there is an 73c87c5fbaSopenharmony_ciunderlying TLS library. 74c87c5fbaSopenharmony_ci 75c87c5fbaSopenharmony_ciIf (D)TLS is going to be used for encrypting the network traffic, then the 76c87c5fbaSopenharmony_ci(D)TLS 77c87c5fbaSopenharmony_ciinformation for Pre-Shared Keys (PSK) or Public Key Infrastructure (PKI) needs 78c87c5fbaSopenharmony_cito be configured before any network traffic starts to flow. For Servers, this 79c87c5fbaSopenharmony_cihas to be done before the Endpoint is created. 80c87c5fbaSopenharmony_ci 81c87c5fbaSopenharmony_ciFor Servers, all the encryption information is held internally by the (D)TLS 82c87c5fbaSopenharmony_cicontext level and the CoAP _context_ level as the Server is listening for new 83c87c5fbaSopenharmony_ciincoming traffic based on the Endpoint definition. The (D)TLS and CoAP 84c87c5fbaSopenharmony_ci_session_ will not get built until the new traffic starts, which is done by the 85c87c5fbaSopenharmony_cilibcoap library. 86c87c5fbaSopenharmony_ci 87c87c5fbaSopenharmony_ciIn principle the set-up sequence for CoAP Servers looks like 88c87c5fbaSopenharmony_ci---- 89c87c5fbaSopenharmony_cicoap_new_context() 90c87c5fbaSopenharmony_cicoap_context_set_pki_root_cas() - if the root CAs need to be updated and using PKI 91c87c5fbaSopenharmony_cicoap_context_set_pki() and/or coap_context_set_psk2() - if encryption is required 92c87c5fbaSopenharmony_cicoap_new_endpoint() 93c87c5fbaSopenharmony_ci---- 94c87c5fbaSopenharmony_ci 95c87c5fbaSopenharmony_ciMultiple endpoints can be set up per _context_, each listening for a new traffic 96c87c5fbaSopenharmony_ciflow with different TCP/UDP protocols, (D)TLS protocols, port numbers, Unix 97c87c5fbaSopenharmony_cipathnames etc. When 98c87c5fbaSopenharmony_cia new traffic flow is started, then the CoAP library will create and start a new 99c87c5fbaSopenharmony_ciserver _session_. 100c87c5fbaSopenharmony_ci 101c87c5fbaSopenharmony_ciFUNCTIONS 102c87c5fbaSopenharmony_ci--------- 103c87c5fbaSopenharmony_ci 104c87c5fbaSopenharmony_ci*Function: coap_context_set_pki()* 105c87c5fbaSopenharmony_ci 106c87c5fbaSopenharmony_ciThe *coap_context_set_pki*() function, for a specific _context_, is used to 107c87c5fbaSopenharmony_ciconfigure the (D)TLS context using the _setup_data_ PKI variables as defined in 108c87c5fbaSopenharmony_cithe coap_dtls_pki_t structure - see *coap_encryption*(3). 109c87c5fbaSopenharmony_ci 110c87c5fbaSopenharmony_ci*Function: coap_context_set_pki_root_cas()* 111c87c5fbaSopenharmony_ci 112c87c5fbaSopenharmony_ciThe *coap_context_set_pki_root_cas*() function is used to define a set of 113c87c5fbaSopenharmony_ciroot CAs to be used instead of the default set of root CAs provided as a part 114c87c5fbaSopenharmony_ciof the TLS library. _ca_file_ points to a PEM encoded file containing the 115c87c5fbaSopenharmony_cilist of CAs. _ca_file_ can be NULL. _ca_dir_ points to a directory 116c87c5fbaSopenharmony_cicontaining a set of PEM encoded files containing rootCAs. _ca_dir_ can be 117c87c5fbaSopenharmony_ciNULL. One or both of _ca_file_ and _ca_dir_ must be set. + 118c87c5fbaSopenharmony_ci*NOTE:* Some TLS libraries send the full list of CAs added by this function 119c87c5fbaSopenharmony_ciduring the (D)TLS session setup handshakes. To stop this, either provide a 120c87c5fbaSopenharmony_cisingle CA using the _ca_file_ definition in _pki_key_ in _setup_data_ variable 121c87c5fbaSopenharmony_ciwhen calling *coap_context_set_pki*(), or set _check_common_ca_ to 0 in 122c87c5fbaSopenharmony_ci_setup_data_ variable. See *coap_encryption*(3). 123c87c5fbaSopenharmony_ci 124c87c5fbaSopenharmony_ci*Function: coap_context_set_psk2()* 125c87c5fbaSopenharmony_ci 126c87c5fbaSopenharmony_ciThe *coap_context_set_psk2*() function is used to configure the (D)TLS context 127c87c5fbaSopenharmony_ciusing the _setup_data_ PSK variables as defined in the 128c87c5fbaSopenharmony_cicoap_dtls_spsk_t structure - see *coap_encryption*(3). 129c87c5fbaSopenharmony_ciThis function can only be used for servers as _setup_data_ provides 130c87c5fbaSopenharmony_cia _hint_, not an _identity_. 131c87c5fbaSopenharmony_ci 132c87c5fbaSopenharmony_ci*Function: coap_new_endpoint()* 133c87c5fbaSopenharmony_ci 134c87c5fbaSopenharmony_ciThe *coap_new_endpoint*() function creates a new endpoint for _context_ that 135c87c5fbaSopenharmony_ciis listening for new traffic as defined in _listen_addr_ 136c87c5fbaSopenharmony_ci(see *coap_address_t*(3)). If the address family is AF_INET or AF_INET6, then it 137c87c5fbaSopenharmony_cilistens on the IP address and port number defined by _listen_addr_. If the 138c87c5fbaSopenharmony_ciport number is 0, then the default CoAP port is used. If the address family is 139c87c5fbaSopenharmony_ciAF_UNIX, then it listens on the defined unix domain path which has to be 140c87c5fbaSopenharmony_ciunique per endpoint. This unique unix domain path will get deleted on 141c87c5fbaSopenharmony_ciclean application exit. 142c87c5fbaSopenharmony_ci 143c87c5fbaSopenharmony_ciDifferent CoAP protocols can be defined for _proto_ - the current supported 144c87c5fbaSopenharmony_cilist is: 145c87c5fbaSopenharmony_ci 146c87c5fbaSopenharmony_ci[source, c] 147c87c5fbaSopenharmony_ci---- 148c87c5fbaSopenharmony_ciCOAP_PROTO_UDP 149c87c5fbaSopenharmony_ciCOAP_PROTO_DTLS 150c87c5fbaSopenharmony_ciCOAP_PROTO_TCP 151c87c5fbaSopenharmony_ciCOAP_PROTO_TLS 152c87c5fbaSopenharmony_ciCOAP_PROTO_WS 153c87c5fbaSopenharmony_ciCOAP_PROTO_WSS 154c87c5fbaSopenharmony_ci---- 155c87c5fbaSopenharmony_ci 156c87c5fbaSopenharmony_ci*coap_tcp_is_supported*(3), *coap_dtls_is_supported*(3), 157c87c5fbaSopenharmony_ci*coap_tls_is_supported*(3), *coap_ws_is_supported*(3) and 158c87c5fbaSopenharmony_ci*coap_wss_is_supported*(3) can be used for checking whether the underlying 159c87c5fbaSopenharmony_ciTCP, (D)TLS or WebSocket protocol support is available. 160c87c5fbaSopenharmony_ciSee *coap_tls_library(3)* for further information on the types of (D)TLS 161c87c5fbaSopenharmony_cisessions supported. 162c87c5fbaSopenharmony_ci 163c87c5fbaSopenharmony_ciWhen traffic starts to come in from a client, a server CoAP session is created 164c87c5fbaSopenharmony_ciassociated with this endpoint. This CoAP session is created with a reference 165c87c5fbaSopenharmony_cicount of 0. This means that if the server session is not used for 5 minutes, 166c87c5fbaSopenharmony_cithen it will get completely freed off. See *coap_session_reference*(3) and 167c87c5fbaSopenharmony_ci*coap_session_release*(3) for further information. 168c87c5fbaSopenharmony_ci 169c87c5fbaSopenharmony_ci*Function: coap_free_endpoint()* 170c87c5fbaSopenharmony_ci 171c87c5fbaSopenharmony_ciThe *coap_free_endpoint*() function must be used to free off the _endpoint_. 172c87c5fbaSopenharmony_ciIt clears out all the sessions associated with this endpoint along with 173c87c5fbaSopenharmony_ciany data associated with the sessions as well as 174c87c5fbaSopenharmony_cideleting the unix domain path if the address family is AF_UNIX. 175c87c5fbaSopenharmony_ci 176c87c5fbaSopenharmony_ci*Function: coap_endpoint_set_default_mtu()* 177c87c5fbaSopenharmony_ci 178c87c5fbaSopenharmony_ciThe *coap_endpoint_set_default_mtu*() function is used to set the MTU size 179c87c5fbaSopenharmony_ci(the maximum message size) of the data in a packet, excluding any IP or 180c87c5fbaSopenharmony_ciTCP/UDP overhead to _mtu_ for the _endpoint_. A sensible default is 1280. 181c87c5fbaSopenharmony_ci 182c87c5fbaSopenharmony_ci*Function: coap_join_mcast_group_intf()* 183c87c5fbaSopenharmony_ci 184c87c5fbaSopenharmony_ciThe *coap_join_mcast_group_intf*() function is used to join the currently 185c87c5fbaSopenharmony_cidefined endpoints that are UDP, associated with _context_, to the defined 186c87c5fbaSopenharmony_cimulticast group _groupname_. If _ifname_ is not NULL, then the multicast group 187c87c5fbaSopenharmony_ciis associated with this interface, otherwise the underlying O/S will choose the 188c87c5fbaSopenharmony_cifirst appropriate interface. When the endpoint is freed off, the associated 189c87c5fbaSopenharmony_cimulticast group will be removed. The registered multicast addresses for CoAP 190c87c5fbaSopenharmony_ciare 224.0.1.187, ff0x::fd (Variable-Scope) - i.e. ff02::fd (Link-Local) and 191c87c5fbaSopenharmony_ciff05::fd (Site-Local). 192c87c5fbaSopenharmony_ci 193c87c5fbaSopenharmony_ci*NOTE:* multicast is not supported for address family type AF_UNIX. 194c87c5fbaSopenharmony_ci 195c87c5fbaSopenharmony_ci*Function: coap_mcast_per_resource()* 196c87c5fbaSopenharmony_ci 197c87c5fbaSopenharmony_ciThe *coap_mcast_per_resource*() function enables mcast to be controlled on a 198c87c5fbaSopenharmony_ciper resource basis giving the server application flexibility in how to respond 199c87c5fbaSopenharmony_cito mcast requests. With this enabled, this is done through additional flag 200c87c5fbaSopenharmony_cidefinitions when setting up each resource. See *coap_resource*(3). 201c87c5fbaSopenharmony_ci 202c87c5fbaSopenharmony_ciRETURN VALUES 203c87c5fbaSopenharmony_ci------------- 204c87c5fbaSopenharmony_ci*coap_context_set_pki*(), *coap_context_set_pki_root_cas*() and 205c87c5fbaSopenharmony_ci*coap_context_set_psk2*() return 1 on success, 0 on failure. 206c87c5fbaSopenharmony_ci 207c87c5fbaSopenharmony_ci*coap_new_endpoint*() returns a newly created endpoint or 208c87c5fbaSopenharmony_ciNULL if there is a creation failure. 209c87c5fbaSopenharmony_ci 210c87c5fbaSopenharmony_ci*coap_join_mcast_group_intf*() returns 0 on success, -1 on failure. 211c87c5fbaSopenharmony_ci 212c87c5fbaSopenharmony_ciEXAMPLES 213c87c5fbaSopenharmony_ci-------- 214c87c5fbaSopenharmony_ci*CoAP Server Non-Encrypted Setup* 215c87c5fbaSopenharmony_ci 216c87c5fbaSopenharmony_ci[source, c] 217c87c5fbaSopenharmony_ci---- 218c87c5fbaSopenharmony_ci#include <coap@LIBCOAP_API_VERSION@/coap.h> 219c87c5fbaSopenharmony_ci 220c87c5fbaSopenharmony_cistatic coap_context_t * 221c87c5fbaSopenharmony_cisetup_server_context (void) { 222c87c5fbaSopenharmony_ci coap_endpoint_t *endpoint; 223c87c5fbaSopenharmony_ci coap_address_t listen_addr; 224c87c5fbaSopenharmony_ci coap_context_t *context = coap_new_context(NULL); 225c87c5fbaSopenharmony_ci 226c87c5fbaSopenharmony_ci if (!context) 227c87c5fbaSopenharmony_ci return NULL; 228c87c5fbaSopenharmony_ci /* See coap_block(3) */ 229c87c5fbaSopenharmony_ci coap_context_set_block_mode(context, 230c87c5fbaSopenharmony_ci COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 231c87c5fbaSopenharmony_ci 232c87c5fbaSopenharmony_ci 233c87c5fbaSopenharmony_ci /* See coap_address(3) */ 234c87c5fbaSopenharmony_ci coap_address_init(&listen_addr); 235c87c5fbaSopenharmony_ci listen_addr.addr.sa.sa_family = AF_INET; 236c87c5fbaSopenharmony_ci listen_addr.addr.sin.sin_port = htons (5683); 237c87c5fbaSopenharmony_ci 238c87c5fbaSopenharmony_ci endpoint = coap_new_endpoint(context, &listen_addr, COAP_PROTO_UDP); 239c87c5fbaSopenharmony_ci if (!endpoint) { 240c87c5fbaSopenharmony_ci coap_free_context(context); 241c87c5fbaSopenharmony_ci return NULL; 242c87c5fbaSopenharmony_ci } 243c87c5fbaSopenharmony_ci 244c87c5fbaSopenharmony_ci /* Initialize resources - See coap_resource(3) init_resources() example */ 245c87c5fbaSopenharmony_ci 246c87c5fbaSopenharmony_ci return context; 247c87c5fbaSopenharmony_ci} 248c87c5fbaSopenharmony_ci---- 249c87c5fbaSopenharmony_ci 250c87c5fbaSopenharmony_ci*CoAP Server Non-Encrypted Unix Domain Setup* 251c87c5fbaSopenharmony_ci 252c87c5fbaSopenharmony_ci[source, c] 253c87c5fbaSopenharmony_ci---- 254c87c5fbaSopenharmony_ci#include <coap@LIBCOAP_API_VERSION@/coap.h> 255c87c5fbaSopenharmony_ci 256c87c5fbaSopenharmony_ci#include <stdio.h> 257c87c5fbaSopenharmony_ci#include <unistd.h> 258c87c5fbaSopenharmony_ci 259c87c5fbaSopenharmony_ci/* This need to be unique per endpoint */ 260c87c5fbaSopenharmony_ci#define UNIX_DOMAIN_LISTEN_DGRAM "/tmp/server.dgram" 261c87c5fbaSopenharmony_ci 262c87c5fbaSopenharmony_cistatic coap_context_t * 263c87c5fbaSopenharmony_cisetup_server_context (void) { 264c87c5fbaSopenharmony_ci coap_endpoint_t *endpoint; 265c87c5fbaSopenharmony_ci coap_address_t listen_addr; 266c87c5fbaSopenharmony_ci coap_context_t *context = coap_new_context(NULL); 267c87c5fbaSopenharmony_ci 268c87c5fbaSopenharmony_ci if (!context) 269c87c5fbaSopenharmony_ci return NULL; 270c87c5fbaSopenharmony_ci /* See coap_block(3) */ 271c87c5fbaSopenharmony_ci coap_context_set_block_mode(context, 272c87c5fbaSopenharmony_ci COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 273c87c5fbaSopenharmony_ci 274c87c5fbaSopenharmony_ci 275c87c5fbaSopenharmony_ci /* See coap_address(3) */ 276c87c5fbaSopenharmony_ci coap_address_set_unix_domain(&listen_addr, 277c87c5fbaSopenharmony_ci (const uint8_t *)UNIX_DOMAIN_LISTEN_DGRAM, 278c87c5fbaSopenharmony_ci strlen(UNIX_DOMAIN_LISTEN_DGRAM)); 279c87c5fbaSopenharmony_ci /* Only do this if you know it is safe to do so */ 280c87c5fbaSopenharmony_ci unlink(listen_addr.addr.cun.sun_path); 281c87c5fbaSopenharmony_ci 282c87c5fbaSopenharmony_ci endpoint = coap_new_endpoint(context, &listen_addr, COAP_PROTO_UDP); 283c87c5fbaSopenharmony_ci if (!endpoint) { 284c87c5fbaSopenharmony_ci coap_free_context(context); 285c87c5fbaSopenharmony_ci return NULL; 286c87c5fbaSopenharmony_ci } 287c87c5fbaSopenharmony_ci 288c87c5fbaSopenharmony_ci /* Initialize resources - See coap_resource(3) init_resources() example */ 289c87c5fbaSopenharmony_ci 290c87c5fbaSopenharmony_ci return context; 291c87c5fbaSopenharmony_ci} 292c87c5fbaSopenharmony_ci---- 293c87c5fbaSopenharmony_ci 294c87c5fbaSopenharmony_ci*CoAP Server DTLS PKI Setup* 295c87c5fbaSopenharmony_ci[source, c] 296c87c5fbaSopenharmony_ci---- 297c87c5fbaSopenharmony_ci#include <coap@LIBCOAP_API_VERSION@/coap.h> 298c87c5fbaSopenharmony_ci 299c87c5fbaSopenharmony_citypedef struct valid_cns_t { 300c87c5fbaSopenharmony_ci size_t count; 301c87c5fbaSopenharmony_ci char **cn_list; 302c87c5fbaSopenharmony_ci} valid_cns_t; 303c87c5fbaSopenharmony_ci 304c87c5fbaSopenharmony_ci/* 305c87c5fbaSopenharmony_ci * Common Name (CN) Callback verifier 306c87c5fbaSopenharmony_ci */ 307c87c5fbaSopenharmony_cistatic int 308c87c5fbaSopenharmony_civerify_cn_callback(const char *cn, 309c87c5fbaSopenharmony_ci const uint8_t *asn1_public_cert, 310c87c5fbaSopenharmony_ci size_t asn1_length, 311c87c5fbaSopenharmony_ci coap_session_t *c_session, 312c87c5fbaSopenharmony_ci unsigned depth, 313c87c5fbaSopenharmony_ci int validated, 314c87c5fbaSopenharmony_ci void *arg 315c87c5fbaSopenharmony_ci) { 316c87c5fbaSopenharmony_ci valid_cns_t *valid_cn_list = (valid_cns_t*)arg; 317c87c5fbaSopenharmony_ci size_t i; 318c87c5fbaSopenharmony_ci /* Remove (void) definition if variable is used */ 319c87c5fbaSopenharmony_ci (void)asn1_public_cert; 320c87c5fbaSopenharmony_ci (void)asn1_length; 321c87c5fbaSopenharmony_ci (void)c_session; 322c87c5fbaSopenharmony_ci (void)depth; 323c87c5fbaSopenharmony_ci (void)validated; 324c87c5fbaSopenharmony_ci 325c87c5fbaSopenharmony_ci /* Check that the CN is valid */ 326c87c5fbaSopenharmony_ci for (i = 0; i < valid_cn_list->count; i++) { 327c87c5fbaSopenharmony_ci if (!strcasecmp(cn, valid_cn_list->cn_list[i])) { 328c87c5fbaSopenharmony_ci return 1; 329c87c5fbaSopenharmony_ci } 330c87c5fbaSopenharmony_ci } 331c87c5fbaSopenharmony_ci return 0; 332c87c5fbaSopenharmony_ci} 333c87c5fbaSopenharmony_ci 334c87c5fbaSopenharmony_citypedef struct sni_def_t { 335c87c5fbaSopenharmony_ci char* sni; 336c87c5fbaSopenharmony_ci coap_dtls_key_t key; 337c87c5fbaSopenharmony_ci} sni_def_t; 338c87c5fbaSopenharmony_ci 339c87c5fbaSopenharmony_citypedef struct valid_snis_t { 340c87c5fbaSopenharmony_ci size_t count; 341c87c5fbaSopenharmony_ci sni_def_t *sni_list; 342c87c5fbaSopenharmony_ci} valid_snis_t; 343c87c5fbaSopenharmony_ci 344c87c5fbaSopenharmony_ci/* 345c87c5fbaSopenharmony_ci * Subject Name Identifier (SNI) callback verifier 346c87c5fbaSopenharmony_ci */ 347c87c5fbaSopenharmony_cistatic coap_dtls_key_t * 348c87c5fbaSopenharmony_civerify_pki_sni_callback(const char *sni, 349c87c5fbaSopenharmony_ci void *arg 350c87c5fbaSopenharmony_ci) { 351c87c5fbaSopenharmony_ci valid_snis_t *valid_sni_list = (valid_snis_t *)arg; 352c87c5fbaSopenharmony_ci size_t i; 353c87c5fbaSopenharmony_ci 354c87c5fbaSopenharmony_ci /* Check that the SNI is valid */ 355c87c5fbaSopenharmony_ci for (i = 0; i < valid_sni_list->count; i++) { 356c87c5fbaSopenharmony_ci if (!strcasecmp(sni, valid_sni_list->sni_list[i].sni)) { 357c87c5fbaSopenharmony_ci return &valid_sni_list->sni_list[i].key; 358c87c5fbaSopenharmony_ci } 359c87c5fbaSopenharmony_ci } 360c87c5fbaSopenharmony_ci return NULL; 361c87c5fbaSopenharmony_ci} 362c87c5fbaSopenharmony_ci 363c87c5fbaSopenharmony_ci/* 364c87c5fbaSopenharmony_ci * Set up PKI encryption information 365c87c5fbaSopenharmony_ci */ 366c87c5fbaSopenharmony_cistatic coap_context_t * 367c87c5fbaSopenharmony_cisetup_server_context_pki (const char *public_cert_file, 368c87c5fbaSopenharmony_ci const char *private_key_file, 369c87c5fbaSopenharmony_ci const char *ca_file, 370c87c5fbaSopenharmony_ci valid_cns_t *valid_cn_list, 371c87c5fbaSopenharmony_ci valid_snis_t *valid_sni_list 372c87c5fbaSopenharmony_ci) { 373c87c5fbaSopenharmony_ci coap_endpoint_t *endpoint; 374c87c5fbaSopenharmony_ci coap_address_t listen_addr; 375c87c5fbaSopenharmony_ci coap_dtls_pki_t dtls_pki; 376c87c5fbaSopenharmony_ci coap_context_t *context; 377c87c5fbaSopenharmony_ci 378c87c5fbaSopenharmony_ci /* See coap_tls_library(3) */ 379c87c5fbaSopenharmony_ci if (!coap_dtls_is_supported()) 380c87c5fbaSopenharmony_ci return NULL; 381c87c5fbaSopenharmony_ci 382c87c5fbaSopenharmony_ci context = coap_new_context(NULL); 383c87c5fbaSopenharmony_ci if (!context) 384c87c5fbaSopenharmony_ci return NULL; 385c87c5fbaSopenharmony_ci /* See coap_block(3) */ 386c87c5fbaSopenharmony_ci coap_context_set_block_mode(context, 387c87c5fbaSopenharmony_ci COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 388c87c5fbaSopenharmony_ci 389c87c5fbaSopenharmony_ci 390c87c5fbaSopenharmony_ci memset (&dtls_pki, 0, sizeof (dtls_pki)); 391c87c5fbaSopenharmony_ci 392c87c5fbaSopenharmony_ci /* see coap_encryption(3) */ 393c87c5fbaSopenharmony_ci dtls_pki.version = COAP_DTLS_PKI_SETUP_VERSION; 394c87c5fbaSopenharmony_ci dtls_pki.verify_peer_cert = 1; 395c87c5fbaSopenharmony_ci dtls_pki.check_common_ca = 1; 396c87c5fbaSopenharmony_ci dtls_pki.allow_self_signed = 1; 397c87c5fbaSopenharmony_ci dtls_pki.allow_expired_certs = 1; 398c87c5fbaSopenharmony_ci dtls_pki.cert_chain_validation = 1; 399c87c5fbaSopenharmony_ci dtls_pki.cert_chain_verify_depth = 1; 400c87c5fbaSopenharmony_ci dtls_pki.check_cert_revocation = 1; 401c87c5fbaSopenharmony_ci dtls_pki.allow_no_crl = 1; 402c87c5fbaSopenharmony_ci dtls_pki.allow_expired_crl = 1; 403c87c5fbaSopenharmony_ci dtls_pki.allow_bad_md_hash = 0; 404c87c5fbaSopenharmony_ci dtls_pki.allow_short_rsa_length = 0; 405c87c5fbaSopenharmony_ci dtls_pki.is_rpk_not_cert = 0; /* Set to 1 if RPK */ 406c87c5fbaSopenharmony_ci dtls_pki.validate_cn_call_back = verify_cn_callback; 407c87c5fbaSopenharmony_ci dtls_pki.cn_call_back_arg = valid_cn_list; 408c87c5fbaSopenharmony_ci dtls_pki.validate_sni_call_back = verify_pki_sni_callback; 409c87c5fbaSopenharmony_ci dtls_pki.sni_call_back_arg = valid_sni_list; 410c87c5fbaSopenharmony_ci dtls_pki.additional_tls_setup_call_back = NULL; 411c87c5fbaSopenharmony_ci dtls_pki.client_sni = NULL; 412c87c5fbaSopenharmony_ci dtls_pki.pki_key.key_type = COAP_PKI_KEY_PEM; 413c87c5fbaSopenharmony_ci dtls_pki.pki_key.key.pem.ca_file = ca_file; 414c87c5fbaSopenharmony_ci dtls_pki.pki_key.key.pem.public_cert = public_cert_file; 415c87c5fbaSopenharmony_ci dtls_pki.pki_key.key.pem.private_key = private_key_file; 416c87c5fbaSopenharmony_ci 417c87c5fbaSopenharmony_ci if (coap_context_set_pki(context, &dtls_pki)) { 418c87c5fbaSopenharmony_ci coap_free_context(context); 419c87c5fbaSopenharmony_ci return NULL; 420c87c5fbaSopenharmony_ci } 421c87c5fbaSopenharmony_ci 422c87c5fbaSopenharmony_ci /* See coap_address(3) */ 423c87c5fbaSopenharmony_ci coap_address_init(&listen_addr); 424c87c5fbaSopenharmony_ci listen_addr.addr.sa.sa_family = AF_INET; 425c87c5fbaSopenharmony_ci listen_addr.addr.sin.sin_port = htons (5684); 426c87c5fbaSopenharmony_ci 427c87c5fbaSopenharmony_ci endpoint = coap_new_endpoint(context, &listen_addr, COAP_PROTO_DTLS); 428c87c5fbaSopenharmony_ci if (!endpoint) { 429c87c5fbaSopenharmony_ci coap_free_context(context); 430c87c5fbaSopenharmony_ci return NULL; 431c87c5fbaSopenharmony_ci } 432c87c5fbaSopenharmony_ci 433c87c5fbaSopenharmony_ci /* Initialize resources - See coap_resource(3) init_resources() example */ 434c87c5fbaSopenharmony_ci 435c87c5fbaSopenharmony_ci return context; 436c87c5fbaSopenharmony_ci} 437c87c5fbaSopenharmony_ci---- 438c87c5fbaSopenharmony_ci 439c87c5fbaSopenharmony_ci*CoAP Server DTLS PSK Setup* 440c87c5fbaSopenharmony_ci[source, c] 441c87c5fbaSopenharmony_ci---- 442c87c5fbaSopenharmony_ci#include <coap@LIBCOAP_API_VERSION@/coap.h> 443c87c5fbaSopenharmony_ci 444c87c5fbaSopenharmony_citypedef struct id_def_t { 445c87c5fbaSopenharmony_ci char* id; 446c87c5fbaSopenharmony_ci coap_bin_const_t key; 447c87c5fbaSopenharmony_ci} id_def_t; 448c87c5fbaSopenharmony_ci 449c87c5fbaSopenharmony_citypedef struct valid_ids_t { 450c87c5fbaSopenharmony_ci int count; 451c87c5fbaSopenharmony_ci id_def_t *id_list; 452c87c5fbaSopenharmony_ci} valid_ids_t; 453c87c5fbaSopenharmony_ci 454c87c5fbaSopenharmony_ci/* 455c87c5fbaSopenharmony_ci * PSK Identity Pre-Shared Key selection Callback function 456c87c5fbaSopenharmony_ci */ 457c87c5fbaSopenharmony_cistatic const coap_bin_const_t * 458c87c5fbaSopenharmony_civerify_id_callback(coap_bin_const_t *identity, 459c87c5fbaSopenharmony_ci coap_session_t *c_session, 460c87c5fbaSopenharmony_ci void *arg 461c87c5fbaSopenharmony_ci) { 462c87c5fbaSopenharmony_ci valid_ids_t *valid_id_list = (valid_ids_t*)arg; 463c87c5fbaSopenharmony_ci int i; 464c87c5fbaSopenharmony_ci /* Remove (void) definition if variable is used */ 465c87c5fbaSopenharmony_ci (void)c_session; 466c87c5fbaSopenharmony_ci 467c87c5fbaSopenharmony_ci /* Check that the Identity is valid */ 468c87c5fbaSopenharmony_ci for (i = 0; i < valid_id_list->count; i++) { 469c87c5fbaSopenharmony_ci if (!strcasecmp((const char*)identity->s, valid_id_list->id_list[i].id)) { 470c87c5fbaSopenharmony_ci return &valid_id_list->id_list[i].key; 471c87c5fbaSopenharmony_ci } 472c87c5fbaSopenharmony_ci } 473c87c5fbaSopenharmony_ci return NULL; 474c87c5fbaSopenharmony_ci} 475c87c5fbaSopenharmony_ci 476c87c5fbaSopenharmony_citypedef struct sni_psk_def_t { 477c87c5fbaSopenharmony_ci char* sni; 478c87c5fbaSopenharmony_ci coap_dtls_spsk_info_t psk_info; 479c87c5fbaSopenharmony_ci} sni_psk_def_t; 480c87c5fbaSopenharmony_ci 481c87c5fbaSopenharmony_citypedef struct valid_psk_snis_t { 482c87c5fbaSopenharmony_ci int count; 483c87c5fbaSopenharmony_ci sni_psk_def_t *sni_list; 484c87c5fbaSopenharmony_ci} valid_psk_snis_t; 485c87c5fbaSopenharmony_ci 486c87c5fbaSopenharmony_ci/* 487c87c5fbaSopenharmony_ci * PSK Subject Name Identifier (SNI) callback verifier 488c87c5fbaSopenharmony_ci */ 489c87c5fbaSopenharmony_cistatic const coap_dtls_spsk_info_t * 490c87c5fbaSopenharmony_civerify_psk_sni_callback(const char *sni, 491c87c5fbaSopenharmony_ci coap_session_t *c_session, 492c87c5fbaSopenharmony_ci void *arg 493c87c5fbaSopenharmony_ci) { 494c87c5fbaSopenharmony_ci valid_psk_snis_t *valid_sni_list = (valid_psk_snis_t *)arg; 495c87c5fbaSopenharmony_ci int i; 496c87c5fbaSopenharmony_ci /* Remove (void) definition if variable is used */ 497c87c5fbaSopenharmony_ci (void)c_session; 498c87c5fbaSopenharmony_ci 499c87c5fbaSopenharmony_ci /* Check that the SNI is valid */ 500c87c5fbaSopenharmony_ci for (i = 0; i < valid_sni_list->count; i++) { 501c87c5fbaSopenharmony_ci if (!strcasecmp(sni, valid_sni_list->sni_list[i].sni)) { 502c87c5fbaSopenharmony_ci return &valid_sni_list->sni_list[i].psk_info; 503c87c5fbaSopenharmony_ci } 504c87c5fbaSopenharmony_ci } 505c87c5fbaSopenharmony_ci return NULL; 506c87c5fbaSopenharmony_ci} 507c87c5fbaSopenharmony_ci 508c87c5fbaSopenharmony_cistatic coap_context_t * 509c87c5fbaSopenharmony_cisetup_server_context_psk (const char *hint, 510c87c5fbaSopenharmony_ci const uint8_t *key, 511c87c5fbaSopenharmony_ci unsigned int key_len, 512c87c5fbaSopenharmony_ci valid_ids_t *valid_id_list, 513c87c5fbaSopenharmony_ci valid_psk_snis_t *valid_sni_list 514c87c5fbaSopenharmony_ci) { 515c87c5fbaSopenharmony_ci coap_endpoint_t *endpoint; 516c87c5fbaSopenharmony_ci coap_address_t listen_addr; 517c87c5fbaSopenharmony_ci coap_context_t *context; 518c87c5fbaSopenharmony_ci coap_dtls_spsk_t dtls_psk; 519c87c5fbaSopenharmony_ci 520c87c5fbaSopenharmony_ci /* See coap_tls_library(3) */ 521c87c5fbaSopenharmony_ci if (!coap_dtls_is_supported()) 522c87c5fbaSopenharmony_ci return NULL; 523c87c5fbaSopenharmony_ci 524c87c5fbaSopenharmony_ci context = coap_new_context(NULL); 525c87c5fbaSopenharmony_ci if (!context) 526c87c5fbaSopenharmony_ci return NULL; 527c87c5fbaSopenharmony_ci /* See coap_block(3) */ 528c87c5fbaSopenharmony_ci coap_context_set_block_mode(context, 529c87c5fbaSopenharmony_ci COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY); 530c87c5fbaSopenharmony_ci 531c87c5fbaSopenharmony_ci 532c87c5fbaSopenharmony_ci memset (&dtls_psk, 0, sizeof (dtls_psk)); 533c87c5fbaSopenharmony_ci 534c87c5fbaSopenharmony_ci /* see coap_encryption(3) */ 535c87c5fbaSopenharmony_ci dtls_psk.version = COAP_DTLS_SPSK_SETUP_VERSION; 536c87c5fbaSopenharmony_ci dtls_psk.validate_id_call_back = verify_id_callback; 537c87c5fbaSopenharmony_ci dtls_psk.id_call_back_arg = valid_id_list; 538c87c5fbaSopenharmony_ci dtls_psk.validate_sni_call_back = verify_psk_sni_callback; 539c87c5fbaSopenharmony_ci dtls_psk.sni_call_back_arg = valid_sni_list; 540c87c5fbaSopenharmony_ci dtls_psk.psk_info.hint.s = (const uint8_t*)hint; 541c87c5fbaSopenharmony_ci dtls_psk.psk_info.hint.length = hint ? strlen(hint) : 0; 542c87c5fbaSopenharmony_ci dtls_psk.psk_info.key.s = key; 543c87c5fbaSopenharmony_ci dtls_psk.psk_info.key.length = key_len; 544c87c5fbaSopenharmony_ci 545c87c5fbaSopenharmony_ci if (coap_context_set_psk2(context, &dtls_psk)) { 546c87c5fbaSopenharmony_ci coap_free_context(context); 547c87c5fbaSopenharmony_ci return NULL; 548c87c5fbaSopenharmony_ci } 549c87c5fbaSopenharmony_ci 550c87c5fbaSopenharmony_ci /* See coap_address(3) */ 551c87c5fbaSopenharmony_ci coap_address_init(&listen_addr); 552c87c5fbaSopenharmony_ci listen_addr.addr.sa.sa_family = AF_INET; 553c87c5fbaSopenharmony_ci listen_addr.addr.sin.sin_port = htons (5684); 554c87c5fbaSopenharmony_ci 555c87c5fbaSopenharmony_ci endpoint = coap_new_endpoint(context, &listen_addr, COAP_PROTO_DTLS); 556c87c5fbaSopenharmony_ci if (!endpoint) { 557c87c5fbaSopenharmony_ci coap_free_context(context); 558c87c5fbaSopenharmony_ci return NULL; 559c87c5fbaSopenharmony_ci } 560c87c5fbaSopenharmony_ci 561c87c5fbaSopenharmony_ci /* Initialize resources - See coap_resource(3) init_resources() example */ 562c87c5fbaSopenharmony_ci 563c87c5fbaSopenharmony_ci return context; 564c87c5fbaSopenharmony_ci} 565c87c5fbaSopenharmony_ci---- 566c87c5fbaSopenharmony_ci 567c87c5fbaSopenharmony_ciSEE ALSO 568c87c5fbaSopenharmony_ci-------- 569c87c5fbaSopenharmony_ci*coap_address*(3), *coap_block*(3), *coap_context*(3), *coap_encryption*(3), 570c87c5fbaSopenharmony_ci*coap_endpoint_client*(3), *coap_resource*(3), *coap_session*(3) and 571c87c5fbaSopenharmony_ci*coap_tls_library*(3) 572c87c5fbaSopenharmony_ci 573c87c5fbaSopenharmony_ciFURTHER INFORMATION 574c87c5fbaSopenharmony_ci------------------- 575c87c5fbaSopenharmony_ciSee 576c87c5fbaSopenharmony_ci 577c87c5fbaSopenharmony_ci"https://rfc-editor.org/rfc/rfc7252[RFC7252: The Constrained Application Protocol (CoAP)]" 578c87c5fbaSopenharmony_ci 579c87c5fbaSopenharmony_ci"https://rfc-editor.org/rfc/rfc8323[RFC8323: CoAP (Constrained Application Protocol) over TCP, TLS, and WebSockets]" 580c87c5fbaSopenharmony_ci 581c87c5fbaSopenharmony_cifor further information. 582c87c5fbaSopenharmony_ci 583c87c5fbaSopenharmony_ciBUGS 584c87c5fbaSopenharmony_ci---- 585c87c5fbaSopenharmony_ciPlease report bugs on the mailing list for libcoap: 586c87c5fbaSopenharmony_cilibcoap-developers@lists.sourceforge.net or raise an issue on GitHub at 587c87c5fbaSopenharmony_cihttps://github.com/obgm/libcoap/issues 588c87c5fbaSopenharmony_ci 589c87c5fbaSopenharmony_ciAUTHORS 590c87c5fbaSopenharmony_ci------- 591c87c5fbaSopenharmony_ciThe libcoap project <libcoap-developers@lists.sourceforge.net> 592