use crate::{
crypto::{
KeyMatchStrength,
verifier::{JwsVerifier, KeyMatch, VerifyError},
},
platform::MaybeSendSync,
};
#[derive(Debug, Clone)]
pub struct RetryingVerifier<V> {
inner: V,
}
impl<V: JwsVerifier + std::fmt::Debug + MaybeSendSync> RetryingVerifier<V> {
pub fn new(inner: V) -> Self {
Self { inner }
}
}
impl<V: JwsVerifier + std::fmt::Debug + MaybeSendSync> JwsVerifier for RetryingVerifier<V> {
type Error = V::Error;
fn key_match(&self, key_match: &KeyMatch<'_>) -> Option<KeyMatchStrength> {
self.inner.key_match(key_match)
}
async fn verify(
&self,
input: &[u8],
signature: &[u8],
key_match: &KeyMatch<'_>,
) -> Result<(), VerifyError<Self::Error>> {
match self.inner.verify(input, signature, key_match).await {
Err(VerifyError::NoMatchingKey) => {
if self.inner.try_refresh().await {
self.inner.verify(input, signature, key_match).await
} else {
Err(VerifyError::NoMatchingKey)
}
}
other => other,
}
}
async fn try_refresh(&self) -> bool {
self.inner.try_refresh().await
}
}