Skip to main content

Crate canaad_core

Crate canaad_core 

Source
Expand description

Core library for AAD canonicalization per RFC 8785 (JCS).

Provides deterministic serialization and contextual binding for AEAD additional authenticated data. Mitigates confused deputy attacks, cross-tenant decryption, and purpose confusion by binding ciphertext to tenant, resource, and purpose fields with a canonical byte representation.

See the AAD specification for the full schema, constraint set, and test vectors. Architecture and integration guidance at gnu.foo/projects/canaad.

§Architecture

The library exposes two layers:

  • Default-profile layer (parse_default, validate_default, canonicalize_default, canonicalize_default_string): enforces the standard AAD field set — v, tenant, resource, purpose, optional ts and x_* extensions.

  • Generic-object layer (validate_object, canonicalize_object, canonicalize_object_string): applies core rules only (size, duplicate-key detection, object assertion, JCS canonicalization) without requiring any specific fields. Use this layer to build custom profiles on top of canaad.

§Quick Start

§Default profile

use canaad_core::{parse_default, canonicalize_default, canonicalize_default_string, AadContext};

// Parse and validate existing JSON against the default profile
let json = r#"{"v":1,"tenant":"org_abc","resource":"secrets/db","purpose":"encryption"}"#;
let ctx = parse_default(json)?;
let canonical = ctx.canonicalize_string()?;

// Or build from scratch
let ctx = AadContext::new("org_abc", "secrets/db", "encryption")?
    .with_timestamp(1706400000)?
    .with_string_extension("x_vault_cluster", "us-east-1")?;

let bytes = ctx.canonicalize()?;

§Generic object (custom profile)

use canaad_core::canonicalize_object;

// Canonicalize any valid JSON object without profile validation
let json = r#"{"z":"last","a":"first"}"#;
let bytes = canonicalize_object(json)?;

§Validation Rules (default profile)

  • Version (v): Must be 1
  • Tenant: 1-256 bytes, no NUL bytes
  • Resource: 1-1024 bytes, no NUL bytes
  • Purpose: 1+ bytes, no NUL bytes
  • Timestamp (ts): Optional, 0 to 2^53-1
  • Extension keys: Must match pattern x_<app>_<field> where app is [a-z]+ and field is [a-z_]+
  • All integers: 0 to 2^53-1 (JavaScript safe integer range)
  • Total serialized size: Maximum 16 KiB
  • No duplicate keys allowed

Structs§

AadContext
AAD context with all validated fields.
AadContextBuilder
Builder for constructing an AadContext.
FieldKey
Field key matching pattern [a-z_]+.
Purpose
Purpose/usage context (1+ bytes, no NUL).
Resource
Resource path or identifier (1-1024 bytes, no NUL).
SafeInt
A safe integer in the range 0 to 2^53-1.
Tenant
Tenant identifier (1-256 bytes, no NUL).

Enums§

AadError
All possible errors during AAD parsing, validation, and canonicalization.
ExtensionValue
Extension field value: string or integer.
JsonType
JSON value type for error reporting.

Constants§

CURRENT_VERSION
Current supported schema version.
MAX_AAD_SIZE
Maximum serialized AAD size in bytes (16 KiB).
MAX_SAFE_INTEGER
Maximum safe integer value (2^53 - 1) for cross-platform compatibility.
RESERVED_KEYS
Reserved field names that cannot be used as extensions.

Functions§

canonicalize_default
Canonicalizes a JSON string to bytes using the default AAD profile.
canonicalize_default_string
Canonicalizes a JSON string to a UTF-8 string using the default AAD profile.
canonicalize_object
Canonicalizes any valid JSON object to bytes per RFC 8785.
canonicalize_object_string
Canonicalizes any valid JSON object to a UTF-8 string per RFC 8785.
parse_default
Parses a JSON string into a validated AadContext.
validate_default
Alias for parse_default — same validation, same return type.
validate_object
Validates any JSON string against core rules (size, duplicate keys, object shape).

Type Aliases§

Extensions
Extension fields map.