Skip to main content

KeyPackageBundle

Struct KeyPackageBundle 

Source
pub struct KeyPackageBundle {
    pub package_id: String,
    pub user_id: String,
    pub key_package_data: Vec<u8>,
    pub created_at_ms: u64,
    pub expires_at_ms: u64,
    pub synced: bool,
    pub reserved_for_publication: bool,
    pub assigned_peer: Option<String>,
    pub provider_hash_ref: Option<Vec<u8>>,
}
Expand description

A bundle containing a key package and metadata for distribution.

Fields§

§package_id: String

Unique identifier for this key package.

§user_id: String

User ID this key package belongs to.

§key_package_data: Vec<u8>

Serialized MLS KeyPackage bytes.

§created_at_ms: u64

Timestamp when the key package was created (milliseconds since epoch).

§expires_at_ms: u64

Timestamp when the key package expires (milliseconds since epoch).

§synced: bool

Whether the application has published this package itself, through MlsManager::mark_key_package_synced.

A synced package stands in a record somebody else holds, so a stranger may still build a Welcome against it. Two things follow, and both are the single-use rule Self::reserved_for_publication already applies: the package is withheld from both entry points that hand packages out, or a pushed-to peer and whoever fetched the uploaded copy would race for one init key; and the record is kept, because the record is the only thing that carries expiry. Deleting it instead, which is what marking used to do, left the private init key in the provider with no path to destruction at all (issue 367).

§reserved_for_publication: bool

Whether this package is reserved for a publication slot.

An MLS key package’s init key is consumed by the first peer who uses it, so a package standing in a published record must not also be handed to a peer over the push path: the second user of it builds a Welcome that can never be processed. Reserved packages are therefore invisible to both entry points that hand packages out — MlsManager::take_push_key_package (the push path) and MlsManager::get_or_create_key_package (the peer-less one).

Additive and defaulted, so packages written before this field existed deserialize as unreserved — which is what they are.

§assigned_peer: Option<String>

The peer this package has been handed to over the push path, if any.

This is what keeps the push path from advertising one init key to everybody: a package is claimed by the first peer it is pushed to and afterwards only ever re-handed to that peer, so a repeat push costs no new key material while two peers never share one. RFC 9420 §16.8 asks for a key package to be rotated as soon as possible after use; the rotation trigger is consumption, which MlsManager::key_package_by_id already reports, and a consumed package’s successor is minted on the next push to that peer.

None means unclaimed — either minted outside the push path (the peer-less FFI entry point) or written before this field existed. Those are claimable, so upgrading does not strand the package already in storage.

Local bookkeeping only: never serialized onto the wire, and never part of the FFI record.

§provider_hash_ref: Option<Vec<u8>>

The TLS-serialized OpenMLS hash reference this package’s private init key is stored under in the provider, stamped at mint time.

A cache: deriving the reference from key_package_data costs a TLS parse plus a signature validation, and the push path’s pool scan checks every stored package’s usability on every push — without this it pays that per package per push. Records written before the field existed deserialize as None and are backfilled on their first load.

Local bookkeeping only, like Self::assigned_peer: never on the wire, never in the FFI record.

Implementations§

Source§

impl KeyPackageBundle

Source

pub fn new( package_id: String, user_id: String, key_package_data: Vec<u8>, lifetime_secs: u64, ) -> Self

Creates a new key package bundle.

Source

pub fn withheld_from_hand_out(&self) -> bool

Whether this package stands in a record somebody else holds, and so must never be handed out by this device.

One predicate rather than two checks at each hand-out site, so the push path and the peer-less getter cannot come to disagree about which packages are spoken for.

Source

pub fn is_expired(&self) -> bool

Checks if the key package has expired (local device’s own packages only).

This compares against the local clock and is valid because created_at_ms and expires_at_ms were set on this same device.

Source

pub fn expired_past_grace(&self, grace_secs: u64) -> bool

Whether the package expired more than grace_secs ago.

Expiry and the destruction of the private init key are deliberately two different moments. An expired package is no longer advertised, but a peer holding a copy handed out just before expiry may still Welcome us — and that Welcome is only processable while the init key is in provider storage. The grace window is how long that stays true; past it the key material is destroyed rather than left resident for the life of the install.

Source

pub fn remaining_lifetime_ms(&self) -> u64

Returns the remaining valid lifetime in milliseconds.

Used when transmitting key packages to peers: the receiver applies this duration relative to their own clock, eliminating cross-device clock skew from expiry calculations.

Source

pub fn from_transfer( package_id: String, user_id: String, key_package_data: Vec<u8>, remaining_lifetime_ms: u64, ) -> Self

Creates a bundle from received transfer data, computing local expiry from the sender-provided remaining lifetime.

Trait Implementations§

Source§

impl Clone for KeyPackageBundle

Source§

fn clone(&self) -> Self

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 Debug for KeyPackageBundle

Source§

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

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

impl<'de> Deserialize<'de> for KeyPackageBundle

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for KeyPackageBundle

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

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> Classify for T

Source§

type Classified = T

Source§

fn classify(self) -> T

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> Declassify for T

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more