Expand description
Module to encode/decode COSE messages.
§Examples
§cose-sign1
cose-sign1 message with ECDSA w/ SHA-256 algorithm
§Encode cose-sign1 message
use cose::message::CoseMessage;
use cose::keys;
use cose::algs;
use hex;
fn main() {
let msg = b"This is the content.".to_vec();
let kid = b"11".to_vec();
// cose-key to encode the message
let mut key = keys::CoseKey::new();
key.kty(keys::EC2);
key.alg(algs::ES256);
key.crv(keys::P_256);
key.x(hex::decode("bac5b11cad8f99f9c72b05cf4b9e26d244dc189f745228255a219a86d6a09eff").unwrap());
key.y(hex::decode("20138bf82dc1b6d562be0fa54ab7804a3a64b6d72ccfed6b6fb6ed28bbfc117e").unwrap());
key.d(hex::decode("57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3").unwrap());
key.key_ops(vec![keys::KEY_OPS_SIGN, keys::KEY_OPS_VERIFY]);
// Prepare cose_sign1 message
let mut sign1 = CoseMessage::new_sign();
sign1.header.alg(algs::ES256, true, false);
sign1.header.kid(kid, true, false);
sign1.payload(msg);
sign1.key(&key).unwrap();
// Generate the Signature
sign1.secure_content(None).unwrap();
// Encode the message with the payload
sign1.encode(true).unwrap();
}
§Decode cose-sign1 message
use cose::message::CoseMessage;
use cose::keys;
use cose::algs;
use hex;
fn main() {
// COSE_KEY to decode the message
let mut key = keys::CoseKey::new();
key.kty(keys::EC2);
key.alg(algs::ES256);
key.crv(keys::P_256);
key.x(hex::decode("bac5b11cad8f99f9c72b05cf4b9e26d244dc189f745228255a219a86d6a09eff").unwrap());
key.y(hex::decode("20138bf82dc1b6d562be0fa54ab7804a3a64b6d72ccfed6b6fb6ed28bbfc117e").unwrap());
key.d(hex::decode("57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3").unwrap());
key.key_ops(vec![keys::KEY_OPS_SIGN, keys::KEY_OPS_VERIFY]);
// Generate CoseSign struct with the cose-sign1 message to decode
let mut verify = CoseMessage::new_sign();
verify.bytes =
hex::decode("d28447a2012604423131a054546869732069732074686520636f6e74656e742e5840dc93ddf7d5aff58131589087eaa65eeffa0baf2e72201ee91c0ca876ec42fdfb2a67dbc6ea1a95d2257cec645cf789808c0a392af045e2bc1bdb6746d80f221b").unwrap();
// Initial decoding
verify.init_decoder(None).unwrap();
// Add key and verify the signature
verify.key(&key).unwrap();
verify.decode(None, None).unwrap();
}
§cose-sign
Encode and decode cose-sign message with 2 signers, both using ECDSA w/ SHA-256
§Encode cose-sign message
use cose::message::CoseMessage;
use cose::keys;
use cose::algs;
use cose::agent::CoseAgent;
use hex;
fn main() {
let msg = b"This is the content.".to_vec();
let s1_kid = b"11".to_vec();
let s2_kid = b"22".to_vec();
// Prepare signer 1 key
let mut s1_key = keys::CoseKey::new();
s1_key.kty(keys::EC2);
s1_key.alg(algs::ES256);
s1_key.crv(keys::P_256);
s1_key.d(hex::decode("57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3").unwrap());
s1_key.key_ops(vec![keys::KEY_OPS_SIGN]);
// Prepare signer 2 key
let mut s2_key = keys::CoseKey::new();
s2_key.kty(keys::OKP);
s2_key.alg(algs::EDDSA);
s2_key.crv(keys::ED25519);
s2_key.d(hex::decode("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60").unwrap());
s2_key.key_ops(vec![keys::KEY_OPS_SIGN]);
// Prepare cose-sign message
let mut sign = CoseMessage::new_sign();
sign.payload(msg);
// Add signer 1
let mut signer1 = CoseAgent::new();
signer1.header.alg(algs::ES256, true, false);
signer1.header.kid(s1_kid.clone(), false, false);
signer1.key(&s1_key).unwrap();
sign.add_agent(&mut signer1).unwrap();
// Add signer 2
let mut signer2 = CoseAgent::new();
signer2.header.alg(algs::EDDSA, true, false);
signer2.header.kid(s2_kid.clone(), false, false);
signer2.key(&s2_key).unwrap();
sign.add_agent(&mut signer2).unwrap();
// Generate signature without AAD
sign.secure_content(None).unwrap();
// Encode the cose-sign message
sign.encode(true).unwrap();
}
§Decode cose-sign message
use cose::message::CoseMessage;
use cose::keys;
use cose::algs;
use cose::agent::CoseAgent;
use hex;
fn main() {
let s1_kid = b"11".to_vec();
let s2_kid = b"22".to_vec();
// Prepare signer 1 key
let mut s1_key = keys::CoseKey::new();
s1_key.kty(keys::EC2);
s1_key.alg(algs::ES256);
s1_key.crv(keys::P_256);
s1_key.kid(b"1".to_vec());
s1_key.x(hex::decode("bac5b11cad8f99f9c72b05cf4b9e26d244dc189f745228255a219a86d6a09eff").unwrap());
s1_key.y(hex::decode("20138bf82dc1b6d562be0fa54ab7804a3a64b6d72ccfed6b6fb6ed28bbfc117e").unwrap());
s1_key.key_ops(vec![keys::KEY_OPS_VERIFY]);
// Prepare signer 2 key
let mut s2_key = keys::CoseKey::new();
s2_key.kty(keys::OKP);
s2_key.alg(algs::EDDSA);
s2_key.crv(keys::ED25519);
s2_key.x(hex::decode("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a").unwrap());
s2_key.key_ops(vec![keys::KEY_OPS_VERIFY]);
// Generate CoseSign with the cose-sign message to decode
let mut verify = CoseMessage::new_sign();
verify.bytes =
hex::decode("d8628440a054546869732069732074686520636f6e74656e742e828343a10126a1044231315840a45d63392d72cfef8bd08ec6a17e40364f8b3094558f1f8078c497718de536dceadfb4a637804b31e21572ba3714e03b0b5510e243b0240c252da3a827ba4e998343a10127a104423232584081d92439ecaf31f11f611054346d50b5fbd4e5cfe00c1c237cf673fa3948678b378eacd5eecf6f680980f818a8ecc57a8b4c733ec2fd8d03ae3ba04a02ea4a06").unwrap();
verify.init_decoder(None).unwrap();
// Get signer 1 and verify
let mut index1 = verify.get_agent(&s1_kid).unwrap()[0];
verify.agents[index1].key(&s1_key).unwrap();
verify.decode(None, Some(index1)).unwrap();
// Get signer 2 and verify
let mut index2 = verify.get_agent(&s2_kid).unwrap()[0];
verify.agents[index2].key(&s2_key).unwrap();
verify.decode(None, Some(index2)).unwrap();
}
//! ## cose-encrypt0
cose-encrypt0 message with ChaCha20/Poly1305 algorithm
§Encode cose-encrypt0 message
use cose::message::CoseMessage;
use cose::keys;
use cose::algs;
use hex;
fn main() {
let msg = b"This is the content.".to_vec();
let kid = b"secret".to_vec();
// Prepare the cose-key
let mut key = keys::CoseKey::new();
key.kty(keys::SYMMETRIC);
key.alg(algs::CHACHA20);
key.k(hex::decode("849b57219dae48de646d07dbb533566e976686457c1491be3a76dcea6c427188").unwrap());
key.key_ops(vec![keys::KEY_OPS_ENCRYPT, keys::KEY_OPS_DECRYPT]);
// Prepare cose-encrypt0 message
let mut enc0 = CoseMessage::new_encrypt();
enc0.header.alg(algs::CHACHA20, true, false);
enc0.header.iv(hex::decode("89f52f65a1c580933b5261a7").unwrap(), true, false);
enc0.payload(msg);
enc0.key(&key).unwrap();
// Generate the ciphertext with no AAD.
enc0.secure_content(None).unwrap();
// Encode the cose-encrypt0 message with the ciphertext included
enc0.encode(true).unwrap();
}
§Decode cose-encrypt0 message
use cose::message::CoseMessage;
use cose::keys;
use cose::algs;
use hex;
fn main() {
let expected_msg = b"This is the content.".to_vec();
// Prepare the cose-key
let mut key = keys::CoseKey::new();
key.kty(keys::SYMMETRIC);
key.alg(algs::CHACHA20);
key.k(hex::decode("849b57219dae48de646d07dbb533566e976686457c1491be3a76dcea6c427188").unwrap());
key.key_ops(vec![keys::KEY_OPS_ENCRYPT, keys::KEY_OPS_DECRYPT]);
// Generate CoseEncrypt struct with the cose-encrypt0 message to decode
let mut dec0 = CoseMessage::new_encrypt();
dec0.bytes =
hex::decode("d08352a2011818054c89f52f65a1c580933b5261a7a0582481c32c048134989007b3b5b932811ea410eeab15bd0de5d5ac5be03c84dce8c88871d6e9").unwrap();
// Initial decoding of the message
dec0.init_decoder(None).unwrap();
// Add cose-key
dec0.key(&key).unwrap();
// Decrypt the cose-encrypt0 message
let msg = dec0.decode(None, None).unwrap();
assert_eq!(msg, expected_msg);
}
§cose-encrypt
Encode and decode cose-encrypt message with AES-GCM algorithm with 2 recipients, one using A128KW as the key agreement and the other using the ECDH-ES + A128KW key agreement.
§Encode cose-encrypt message
use cose::message::CoseMessage;
use cose::keys;
use cose::headers;
use cose::algs;
use cose::agent::CoseAgent;
use hex;
fn main() {
let msg = b"This is the content.".to_vec();
let r1_kid = b"11".to_vec();
let r2_kid = b"22".to_vec();
// Prepare recipient 1 cose-key
let mut r1_key = keys::CoseKey::new();
r1_key.kty(keys::SYMMETRIC);
r1_key.alg(algs::A128KW);
r1_key.k(hex::decode("849b57219dae48de646d07dbb533566e976686457c1491be3a76dcea6c427188").unwrap());
r1_key.key_ops(vec![keys::KEY_OPS_WRAP, keys::KEY_OPS_UNWRAP]);
// Prepare recipient 2 cose-key
let mut r2_key = keys::CoseKey::new();
r2_key.kty(keys::EC2);
r2_key.crv(keys::P_256);
r2_key.x(hex::decode("98F50A4FF6C05861C8860D13A638EA56C3F5AD7590BBFBF054E1C7B4D91D6280").unwrap());
// Prepare recipient 2 sender ephermeral ECDH key
let mut r2_eph_key = keys::CoseKey::new();
r2_eph_key.kty(keys::EC2);
r2_eph_key.crv(keys::P_256);
r2_eph_key.x(hex::decode("bac5b11cad8f99f9c72b05cf4b9e26d244dc189f745228255a219a86d6a09eff").unwrap());
r2_eph_key.d(hex::decode("57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3").unwrap());
r2_eph_key.key_ops(vec![keys::KEY_OPS_DERIVE]);
// Prepare cose-encrypt message
let mut enc = CoseMessage::new_encrypt();
enc.header.alg(algs::A256GCM, true, false);
enc.header.iv(hex::decode("89f52f65a1c580933b5261a7").unwrap(), true, false);
enc.payload(msg);
// Add recipient 1 (A128KW)
let mut recipient1 = CoseAgent::new();
recipient1.header.alg(algs::A128KW, true, false);
recipient1.header.kid(r1_kid.clone(), false, false);
recipient1.key(&r1_key).unwrap();
enc.add_agent(&mut recipient1).unwrap();
// Add recipient 2 (ECDH_ES_A128KW)
let mut recipient2 = CoseAgent::new();
recipient2.header.alg(algs::ECDH_ES_A128KW, true, false);
recipient2.header.kid(r2_kid.clone(), false, false);
recipient2.key(&r2_key).unwrap();
recipient2.header.ephemeral_key(r2_eph_key, true, false);
enc.add_agent(&mut recipient2).unwrap();
// Generate ciphertext without AAD
enc.secure_content(None).unwrap();
// Encode the cose-encrypt message
enc.encode(true).unwrap();
}
§Decode cose-encrypt message
use cose::message::CoseMessage;
use cose::keys;
use cose::headers;
use cose::algs;
use cose::agent::CoseAgent;
use hex;
fn main() {
let msg = b"This is the content.".to_vec();
let r1_kid = b"11".to_vec();
let r2_kid = b"22".to_vec();
// Prepare recipient 1 key
let mut r1_key = keys::CoseKey::new();
r1_key.kty(keys::SYMMETRIC);
r1_key.alg(algs::A128KW);
r1_key.k(hex::decode("849b57219dae48de646d07dbb533566e976686457c1491be3a76dcea6c427188").unwrap());
r1_key.key_ops(vec![keys::KEY_OPS_WRAP, keys::KEY_OPS_UNWRAP]);
// Prepare recipient 2 key
let mut r2_key = keys::CoseKey::new();
r2_key.kty(keys::EC2);
r2_key.crv(keys::P_256);
r2_key.x(hex::decode("98F50A4FF6C05861C8860D13A638EA56C3F5AD7590BBFBF054E1C7B4D91D6280").unwrap());
r2_key.y(hex::decode("F01400B089867804B8E9FC96C3932161F1934F4223069170D924B7E03BF822BB").unwrap());
r2_key.d(hex::decode("02D1F7E6F26C43D4868D87CEB2353161740AACF1F7163647984B522A848DF1C3").unwrap());
r2_key.key_ops(vec![keys::KEY_OPS_DERIVE]);
// Generate CoseEncrypt struct with the cose-encrypt message to decode
let mut dec = CoseMessage::new_encrypt();
dec.bytes =
hex::decode("d8608451a20103054c89f52f65a1c580933b5261a7a058243e102aa2950238585d10e72c9d485352814e3ce00ac7482fb08538225622248e4daa3d06828343a10122a104423131582800e14bb6ac7246738dc6cd8232340fb37623c7a2667e474a0c56cc6f742f2d3f15969b5c58351fea835832a201381c20a5010203262001215820bac5b11cad8f99f9c72b05cf4b9e26d244dc189f745228255a219a86d6a09eff048107a1044232325828f9b936b424c591bd5491916e98e4d6d71a4ea6fdf6a2c193718825787fac8d4c1df2c4f8473243c9").unwrap();
dec.init_decoder(None).unwrap();
// Get recipient 1 and decode message
let mut r1_i = dec.get_agent(&r1_kid).unwrap()[0];
dec.agents[r1_i].key(&r1_key).unwrap();
let resp = dec.decode(None, Some(r1_i)).unwrap();
assert_eq!(resp, msg);
// Get recipient 2 and decode message
let mut r2_i = dec.get_agent(&r2_kid).unwrap()[0];
dec.agents[r2_i].key(&r2_key).unwrap();
let resp2 = dec.decode(None, Some(r2_i)).unwrap();
assert_eq!(resp2, msg);
}
//! ## cose-mac0
Encode and decode cose-mac0 message with AES-MAC algorithm
§Encode cose-mac0 message
use cose::message::CoseMessage;
use cose::keys;
use cose::algs;
use hex;
fn main() {
let msg = b"This is the content.".to_vec();
// Prepare the cose-key
let mut key = keys::CoseKey::new();
key.kty(keys::SYMMETRIC);
key.alg(algs::AES_MAC_256_128);
key.k(hex::decode("849b57219dae48de646d07dbb533566e976686457c1491be3a76dcea6c427188").unwrap());
key.key_ops(vec![keys::KEY_OPS_MAC, keys::KEY_OPS_MAC_VERIFY]);
// Prepare the cose-mac0 message
let mut mac0 = CoseMessage::new_mac();
mac0.header.alg(algs::AES_MAC_256_128, true, false);
// Add the payload
mac0.payload(msg);
// Add cose-key
mac0.key(&key).unwrap();
// Generate MAC tag without AAD
mac0.secure_content(None).unwrap();
// Encode the cose-mac0 message with the payload included
mac0.encode(true).unwrap();
}
§Decode cose-mac0 message
use cose::message::CoseMessage;
use cose::keys;
use cose::algs;
use hex;
fn main() {
// Prepare the cose-key
let mut key = keys::CoseKey::new();
key.kty(keys::SYMMETRIC);
key.alg(algs::AES_MAC_256_128);
key.k(hex::decode("849b57219dae48de646d07dbb533566e976686457c1491be3a76dcea6c427188").unwrap());
key.key_ops(vec![keys::KEY_OPS_MAC, keys::KEY_OPS_MAC_VERIFY]);
// Generate CoseMAC struct with the cose-mac0 message to decode
let mut verify = CoseMessage::new_mac();
verify.bytes =
hex::decode("d18444a101181aa054546869732069732074686520636f6e74656e742e50403152cc208c1d501e1dc2a789ae49e4").unwrap();
// Initial decoding of the message
verify.init_decoder(None).unwrap();
// Add cose-key
verify.key(&key).unwrap();
// Verify the MAC tag of the cose-mac0 message
verify.decode(None, None).unwrap();
}
§MAC
Encode and decode cose-mac message with AES-MAC algorithm with 2 recipients, one using A128KW as the key agreement and the other using the ECDH-ES + A128KW key agreement.
§Encode cose-mac message
use cose::message::CoseMessage;
use cose::keys;
use cose::algs;
use cose::agent::CoseAgent;
use hex;
fn main() {
let msg = b"This is the content.".to_vec();
let r1_kid = b"11".to_vec();
let r2_kid = b"22".to_vec();
// Prepare recipient 1 cose-key
let mut r1_key = keys::CoseKey::new();
r1_key.kty(keys::SYMMETRIC);
r1_key.alg(algs::A128KW);
r1_key.k(hex::decode("849b57219dae48de646d07dbb533566e976686457c1491be3a76dcea6c427188").unwrap());
r1_key.key_ops(vec![keys::KEY_OPS_WRAP, keys::KEY_OPS_UNWRAP]);
// Prepare recipient 2 cose-key
let mut r2_key = keys::CoseKey::new();
r2_key.kty(keys::EC2);
r2_key.crv(keys::P_256);
r2_key.x(hex::decode("98F50A4FF6C05861C8860D13A638EA56C3F5AD7590BBFBF054E1C7B4D91D6280").unwrap());
// Prepare recipient 2 sender ephemeral key
let mut r2_eph_key = keys::CoseKey::new();
r2_eph_key.kty(keys::EC2);
r2_eph_key.crv(keys::P_256);
r2_eph_key.x(hex::decode("bac5b11cad8f99f9c72b05cf4b9e26d244dc189f745228255a219a86d6a09eff").unwrap());
r2_eph_key.d(hex::decode("57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3").unwrap());
r2_eph_key.key_ops(vec![keys::KEY_OPS_DERIVE]);
// Prepare CoseMAC message
let mut mac = CoseMessage::new_mac();
mac.header.alg(algs::AES_MAC_256_128, true, false);
mac.payload(msg);
// Add recipient 1 (A128KW)
let mut recipient1 = CoseAgent::new();
recipient1.header.alg(algs::A128KW, true, false);
recipient1.header.kid(r1_kid.clone(), false, false);
recipient1.key(&r1_key).unwrap();
mac.add_agent(&mut recipient1).unwrap();
// Add recipient 2 (ECDH_ES_A128KW)
let mut recipient2 = CoseAgent::new();
recipient2.header.alg(algs::ECDH_ES_A128KW, true, false);
recipient2.header.kid(r2_kid.clone(), false, false);
recipient2.header.salt(vec![0; 32], false, false);
recipient2.key(&r2_key).unwrap();
recipient2.header.ephemeral_key(r2_eph_key.clone(), true, false);
mac.add_agent(&mut recipient2).unwrap();
// Generate tag without AAD
mac.secure_content(None).unwrap();
// Encode the cose-mac message
mac.encode(true).unwrap();
}
§Decode cose-mac message
use cose::message::CoseMessage;
use cose::keys;
use cose::algs;
use cose::agent::CoseAgent;
use hex;
fn main() {
let r1_kid = b"11".to_vec();
let r2_kid = b"22".to_vec();
// Prepare recipient 1 cose-key
let mut r1_key = keys::CoseKey::new();
r1_key.kty(keys::SYMMETRIC);
r1_key.alg(algs::A128KW);
r1_key.k(hex::decode("849b57219dae48de646d07dbb533566e976686457c1491be3a76dcea6c427188").unwrap());
r1_key.key_ops(vec![keys::KEY_OPS_WRAP, keys::KEY_OPS_UNWRAP]);
// Prepare recipient 2 cose-key
let mut r2_key = keys::CoseKey::new();
r2_key.kty(keys::EC2);
r2_key.crv(keys::P_256);
r2_key.d(hex::decode("02D1F7E6F26C43D4868D87CEB2353161740AACF1F7163647984B522A848DF1C3").unwrap());
r2_key.key_ops(vec![keys::KEY_OPS_DERIVE]);
// Generate CoseMAC struct with the cose-mac message to decode
let mut verifier = CoseMessage::new_mac();
verifier.bytes =
hex::decode("d8618544a101181aa054546869732069732074686520636f6e74656e742e5064f33e4802d33bceec3fba4333ec5bf3828343a10122a10442313158281d77d288a153ab460c7c5c05e417b91becd26e9b73d2a0733c3b801db4885e51a635a2759801801b835832a201381c20a5010203262001215820bac5b11cad8f99f9c72b05cf4b9e26d244dc189f745228255a219a86d6a09eff048107a20442323233582000000000000000000000000000000000000000000000000000000000000000005828e53a16090a9caf558a6a2d2709cf195ee28ea55ae92c8e0ddddac26fbee3eb76e494ecd7cfbf49c8").unwrap();
verifier.init_decoder(None).unwrap();
// Get recipient 1 and decode message
let mut index1 = verifier.get_agent(&r1_kid).unwrap()[0];
verifier.agents[index1].key(&r1_key).unwrap();
verifier.decode(None, Some(index1)).unwrap();
// Get recipient 2 and decode message
let mut index2 = verifier.get_agent(&r2_kid).unwrap()[0];
verifier.agents[index2].key(&r2_key).unwrap();
verifier.decode(None, Some(index2)).unwrap();
}
Structs§
- Cose
Message - Structure to encode/decode cose-sign and cose-sign1 messages