From fb6709979b355c21e37dd7508794084407ba5061 Mon Sep 17 00:00:00 2001 From: "Charles E. Lehner" Date: Fri, 19 Mar 2021 15:13:03 -0400 Subject: [PATCH] Add Source::KeyAndPattern and DIDMethods::generate Allow passing an additional string to a DID method in the generate function. Implement generate on DIDMethods to allow generating a DID from a set of DID methods given a DID method name and optional additional string, separated by a colon (':'). The additional string may be a prefix or pattern for the DID's method-specific ID, according to the DID method. --- CHANGELOG.md | 2 ++ did-ethr/src/lib.rs | 7 +++++++ did-key/src/lib.rs | 7 +++++++ did-sol/src/lib.rs | 7 +++++++ did-tezos/src/lib.rs | 7 +++++++ src/did.rs | 27 +++++++++++++++++++++++++++ 6 files changed, 57 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d61965f5b..588305065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support HTTP(S) requests in WASM and on Android. - Support relative DID URLs in DID documents. - Support [publicKeyBase58][] for Ed25519. +- Added `DIDMethods::generate` function. ### Changed - Make `ResolutionResult` struct public. @@ -55,6 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add name to `Error::ResourceNotFound`. - Make `jws::sign_bytes` return bytes instead of string. - Allow multiple proofs and multiple verification methods in a DID document +- Added `Source::KeyAndPattern` enum variant. ### Fixed - Fix `tz1` hashing. diff --git a/did-ethr/src/lib.rs b/did-ethr/src/lib.rs index 38cc87950..f258f8179 100644 --- a/did-ethr/src/lib.rs +++ b/did-ethr/src/lib.rs @@ -138,6 +138,13 @@ impl DIDMethod for DIDEthr { fn generate(&self, source: &Source) -> Option { let jwk = match source { Source::Key(jwk) => jwk, + Source::KeyAndPattern(jwk, pattern) => { + if !pattern.is_empty() { + // TODO: support pattern + return None; + } + jwk + } _ => return None, }; let hash = match ssi::keccak_hash::hash_public_key(jwk) { diff --git a/did-key/src/lib.rs b/did-key/src/lib.rs index f3dd49a17..db443f861 100644 --- a/did-key/src/lib.rs +++ b/did-key/src/lib.rs @@ -193,6 +193,13 @@ impl DIDMethod for DIDKey { fn generate(&self, source: &Source) -> Option { let jwk = match source { Source::Key(jwk) => jwk, + Source::KeyAndPattern(jwk, pattern) => { + if !pattern.is_empty() { + // pattern not supported + return None; + } + jwk + } _ => return None, }; let did = match jwk.params { diff --git a/did-sol/src/lib.rs b/did-sol/src/lib.rs index 44ff09ea6..7381fa3d9 100644 --- a/did-sol/src/lib.rs +++ b/did-sol/src/lib.rs @@ -140,6 +140,13 @@ impl DIDMethod for DIDSol { fn generate(&self, source: &Source) -> Option { let jwk = match source { Source::Key(jwk) => jwk, + Source::KeyAndPattern(jwk, pattern) => { + if !pattern.is_empty() { + // pattern not supported + return None; + } + jwk + } _ => return None, }; let did = match jwk.params { diff --git a/did-tezos/src/lib.rs b/did-tezos/src/lib.rs index 8600ec08b..b2e2dee38 100644 --- a/did-tezos/src/lib.rs +++ b/did-tezos/src/lib.rs @@ -265,6 +265,13 @@ impl DIDMethod for DIDTz { fn generate(&self, source: &Source) -> Option { let jwk = match source { Source::Key(jwk) => jwk, + Source::KeyAndPattern(jwk, pattern) => { + if !pattern.is_empty() { + // TODO: support pattern + return None; + } + jwk + } _ => return None, }; let hash = match hash_public_key(jwk) { diff --git a/src/did.rs b/src/did.rs index 0229967e5..ea43fc97f 100644 --- a/src/did.rs +++ b/src/did.rs @@ -206,7 +206,10 @@ pub enum Resource { #[derive(Debug, Clone, PartialEq)] #[non_exhaustive] pub enum Source<'a> { + /// Public key Key(&'a JWK), + /// Public key and additional pattern + KeyAndPattern(&'a JWK, &'a str), } #[derive(Debug, Serialize, Deserialize, Clone, Default)] @@ -292,6 +295,30 @@ impl<'a> DIDMethods<'a> { }; Ok(method) } + + /// Generate a DID given some input + pub fn generate(&self, source: &Source) -> Option { + let (jwk, pattern) = match source { + Source::Key(_) => { + // Need name/pattern to select DID method + return None; + } + Source::KeyAndPattern(jwk, pattern) => (jwk, pattern), + }; + let mut parts = pattern.splitn(2, ':'); + let method_name = parts.next().unwrap(); + let method = match self.methods.get(method_name) { + Some(method) => method, + None => return None, + }; + if let Some(method_pattern) = parts.next() { + let source = Source::KeyAndPattern(jwk, method_pattern); + method.generate(&source) + } else { + let source = Source::Key(jwk); + method.generate(&source) + } + } } #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]