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, optionaltsandx_*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.
- AadContext
Builder - Builder for constructing an
AadContext. - Field
Key - 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.
- Extension
Value - Extension field value: string or integer.
- Json
Type - 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.