pub struct RegistryVerifierResolver { /* private fields */ }Expand description
A set of verification keys that can be registered and revoked while the
server runs: the resolver for devices or peers that enrol after start-up
(the immutable StaticVerifierResolver
is fixed at construction). Holds every key type the verifier accepts:
Ed25519, ESP256 and the two HMAC algorithms.
Share it as an Arc: hand a clone to the envelope (an Arc<dyn CoseVerifierResolver>) and keep one for register and
revoke.
use std::sync::Arc;
use cratestack_cose::{
CoseAlg, CoseVerifierResolver, Ed25519Signer, RegistryVerifierResolver,
};
let registry = Arc::new(RegistryVerifierResolver::new());
let for_envelope: Arc<dyn CoseVerifierResolver> = registry.clone();
let key = Ed25519Signer::from_seed(&[7; 32]).verify_key();
assert!(for_envelope.resolve(&key.kid(), CoseAlg::Ed25519).await?.is_empty());
let kid = registry.register(key.clone())?; // a device enrols
assert_eq!(kid, key.kid());
assert_eq!(for_envelope.resolve(&kid, CoseAlg::Ed25519).await?, vec![key]);
assert_eq!(registry.revoke(&kid), 1); // and is cut off
assert!(for_envelope.resolve(&kid, CoseAlg::Ed25519).await?.is_empty());The kid is the first 8 bytes of the key’s RFC 9679 thumbprint,
computed from the key (so it cannot be filed under another). Keys with
the same kid (an 8-byte collision, or one HMAC secret registered for
both HMAC algorithms) are all kept, and all returned for it.
Concurrency. Every call takes one short lock and none is held across
an .await. A register or revoke is atomic: a concurrent
resolve sees the registry wholly
before it or wholly after. A request whose resolve already returned the
key still finishes verifying with it, so a revocation takes effect for
requests that resolve after it returns, not for ones already in flight.
A register that returned is visible to every later resolve.
Unknown kids resolve to Ok(vec![]), never Err, as the trait
requires. State is per process: replicas each need the same
registrations.
Implementations§
Source§impl RegistryVerifierResolver
impl RegistryVerifierResolver
Sourcepub fn new() -> RegistryVerifierResolver
pub fn new() -> RegistryVerifierResolver
An empty registry with no bound on its size.
Sourcepub fn with_max_keys(max_keys: usize) -> RegistryVerifierResolver
pub fn with_max_keys(max_keys: usize) -> RegistryVerifierResolver
An empty registry holding at most max_keys keys. A server that
registers keys on behalf of callers uses this to bound memory.
use cratestack_cose::{Ed25519Signer, RegistryVerifierResolver};
let registry = RegistryVerifierResolver::with_max_keys(1);
registry.register(Ed25519Signer::from_seed(&[1; 32]).verify_key())?;
assert!(registry
.register(Ed25519Signer::from_seed(&[2; 32]).verify_key())
.is_err());Sourcepub fn register(&self, key: CoseVerifyKey) -> Result<[u8; 8], CratestackError>
pub fn register(&self, key: CoseVerifyKey) -> Result<[u8; 8], CratestackError>
Register key and return its kid. Registering a key that is
already present changes nothing and succeeds, even when the registry
is full. Fails with CratestackError::Conflict when a new key would
exceed the bound; the registry is then unchanged.
Sourcepub fn revoke(&self, kid: &[u8]) -> usize
pub fn revoke(&self, kid: &[u8]) -> usize
Remove every key filed under kid and return how many there were
(0 for an unknown or malformed kid: revoking twice is harmless).
One HMAC secret registered for both algorithms goes with it, and so
does any other key whose 8-byte kid collides (an unrelated
device). To revoke one device, use revoke_key.
Sourcepub fn revoke_key(&self, key: &CoseVerifyKey) -> bool
pub fn revoke_key(&self, key: &CoseVerifyKey) -> bool
Remove exactly key and nothing else that shares its kid. true
if it was registered.
Trait Implementations§
Source§impl CoseVerifierResolver for RegistryVerifierResolver
impl CoseVerifierResolver for RegistryVerifierResolver
Source§fn resolve<'life0, 'life1, 'async_trait>(
&'life0 self,
kid: &'life1 [u8],
alg: CoseAlg,
) -> Pin<Box<dyn Future<Output = Result<Vec<CoseVerifyKey>, CratestackError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
RegistryVerifierResolver: 'async_trait,
fn resolve<'life0, 'life1, 'async_trait>(
&'life0 self,
kid: &'life1 [u8],
alg: CoseAlg,
) -> Pin<Box<dyn Future<Output = Result<Vec<CoseVerifyKey>, CratestackError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
RegistryVerifierResolver: 'async_trait,
kid is kid and which verifies alg; Ok(vec![])
if there is none. Err only for a backend failure.Source§impl Debug for RegistryVerifierResolver
impl Debug for RegistryVerifierResolver
Source§impl Default for RegistryVerifierResolver
impl Default for RegistryVerifierResolver
Source§fn default() -> RegistryVerifierResolver
fn default() -> RegistryVerifierResolver
Auto Trait Implementations§
impl !Freeze for RegistryVerifierResolver
impl RefUnwindSafe for RegistryVerifierResolver
impl Send for RegistryVerifierResolver
impl Sync for RegistryVerifierResolver
impl Unpin for RegistryVerifierResolver
impl UnsafeUnpin for RegistryVerifierResolver
impl UnwindSafe for RegistryVerifierResolver
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§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 more§impl<'src, T> IntoMaybe<'src, T> for Twhere
T: 'src,
impl<'src, T> IntoMaybe<'src, T> for Twhere
T: 'src,
impl<T> MaybeSend for T
impl<T> MaybeSendSync for T
§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
§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();§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
§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();§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
§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();§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
§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();§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.
§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);