libwebsockets
Lightweight C library for HTML5 websockets
lws-cose.h
Go to the documentation of this file.
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 /** \defgroup cose COSE apis
26  * ##COSE related functions
27  * \ingroup lwsaoi
28  *
29  * COSE RFC 8152 relates to signed and encrypted CBOR
30  */
31 //@{
32 
33 enum {
34  /* RFC8152: Table 2: Common Header Parameters
35  * https://www.iana.org/assignments/cose/cose.xhtml#header-parameters
36  */
37 
38  LWSCOSE_WKL_ALG = 1, /* int / tstr */
39  LWSCOSE_WKL_CRIT, /* [+ label ] */
40  LWSCOSE_WKL_CONTENT_TYPE, /* tstr / uint */
41  LWSCOSE_WKL_KID, /* bstr */
42  LWSCOSE_WKL_IV, /* bstr */
44  LWSCOSE_WKL_COUNTERSIG, /* COSE sig(s) */
45  LWSCOSE_WKL_COUNTERSIG0 = 9, /* bstr */
47  LWSCOSE_WKL_CUPH_NONCE = 256, /* bstr */
48  LWSCOSE_WKL_CUPH_OWNER_PUBKEY = 257, /* array */
49 
50  /* RFC8152: Table 3: key map labels */
51 
52  LWSCOSE_WKK_KTY = 1, /* int / tstr */
53  LWSCOSE_WKK_KID, /* bstr */
54  LWSCOSE_WKK_ALG, /* int / tstr */
55  LWSCOSE_WKK_KEY_OPS, /* [ + (int / tstr) ] */
56  LWSCOSE_WKK_BASE_IV, /* bstr */
57 
58  /* RFC8152: Table 4: Key Operation Values */
59 
70 
71  /* RFC8152: Table 5: ECDSA algs */
72 
76 
77  /* RFC8152: Table 6: EDDSA algs */
78 
80 
81  /* RFC8152: Table 7: HMAC algs */
82 
87 
88  /* RFC8152: Table 8: AES algs */
89 
94 
95  /* RFC8152: Table 9: AES GCM algs */
96 
100 
101  /* RFC8152: Table 10: AES CCM algs */
102 
111 
112  /* RFC8152: Table 11: CHACHA20 / Poly1305 */
113 
115 
116  /* RFC8152: Table 13: HKDF param */
117 
119 
120  /* RFC8152: Table 14: Context Algorithm Parameters */
121 
128 
129  /* RFC8152: Table 15: Direct key */
130 
132 
133  /* RFC8152: Table 16: Direct key with KDF */
134 
139 
140  /* RFC8152: Table 17: AES Key Wrap Algorithm Values */
141 
145 
146  /* RFC8152: Table 18: ECDH Algorithm Values */
147 
152 
153  /* RFC8152: Table 19: ECDH Algorithm Parameters */
154 
158 
159  /* RFC8152: Table 20: ECDH Algorithm Parameters with key wrap */
160 
167 
168  /* RFC8152: Table 21: Key Type Values
169  * https://www.iana.org/assignments/cose/cose.xhtml#key-type
170  */
171 
178 
179 
180  /* RFC8152: Table 22: Elliptic Curves
181  * https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves
182  */
183 
192 
193  /* RFC8152: Table 23: EC Key Parameters */
194 
199 
200  /* RFC8152: Table 24: Octet Key Pair (OKP) Parameters */
201 
205 
206  /* Additional from
207  * https://www.iana.org/assignments/cose/cose.xhtml#key-type-parameters
208  */
209 
222 
223  /* RFC8152: Table 25: Symmetric Key Parameters */
224 
226 
227  /* RFC8152: Table 26: CoAP Content-Formats for COSE */
228 
237 
238  /* RFC8152: Table 27: Header Parameter for CounterSignature0 */
239 
241 
242  /* RFC8812: Table 1: RSASSA-PKCS1-v1_5 Algorithm Values */
243 
244  LWSCOSE_WKARSA_ALG_RS256 = -257, /* + SHA-256 */
245  LWSCOSE_WKARSA_ALG_RS384 = -258, /* + SHA-384 */
246  LWSCOSE_WKARSA_ALG_RS512 = -259, /* + SHA-512 */
247 };
248 
255 
257 };
258 
260 
261 LWS_VISIBLE LWS_EXTERN const char *
263 
264 LWS_VISIBLE LWS_EXTERN cose_param_t
265 lws_cose_name_to_alg(const char *name);
266 
267 /*
268  * cose_key
269  */
270 
271 typedef struct lws_cose_key {
272  /* key data elements */
274  /* generic meta key elements, like KID */
276  lws_dll2_t list; /* used when part of a set */
277  int gencrypto_kty; /**< one of LWS_GENCRYPTO_KTY_ */
281  char private_key; /* nonzero = has private key elements */
282 } lws_cose_key_t;
283 
284 typedef int (*lws_cose_key_import_callback)(struct lws_cose_key *s, void *user);
285 
286 /** lws_cose_jwk_import() - Create an lws_cose_key_t object from cose_key CBOR
287  *
288  * \param pkey_set: NULL, or a pointer to an lws_dll2_owner_t for a cose_key set
289  * \param cb: callback for each jwk-processed key, or NULL if importing a single
290  * key with no parent "keys" JSON
291  * \param user: pointer to be passed to the callback, otherwise ignored by lws.
292  * NULL if importing a single key with no parent "keys" JSON
293  * \param in: a single cose_key
294  * \param len: the length of the cose_key in bytes
295  *
296  * Creates a single lws_cose_key_t if \p pkey_set is NULL or if the incoming
297  * CBOR doesn't start with an array, otherwise expects a CBOR array containing
298  * zero or more cose_key CBOR, and adds each to the \p pkey_set
299  * lws_dll2_owner_t struct. Created lws_cose_key_t are filled with data from
300  * the COSE representation and can be used with other COSE crypto ops.
301  */
302 LWS_VISIBLE LWS_EXTERN lws_cose_key_t *
303 lws_cose_key_import(lws_dll2_owner_t *pkey_set, lws_cose_key_import_callback cb,
304  void *user, const uint8_t *in, size_t len);
305 
306 /** lws_cose_key_export() - Create cose_key CBOR from an lws_cose_key_t
307  *
308  * \param ck: the lws_cose_key_t to export to CBOR
309  * \param ctx: the CBOR writing context (same as for lws_lec_printf())
310  * \param flags: 0 to export only public elements, or LWSJWKF_EXPORT_PRIVATE
311  *
312  * Creates an lws_jwk struct filled with data from the COSE representation.
313  */
314 LWS_VISIBLE LWS_EXTERN enum lws_lec_pctx_ret
315 lws_cose_key_export(lws_cose_key_t *ck, lws_lec_pctx_t *ctx, int flags);
316 
317 /**
318  * lws_cose_key_generate() - generate a fresh key
319  *
320  * \param context: the lws_context used to get random
321  * \param cose_kty: one of LWSCOSE_WKKTV_ indicating the well-known key type
322  * \param use_mask: 0, or a bitfield where (1 << LWSCOSE_WKKO_...) set means valid for use
323  * \param bits: key bits for RSA
324  * \param curve: for EC keys, one of "P-256", "P-384" or "P-521" currently
325  * \param kid: string describing the key, or NULL
326  *
327  * Create an lws_cose_key_t of the specified type and return it
328  */
329 LWS_VISIBLE LWS_EXTERN lws_cose_key_t *
330 lws_cose_key_generate(struct lws_context *context, cose_param_t cose_kty,
331  int use_mask, int bits, const char *curve,
332  const uint8_t *kid, size_t kl);
333 
334 LWS_VISIBLE LWS_EXTERN lws_cose_key_t *
335 lws_cose_key_from_set(lws_dll2_owner_t *set, const uint8_t *kid, size_t kl);
336 
337 LWS_VISIBLE LWS_EXTERN void
338 lws_cose_key_destroy(lws_cose_key_t **ck);
339 
340 LWS_VISIBLE LWS_EXTERN void
341 lws_cose_key_set_destroy(lws_dll2_owner_t *o);
342 
343 /* only available in _DEBUG build */
344 
345 LWS_VISIBLE LWS_EXTERN void
346 lws_cose_key_dump(const lws_cose_key_t *ck);
347 
348 /*
349  * cose_sign
350  */
351 
352 struct lws_cose_validate_context;
353 
354 
359  SIGTYPE_COUNTERSIGNED, /* not yet supported */
360  SIGTYPE_MAC, /* only supported for validation */
362 };
363 
364 /* a list of these result objects is the output of the validation process */
365 
366 typedef struct {
368 
369  const lws_cose_key_t *cose_key;
371 
372  int result; /* 0 = validated */
373 
374 } lws_cose_validate_res_t;
375 
376 enum {
380 };
381 
382 typedef struct {
383  struct lws_cose_validate_context *cps;
384  const uint8_t *ext;
386 } lws_cose_sig_ext_pay_t;
387 
388 typedef int (*lws_cose_sign_ext_pay_cb_t)(lws_cose_sig_ext_pay_t *x);
389 typedef int (*lws_cose_validate_pay_cb_t)(struct lws_cose_validate_context *cps,
390  void *opaque, const uint8_t *paychunk,
391  size_t paychunk_len);
392 
394  struct lws_context *cx;
395  /**< REQUIRED: the lws context */
397  /**< REQUIRED: one or more cose_keys */
398 
400  /**< 0 if a CBOR tag is in the sig, else one of SIGTYPE_MULTI,
401  * SIGTYPE_SINGLE, etc*/
402 
404  /**< optional: called back with unvalidated payload pieces */
405  void *pay_opaque;
406  /**< optional: passed into pay_cb callback along with payload chunk */
407 
409  /**< optional extra application data provision callback */
410  void *ext_opaque;
411  /**< optional extra application data provision callback opaque */
413  /**< if we have extra app data, this must be set to the length of it */
414 } lws_cose_validate_create_info_t;
415 
416 /**
417  * lws_cose_validate_create() - create a signature validation context
418  *
419  * \param info: struct describing the validation context to create
420  *
421  * Creates a signature validation context set up as described in \p info.
422  *
423  * You can then pass the signature cbor chunks to it using
424  * lws_cose_validate_chunk(), finialize and get the results list using
425  * lws_cose_validate_results() and destroy with lws_cose_validate_destroy().
426  */
427 LWS_VISIBLE LWS_EXTERN struct lws_cose_validate_context *
428 lws_cose_validate_create(const lws_cose_validate_create_info_t *info);
429 
430 /**
431  * lws_cose_validate_chunk() - passes chunks of CBOR into the signature validator
432  *
433  * \param cps: the validation context
434  * \param in: the chunk of CBOR (does not have to be logically complete)
435  * \param in_len: number of bytes available at \p in
436  *
437  * Parses signature CBOR to produce a list of result objects.
438  *
439  *
440  */
441 LWS_VISIBLE LWS_EXTERN int
442 lws_cose_validate_chunk(struct lws_cose_validate_context *cps,
443  const uint8_t *in, size_t in_len, size_t *used_in);
444 
445 LWS_VISIBLE LWS_EXTERN lws_dll2_owner_t *
446 lws_cose_validate_results(struct lws_cose_validate_context *cps);
447 
448 LWS_VISIBLE LWS_EXTERN void
449 lws_cose_validate_destroy(struct lws_cose_validate_context **cps);
450 
451 struct lws_cose_sign_context;
452 
453 #define LCSC_FL_ADD_CBOR_TAG (1 << 0)
454 #define LCSC_FL_ADD_CBOR_PREFER_MAC0 (1 << 1)
455 
457  struct lws_context *cx;
458  /**< REQUIRED: the lws context */
460  /**< REQUIRED: one or more cose_keys */
461 
463  /**< REQUIRED: the cbor output context to emit to, user must
464  * initialize with lws_lec_init() beforehand */
465 
467  /**< optional extra application data provision callback */
468  void *ext_opaque;
469  /**< optional extra application data provision callback opaque */
471  /**< if we have extra app data, this must be set to the length of it */
472 
474  /**< REQUIRED: size of the inline payload we will provide */
475 
476  int flags;
477  /**< bitmap of LCSC_FL_* */
479  /**< 0, or sign type hint */
480 } lws_cose_sign_create_info_t;
481 
482 /**
483  * lws_cose_sign_create() - Create a signing context
484  *
485  * \param info: a structure describing the signing context you want to create
486  *
487  * This allocates and returns a signing context created according to what is in
488  * the \p info parameter.
489  *
490  * \p info must be prepared with the lws_context, a keyset to use, a CBOR
491  * output context, and the inline payload length.
492  *
493  * Returns NULL on failure or the created signing context ready to add alg(s)
494  * to.
495  */
496 
497 LWS_VISIBLE LWS_EXTERN struct lws_cose_sign_context *
498 lws_cose_sign_create(const lws_cose_sign_create_info_t *info);
499 
500 LWS_VISIBLE LWS_EXTERN int
501 lws_cose_sign_add(struct lws_cose_sign_context *csc, cose_param_t alg,
502  const lws_cose_key_t *ck);
503 
504 LWS_VISIBLE LWS_EXTERN enum lws_lec_pctx_ret
505 lws_cose_sign_payload_chunk(struct lws_cose_sign_context *csc,
506  const uint8_t *in, size_t in_len);
507 
508 LWS_VISIBLE LWS_EXTERN void
509 lws_cose_sign_destroy(struct lws_cose_sign_context **csc);
510 
511 //@}