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