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: StringUnique identifier for this key package.
user_id: StringUser ID this key package belongs to.
key_package_data: Vec<u8>Serialized MLS KeyPackage bytes.
created_at_ms: u64Timestamp when the key package was created (milliseconds since epoch).
expires_at_ms: u64Timestamp when the key package expires (milliseconds since epoch).
synced: boolWhether 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: boolWhether 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
impl KeyPackageBundle
Sourcepub fn new(
package_id: String,
user_id: String,
key_package_data: Vec<u8>,
lifetime_secs: u64,
) -> KeyPackageBundle
pub fn new( package_id: String, user_id: String, key_package_data: Vec<u8>, lifetime_secs: u64, ) -> KeyPackageBundle
Creates a new key package bundle.
Sourcepub fn withheld_from_hand_out(&self) -> bool
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.
Sourcepub fn is_expired(&self) -> bool
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.
Sourcepub fn expired_past_grace(&self, grace_secs: u64) -> bool
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.
Sourcepub fn remaining_lifetime_ms(&self) -> u64
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.
Sourcepub fn from_transfer(
package_id: String,
user_id: String,
key_package_data: Vec<u8>,
remaining_lifetime_ms: u64,
) -> KeyPackageBundle
pub fn from_transfer( package_id: String, user_id: String, key_package_data: Vec<u8>, remaining_lifetime_ms: u64, ) -> KeyPackageBundle
Creates a bundle from received transfer data, computing local expiry from the sender-provided remaining lifetime.
Trait Implementations§
Source§impl Clone for KeyPackageBundle
impl Clone for KeyPackageBundle
Source§fn clone(&self) -> KeyPackageBundle
fn clone(&self) -> KeyPackageBundle
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for KeyPackageBundle
impl Debug for KeyPackageBundle
Source§impl<'de> Deserialize<'de> for KeyPackageBundle
impl<'de> Deserialize<'de> for KeyPackageBundle
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<KeyPackageBundle, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<KeyPackageBundle, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
Source§impl Serialize for KeyPackageBundle
impl Serialize for KeyPackageBundle
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
Auto Trait Implementations§
impl Freeze for KeyPackageBundle
impl RefUnwindSafe for KeyPackageBundle
impl Send for KeyPackageBundle
impl Sync for KeyPackageBundle
impl Unpin for KeyPackageBundle
impl UnsafeUnpin for KeyPackageBundle
impl UnwindSafe for KeyPackageBundle
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Declassify for T
impl<T> Declassify for T
type Declassified = T
fn declassify(self) -> T
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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 moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);