Crate cose

source ·
Expand description

CBOR Object Signing and Encryption, COSE (RFC 8152), implementation for Rust.

This library offers a set of methods and structures to help encoding/decoding a COSE message, including the respective cryptographic operations with the given parameters.

The cryptographic functions used in this library are from the rust-openssl and rand crates and the CBOR encoding/decoding methods are from the cbor-codec crate.

Examples

The following examples, demonstrate how to encode and decode COSE messages in different types without the recipients/signers bucket. Examples with the recipients/signers bucket can be found in the modules message and agent.

cose-sign1

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::ES512);
    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]);

    // Prepare cose-sign1 message
    let mut sign1 = CoseMessage::new_sign();
    sign1.header.alg(algs::ES512, 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.key_ops(vec![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-encrypt0

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]);

    // 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_DECRYPT]);


    // Generate CoseEncrypt struct with the cose-encryt0 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-mac0

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]);

    // 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_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();
}

Modules

  • Module to build recipients/signers for the various types of COSE messages.
  • A collection of COSE algorithm identifiers.
  • Errors returned by the module, including rust-openssl and cbor-codec errors.
  • Module to build COSE message headers (protected and unprotected).
  • Module to encode/decode cose-keys/cose-keySets.
  • Module to encode/decode COSE messages.
  • Utilities to help the process of encoding/decoding a COSE message.