1COAP_CONTEXT(3)                 libcoap Manual                 COAP_CONTEXT(3)
2
3
4

NAME

6       coap_context, coap_new_context, coap_free_context,
7       coap_context_set_pki, coap_context_set_psk, coap_new_endpoint,
8       coap_free_endpoint, coap_endpoint_set_default_mtu - Work with CoAP
9       contexts
10

SYNOPSIS

12       #include <coap2/coap.h>
13
14       coap_context_t *coap_new_context(const coap_address_t *listen_addr);
15
16       void coap_free_context(coap_context_t *context);
17
18       int coap_context_set_pki(coap_context_t *context, coap_dtls_pki_t
19       *setup_data);
20
21       int coap_context_set_pki_root_cas(coap_context_t *context, const char
22       *ca_file, const char *ca_dir);
23
24       int coap_context_set_psk(coap_context_t *context, const char *hint,
25       const uint8_t *key, size_t key_len);
26
27       coap_endpoint_t *coap_new_endpoint(coap_context_t *context, const
28       coap_address_t *listen_addr, coap_proto_t proto);
29
30       void coap_free_endpoint(coap_endpoint_t *endpoint);
31
32       void coap_endpoint_set_default_mtu(coap_endpoint_t *endpoint, unsigned
33       mtu);
34
35       Link with -lcoap-2, -lcoap-2-gnutls, -lcoap-2-openssl or
36       -lcoap-2-tinydtls depending on your (D)TLS library type.
37

DESCRIPTION

39       This man page focuses on the CoAP Context.
40
41       The CoAP stack’s global state is stored in a coap_context_t Context
42       object. Resources, Endpoints and Sessions are associated with this
43       context object. There can be more than one coap_context_t object per
44       application, it is up to the application to manage each one
45       accordingly.
46
47       The Session network traffic can be encrypted or un-encrypted if there
48       is an underlying TLS library.
49
50       If TLS is going to be used for encrypting the network traffic, then the
51       TLS information for Pre-Shared Keys (PSK) or Public Key Infrastructure
52       (PKI) needs to be configured before any network traffic starts to flow.
53       For Servers, this has to be done before the Endpoint is created, for
54       Clients, this is done during the Client Session set up.
55
56       For Servers, all the encryption information is held internally by the
57       TLS Context level and the CoAP Context level as the Server is listening
58       for new incoming traffic based on the Endpoint definition. The TLS and
59       CoAP session will not get built until the new traffic starts, which is
60       done by the libcoap library, with the session having a reference count
61       of 1.
62
63       For Clients, all the encryption information can be held at the TLS
64       Context and CoAP Context levels, or at the TLS Session and CoAP Session
65       levels. If defined at the Context level, then when Sessions are
66       created, they will inherit the Context definitions, unless they have
67       separately been defined for the Session level, in which case the
68       Session version will get used. Typically the information will be
69       configured at the Session level for Clients.
70
71       In principle the set-up sequence for CoAP Servers looks like
72
73           coap_new_context()
74           coap_context_set_pki_root_cas() - if the root CAs need to be updated and PKI
75           coap_context_set_pki() and/or coap_context_set_psk() - if encryption is required
76           coap_new_endpoint()
77
78       Multiple endpoints can be set up per Context, each listening for a new
79       traffic flow with different TCP/UDP protocols, TLS protocols, port
80       numbers etc. When a new traffic flow is started, then the CoAP library
81       will create and start a new server session.
82
83       In principle the set-up sequence for CoAP Clients looks like
84
85           coap_new_context()
86           coap_context_set_pki_root_cas() if the root CAs need to be updated and PKI
87           coap_new_client_session(), coap_new_client_session_pki() or coap_new_client_session_psk()
88
89       Multiple client sessions are supported per Context.
90
91       The coap_new_context() function creates a new Context that is then used
92       to keep all the CoAP Resources, Endpoints and Sessions information. The
93       optional listen_addr parameter, if set for a CoAP server, creates an
94       Endpoint that is added to the context that is listening for
95       un-encrypted traffic on the IP address and port number defined by
96       listen_addr.
97
98       The coap_free_context() function must be used to release the CoAP stack
99       context. It clears all entries from the receive queue and send queue
100       and deletes the Resources that have been registered with context, and
101       frees the attached Sessions and Endpoints.
102
103       The coap_context_set_pki() function, for a specific context, is used to
104       configure the TLS context using the setup_data variables as defined in
105       the coap_dtls_pki_t structure - see *coap_encrytion(*3).
106
107       The coap_context_set_pki_root_cas() function is used to define a set of
108       root CAs to be used instead of the default set of root CAs provided as
109       a part of the TLS library. ca_file points to a PEM encoded file
110       containing the list of CAs. ca_file can be NULL. _ca_dir points to a
111       directory containing a set of PEM encoded files containing rootCAs.
112       ca_dir can be NULL. One or both of ca_file and ca_dir must be set.
113
114       The coap_context_set_psk() function is used to configure the TLS
115       context using the server hint, PreShared Key key with length key_len.
116       All parameters must be defined, NULL is not valid. An empty string is
117       valid for hint. key_len must be greater than 0. This function can only
118       be used for Servers as it provides a hint, not an identity.
119
120       The coap_new_endpoint() function creates a new endpoint for context
121       that is listening for new traffic on the IP address and port number
122       defined by listen_addr. Different CoAP protocols can be defined for
123       proto - the current supported list is:
124
125           COAP_PROTO_UDP
126           COAP_PROTO_DTLS
127           COAP_PROTO_TCP
128           COAP_PROTO_TLS
129
130       The coap_free_endpoint() function must be used to free off the
131       endpoint. It clears out all the sessions associated with this endpoint.
132
133       The coap_endpoint_set_default_mtu() function is used to set the MTU
134       size (the maximum message size) of the data in a packet, excluding any
135       IP or TCP/UDP overhead to mtu for the endpoint. A sensible default is
136       1280.
137

RETURN VALUES

139       coap_new_context() function returns a newly created context or NULL if
140       there is a creation failure.
141
142       coap_context_set_pki(), coap_context_set_pki_root_cas() and
143       coap_context_set_psk() functions return 1 on success, 0 on failure.
144
145       coap_new_endpoint() function returns a newly created endpoint or NULL
146       if there is a creation failure.
147

EXAMPLES

149       CoAP Server Non-Encrypted Setup
150
151           #include <coap2/coap.h>
152
153           static coap_context_t *
154           setup_server_context (void) {
155             coap_endpoint_t *endpoint;
156             coap_address_t listen_addr;
157             coap_context_t *context = coap_new_context(NULL);
158
159             if (!context)
160               return NULL;
161
162             coap_address_init(&listen_addr);
163             listen_addr.addr.sa.sa_family = AF_INET;
164             listen_addr.addr.sin.sin_port = htons (5683);
165
166             endpoint = coap_new_endpoint(context, &listen_addr, COAP_PROTO_UDP);
167             if (!endpoint) {
168               coap_free_context(context);
169               return NULL;
170             }
171
172             /* See coap_resource(3) */
173             init_resources(context);
174
175             return context;
176           }
177
178       CoAP Server DTLS PKI Setup
179
180           #include <coap2/coap.h>
181
182           typedef struct valid_cns_t {
183             int count;
184             char **cn_list;
185           } valid_cns_t;
186
187           /*
188            * Common Name (CN) Callback verifier
189            */
190           static int
191           verify_cn_callback(const char *cn,
192                              const uint8_t *asn1_public_cert,
193                              size_t asn1_length,
194                              coap_session_t *session,
195                              unsigned depth,
196                              int validated,
197                              void *arg
198           ) {
199             valid_cns_t *valid_cn_list = ( valid_cns_t*)arg;
200             int i;
201
202             /* Check that the CN is valid */
203             for (i = 0; i < valid_cn_list->count; i++) {
204               if (!strcasecmp(cn, valid_cn_list->cn_list[i])) {
205                 return 1;
206               }
207             }
208             return 0;
209           }
210
211           typedef struct sni_def_t {
212             char* sni;
213             coap_dtls_key_t key;
214           } sni_def_t;
215
216           typedef struct valid_snis_t {
217             int count;
218             sni_def_t *sni_list;
219           } valid_snis_t;
220
221           /*
222            * Subject Name Identifier (SNI) callback verifier
223            */
224           static coap_dtls_key_t *
225           verify_sni_callback(const char *sni,
226                               void *arg
227           ) {
228             valid_snis_t *valid_sni_list = (valid_snis_t *)arg;
229             int i;
230
231             /* Check that the SNI is valid */
232             for (i = 0; i < valid_sni_list->count; i++) {
233               if (!strcasecmp(sni, valid_sni_list->sni_list[i].sni)) {
234                 return &valid_sni_list->sni_list[i].key;
235               }
236             }
237             return NULL;
238           }
239
240           /*
241            * Set up PKI encryption information
242            */
243           static coap_context_t *
244           setup_server_context_pki (const char *public_cert_file,
245                                     const char *private_key_file,
246                                     const char *ca_file,
247                                     valid_cns_t *valid_cn_list,
248                                     valid_snis_t *valid_sni_list
249           ) {
250             coap_endpoint_t *endpoint;
251             coap_address_t listen_addr;
252             coap_dtls_pki_t dtls_pki;
253             coap_context_t *context;
254
255             /* See coap_tls_library(3) */
256             if (!coap_dtls_is_supported())
257               return NULL;
258
259             context = coap_new_context(NULL);
260             if (!context)
261               return NULL;
262
263             memset (&dtls_pki, 0, sizeof (dtls_pki));
264
265             /* see coap_encryption(3) */
266             dtls_pki.version                 = COAP_DTLS_PKI_SETUP_VERSION;
267             dtls_pki.verify_peer_cert        = 1;
268             dtls_pki.require_peer_cert       = 1;
269             dtls_pki.allow_self_signed       = 1;
270             dtls_pki.allow_expired_certs     = 1;
271             dtls_pki.cert_chain_validation   = 1;
272             dtls_pki.cert_chain_verify_depth = 1;
273             dtls_pki.check_cert_revocation   = 1;
274             dtls_pki.allow_no_crl            = 1;
275             dtls_pki.allow_expired_crl       = 1;
276             dtls_pki.validate_cn_call_back   = verify_cn_callback;
277             dtls_pki.cn_call_back_arg        = valid_cn_list;
278             dtls_pki.validate_sni_call_back  = verify_sni_callback;
279             dtls_pki.sni_call_back_arg       = valid_sni_list;
280             dtls_pki.additional_tls_setup_call_back = NULL;
281             dtls_pki.client_sni              = NULL;
282             dtls_pki.pki_key.key_type        = COAP_PKI_KEY_PEM;
283             dtls_pki.pki_key.key.pem.ca_file = ca_file;
284             dtls_pki.pki_key.key.pem.public_cert = public_cert_file;
285             dtls_pki.pki_key.key.pem.private_key = private_key_file;
286
287             if (coap_context_set_pki(context, &dtls_pki)) {
288               coap_free_context(context);
289               return NULL;
290             }
291
292             coap_address_init(&listen_addr);
293             listen_addr.addr.sa.sa_family = AF_INET;
294             listen_addr.addr.sin.sin_port = htons (5684);
295
296             endpoint = coap_new_endpoint(context, &listen_addr, COAP_PROTO_DTLS);
297             if (!endpoint) {
298               coap_free_context(context);
299               return NULL;
300             }
301
302             /* See coap_resource(3) */
303             init_resources(context);
304
305             return context;
306           }
307
308       CoAP Server DTLS PSK Setup
309
310           #include <coap2/coap.h>
311
312           static coap_context_t *
313           setup_server_context_psk (const char *hint,
314                                     const uint8_t *key,
315                                     unsigned key_len
316           ) {
317             coap_endpoint_t *endpoint;
318             coap_address_t listen_addr;
319             coap_context_t *context;
320
321             /* See coap_tls_library(3) */
322             if (!coap_dtls_is_supported())
323               return NULL;
324
325             context = coap_new_context(NULL);
326             if (!context)
327               return NULL;
328
329             if (coap_context_set_psk(context, hint, key, key_len)) {
330               coap_free_context(context);
331               return NULL;
332             }
333
334             coap_address_init(&listen_addr);
335             listen_addr.addr.sa.sa_family = AF_INET;
336             listen_addr.addr.sin.sin_port = htons (5684);
337
338             endpoint = coap_new_endpoint(context, &listen_addr, COAP_PROTO_DTLS);
339             if (!endpoint) {
340               coap_free_context(context);
341               return NULL;
342             }
343
344             /* See coap_resource(3) */
345             init_resources(context);
346
347             return context;
348           }
349

SEE ALSO

351       coap_encryption(3), coap_resource(3), coap_session(3) and
352       coap_tls_library(3)
353

FURTHER INFORMATION

355       See "RFC7252: The Constrained Application Protocol (CoAP)" for further
356       information.
357

BUGS

359       Please report bugs on the mailing list for libcoap:
360       libcoap-developers@lists.sourceforge.net
361

AUTHORS

363       The libcoap project <libcoap-developers@lists.sourceforge.net>
364
365
366
367coap_context 4.2.1                01/26/2021                   COAP_CONTEXT(3)
Impressum