solid_pod_rs_didkey/
verifier.rs1use async_trait::async_trait;
8use solid_pod_rs::auth::self_signed::{
9 ProofEnvelope, SelfSignedError, SelfSignedVerifier, VerifiedSubject,
10};
11
12use crate::jwt::verify_self_signed_jwt;
13
14pub const DEFAULT_SKEW_SECONDS: u64 = 60;
16
17#[derive(Debug, Clone)]
19pub struct DidKeyVerifier {
20 skew: u64,
21}
22
23impl DidKeyVerifier {
24 pub fn new() -> Self {
26 Self {
27 skew: DEFAULT_SKEW_SECONDS,
28 }
29 }
30
31 #[must_use]
33 pub fn with_skew(mut self, skew_seconds: u64) -> Self {
34 self.skew = skew_seconds;
35 self
36 }
37}
38
39impl Default for DidKeyVerifier {
40 fn default() -> Self {
41 Self::new()
42 }
43}
44
45fn looks_like_compact_jws(s: &str) -> bool {
51 let dots = s.bytes().filter(|b| *b == b'.').count();
52 dots == 2
53 && s.bytes().all(|b| {
54 b.is_ascii_alphanumeric() || matches!(b, b'-' | b'_' | b'.' | b'=')
55 })
56}
57
58#[async_trait]
59impl SelfSignedVerifier for DidKeyVerifier {
60 async fn verify(
61 &self,
62 envelope: &ProofEnvelope<'_>,
63 ) -> Result<Option<VerifiedSubject>, SelfSignedError> {
64 if !looks_like_compact_jws(envelope.proof) {
65 return Ok(None);
66 }
67 match verify_self_signed_jwt(
68 envelope.proof,
69 envelope.uri,
70 envelope.method,
71 envelope.now_unix,
72 self.skew,
73 ) {
74 Ok(verified) => Ok(Some(VerifiedSubject {
75 did: verified.did,
76 verification_method: verified.verification_method,
77 })),
78 Err(crate::error::DidKeyError::MalformedJwt(m)) => {
79 Err(SelfSignedError::Malformed(m))
80 }
81 Err(crate::error::DidKeyError::InvalidHeader(m))
82 | Err(crate::error::DidKeyError::NotDidKey(m)) => {
83 let _ = m;
89 Ok(None)
90 }
91 Err(crate::error::DidKeyError::InvalidClaims(m)) => {
92 Err(SelfSignedError::ScopeMismatch(m))
93 }
94 Err(crate::error::DidKeyError::BadSignature(m)) => {
95 Err(SelfSignedError::InvalidSignature(m))
96 }
97 Err(e) => Err(SelfSignedError::Other(e.to_string())),
98 }
99 }
100
101 fn name(&self) -> &'static str {
102 "did:key"
103 }
104}