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

NAME

6       coap_oscore, coap_oscore_is_supported, coap_new_oscore_conf,
7       coap_delete_oscore_conf, coap_new_oscore_recipient,
8       coap_delete_oscore_recipient, coap_new_client_session_oscore,
9       coap_new_client_session_oscore_pki, coap_new_client_session_oscore_psk,
10       coap_context_oscore_server - Work with CoAP OSCORE
11

SYNOPSIS

13       #include <coap3/coap.h>
14
15       int coap_oscore_is_supported(void);
16
17       coap_oscore_conf_t *coap_new_oscore_conf(coap_str_const_t conf_mem,
18       coap_oscore_save_seq_num_t save_seq_num_func, void
19       *save_seq_num_func_param, uint64_t start_seq_num);
20
21       int coap_delete_oscore_conf(coap_oscore_conf_t *oscore_conf);
22
23       int coap_new_oscore_recipient(coap_context_t *context, coap_bin_const_t
24       *recipient_id);
25
26       int coap_delete_oscore_recipient(coap_context_t *context,
27       coap_bin_const_t *recipient_id);
28
29       coap_session_t *coap_new_client_session_oscore(coap_context_t *context,
30       const coap_address_t *local_if, const coap_address_t *server,
31       coap_proto_t proto, coap_oscore_conf_t *oscore_conf);
32
33       coap_session_t *coap_new_client_session_oscore_psk(coap_context_t
34       *context, const coap_address_t *local_if, const coap_address_t *server,
35       coap_proto_t proto, coap_dtls_cpsk_t *psk_data, coap_oscore_conf_t
36       *oscore_conf);
37
38       coap_session_t *coap_new_client_session_oscore_pki(coap_context_t
39       *context, const coap_address_t *local_if, const coap_address_t *server,
40       coap_proto_t proto, coap_dtls_pki_t *pki_data, coap_oscore_conf_t
41       *oscore_conf);
42
43       int coap_context_oscore_server(coap_context_t *context,
44       coap_oscore_conf_t *oscore_conf);
45
46       For specific (D)TLS library support, link with -lcoap-3-notls,
47       -lcoap-3-gnutls, -lcoap-3-openssl, -lcoap-3-mbedtls or
48       -lcoap-3-tinydtls. Otherwise, link with -lcoap-3 to get the default
49       (D)TLS library support.
50

DESCRIPTION

52       This describes libcoap’s support for using OSCORE as defined in
53       RFC8613.
54
55       OSCORE provides end-to-end protection between endpoints communicating
56       using CoAP. (D)TLS can only protect HOP by HOP traffic which allows
57       proxies to manipulate information.
58

CALLBACK HANDLER

60       Callback Type: coap_oscore_save_seq_num_t
61
62       The coap_oscore_save_seq_num_t method handler function prototype is
63       defined as:
64
65           typedef int (*coap_oscore_save_seq_num_t)(uint64_t sender_seq_num, void *param);
66
67       and returns 0 on failure, 1 on succes.
68

FUNCTIONS

70       Function: coap_oscore_is_supported()
71
72       The coap_oscore_is_supported() function returns 1 if OSCORE is
73       supported, otherwise 0.
74
75       Function: coap_new_oscore_conf()
76
77       The coap_new_oscore_conf() function is used to build a new OSCORE
78       configuration. It parses the provided OSCORE configuration in conf_mem.
79       The format of the keywords, encoding types and values is documented in
80       coap-oscore-conf(5). It also sets an optional function
81       save_seq_num_func (which gets save_seq_num_func_param passed in) that
82       is called to store the next Sender Sequence Number (SSN) in
83       non-volatile storage. The latest next SSN from non-volatile storage (or
84       0) is then put in start_seq_num. SSN are used so that anti-replay
85       mechanisms do not kick in following application restarts. The rate of
86       calling save_seq_num_func can be controlled by the ssn_freq parameter
87       as defined in coap-oscore-conf(5).
88
89       This OSCORE configuration is then used in the client and server OSCORE
90       version of the setup functions.
91
92       If the server is proxy enabled and the new incoming session is OSCORE
93       encoded with the Outer CoAP ProxyScheme and Host options set, then the
94       libcoap logic will determine whether the server is the final endpoint
95       of the session, or whether the proxy will be forwarding the session off
96       to another server, based on how coap_resource_proxy_uri_init(3)
97       configured the proxy logic. If the session is going to forwarded, then
98       the OSCORE protection will not be removed.
99
100       If coap_context_oscore_server() is not called and the proxy logic (if
101       set) indicates the session will get forwarded, then the OSCORE
102       protection is untouched, otherwise the session will get dropped with an
103       unknown critical option error response.
104
105       Function: coap_new_oscore_recipient()
106
107       The coap_new_oscore_recipient() is used to add a new recipient_id to
108       the OSCORE information associated with context. The new recipient_id
109       should be unique and this function should only be used for server based
110       applications as the client will only ever use the first defined
111       recipient_id. It is assumed that coap_context_oscore_server() has
112       already been called to update context with the appropriate OSCORE
113       information.
114
115       Function: coap_delete_oscore_recipient()
116
117       The coap_delete_oscore_recipient() is used to remove the recipient_id
118       from the OSCORE information associated with context. OSCORE Traffic
119       continuing to use recipient_id will then fail.
120
121       Function: coap_delete_oscore_conf()
122
123       The coap_delete_oscore_conf() function is used to free off the
124       coap_oscore_conf_t structure oscore_conf as returned by
125       coap_new_oscore_conf(). Normally this function never needs to be called
126       as oscore_conf is freed off by the call the client or server setup
127       functions.
128
129       Function: coap_new_client_session_oscore()
130
131       The coap_new_client_session_oscore() is basically the same as
132       coap_new_client_session(3), but has an additional parameter oscore_conf
133       that is created by coap_new_oscore_conf(). This function creates a
134       client endpoint for a specific context and initiates a new client
135       session to the specified server using the CoAP protocol proto and
136       OSCORE protected by the oscore_conf definition (which is freed off by
137       this call). If the port is set to 0 in server, then the default CoAP
138       port is used. Normally local_if would be set to NULL, but by specifying
139       local_if the source of the network session can be bound to a specific
140       IP address or port. The session will initially have a reference count
141       of 1.
142
143       Function: coap_new_client_session_oscore_psk()
144
145       The coap_new_client_session_oscore_psk() is basically the same as
146       coap_new_client_session_psk2(3), but has an additional parameter
147       oscore_conf that is created by coap_new_oscore_conf(). This function,
148       for a specific context, is used to configure the TLS context using the
149       setup_data variables as defined in the coap_dtls_cpsk_t structure in
150       the newly created endpoint session - see coap_encryption(3), as well as
151       OSCORE protected by the oscore_conf definition (which is freed off by
152       this call). The connection is to the specified server using the CoAP
153       protocol proto. If the port is set to 0 in server, then the default
154       CoAP port is used. Normally local_if would be set to NULL, but by
155       specifying local_if the source of the network session can be bound to a
156       specific IP address or port. The session will initially have a
157       reference count of 1.
158
159       Function: coap_new_client_session_oscore_pki()
160
161       The coap_new_client_session_oscore_pki() is basically the same as
162       coap_new_client_session_pki(3), but has an additional parameter
163       oscore_conf that is created by coap_new_oscore_conf(). This function,
164       for a specific context, is used to configure the TLS context using the
165       setup_data variables as defined in the coap_dtls_pki_t structure in the
166       newly created endpoint session - see coap_encryption(3), as well as
167       OSCORE protected by the oscore_conf definition (which is freed off by
168       this call). The connection is to the specified server using the CoAP
169       protocol proto. If the port is set to 0 in server, then the default
170       CoAP port is used. Normally local_if would be set to NULL, but by
171       specifying local_if the source of the network session can be bound to a
172       specific IP address or port. The session will initially have a
173       reference count of 1.
174
175       Function: coap_context_oscore_server()
176
177       The coap_context_oscore_server() function is used to enable the server
178       to support OSCORE incoming sessions. It updates context with the OSCORE
179       configure oscore_conf (which is freed off by this call).
180

RETURN VALUES

182       coap_new_client_session_oscore(), coap_new_client_session_oscore_psk()
183       and coap_new_client_session_oscore_pki() return a newly created client
184       session or NULL if there is a malloc or parameter failure.
185
186       coap_new_oscore_conf() returns a coap_oscore_conf_t or NULL on failure.
187
188       coap_oscore_is_supported(), coap_context_oscore_server(),
189       coap_delete_oscore_conf(), coap_new_oscore_recipient() and
190       coap_delete_oscore_recipient() return 0 on failure, 1 on success.
191

EXAMPLES

193       Client Setup
194
195           #include <coap3/coap.h>
196
197           #include <netinet/in.h>
198           #include <stdio.h>
199
200           static uint8_t oscore_config[] =
201             "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
202             "master_salt,hex,\"9e7ca92223786340\"\n"
203             "server_id,ascii,\"client\"\n"
204             "recipient_id,ascii,\"server\"\n"
205             "replay_window,integer,30\n"
206             "aead_alg,integer,10\n"
207             "hkdf_alg,integer,-10\n"
208           ;
209           static FILE *oscore_seq_num_fp = NULL;
210           /* Not a particularly safe place to keep next Sender Sequence Number ... */
211           static const char* oscore_seq_save_file = "/tmp/client.seq";
212
213           static int
214           oscore_save_seq_num(uint64_t sender_seq_num, void *param COAP_UNUSED) {
215             if (oscore_seq_num_fp) {
216               rewind(oscore_seq_num_fp);
217               fprintf(oscore_seq_num_fp, "%lu\n", sender_seq_num);
218               fflush(oscore_seq_num_fp);
219             }
220             return 1;
221           }
222
223           static coap_session_t *
224           setup_client_session (struct in_addr ip_address) {
225             coap_session_t *session;
226             coap_address_t server;
227             /* See coap_context(3) */
228             coap_context_t *context = coap_new_context(NULL);
229
230             if (!context)
231               return NULL;
232
233             /* See coap_block(3) */
234             coap_context_set_block_mode(context,
235                                         COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
236
237
238             coap_address_init(&server);
239             server.addr.sa.sa_family = AF_INET;
240             server.addr.sin.sin_addr = ip_address;
241             server.addr.sin.sin_port = htons (5683);
242
243             if (coap_oscore_is_supported()) {
244               coap_str_const_t config = { sizeof (oscore_config), oscore_config };
245               uint64_t start_seq_num = 0;
246               coap_oscore_conf_t *oscore_conf;
247
248               if (oscore_seq_save_file) {
249                 oscore_seq_num_fp = fopen(oscore_seq_save_file, "r+");
250                 if (oscore_seq_num_fp == NULL) {
251                   /* Try creating it */
252                   oscore_seq_num_fp = fopen(oscore_seq_save_file, "w+");
253                   if (oscore_seq_num_fp == NULL) {
254                     coap_log_err("OSCORE save restart info file error: %s\n",
255                              oscore_seq_save_file);
256                     return NULL;
257                   }
258                 }
259                 fscanf(oscore_seq_num_fp, "%ju", &start_seq_num);
260               }
261               oscore_conf = coap_new_oscore_conf(config, oscore_save_seq_num,
262                                                  NULL, start_seq_num);
263               if (!oscore_conf) {
264                 coap_free_context(context);
265                 return NULL;
266               }
267               session = coap_new_client_session_oscore(context, NULL, &server,
268                                                        COAP_PROTO_UDP, oscore_conf);
269             } else {
270               session = coap_new_client_session(context, NULL, &server, COAP_PROTO_UDP);
271             }
272             if (!session) {
273               coap_free_context(context);
274               return NULL;
275             }
276             /* The context is in session->context */
277             return session;
278           }
279
280       Server Setup
281
282           #include <coap3/coap.h>
283           #include <stdio.h>
284
285           static uint8_t oscore_config[] =
286             "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
287             "master_salt,hex,\"9e7ca92223786340\"\n"
288             "sender_id,ascii,\"server\"\n"
289             "recipient_id,ascii,\"client\"\n"
290             "replay_window,integer,30\n"
291             "aead_alg,integer,10\n"
292             "hkdf_alg,integer,-10\n"
293           ;
294           static FILE *oscore_seq_num_fp = NULL;
295           /* Not a particularly safe place to keep next Sender Sequence Number ... */
296           static const char* oscore_seq_save_file = "/tmp/server.seq";
297
298           static int
299           oscore_save_seq_num(uint64_t sender_seq_num, void *param COAP_UNUSED) {
300             if (oscore_seq_num_fp) {
301               rewind(oscore_seq_num_fp);
302               fprintf(oscore_seq_num_fp, "%lu\n", sender_seq_num);
303               fflush(oscore_seq_num_fp);
304             }
305             return 1;
306           }
307
308           static int
309           setup_context (void) {
310             /* See coap_context(3) */
311             coap_context_t *context = coap_new_context(NULL);
312
313             if (!context)
314               return 0;
315
316             /* See coap_block(3) */
317             coap_context_set_block_mode(context,
318                                         COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);
319
320             if (coap_oscore_is_supported()) {
321               coap_str_const_t config = { sizeof (oscore_config), oscore_config };
322               uint64_t start_seq_num = 0;
323               coap_oscore_conf_t *oscore_conf;
324
325               if (oscore_seq_save_file) {
326                 oscore_seq_num_fp = fopen(oscore_seq_save_file, "r+");
327                 if (oscore_seq_num_fp == NULL) {
328                   /* Try creating it */
329                   oscore_seq_num_fp = fopen(oscore_seq_save_file, "w+");
330                   if (oscore_seq_num_fp == NULL) {
331                     coap_log_err("OSCORE save restart info file error: %s\n",
332                              oscore_seq_save_file);
333                     return 0;
334                   }
335                 }
336                 fscanf(oscore_seq_num_fp, "%ju", &start_seq_num);
337               }
338               oscore_conf = coap_new_oscore_conf(config, oscore_save_seq_num,
339                                                  NULL, start_seq_num);
340               if (!oscore_conf) {
341                 coap_free_context(context);
342                 return 0;
343               }
344               coap_context_oscore_server(context, oscore_conf);
345             }
346             return 1;
347           }
348

SEE ALSO

350       coap_endpoint_client(3), coap_endpoint_server(3) and
351       coap-oscore-conf(5)
352

FURTHER INFORMATION

354       See
355
356       "RFC7252: The Constrained Application Protocol (CoAP)"
357
358       "RFC8613: Object Security for Constrained RESTful Environments
359       (OSCORE)"
360
361       for further information.
362

BUGS

364       Please report bugs on the mailing list for libcoap:
365       libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at
366       https://github.com/obgm/libcoap/issues
367

AUTHORS

369       The libcoap project <libcoap-developers@lists.sourceforge.net>
370
371
372
373coap_oscore 4.3.4                 10/09/2023                    COAP_OSCORE(3)
Impressum