1use core::fmt;
5use std::sync::{Arc, PoisonError, RwLock};
6
7use super::{Identifier, Identity, IdentityError, IdentityKind};
8use crate::did::{DidMethod, DidUrl};
9use crate::jose::{Jwk, JwsAlgorithm, KeyType, SignError, Signer};
10use crate::keys::{KeyId, KeySigner, KeySpec, KeyStore, KeyStoreError};
11use crate::resolver::DidProducer;
12
13pub struct KeyStoreIdentity {
60 store: Arc<dyn KeyStore>,
61 producers: Vec<Arc<dyn DidProducer<Params = ()>>>,
62 generate_missing: bool,
63 bindings: RwLock<Vec<Binding>>,
64}
65
66#[derive(Clone)]
68struct Binding {
69 kind: IdentityKind,
70 signer: KeySigner<Arc<dyn KeyStore>>,
71 identifier: Identifier,
72 kid: Option<String>,
73}
74
75impl KeyStoreIdentity {
76 pub fn new(store: Arc<dyn KeyStore>) -> Self {
78 Self {
79 store,
80 producers: Vec::new(),
81 generate_missing: false,
82 bindings: RwLock::new(Vec::new()),
83 }
84 }
85
86 #[must_use]
93 pub fn with_producer(mut self, producer: impl DidProducer<Params = ()> + 'static) -> Self {
94 self.producers
95 .retain(|registered| registered.method() != producer.method());
96 self.producers.push(Arc::new(producer));
97 self
98 }
99
100 #[must_use]
104 pub fn generate_missing(mut self, enabled: bool) -> Self {
105 self.generate_missing = enabled;
106 self
107 }
108
109 pub async fn bind(
121 &self,
122 kind: IdentityKind,
123 alg: JwsAlgorithm,
124 key: KeyId,
125 ) -> Result<Identifier, IdentityError> {
126 let binding = self.derive(kind, alg, key).await?;
127 let identifier = binding.identifier.clone();
128 self.insert(binding, true);
129 Ok(identifier)
130 }
131
132 pub async fn bind_did_url(
145 &self,
146 kind: IdentityKind,
147 alg: JwsAlgorithm,
148 key: KeyId,
149 url: DidUrl,
150 ) -> Result<Identifier, IdentityError> {
151 match &kind {
152 IdentityKind::Did(method) if method.matches(url.did()) => {}
153 _ => return Err(IdentityError::UnsupportedKind(kind)),
154 }
155 let signer = self.signer_for(alg, key).await?;
156 let identifier = Identifier::Did(url.did().clone());
157 self.insert(
158 Binding {
159 kind,
160 signer,
161 identifier: identifier.clone(),
162 kid: Some(url.to_string()),
163 },
164 true,
165 );
166 Ok(identifier)
167 }
168
169 pub fn bindings(&self) -> Vec<(IdentityKind, JwsAlgorithm, KeyId)> {
172 self.read()
173 .iter()
174 .map(|binding| {
175 (
176 binding.kind.clone(),
177 binding.signer.alg(),
178 binding.signer.key_id().clone(),
179 )
180 })
181 .collect()
182 }
183
184 async fn signer_for(
187 &self,
188 alg: JwsAlgorithm,
189 key: KeyId,
190 ) -> Result<KeySigner<Arc<dyn KeyStore>>, IdentityError> {
191 KeySigner::new(Arc::clone(&self.store), key, alg)
192 .await
193 .map_err(|error| match error {
194 KeyStoreError::UnsupportedAlgorithm(alg) => {
195 IdentityError::UnsupportedAlgorithm(alg)
196 }
197 error => IdentityError::KeyStore(error),
198 })
199 }
200
201 async fn derive(
203 &self,
204 kind: IdentityKind,
205 alg: JwsAlgorithm,
206 key: KeyId,
207 ) -> Result<Binding, IdentityError> {
208 let producer = match &kind {
209 IdentityKind::Did(method) => Some(
210 self.producer(method)
211 .ok_or_else(|| IdentityError::UnsupportedKind(kind.clone()))?,
212 ),
213 IdentityKind::JwkThumbprint => None,
214 };
215 let signer = self.signer_for(alg, key).await?;
216 let public = signer.public_jwk().public();
217 let (identifier, kid) = match (&kind, producer) {
218 (IdentityKind::Did(method), Some(producer)) => {
219 let document = producer.produce(&[public], ()).await?;
220 if !method.matches(&document.id) {
221 return Err(IdentityError::UnsupportedKind(kind));
222 }
223 let kid = document
224 .methods(None)
225 .next()
226 .map(|method| method.id.to_string())
227 .ok_or_else(|| IdentityError::NoVerificationMethod(document.id.clone()))?;
228 (Identifier::Did(document.id), Some(kid))
229 }
230 _ => (Identifier::JwkThumbprint(public.thumbprint_sha256()?), None),
231 };
232 Ok(Binding {
233 kind,
234 signer,
235 identifier,
236 kid,
237 })
238 }
239
240 fn producer(&self, method: &DidMethod) -> Option<&Arc<dyn DidProducer<Params = ()>>> {
242 self.producers
243 .iter()
244 .find(|producer| producer.method() == method.name())
245 }
246
247 async fn binding(
249 &self,
250 kind: &IdentityKind,
251 alg: JwsAlgorithm,
252 ) -> Result<Binding, IdentityError> {
253 if let Some(binding) = self.find(kind, alg) {
254 return Ok(binding);
255 }
256 if !self.generate_missing {
257 return Err(if self.read().iter().any(|binding| binding.kind == *kind) {
258 IdentityError::UnsupportedAlgorithm(alg)
259 } else {
260 IdentityError::UnsupportedKind(kind.clone())
261 });
262 }
263 if let IdentityKind::Did(method) = kind
264 && self.producer(method).is_none()
265 {
266 return Err(IdentityError::UnsupportedKind(kind.clone()));
267 }
268 let capabilities = self.store.capabilities();
269 let Some(key_type) = key_type_for(alg).filter(|_| capabilities.supports(alg)) else {
270 return Err(IdentityError::UnsupportedAlgorithm(alg));
271 };
272 if !capabilities.can_generate {
273 return Err(KeyStoreError::Unsupported("generate").into());
274 }
275 let key = self.store.generate(KeySpec::new(key_type, alg)).await?;
276 let binding = match self.derive(kind.clone(), alg, key.clone()).await {
277 Ok(binding) => binding,
278 Err(error) => {
279 self.discard(&key).await;
280 return Err(error);
281 }
282 };
283 let kept = self.insert(binding, false);
284 if kept.signer.key_id() != &key {
286 self.discard(&key).await;
287 }
288 Ok(kept)
289 }
290
291 async fn discard(&self, key: &KeyId) {
293 if self.store.capabilities().can_delete {
294 let _ = self.store.delete(key).await;
296 }
297 }
298
299 fn find(&self, kind: &IdentityKind, alg: JwsAlgorithm) -> Option<Binding> {
300 self.read()
301 .iter()
302 .find(|binding| binding.kind == *kind && binding.signer.alg() == alg)
303 .cloned()
304 }
305
306 fn insert(&self, binding: Binding, replace: bool) -> Binding {
309 let mut bindings = self
310 .bindings
311 .write()
312 .unwrap_or_else(PoisonError::into_inner);
313 let existing = bindings
314 .iter_mut()
315 .find(|bound| bound.kind == binding.kind && bound.signer.alg() == binding.signer.alg());
316 match existing {
317 Some(bound) if replace => {
318 *bound = binding.clone();
319 binding
320 }
321 Some(bound) => bound.clone(),
322 None => {
323 bindings.push(binding.clone());
324 binding
325 }
326 }
327 }
328
329 fn read(&self) -> std::sync::RwLockReadGuard<'_, Vec<Binding>> {
330 self.bindings.read().unwrap_or_else(PoisonError::into_inner)
331 }
332}
333
334fn key_type_for(alg: JwsAlgorithm) -> Option<KeyType> {
337 match alg {
338 JwsAlgorithm::EdDSA => Some(KeyType::Ed25519),
339 JwsAlgorithm::ES256 => Some(KeyType::P256),
340 JwsAlgorithm::ES256K => Some(KeyType::Secp256k1),
341 JwsAlgorithm::RS256 | JwsAlgorithm::PS256 => Some(KeyType::Rsa2048),
342 JwsAlgorithm::ES384 => None,
343 }
344}
345
346impl fmt::Debug for KeyStoreIdentity {
347 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
348 let producers: Vec<&str> = self
349 .producers
350 .iter()
351 .map(|producer| producer.method())
352 .collect();
353 f.debug_struct("KeyStoreIdentity")
354 .field("producers", &producers)
355 .field("generate_missing", &self.generate_missing)
356 .field("bindings", &self.bindings())
357 .finish_non_exhaustive()
358 }
359}
360
361#[async_trait::async_trait]
362impl Identity for KeyStoreIdentity {
363 fn capabilities(&self) -> Vec<(IdentityKind, JwsAlgorithm)> {
368 let mut pairs: Vec<(IdentityKind, JwsAlgorithm)> = self
369 .read()
370 .iter()
371 .map(|binding| (binding.kind.clone(), binding.signer.alg()))
372 .collect();
373 let capabilities = self.store.capabilities();
374 if self.generate_missing && capabilities.can_generate {
375 let kinds = self
376 .producers
377 .iter()
378 .filter_map(|producer| DidMethod::new(producer.method()).ok())
379 .map(IdentityKind::Did)
380 .chain([IdentityKind::JwkThumbprint]);
381 for kind in kinds {
382 for &alg in &capabilities.algorithms {
383 if key_type_for(alg).is_some() && !pairs.contains(&(kind.clone(), alg)) {
384 pairs.push((kind.clone(), alg));
385 }
386 }
387 }
388 }
389 pairs
390 }
391
392 async fn identifier(
393 &self,
394 kind: &IdentityKind,
395 alg: JwsAlgorithm,
396 ) -> Result<Identifier, IdentityError> {
397 Ok(self.binding(kind, alg).await?.identifier)
398 }
399
400 async fn public_jwk(
401 &self,
402 kind: &IdentityKind,
403 alg: JwsAlgorithm,
404 ) -> Result<Jwk, IdentityError> {
405 Ok(self.binding(kind, alg).await?.signer.public_jwk().public())
406 }
407
408 async fn signer(
409 &self,
410 kind: &IdentityKind,
411 alg: JwsAlgorithm,
412 ) -> Result<Box<dyn Signer + '_>, IdentityError> {
413 let binding = self.binding(kind, alg).await?;
414 Ok(Box::new(BoundSigner {
415 signer: binding.signer,
416 kid: binding.kid,
417 }))
418 }
419}
420
421struct BoundSigner {
424 signer: KeySigner<Arc<dyn KeyStore>>,
425 kid: Option<String>,
426}
427
428#[async_trait::async_trait]
429impl Signer for BoundSigner {
430 fn alg(&self) -> JwsAlgorithm {
431 self.signer.alg()
432 }
433
434 fn kid(&self) -> Option<&str> {
435 self.kid.as_deref()
436 }
437
438 async fn sign(&self, signing_input: &[u8]) -> Result<Vec<u8>, SignError> {
439 self.signer.sign(signing_input).await
440 }
441}