Skip to content

Commit

Permalink
Expose public key getter on verification method (#941)
Browse files Browse the repository at this point in the history
Signed-off-by: Miroslav Kovar <miroslav.kovar@absa.africa>
  • Loading branch information
mirgee authored Aug 21, 2023
1 parent 2fec017 commit 37a3130
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 14 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions did_doc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"
base64 = "0.21.2"
bs58 = "0.5.0"
did_parser = { path = "../did_parser" }
public_key = { path = "../public_key" }
hex = "0.4.3"
multibase = "0.9.1"
pem = "2.0.1"
Expand Down
17 changes: 17 additions & 0 deletions did_doc/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use url::ParseError;

use crate::schema::verification_method::VerificationMethodType;

#[derive(Debug)]
pub enum DidDocumentBuilderError {
InvalidInput(String),
Expand All @@ -10,6 +12,8 @@ pub enum DidDocumentBuilderError {
Base58DecodeError(bs58::decode::Error),
Base64DecodeError(base64::DecodeError),
HexDecodeError(hex::FromHexError),
UnsupportedVerificationMethodType(VerificationMethodType),
PublicKeyError(public_key::PublicKeyError),
}

impl std::fmt::Display for DidDocumentBuilderError {
Expand Down Expand Up @@ -39,6 +43,12 @@ impl std::fmt::Display for DidDocumentBuilderError {
DidDocumentBuilderError::HexDecodeError(error) => {
write!(f, "Hex decode error: {}", error)
}
DidDocumentBuilderError::UnsupportedVerificationMethodType(vm_type) => {
write!(f, "Unsupported verification method type: {}", vm_type)
}
DidDocumentBuilderError::PublicKeyError(error) => {
write!(f, "Public key error: {}", error)
}
}
}
}
Expand All @@ -51,6 +61,7 @@ impl std::error::Error for DidDocumentBuilderError {
DidDocumentBuilderError::Base58DecodeError(error) => Some(error),
DidDocumentBuilderError::Base64DecodeError(error) => Some(error),
DidDocumentBuilderError::HexDecodeError(error) => Some(error),
DidDocumentBuilderError::PublicKeyError(error) => Some(error),
_ => None,
}
}
Expand Down Expand Up @@ -91,3 +102,9 @@ impl From<ParseError> for DidDocumentBuilderError {
DidDocumentBuilderError::InvalidInput(error.to_string())
}
}

impl From<public_key::PublicKeyError> for DidDocumentBuilderError {
fn from(error: public_key::PublicKeyError) -> Self {
DidDocumentBuilderError::PublicKeyError(error)
}
}
2 changes: 1 addition & 1 deletion did_doc/src/schema/verification_method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod verification_method;
mod verification_method_kind;
mod verification_method_type;

pub use public_key::PublicKeyField;
pub use self::public_key::PublicKeyField;
pub use verification_method::{
CompleteVerificationMethodBuilder, IncompleteVerificationMethodBuilder, VerificationMethod,
};
Expand Down
2 changes: 0 additions & 2 deletions did_doc/src/schema/verification_method/public_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ impl PublicKeyField {
pub fn base58(&self) -> Result<String, DidDocumentBuilderError> {
Ok(bs58::encode(self.key_decoded()?).into_string())
}

// TODO: This should expose a PublicKey getter
}

#[cfg(test)]
Expand Down
47 changes: 43 additions & 4 deletions did_doc/src/schema/verification_method/verification_method.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use did_parser::{Did, DidUrl};
use public_key::Key;
use serde::{Deserialize, Serialize};

use crate::schema::types::jsonwebkey::JsonWebKey;
use crate::{error::DidDocumentBuilderError, schema::types::jsonwebkey::JsonWebKey};

use super::{public_key::PublicKeyField, VerificationMethodType};

Expand Down Expand Up @@ -37,9 +38,16 @@ impl VerificationMethod {
&self.verification_method_type
}

pub fn public_key(&self) -> &PublicKeyField {
pub fn public_key_field(&self) -> &PublicKeyField {
&self.public_key
}

pub fn public_key(&self) -> Result<Key, DidDocumentBuilderError> {
Ok(Key::new(
self.public_key.key_decoded()?,
self.verification_method_type.try_into()?,
)?)
}
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -224,7 +232,7 @@ mod tests {
assert_eq!(vm.id(), &id);
assert_eq!(vm.controller(), &controller);
assert_eq!(vm.verification_method_type(), &verification_method_type);
match vm.public_key() {
match vm.public_key_field() {
PublicKeyField::Multibase {
public_key_multibase,
} => {
Expand Down Expand Up @@ -252,7 +260,7 @@ mod tests {
assert_eq!(vm.id(), &id);
assert_eq!(vm.controller(), &controller);
assert_eq!(vm.verification_method_type(), &verification_method_type);
match vm.public_key() {
match vm.public_key_field() {
PublicKeyField::Multibase {
public_key_multibase,
} => {
Expand Down Expand Up @@ -281,4 +289,35 @@ mod tests {
);
assert!(vm.is_err());
}

#[test]
fn test_verification_method_public_key() {
let id = create_valid_did_url();
let controller = create_valid_did();
let verification_method_type = create_valid_verification_key_type();
let public_key_multibase_expected = create_valid_multibase();

let vm = VerificationMethod::builder(
id.clone(),
controller.clone(),
verification_method_type.clone(),
)
.add_public_key_multibase(public_key_multibase_expected.clone())
.build();

match vm.public_key_field() {
PublicKeyField::Multibase {
public_key_multibase,
} => {
assert_eq!(
public_key_multibase.to_string(),
public_key_multibase_expected
)
}
_ => panic!("Expected public key to be multibase"),
}

let public_key = vm.public_key().unwrap();
assert_eq!(public_key.multibase58(), public_key_multibase_expected);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use std::fmt::Display;

use public_key::KeyType;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
use crate::error::DidDocumentBuilderError;

#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq)]
pub enum VerificationMethodType {
JsonWebKey2020,
EcdsaSecp256k1VerificationKey2019,
Expand Down Expand Up @@ -46,3 +49,21 @@ impl Display for VerificationMethodType {
}
}
}

impl TryFrom<VerificationMethodType> for KeyType {
type Error = DidDocumentBuilderError;

fn try_from(value: VerificationMethodType) -> Result<Self, Self::Error> {
match value {
VerificationMethodType::Ed25519VerificationKey2018
| VerificationMethodType::Ed25519VerificationKey2020 => Ok(KeyType::Ed25519),
VerificationMethodType::Bls12381G1Key2020 => Ok(KeyType::Bls12381g1),
VerificationMethodType::Bls12381G2Key2020 => Ok(KeyType::Bls12381g2),
VerificationMethodType::X25519KeyAgreementKey2019
| VerificationMethodType::X25519KeyAgreementKey2020 => Ok(KeyType::X25519),
_ => Err(DidDocumentBuilderError::UnsupportedVerificationMethodType(
value,
)),
}
}
}
10 changes: 5 additions & 5 deletions did_peer/src/numalgos/numalgo2/verification_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub fn get_key_by_verification_method(vm: &VerificationMethod) -> Result<Key, Di
}
t @ _ => return Err(DidPeerError::UnsupportedVerificationMethodType(t.to_owned())),
};
Ok(Key::new(vm.public_key().key_decoded()?, key_type)?)
Ok(Key::new(vm.public_key_field().key_decoded()?, key_type)?)
}

fn build_verification_methods_from_type_and_key(
Expand Down Expand Up @@ -159,21 +159,21 @@ mod tests {
let vms = get_verification_methods_by_key(key, &did(), PublicKeyEncoding::Multibase).unwrap();
assert_eq!(vms.len(), 1);
assert_eq!(
vms[0].public_key().key_decoded().unwrap(),
vms[0].public_key_field().key_decoded().unwrap(),
key.multicodec_prefixed_key()
);
assert_ne!(vms[0].public_key().key_decoded().unwrap(), key.key());
assert_ne!(vms[0].public_key_field().key_decoded().unwrap(), key.key());
}

// ... and base58 encoded keys are not
fn test_get_verification_methods_by_key_base58(key: &Key) {
let vms = get_verification_methods_by_key(key, &did(), PublicKeyEncoding::Base58).unwrap();
assert_eq!(vms.len(), 1);
assert_ne!(
vms[0].public_key().key_decoded().unwrap(),
vms[0].public_key_field().key_decoded().unwrap(),
key.multicodec_prefixed_key()
);
assert_eq!(vms[0].public_key().key_decoded().unwrap(), key.key());
assert_eq!(vms[0].public_key_field().key_decoded().unwrap(), key.key());
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion did_resolver_sov/src/resolution/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ mod tests {
"application/did+json"
);
if let PublicKeyField::Base58 { public_key_base58 } =
ddo.verification_method()[0].public_key()
ddo.verification_method()[0].public_key_field()
{
assert_eq!(
public_key_base58,
Expand Down

0 comments on commit 37a3130

Please sign in to comment.