Skip to content

Commit

Permalink
Improve JWK/VM comparison
Browse files Browse the repository at this point in the history
- Generalize matching a JWK against a VM map
- Implement comparing a JWK by public key properties
  • Loading branch information
clehner committed Aug 26, 2021
1 parent 9f7eed7 commit c188ab1
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 20 deletions.
15 changes: 15 additions & 0 deletions src/did.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::caip10::BlockchainAccountId;
use std::collections::BTreeMap as Map;
use std::collections::HashMap;
use std::convert::TryFrom;
Expand Down Expand Up @@ -458,6 +459,20 @@ impl VerificationMethodMap {
}
}
}

/// Verify that a given JWK can be used to satisfy this verification method.
pub fn match_jwk(&self, jwk: &JWK) -> Result<(), Error> {
if let Some(ref account_id) = self.blockchain_account_id {
let account_id = BlockchainAccountId::from_str(&account_id)?;
account_id.verify(&jwk)?;
} else {
let resolved_jwk = self.get_jwk()?;
if !resolved_jwk.equals_public(&jwk) {
Err(Error::KeyMismatch)?;
}
}
Ok(())
}
}

impl FromStr for DIDURL {
Expand Down
45 changes: 45 additions & 0 deletions src/jwk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,51 @@ impl JWK {
key
}

/// Compare JWK equality by public key properties.
/// Equivalent to comparing by [JWK Thumbprint][thumbprint].
pub fn equals_public(&self, other: &JWK) -> bool {
match (&self.params, &other.params) {
(
Params::RSA(RSAParams {
modulus: Some(n1),
exponent: Some(e1),
..
}),
Params::RSA(RSAParams {
modulus: Some(n2),
exponent: Some(e2),
..
}),
) => n1 == n2 && e1 == e2,
(Params::OKP(okp1), Params::OKP(okp2)) => {
okp1.curve == okp2.curve && okp1.public_key == okp2.public_key
}
(
Params::EC(ECParams {
curve: Some(crv1),
x_coordinate: Some(x1),
y_coordinate: Some(y1),
..
}),
Params::EC(ECParams {
curve: Some(crv2),
x_coordinate: Some(x2),
y_coordinate: Some(y2),
..
}),
) => crv1 == crv2 && x1 == x2 && y1 == y2,
(
Params::Symmetric(SymmetricParams {
key_value: Some(kv1),
}),
Params::Symmetric(SymmetricParams {
key_value: Some(kv2),
}),
) => kv1 == kv2,
_ => false,
}
}

pub fn thumbprint(&self) -> Result<String, Error> {
// JWK parameters for thumbprint hashing must be in lexicographical order, and without
// string escaping.
Expand Down
26 changes: 6 additions & 20 deletions src/ldp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::eip712::TypedData;
use crate::error::Error;
use crate::hash::sha256;
use crate::jwk::Base64urlUInt;
use crate::jwk::{Algorithm, OctetParams as JWKOctetParams, Params as JWKParams, JWK};
use crate::jwk::{Algorithm, Params as JWKParams, JWK};
use crate::jws::Header;
use crate::rdf::DataSet;
use crate::urdna2015;
Expand Down Expand Up @@ -739,9 +739,7 @@ impl ProofSuite for EcdsaSecp256k1RecoverySignature2020 {
}
let message = to_jws_payload(document, proof).await?;
let (_header, jwk) = crate::jws::detached_recover(&jws, &message)?;
let account_id_str = vm.blockchain_account_id.ok_or(Error::MissingAccountId)?;
let account_id = BlockchainAccountId::from_str(&account_id_str)?;
account_id.verify(&jwk)?;
vm.match_jwk(&jwk)?;
Ok(Default::default())
}
}
Expand Down Expand Up @@ -835,11 +833,7 @@ impl ProofSuite for Ed25519BLAKE2BDigestSize20Base58CheckEncodedSignature2021 {
.as_ref()
.ok_or(Error::MissingVerificationMethod)?;
let vm = resolve_vm(&verification_method, resolver).await?;
let account_id: BlockchainAccountId = vm
.blockchain_account_id
.ok_or(Error::MissingAccountId)?
.parse()?;
account_id.verify(&jwk)?;
vm.match_jwk(&jwk)?;
let message = to_jws_payload(document, proof).await?;
crate::jws::detached_verify(&jws, &message, &jwk)?;
Ok(Default::default())
Expand Down Expand Up @@ -934,11 +928,7 @@ impl ProofSuite for P256BLAKE2BDigestSize20Base58CheckEncodedSignature2021 {
.as_ref()
.ok_or(Error::MissingVerificationMethod)?;
let vm = resolve_vm(&verification_method, resolver).await?;
let account_id: BlockchainAccountId = vm
.blockchain_account_id
.ok_or(Error::MissingAccountId)?
.parse()?;
account_id.verify(&jwk)?;
vm.match_jwk(&jwk)?;
let message = to_jws_payload(document, proof).await?;
crate::jws::detached_verify(&jws, &message, &jwk)?;
Ok(Default::default())
Expand Down Expand Up @@ -1061,9 +1051,7 @@ impl ProofSuite for Eip712Signature2021 {
x509_thumbprint_sha1: None,
x509_thumbprint_sha256: None,
};
let account_id_str = vm.blockchain_account_id.ok_or(Error::MissingAccountId)?;
let account_id = BlockchainAccountId::from_str(&account_id_str)?;
account_id.verify(&jwk)?;
vm.match_jwk(&jwk)?;
Ok(Default::default())
}
}
Expand Down Expand Up @@ -1331,9 +1319,7 @@ impl ProofSuite for EthereumPersonalSignature2021 {
x509_thumbprint_sha1: None,
x509_thumbprint_sha256: None,
};
let account_id_str = vm.blockchain_account_id.ok_or(Error::MissingAccountId)?;
let account_id = BlockchainAccountId::from_str(&account_id_str)?;
account_id.verify(&jwk)?;
vm.match_jwk(&jwk)?;
Ok(Default::default())
}
}
Expand Down

0 comments on commit c188ab1

Please sign in to comment.