1*1c60b9acSAndroid Build Coastguard Worker# RFC8152 COSE apis 2*1c60b9acSAndroid Build Coastguard Worker 3*1c60b9acSAndroid Build Coastguard Worker||| 4*1c60b9acSAndroid Build Coastguard Worker|---|---|---| 5*1c60b9acSAndroid Build Coastguard Worker|cmake| `LWS_WITH_COSE`| 6*1c60b9acSAndroid Build Coastguard Worker|Header| ./include/libwebsockets/lws-cose.h| 7*1c60b9acSAndroid Build Coastguard Worker|api-test| ./minimal-examples/api-tests/api-test-cose/| 8*1c60b9acSAndroid Build Coastguard Worker|README| ./READMEs/README.cbor-cose.md 9*1c60b9acSAndroid Build Coastguard Worker 10*1c60b9acSAndroid Build Coastguard WorkerCOSE is the CBOR equivalent of the JOSE suite of crypto objects and operations. 11*1c60b9acSAndroid Build Coastguard WorkerYou can represent public and private EC, RSA and SYMMETRIC keys, and sets of 12*1c60b9acSAndroid Build Coastguard Workerkeys of various types; import the logical keys to and from CBOR; and sign / 13*1c60b9acSAndroid Build Coastguard Workerverify and encrypt / decrypt payloads using structured CBOR. Key generation is 14*1c60b9acSAndroid Build Coastguard Workeralso supported. 15*1c60b9acSAndroid Build Coastguard Worker 16*1c60b9acSAndroid Build Coastguard Worker|type|operations|algs| 17*1c60b9acSAndroid Build Coastguard Worker|---|---|---| 18*1c60b9acSAndroid Build Coastguard Worker|lws_cose_key_t|import, export, generation|EC / RSA / SYMMETRIC| 19*1c60b9acSAndroid Build Coastguard Worker|cose_sign1|sign, validate|ES256/384/512, RS256/384/512| 20*1c60b9acSAndroid Build Coastguard Worker|cose_sign|sign, validate|ES256/384/512, RS256/384/512| 21*1c60b9acSAndroid Build Coastguard Worker|cose_mac0|sign, validate|HS256/HS256_64/384/512| 22*1c60b9acSAndroid Build Coastguard Worker|cose_mac|validate only|HS256/HS256_64/384/512| 23*1c60b9acSAndroid Build Coastguard Worker 24*1c60b9acSAndroid Build Coastguard WorkerThe lws COSE support uses the lws gencrypto layer, which calls through to the 25*1c60b9acSAndroid Build Coastguard Workertls crypto library, and so works on both OpenSSL and mbedTLS the same. 26*1c60b9acSAndroid Build Coastguard Worker 27*1c60b9acSAndroid Build Coastguard WorkerAn increasing number of higher-level IETF specifications use COSE underneath. 28*1c60b9acSAndroid Build Coastguard Worker 29*1c60b9acSAndroid Build Coastguard Worker## cose_key and sets 30*1c60b9acSAndroid Build Coastguard Worker 31*1c60b9acSAndroid Build Coastguard WorkerLws provides an `lws_cose_key_t` object to contain a single key's metadata and 32*1c60b9acSAndroid Build Coastguard Workerkey material for EC, RSA and SYMMETRIC key types. 33*1c60b9acSAndroid Build Coastguard Worker 34*1c60b9acSAndroid Build Coastguard WorkerThere is a commandline tool wrapping the key dumping and generation apis 35*1c60b9acSAndroid Build Coastguard Workeravailable at `./minimal-examples/crypto/lws-crypto-cose-key` 36*1c60b9acSAndroid Build Coastguard Worker 37*1c60b9acSAndroid Build Coastguard Worker### cose_key and sets import from CBOR and destroying 38*1c60b9acSAndroid Build Coastguard Worker 39*1c60b9acSAndroid Build Coastguard Worker``` 40*1c60b9acSAndroid Build Coastguard Workerlws_cose_key_t * 41*1c60b9acSAndroid Build Coastguard Workerlws_cose_key_import(lws_dll2_owner_t *pkey_set, lws_cose_key_import_callback cb, 42*1c60b9acSAndroid Build Coastguard Worker void *user, const uint8_t *in, size_t len); 43*1c60b9acSAndroid Build Coastguard Workervoid 44*1c60b9acSAndroid Build Coastguard Workerlws_cose_key_destroy(lws_cose_key_t **ck); 45*1c60b9acSAndroid Build Coastguard Worker 46*1c60b9acSAndroid Build Coastguard Workervoid 47*1c60b9acSAndroid Build Coastguard Workerlws_cose_key_set_destroy(lws_dll2_owner_t *o); 48*1c60b9acSAndroid Build Coastguard Worker``` 49*1c60b9acSAndroid Build Coastguard Worker 50*1c60b9acSAndroid Build Coastguard WorkerTo convert a single key, `pkey_set` should be NULL and the created key will be 51*1c60b9acSAndroid Build Coastguard Workerreturned, for a cose_key set, which is simply a CBOR array of cose_keys, it 52*1c60b9acSAndroid Build Coastguard Workershould be a prepared (ie, zero'd down if nothing in it) lws_dll2_owner_t that 53*1c60b9acSAndroid Build Coastguard Workerwill contain the resulting list of `lws_cose_key_t` objects that were created. 54*1c60b9acSAndroid Build Coastguard WorkerIn both cases the return is NULL if there was a fatal error and anything created 55*1c60b9acSAndroid Build Coastguard Workerhas been cleaned up, the return has no other meaning in the cose_key set case. 56*1c60b9acSAndroid Build Coastguard Worker 57*1c60b9acSAndroid Build Coastguard Worker`lws_cose_key_destroy()` destroys a single `lws_cose_key_t` and sets the 58*1c60b9acSAndroid Build Coastguard Workercontents of the pointer to NULL, for cose_key sets you instead pass a pointer to 59*1c60b9acSAndroid Build Coastguard Workerthe owner object to `lws_cose_key_set_destroy()` to destroy all the keys in the 60*1c60b9acSAndroid Build Coastguard Workerset in one step. 61*1c60b9acSAndroid Build Coastguard Worker 62*1c60b9acSAndroid Build Coastguard Workercose_key has some confusions about type, kty and alg may be either ints, 63*1c60b9acSAndroid Build Coastguard Workerrepresenting well-known standardized key and alg types, or freeform strings. 64*1c60b9acSAndroid Build Coastguard WorkerWe convert the well-known ints to their string representations at import, so 65*1c60b9acSAndroid Build Coastguard Workerthere can be no confusion later. 66*1c60b9acSAndroid Build Coastguard Worker 67*1c60b9acSAndroid Build Coastguard Worker### cose_key generation 68*1c60b9acSAndroid Build Coastguard Worker 69*1c60b9acSAndroid Build Coastguard Worker``` 70*1c60b9acSAndroid Build Coastguard Workerlws_cose_key_t * 71*1c60b9acSAndroid Build Coastguard Workerlws_cose_key_generate(struct lws_context *context, int cose_kty, int use_mask, 72*1c60b9acSAndroid Build Coastguard Worker int bits, const char *curve, const char *kid); 73*1c60b9acSAndroid Build Coastguard Worker``` 74*1c60b9acSAndroid Build Coastguard Worker 75*1c60b9acSAndroid Build Coastguard WorkerThis creates an `lws_cose_key_t`, generates a key (SYMMETRIC) or keypair into 76*1c60b9acSAndroid Build Coastguard Workerit and returns a pointer to it. 77*1c60b9acSAndroid Build Coastguard Worker 78*1c60b9acSAndroid Build Coastguard Worker`cose_kty` is one of `LWSCOSE_WKKTV_OKP`, `LWSCOSE_WKKTV_EC2`, `LWSCOSE_WKKTV_RSA`, 79*1c60b9acSAndroid Build Coastguard Workeror `LWSCOSE_WKKTV_SYMMETRIC`. `bits` is valid for RSA keys and for EC keys, 80*1c60b9acSAndroid Build Coastguard Worker`curve` should be a well-known curve name, one of `P-256`, `P-384` and `P-521` 81*1c60b9acSAndroid Build Coastguard Workercurrently. `use_mask` is a bitfield made up of (1 << LWSCOSE_WKKO_...) set to 82*1c60b9acSAndroid Build Coastguard Workerenable the usage on the key. 83*1c60b9acSAndroid Build Coastguard Worker 84*1c60b9acSAndroid Build Coastguard Worker### cose_key export to CBOR 85*1c60b9acSAndroid Build Coastguard Worker 86*1c60b9acSAndroid Build Coastguard WorkerThe export api uses the same CBOR write context as `lws_lec_printf()` uses to 87*1c60b9acSAndroid Build Coastguard Workeremit the key into an output buffer. Like the CBOR output apis, it may return 88*1c60b9acSAndroid Build Coastguard Worker`LWS_LECPCTX_RET_AGAIN` to indicate it filled the buffer and should be called 89*1c60b9acSAndroid Build Coastguard Workeragain to fill another buffer. `lws_lec_init()` should be used to prepare the 90*1c60b9acSAndroid Build Coastguard Workerwrite context and `lws_lec_setbuf()` to reset the output buffer on subsequent 91*1c60b9acSAndroid Build Coastguard Workercalls, exactly the same as the CBOR write apis. 92*1c60b9acSAndroid Build Coastguard Worker 93*1c60b9acSAndroid Build Coastguard Worker``` 94*1c60b9acSAndroid Build Coastguard Workerenum lws_lec_pctx_ret 95*1c60b9acSAndroid Build Coastguard Workerlws_cose_key_export(lws_cose_key_t *ck, lws_lec_pctx_t *ctx, int flags); 96*1c60b9acSAndroid Build Coastguard Worker``` 97*1c60b9acSAndroid Build Coastguard Worker 98*1c60b9acSAndroid Build Coastguard Worker`flags` may be 0 to only output the public key pieces, or `LWSJWKF_EXPORT_PRIVATE` 99*1c60b9acSAndroid Build Coastguard Workerto output everything. 100*1c60b9acSAndroid Build Coastguard Worker 101*1c60b9acSAndroid Build Coastguard Worker## Signing and signature validation 102*1c60b9acSAndroid Build Coastguard Worker 103*1c60b9acSAndroid Build Coastguard WorkerCOSE specifies three kinds of signed object, `cose_sign1` which signs a payload 104*1c60b9acSAndroid Build Coastguard Workerwith a single algorithm and key, `cose_sign` which may sign a payload with 105*1c60b9acSAndroid Build Coastguard Workermultiple algorithms and keys, and `countersign`. 106*1c60b9acSAndroid Build Coastguard Worker 107*1c60b9acSAndroid Build Coastguard Worker`cose_sign1` has the advantage it can be validated with a single pass through 108*1c60b9acSAndroid Build Coastguard Workerthe signed object; `cose_sign` unfortunately specifies the parameters of the 109*1c60b9acSAndroid Build Coastguard Workersignatures after the payload and must be done with multiple passes through the 110*1c60b9acSAndroid Build Coastguard Workerpayload, for inline payloads, by caching it in heap. 111*1c60b9acSAndroid Build Coastguard Worker 112*1c60b9acSAndroid Build Coastguard Worker`cose_sign` and `cose_sign1` objects are supported by lws, Countersigned 113*1c60b9acSAndroid Build Coastguard Workerobjects are not yet supported. 114*1c60b9acSAndroid Build Coastguard Worker 115*1c60b9acSAndroid Build Coastguard Worker`cose_mac0` is supported using HMAC for signing and validation, `cose_mac` is 116*1c60b9acSAndroid Build Coastguard Workeronly supported for validation. 117*1c60b9acSAndroid Build Coastguard Worker 118*1c60b9acSAndroid Build Coastguard WorkerThere is a commandline tool wrapping the signing and validation apis 119*1c60b9acSAndroid Build Coastguard Workeravailable at `./minimal-examples/crypto/lws-crypto-cose-sign` 120*1c60b9acSAndroid Build Coastguard Worker 121*1c60b9acSAndroid Build Coastguard Worker### Signature validation 122*1c60b9acSAndroid Build Coastguard Worker 123*1c60b9acSAndroid Build Coastguard WorkerSignature validation does not have to be done synchronously, to facilitate this 124*1c60b9acSAndroid Build Coastguard Workerfirst you create a validation context specifying the type (eg, `SIGTYPE_SINGLE`) 125*1c60b9acSAndroid Build Coastguard Workerand a keyset of public keys the signature might use to validate (notice even a 126*1c60b9acSAndroid Build Coastguard Workersingle key is passed in an lws_dll2_owner_t keyset). 127*1c60b9acSAndroid Build Coastguard Worker 128*1c60b9acSAndroid Build Coastguard WorkerCreation uses a public `lws_cose_validate_create_info_t` info struct 129*1c60b9acSAndroid Build Coastguard Worker 130*1c60b9acSAndroid Build Coastguard Worker``` 131*1c60b9acSAndroid Build Coastguard Workertypedef struct lws_cose_validate_create_info { 132*1c60b9acSAndroid Build Coastguard Worker struct lws_context *cx; 133*1c60b9acSAndroid Build Coastguard Worker /**< REQUIRED: the lws context */ 134*1c60b9acSAndroid Build Coastguard Worker lws_dll2_owner_t *keyset; 135*1c60b9acSAndroid Build Coastguard Worker /**< REQUIRED: one or more cose_keys */ 136*1c60b9acSAndroid Build Coastguard Worker 137*1c60b9acSAndroid Build Coastguard Worker enum lws_cose_sig_types sigtype; 138*1c60b9acSAndroid Build Coastguard Worker /**< 0 if a CBOR tag is in the sig, else one of SIGTYPE_MULTI, 139*1c60b9acSAndroid Build Coastguard Worker * SIGTYPE_SINGLE, etc*/ 140*1c60b9acSAndroid Build Coastguard Worker 141*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_pay_cb_t pay_cb; 142*1c60b9acSAndroid Build Coastguard Worker /**< optional: called back with unvalidated payload pieces */ 143*1c60b9acSAndroid Build Coastguard Worker void *pay_opaque; 144*1c60b9acSAndroid Build Coastguard Worker /**< optional: passed into pay_cb callback along with payload chunk */ 145*1c60b9acSAndroid Build Coastguard Worker 146*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_ext_pay_cb_t ext_cb; 147*1c60b9acSAndroid Build Coastguard Worker /**< optional extra application data provision callback */ 148*1c60b9acSAndroid Build Coastguard Worker void *ext_opaque; 149*1c60b9acSAndroid Build Coastguard Worker /**< optional extra application data provision callback opaque */ 150*1c60b9acSAndroid Build Coastguard Worker size_t ext_len; 151*1c60b9acSAndroid Build Coastguard Worker /**< if we have extra app data, this must be set to the length of it */ 152*1c60b9acSAndroid Build Coastguard Worker} lws_cose_validate_create_info_t; 153*1c60b9acSAndroid Build Coastguard Worker``` 154*1c60b9acSAndroid Build Coastguard Worker 155*1c60b9acSAndroid Build Coastguard Worker``` 156*1c60b9acSAndroid Build Coastguard Workerstruct lws_cose_validate_context * 157*1c60b9acSAndroid Build Coastguard Workerlws_cose_validate_create(const lws_cose_validate_create_info_t *info); 158*1c60b9acSAndroid Build Coastguard Worker 159*1c60b9acSAndroid Build Coastguard Workervoid 160*1c60b9acSAndroid Build Coastguard Workerlws_cose_validate_destroy(struct lws_cose_validate_context **cps); 161*1c60b9acSAndroid Build Coastguard Worker``` 162*1c60b9acSAndroid Build Coastguard Worker 163*1c60b9acSAndroid Build Coastguard Workerafter that as pieces of the signature CBOR become available, they can be 164*1c60b9acSAndroid Build Coastguard Workerprocessed by the validation context 165*1c60b9acSAndroid Build Coastguard Worker 166*1c60b9acSAndroid Build Coastguard Worker``` 167*1c60b9acSAndroid Build Coastguard Workerint 168*1c60b9acSAndroid Build Coastguard Workerlws_cose_validate_chunk(struct lws_cose_validate_context *cps, 169*1c60b9acSAndroid Build Coastguard Worker const uint8_t *in, size_t in_len, size_t *used_in); 170*1c60b9acSAndroid Build Coastguard Worker``` 171*1c60b9acSAndroid Build Coastguard Worker 172*1c60b9acSAndroid Build Coastguard WorkerThe parsing of the signature yields a list of result objects indicating 173*1c60b9acSAndroid Build Coastguard Workerinformation about each signature it encountered and whether it was validated or 174*1c60b9acSAndroid Build Coastguard Workernot. The parsing itself only fails if there is an unrecoverable error, the 175*1c60b9acSAndroid Build Coastguard Workercompletion of parsing does not indicate validation, it may yield zero or more 176*1c60b9acSAndroid Build Coastguard Workerresult objects indicating the validation failed. 177*1c60b9acSAndroid Build Coastguard Worker 178*1c60b9acSAndroid Build Coastguard Worker``` 179*1c60b9acSAndroid Build Coastguard Workerlws_dll2_owner_t * 180*1c60b9acSAndroid Build Coastguard Workerlws_cose_validate_results(struct lws_cose_validate_context *cps); 181*1c60b9acSAndroid Build Coastguard Worker 182*1c60b9acSAndroid Build Coastguard Workertypedef struct { 183*1c60b9acSAndroid Build Coastguard Worker lws_dll2_t list; 184*1c60b9acSAndroid Build Coastguard Worker 185*1c60b9acSAndroid Build Coastguard Worker const lws_cose_key_t *cose_key; 186*1c60b9acSAndroid Build Coastguard Worker cose_param_t cose_alg; 187*1c60b9acSAndroid Build Coastguard Worker 188*1c60b9acSAndroid Build Coastguard Worker int result; /* 0 = validated */ 189*1c60b9acSAndroid Build Coastguard Worker 190*1c60b9acSAndroid Build Coastguard Worker} lws_cose_validate_res_t; 191*1c60b9acSAndroid Build Coastguard Worker``` 192*1c60b9acSAndroid Build Coastguard Worker 193*1c60b9acSAndroid Build Coastguard WorkerIt's like this because for multiple signatures, we may only have keys for some 194*1c60b9acSAndroid Build Coastguard Workerof them, and we may have different policies for validation that can only be 195*1c60b9acSAndroid Build Coastguard Workerassessed as a whole, eg, we may inisit that signatures pass with specific 196*1c60b9acSAndroid Build Coastguard Workeralgorithms, or all signatures for specific keys must be present and pass. This 197*1c60b9acSAndroid Build Coastguard Workerway user code can assess the situation after the signature parsing and make its 198*1c60b9acSAndroid Build Coastguard Workerdecision about overall validity according to its own policies. 199*1c60b9acSAndroid Build Coastguard Worker 200*1c60b9acSAndroid Build Coastguard Worker## Signing 201*1c60b9acSAndroid Build Coastguard Worker 202*1c60b9acSAndroid Build Coastguard WorkerSigning is again done by creating a signing context using an info struct to pass 203*1c60b9acSAndroid Build Coastguard Workerin the paramter (a `lws_cose_sign_create_info_t`). 204*1c60b9acSAndroid Build Coastguard Worker 205*1c60b9acSAndroid Build Coastguard Worker``` 206*1c60b9acSAndroid Build Coastguard Worker#define LCSC_FL_ADD_CBOR_TAG (1 << 0) 207*1c60b9acSAndroid Build Coastguard Worker#define LCSC_FL_ADD_CBOR_PREFER_MAC0 (1 << 1) 208*1c60b9acSAndroid Build Coastguard Worker 209*1c60b9acSAndroid Build Coastguard Workertypedef struct lws_cose_sign_create_info { 210*1c60b9acSAndroid Build Coastguard Worker struct lws_context *cx; 211*1c60b9acSAndroid Build Coastguard Worker /**< REQUIRED: the lws context */ 212*1c60b9acSAndroid Build Coastguard Worker lws_dll2_owner_t *keyset; 213*1c60b9acSAndroid Build Coastguard Worker /**< REQUIRED: one or more cose_keys */ 214*1c60b9acSAndroid Build Coastguard Worker 215*1c60b9acSAndroid Build Coastguard Worker lws_lec_pctx_t *lec; 216*1c60b9acSAndroid Build Coastguard Worker /**< REQUIRED: the cbor output context to emit to, user must 217*1c60b9acSAndroid Build Coastguard Worker * initialize with lws_lec_init() beforehand */ 218*1c60b9acSAndroid Build Coastguard Worker 219*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_ext_pay_cb_t ext_cb; 220*1c60b9acSAndroid Build Coastguard Worker /**< optional extra application data provision callback */ 221*1c60b9acSAndroid Build Coastguard Worker void *ext_opaque; 222*1c60b9acSAndroid Build Coastguard Worker /**< optional extra application data provision callback opaque */ 223*1c60b9acSAndroid Build Coastguard Worker size_t ext_len; 224*1c60b9acSAndroid Build Coastguard Worker /**< if we have extra app data, this must be set to the length of it */ 225*1c60b9acSAndroid Build Coastguard Worker 226*1c60b9acSAndroid Build Coastguard Worker size_t inline_payload_len; 227*1c60b9acSAndroid Build Coastguard Worker /**< REQUIRED: size of the inline payload we will provide */ 228*1c60b9acSAndroid Build Coastguard Worker 229*1c60b9acSAndroid Build Coastguard Worker int flags; 230*1c60b9acSAndroid Build Coastguard Worker /**< bitmap of LCSC_FL_* */ 231*1c60b9acSAndroid Build Coastguard Worker enum lws_cose_sig_types sigtype; 232*1c60b9acSAndroid Build Coastguard Worker /**< 0, or sign type hint */ 233*1c60b9acSAndroid Build Coastguard Worker} lws_cose_sign_create_info_t; 234*1c60b9acSAndroid Build Coastguard Worker``` 235*1c60b9acSAndroid Build Coastguard Worker 236*1c60b9acSAndroid Build Coastguard Worker``` 237*1c60b9acSAndroid Build Coastguard Workerstruct lws_cose_sign_context * 238*1c60b9acSAndroid Build Coastguard Workerlws_cose_sign_create(const lws_cose_sign_create_info_t *info); 239*1c60b9acSAndroid Build Coastguard Worker``` 240*1c60b9acSAndroid Build Coastguard Worker 241*1c60b9acSAndroid Build Coastguard WorkerAfter creating the signing context, you call `lws_cose_sign_add()` one or more 242*1c60b9acSAndroid Build Coastguard Workertimes to add algorithms and keys to sign with (since cose_sign allows multiple 243*1c60b9acSAndroid Build Coastguard Workerrecipients with the same payload signed in different ways). 244*1c60b9acSAndroid Build Coastguard Worker 245*1c60b9acSAndroid Build Coastguard Worker``` 246*1c60b9acSAndroid Build Coastguard Workerint 247*1c60b9acSAndroid Build Coastguard Workerlws_cose_sign_add(struct lws_cose_sign_context *csc, cose_param_t alg, 248*1c60b9acSAndroid Build Coastguard Worker const lws_cose_key_t *ck); 249*1c60b9acSAndroid Build Coastguard Worker``` 250*1c60b9acSAndroid Build Coastguard Worker 251*1c60b9acSAndroid Build Coastguard WorkerThe payload does not have to be provided all at once and can be passed in chunk 252*1c60b9acSAndroid Build Coastguard Workerby chunk over time via `lws_cose_sign_payload_chunk()`. 253*1c60b9acSAndroid Build Coastguard Worker 254*1c60b9acSAndroid Build Coastguard WorkerOutput is mediated via an lws CBOR output context provided in the info at 255*1c60b9acSAndroid Build Coastguard Workercreation-time, it's only emitted during the `lws_cose_sign_payload_chunk()` 256*1c60b9acSAndroid Build Coastguard Workerphase. If it returns `LWS_LECPCTX_RET_AGAIN`, you must call that api again 257*1c60b9acSAndroid Build Coastguard Workerafter using the CBOR output context data and resetting its buffer by 258*1c60b9acSAndroid Build Coastguard Worker`lws_lec_setbuf()`, so it can continue to output. 259*1c60b9acSAndroid Build Coastguard Worker 260*1c60b9acSAndroid Build Coastguard Worker``` 261*1c60b9acSAndroid Build Coastguard Workerenum lws_lec_pctx_ret 262*1c60b9acSAndroid Build Coastguard Workerlws_cose_sign_payload_chunk(struct lws_cose_sign_context *csc, 263*1c60b9acSAndroid Build Coastguard Worker const uint8_t *in, size_t in_len); 264*1c60b9acSAndroid Build Coastguard Worker``` 265*1c60b9acSAndroid Build Coastguard Worker 266*1c60b9acSAndroid Build Coastguard WorkerFinally the signing context is destroyed. 267*1c60b9acSAndroid Build Coastguard Worker 268*1c60b9acSAndroid Build Coastguard Worker``` 269*1c60b9acSAndroid Build Coastguard Workervoid 270*1c60b9acSAndroid Build Coastguard Workerlws_cose_sign_destroy(struct lws_cose_sign_context **csc); 271*1c60b9acSAndroid Build Coastguard Worker``` 272*1c60b9acSAndroid Build Coastguard Worker 273