1COAP_CONTEXT(3) libcoap Manual COAP_CONTEXT(3)
2
3
4
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
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
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
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
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
351 coap_encryption(3), coap_resource(3), coap_session(3) and
352 coap_tls_library(3)
353
355 See "RFC7252: The Constrained Application Protocol (CoAP)" for further
356 information.
357
359 Please report bugs on the mailing list for libcoap:
360 libcoap-developers@lists.sourceforge.net
361
363 The libcoap project <libcoap-developers@lists.sourceforge.net>
364
365
366
367coap_context 4.2.1 01/26/2021 COAP_CONTEXT(3)