Skip to main content

sign_claims

Function sign_claims 

Source
pub async fn sign_claims(
    signer: &(dyn CoseSigner + 'static),
    typ: &str,
    claims: &CwtClaims,
    payload: &[u8],
    external_aad: &[u8],
) -> Result<Vec<u8>, ClaimsError>
Expand description

Sign payload as a claim object: a tagged COSE_Sign1 (tag 18) whose protected header is {1: alg, 4: kid, ? 15: claims, 16: typ}, whose unprotected header is empty and whose payload is embedded.

  • typ (RFC 9596, label 16) names what the object is. It is signed, and open_claims refuses any other, so an object minted for one purpose cannot be replayed as another. It is also what keeps a claim object from opening as a transport envelope, and the reverse. Non-empty, at most MAX_TYP_LEN bytes.
  • claims are written only when present; see CwtClaims for the bounds.
  • external_aad is signed but not sent: the opener must supply the same bytes. Put in it what the object is bound to but does not carry, such as a tenant or a purpose; empty is fine.

The encoding is deterministic (RFC 8949 ยง4.2.1) and an ESP256 signature is low-s, the rules the transport envelope enforces. signer must be a signature signer (Ed25519 or ESP256); an HMAC signer is refused with ClaimsError::Misuse. Nothing is read from a clock: exp and iat are whatever the caller put in.

use cratestack_cose::{CwtClaims, Ed25519Signer, sign_claims};

let signer = Ed25519Signer::from_seed(&[7; 32]);
let claims = CwtClaims { exp: Some(1_790_003_600), ..CwtClaims::default() };
let bytes = sign_claims(&signer, "application/vnd.example.grant+cwt", &claims, b"grant", b"")
    .await
    .unwrap();
assert_eq!(bytes[0], 0xd2); // tag 18