Skip to main content

Context

Struct Context 

Source
pub struct Context<'a>(/* private fields */);
Expand description

The canonical encoding of a context, as bytes.

A context is the same value whether an AEAD authenticates it as associated data or a PRF derives under it: x.into_aad() and x.into_prf_context() both produce this type and both hold the same bytes. Those bytes come from one place, the encoding of the context’s ContextPiece tree, so no consumer can be given a different encoding of the same context on one side than on the other.

The storage is copy-on-write. A context built from a borrowed encoded slice (from_encoded) borrows it; anything the encoder produces is owned.

§Raw bytes

Two methods take raw bytes rather than a typed value, and both mean something specific:

  • from_encoded takes bytes this encoder already produced, for a context that was stored or crossed a language boundary and is now being handed back. Passing it something else, say the raw bytes of a string, gives a context that is not the encoding of that string: Context::from_encoded(b"7") and "7".into_aad() are different contexts.
  • pae frames a list of byte pieces exactly as a composite context is framed. A crate that defines its own domain-separated context shapes builds them with it, leading with a domain label of its own.

Context deliberately does not implement MaybeEmpty. An encoded context can only be judged on its bytes, and framing makes the encoding of an empty value non-empty, so NonEmpty<Context> would certify exactly the degenerate value it exists to exclude. Its parts view, the ContextPiece::Encoded leaf, counts as empty for the same reason, so routing bytes through into_context is not a way around the rule. Prove non-emptiness on the value before it is encoded: NonEmpty<T> where T: IntoContext.

Implementations§

Source§

impl<'a> Context<'a>

Source

pub fn empty() -> Self

The empty context: no bytes at all. The same as ().into_context() encoded, and the value Default gives.

Source

pub fn from_encoded(bytes: impl Into<Cow<'a, [u8]>>) -> Self

A context from bytes this encoder already produced.

Use it to hand back a context that was stored, logged, or received across an FFI boundary as bytes. It does not encode anything: the bytes are the context, verbatim, and when the result is used as a part of a larger context it is written as a ContextPiece::Encoded leaf, untagged. Do not use it to turn a value into a context; implement or call IntoContext for that.

use vitaminc_context::{Context, IntoContext};

let stored = ("users", 7u64).into_context().encode();
let restored = Context::from_encoded(stored.as_bytes());
assert_eq!(restored, stored);
// Re-encoding an encoded context leaves it unchanged.
assert_eq!(restored.clone().into_context().encode(), stored);
Source

pub fn as_bytes(&self) -> &[u8]

The encoded bytes.

Source

pub fn is_empty(&self) -> bool

Whether there are no bytes at all. Only the empty context and the encoding of () are empty; every framed context has at least a count word.

Source

pub fn into_owned(self) -> Context<'static>

Copies the bytes if they are borrowed, so the context can outlive its source.

Source

pub fn pae(pieces: &[&[u8]]) -> Context<'static>

Pre-Authentication Encoding of a list of byte pieces, from the PASETO specification: LE64(count) || (LE64(len(piece)) || piece)*.

Structurally distinct inputs always encode to distinct byte strings. This is the framing every composite context in this crate uses, and the building block a crate uses to define a domain-separated context shape of its own. Lead such a shape with a domain label that is yours; the labels this crate reserves all begin vitaminc/context/.

Source

pub fn refine<'b, C>(&self, component: C) -> Context<'static>
where C: IntoContext<'b>,

Adds a component under this context, with a domain tag so the result cannot collide with any context this crate derives on its own.

The encoding is PAE(domain, self, component). Without the leading domain, a caller could build the reserved option-some label as a context and refine it by x to reach the same bytes for_option_some assigns under x.

Source

pub fn for_map_entry(&self, key: &str) -> Context<'static>

The context a map entry’s value is sealed or derived under, binding the entry key to this context.

Map keys travel in the clear inside a ciphertext container, so without this binding an attacker holding a stored ciphertext could swap or rename keys undetected and silently reassign values to different fields. Every map cipher and map PRF derives each entry’s context through this method, on both the writing and the reading side.

The encoding is PAE(domain, self, key). The leading domain keeps the result apart from a caller binding the tuple (context, key) as a context of its own, which is a two-piece list of typed leaves and so can never equal a three-piece labelled frame.

Source

pub fn for_leaf(&self, version: u8) -> Context<'static>

The context every sealed leaf is finally authenticated under, binding the wire-format version byte that prefixes the stored leaf.

This is the outermost derivation. A cipher applies it at the AEAD seal and open boundary, after every structural derivation (for_map_entry, for_sequence_element, the markers) has produced the caller-visible context. Binding the version under the tag is what makes it more than a parse hint: a stored leaf relabelled with a different version byte fails verification instead of selecting a different, perhaps weaker, set of parsing rules.

The domain label carries no /v1 suffix on purpose. The version is a parameter here, not part of the label.

Source

pub fn for_sequence_element(&self) -> Context<'static>

The context a sequence element is sealed or derived under.

Without this derivation a sequence element would share the caller’s bare context with a top-level single value, byte for byte, so an attacker holding a stored ciphertext could rewrap a single leaf as a one-element sequence and a self-describing decrypt path would verify it. Sealing elements under a labelled derivation means a leaf verifies only in the position it was sealed for.

The element index is deliberately not bound. Records are retrieved in a different order than they were inserted, so element order is a caller obligation, not an authenticated fact.

Source

pub fn for_empty_sequence(&self) -> Context<'static>

Marker context for an empty sequence. See for_none for the marker rule.

Source

pub fn for_empty_map(&self) -> Context<'static>

Marker context for an empty map. See for_none for the marker rule.

Source

pub fn for_none(&self) -> Context<'static>

Marker context for an authenticated absent value, Option::None.

A marker is a sealed empty plaintext whose tag is the only thing authenticating a structural fact. Each marker kind is derived under its own labelled context, PAE(domain, self, kind), so a single leaf sealed under the bare context can never be re-tagged as an absence marker (silent authenticated deletion), an absence marker can never validate as an encrypted empty byte string, and no marker can be replayed as a different structural claim.

Source

pub fn for_option_some(&self) -> Context<'static>

The context an optional value’s Some is derived under.

This is the value side of Option, distinct from the context side. Some(x) as a context is the one-element list PAE([x]), untagged, so that a runtime list of one part is the same context as the static Some. A Some value being derived under a context c uses PAE(domain, c) instead, keeping the derivation of an optional value apart from the derivation of its inner value under the same c.

Trait Implementations§

Source§

impl<'a> Clone for Context<'a>

Source§

fn clone(&self) -> Context<'a>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Debug for Context<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Default for Context<'a>

Source§

fn default() -> Context<'a>

Returns the “default value” for a type. Read more
Source§

impl<'a> Eq for Context<'a>

Source§

impl<'a> Hash for Context<'a>

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<'a> IntoContext<'a> for Context<'a>

An encoded context is a context. As a part of a larger context it is the Encoded leaf, written verbatim and untagged, so re-encoding a context leaves its bytes unchanged.

Source§

fn into_context(self) -> ContextPiece<'a>

Describe self as a tree of parts.
Source§

impl<'a> PartialEq for Context<'a>

Source§

fn eq(&self, other: &Context<'a>) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<'a> StructuralPartialEq for Context<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for Context<'a>

§

impl<'a> RefUnwindSafe for Context<'a>

§

impl<'a> Send for Context<'a>

§

impl<'a> Sync for Context<'a>

§

impl<'a> Unpin for Context<'a>

§

impl<'a> UnsafeUnpin for Context<'a>

§

impl<'a> UnwindSafe for Context<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.