pub struct ExternalSigner { /* private fields */ }Expand description
A signer that hands the bytes to a callback: a key in the Android Keystore or the iOS Secure Enclave, a KMS, a hardware token.
The key is never exported; the callback is asked to sign the complete
Sig_structure and nothing else. On wasm32 neither the callback nor its
future needs to be Send (see CoseSigner).
An Ed25519 key behind a callback, with the platform’s own primitive
standing in for the key store (here, Ed25519Signer):
use cratestack_cose::{CoseAlg, CoseSigner, Ed25519Signer, ExternalSigner};
let key = Ed25519Signer::from_seed(&[7; 32]);
let public = key.verify_key().ed25519_bytes().unwrap();
let signer = ExternalSigner::ed25519(&public, move |tbs| {
let key = key.clone();
async move { key.sign(&tbs).await }
})
.unwrap();
assert_eq!(signer.alg(), CoseAlg::Ed25519);
assert_eq!(signer.kid().len(), 8);A P-256 key:
use cratestack_cose::{CoseAlg, CoseSigner, ExternalSigner, P256Signer};
// A stand-in for a platform keystore.
let key = P256Signer::from_scalar(&[7; 32]).unwrap();
let public = key.verify_key().p256_sec1_uncompressed().unwrap();
let signer = ExternalSigner::esp256(&public, move |tbs| {
let key = key.clone();
async move { key.sign(&tbs).await }
})
.unwrap();
assert_eq!(signer.alg(), CoseAlg::Esp256);
assert_eq!(signer.kid().len(), 8);Implementations§
Source§impl ExternalSigner
impl ExternalSigner
Sourcepub fn esp256<F, Fut>(
public_key_sec1: &[u8],
sign: F,
) -> Result<ExternalSigner, CratestackError>where
F: Fn(Vec<u8>) -> Fut + MaybeSendSync + 'static,
Fut: Future<Output = Result<Vec<u8>, CratestackError>> + MaybeSend + 'static,
pub fn esp256<F, Fut>(
public_key_sec1: &[u8],
sign: F,
) -> Result<ExternalSigner, CratestackError>where
F: Fn(Vec<u8>) -> Fut + MaybeSendSync + 'static,
Fut: Future<Output = Result<Vec<u8>, CratestackError>> + MaybeSend + 'static,
An ESP256 (-9) signer for the P-256 key whose public half is
public_key_sec1 (compressed or uncompressed SEC1). The kid is the
key’s RFC 9679 thumbprint prefix, computed here so the caller cannot
get it wrong.
sign receives the full to-be-signed bytes and must sign them with
ECDSA over SHA-256 (SHA256withECDSA on Android, ecdsaSignatureMessageX962SHA256
on iOS: both hash for you, so pass the bytes as given, never a
digest). It may return the signature DER encoded, which is what both
platform keystores produce, or as the raw 64-byte r ‖ s. A DER
signature is converted; the envelope then normalises to low-s. A
signature that does not verify under public_key_sec1 is refused
here, on every call, instead of failing at the peer as the coarse 401.
Fails with CratestackError::Validation if public_key_sec1 is not a
point on the curve.
Sourcepub fn ed25519<F, Fut>(
public_key: &[u8; 32],
sign: F,
) -> Result<ExternalSigner, CratestackError>where
F: Fn(Vec<u8>) -> Fut + MaybeSendSync + 'static,
Fut: Future<Output = Result<Vec<u8>, CratestackError>> + MaybeSend + 'static,
pub fn ed25519<F, Fut>(
public_key: &[u8; 32],
sign: F,
) -> Result<ExternalSigner, CratestackError>where
F: Fn(Vec<u8>) -> Fut + MaybeSendSync + 'static,
Fut: Future<Output = Result<Vec<u8>, CratestackError>> + MaybeSend + 'static,
An Ed25519 (-19) signer for the key whose public half is
public_key. The kid is the key’s RFC 9679 thumbprint prefix,
computed here so the caller cannot get it wrong.
sign receives the full to-be-signed bytes and must return the
64-byte Ed25519 signature over exactly those bytes (pure Ed25519, as
RFC 8032 defines it, never a pre-hash of them), which is what a Node
crypto.sign(null, tbs, key) or a KMS ED25519 key produces. Any
other length is refused as the signer’s failure, and so is a
signature that does not verify under public_key, which is checked
here on every call instead of failing at the peer as the coarse 401.
Fails with CratestackError::Validation if public_key is not a
point encoding.
Trait Implementations§
Source§impl Clone for ExternalSigner
impl Clone for ExternalSigner
Source§fn clone(&self) -> ExternalSigner
fn clone(&self) -> ExternalSigner
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl CoseSigner for ExternalSigner
impl CoseSigner for ExternalSigner
Source§fn sign<'life0, 'life1, 'async_trait>(
&'life0 self,
to_be_signed: &'life1 [u8],
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, CratestackError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
ExternalSigner: 'async_trait,
fn sign<'life0, 'life1, 'async_trait>(
&'life0 self,
to_be_signed: &'life1 [u8],
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, CratestackError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
ExternalSigner: 'async_trait,
to_be_signed. For HMAC 256/64 this returns the
truncated 8-byte tag. An error is a backend failure (a 500).Auto Trait Implementations§
impl !RefUnwindSafe for ExternalSigner
impl !UnwindSafe for ExternalSigner
impl Freeze for ExternalSigner
impl Send for ExternalSigner
impl Sync for ExternalSigner
impl Unpin for ExternalSigner
impl UnsafeUnpin for ExternalSigner
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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> OrderedSeq<'_, T> for Twhere
T: Clone,
§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);§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
§impl<'p, T> Seq<'p, T> for Twhere
T: Clone,
impl<'p, T> Seq<'p, T> for Twhere
T: Clone,
§type Iter<'a> = Once<&'a T>
where
T: 'a
type Iter<'a> = Once<&'a T> where T: 'a
§fn contains(&self, val: &T) -> boolwhere
T: PartialEq,
fn contains(&self, val: &T) -> boolwhere
T: PartialEq,
§fn to_maybe_ref<'b>(item: <T as Seq<'p, T>>::Item<'b>) -> Maybe<T, &'p T>where
'p: 'b,
fn to_maybe_ref<'b>(item: <T as Seq<'p, T>>::Item<'b>) -> Maybe<T, &'p T>where
'p: 'b,
MaybeRef].