diff --git a/contracts/okp4-dataverse/src/credential/crypto.rs b/contracts/okp4-dataverse/src/credential/crypto.rs index fbe3de5d..848e8f2b 100644 --- a/contracts/okp4-dataverse/src/credential/crypto.rs +++ b/contracts/okp4-dataverse/src/credential/crypto.rs @@ -34,12 +34,16 @@ impl From<(CanonicalizationAlg, DigestAlg, SignatureAlg)> for CryptoSuite { impl CryptoSuite { pub fn verify_document( &self, - unsecured_document: &[Quad<'_>], + unsecured_doc: &[Quad<'_>], + proof_opts: &[Quad<'_>], proof_value: &[u8], pub_key: &[u8], ) -> Result { - let transformed_document = self.canonicalize(unsecured_document)?; - let hash = self.hash(transformed_document); + let unsecured_doc_canon = self.canonicalize(unsecured_doc)?; + let proof_opts_canon = self.canonicalize(proof_opts)?; + + let hash = [self.hash(proof_opts_canon), self.hash(unsecured_doc_canon)].concat(); + self.verify(&hash, proof_value, pub_key) } diff --git a/contracts/okp4-dataverse/src/credential/proof.rs b/contracts/okp4-dataverse/src/credential/proof.rs index daaa5964..93b1380a 100644 --- a/contracts/okp4-dataverse/src/credential/proof.rs +++ b/contracts/okp4-dataverse/src/credential/proof.rs @@ -6,7 +6,7 @@ use crate::credential::rdf_marker::{ }; use itertools::Itertools; use okp4_rdf::dataset::{Dataset, QuadIterator}; -use rio_api::model::{GraphName, Literal, Term}; +use rio_api::model::{GraphName, Literal, Quad, Term}; #[derive(Debug, PartialEq)] pub enum Proof<'a> { @@ -39,12 +39,18 @@ impl<'a> Proof<'a> { } } - pub fn value(&'a self) -> &'a [u8] { + pub fn signature(&'a self) -> &'a [u8] { match self { Proof::Ed25519Signature2020(p) => &p.value, } } + pub fn options(&'a self) -> &'a [Quad<'a>] { + match self { + Proof::Ed25519Signature2020(p) => p.options.as_ref(), + } + } + fn extract_verification_method( dataset: &'a Dataset<'a>, proof_graph: GraphName<'a>, @@ -193,6 +199,7 @@ pub struct Ed25519Signature2020Proof<'a> { created: &'a str, purpose: ProofPurpose, value: Vec, + options: Dataset<'a>, } impl<'a> TryFrom<(&'a Dataset<'a>, GraphName<'a>)> for Ed25519Signature2020Proof<'a> { @@ -211,6 +218,17 @@ impl<'a> TryFrom<(&'a Dataset<'a>, GraphName<'a>)> for Ed25519Signature2020Proof created: Proof::extract_created(dataset, proof_graph)?, purpose: p_purpose.into(), value: p_value, + options: Dataset::new( + dataset + .skip_pattern( + None, + Some(PROOF_RDF_PROOF_VALUE), + None, + Some(Some(proof_graph)), + ) + .map(|quad| *quad) + .collect(), + ), }) } } @@ -289,6 +307,9 @@ mod test { #[test] fn proof_from_dataset() { + let quads = testutil::read_test_quads("proof-ed255192020-options.nq"); + let proof_ok_options = Dataset::from(quads.as_slice()); + let cases: Vec<(&str, Result, InvalidProofError>)> = vec![ ( "proof-ed255192020-ok.nq", @@ -301,6 +322,7 @@ mod test { }, purpose: ProofPurpose::AssertionMethod, value: BASE64_STANDARD.decode("371GN4kfgVEWv3/QY9qx1buNm9gYJGWgYOgMSVKOsnoJekPoQV2fjqR+3XMjd3avpQlARFyD/3a0J5tUS4aBCQ==").unwrap(), + options: proof_ok_options, })), ), ( diff --git a/contracts/okp4-dataverse/src/credential/vc.rs b/contracts/okp4-dataverse/src/credential/vc.rs index d275b1d4..85ba39a3 100644 --- a/contracts/okp4-dataverse/src/credential/vc.rs +++ b/contracts/okp4-dataverse/src/credential/vc.rs @@ -83,7 +83,8 @@ impl<'a> VerifiableCredential<'a> { let crypto_suite = proof.crypto_suite(); crypto_suite.verify_document( self.unsecured_document.as_ref(), - proof.value(), + proof.options(), + proof.signature(), proof.pub_key(), ) } diff --git a/contracts/okp4-dataverse/testdata/proof-ed255192020-options.nq b/contracts/okp4-dataverse/testdata/proof-ed255192020-options.nq new file mode 100644 index 00000000..e40227b6 --- /dev/null +++ b/contracts/okp4-dataverse/testdata/proof-ed255192020-options.nq @@ -0,0 +1,4 @@ +_:b1 "2023-11-29T10:07:56Z"^^ _:b0 . +_:b1 _:b0 . +_:b1 _:b0 . +_:b1 _:b0 .