diff --git a/ssi-json-ld/src/lib.rs b/ssi-json-ld/src/lib.rs index 4cda28612..e8c5e636d 100644 --- a/ssi-json-ld/src/lib.rs +++ b/ssi-json-ld/src/lib.rs @@ -494,7 +494,7 @@ where expand_context, // VC HTTP API Test Suite expect properties to not be silently dropped. // More info: https://github.com/timothee-haudebourg/json-ld/issues/13 - expansion_policy: json_ld::expansion::Policy::Strict, + expansion_policy: json_ld::expansion::Policy::Relaxed, ..Default::default() }; @@ -502,6 +502,7 @@ where let mut generator = rdf_types::generator::Blank::new_with_prefix("b".to_string()).with_default_metadata(); eprintln!("json_to_dataset: 1"); + // this is likely the remote call let mut to_rdf = doc .to_rdf_using(&mut generator, loader, options) .await diff --git a/ssi-jws/src/lib.rs b/ssi-jws/src/lib.rs index 98389fcc6..805c9a002 100644 --- a/ssi-jws/src/lib.rs +++ b/ssi-jws/src/lib.rs @@ -342,6 +342,7 @@ pub fn verify_payload( let result = Verifier::verify_signature_pok(&proof_request, &proof, &proof_nonce); match result { Ok(message_hashes) => { + eprintln!("Signature pok check passes"); let mut i = 0; let mut credential_subject_id = ""; while i < payload.messages.len() { @@ -377,6 +378,7 @@ pub fn verify_payload( } }, Err(_) => { + eprintln!("Signature pok check did not pass"); return Err(Error::InvalidSignature); } } diff --git a/ssi-ldp/src/lib.rs b/ssi-ldp/src/lib.rs index f00d3dfee..972ba898e 100644 --- a/ssi-ldp/src/lib.rs +++ b/ssi-ldp/src/lib.rs @@ -338,6 +338,7 @@ impl LinkedDataProofs { key: &JWK, extra_proof_properties: Option>, ) -> Result { + eprintln!("LinkedDataProofs::sign"); let mut options = options.clone(); // todo re-enable this @@ -415,15 +416,21 @@ async fn to_jws_payload( proof: &Proof, context_loader: &mut ContextLoader, ) -> Result, Error> { + eprintln!("to_jws_payload: 0"); let sigopts_dataset = proof .to_dataset_for_signing(Some(document), context_loader) .await?; + eprintln!("to_jws_payload: 1"); + // this line is the issue, never makes it to 2 let doc_dataset = document .to_dataset_for_signing(None, context_loader) .await?; + eprintln!("to_jws_payload: 2"); let doc_normalized = urdna2015::normalize(doc_dataset.quads().map(QuadRef::from)).into_nquads(); + eprintln!("to_jws_payload: 3"); let sigopts_normalized = urdna2015::normalize(sigopts_dataset.quads().map(QuadRef::from)).into_nquads(); + eprintln!("to_jws_payload: 4"); let sigopts_digest = sha256(sigopts_normalized.as_bytes()); let doc_digest = sha256(doc_normalized.as_bytes()); let data = [ @@ -543,35 +550,128 @@ pub async fn generate_bbs_signature_pok( Ok(proof_with_new_sig) } +fn rename_blank_node_labels(orig: &Vec) -> Vec { + use std::collections::HashMap; + + // hash maps for properties, parents, and substitutions + let mut blank_node_props: HashMap = HashMap::new(); + let mut blank_node_parents: HashMap = HashMap::new(); + let mut blank_node_subs: HashMap = HashMap::new(); + + let mut root_node: Option<&str> = None; + + for nq in orig.iter() { + let split: Vec<&str> = nq.split(" ").collect(); + let left = split[0]; + let middle = split[1]; + let right = split[2]; + + if middle.ends_with("/credentials#credentialSubject>") { + root_node = Some(left); + } + } + + blank_node_subs.insert(root_node.unwrap().to_owned(), "_d:0".to_owned()); + + for nq in orig.iter() { + let split: Vec<&str> = nq.split(" ").collect(); + let left = split[0]; + let middle = split[1]; + let right = split[2]; + if right.starts_with("_:c") { + eprintln!("property={}, blank node label={}", middle, right); + blank_node_props.insert(right.to_owned(), middle.to_owned()); + blank_node_parents.insert(right.to_owned(), left.to_owned()); + } + } + + //eprintln!("properties map: {:?}", &blank_node_props); + //eprintln!("parents map: {:?}", &blank_node_parents); + // at this point, we have properties and parents for each blank node label + + // iterate through the n-quads and construct the substitutions + // key is n-quad, value is parent, either another n-quad or an identifier + for (key, value) in blank_node_parents.iter() { + //eprintln!("key: {}, value: {}", &key, &value); + + let mut path = String::from(""); + let mut curr = key.as_str(); + while curr != root_node.unwrap() { + let prop = blank_node_props[curr].as_str(); + path.push_str(prop); + path.push(':'); + + let parent = blank_node_parents[curr].as_str(); + if parent.starts_with("_:c") { + curr = blank_node_parents[curr].as_str(); + } else { + path.push_str(parent); + path.push(':'); + break; + } + } + + let hash = sha256(path.as_bytes()); + let hash_string = base64::encode_config(hash.as_slice(), base64::URL_SAFE_NO_PAD); + let new_blank_node_label = "_d:".to_owned() + hash_string.as_str(); + eprintln!("key: {}, path: {:?}", key, new_blank_node_label.as_str()); + blank_node_subs.insert(key.to_owned(), new_blank_node_label); + } + + let mut rewritten: Vec = Vec::new(); + + for nq in orig.iter() { + let split: Vec<&str> = nq.split(" ").collect(); + let mut left = split[0]; + let middle = split[1]; + let mut right = split[2]; + + if left.starts_with("_:c") { + left = blank_node_subs[left].as_str(); + } + + if right.starts_with("_:c") { + right = blank_node_subs[right].as_str(); + } + + let nq_rewritten = vec![left, middle, right, "."].join(" "); + rewritten.push(nq_rewritten); + } + + /*for nq in rewritten.iter() { + eprintln!("n-quad: {}", nq); + }*/ + + rewritten +} + async fn to_jws_payload_v2( document: &(dyn LinkedDataDocument + Sync), proof: &Proof, context_loader: &mut ContextLoader, ) -> Result { - eprintln!("to_jws_payload_v2: enter..."); let mut payload = JWSPayload { header: String::new(), messages: Vec::new(), sigopts_digest: [0; 32], }; - eprintln!("to_jws_payload_v2: sigopts hash 1"); let sigopts_dataset = proof .to_dataset_for_signing(Some(document), context_loader) .await?; - eprintln!("to_jws_payload_v2: sigopts hash 2"); let sigopts_normalized = urdna2015::normalize(sigopts_dataset.quads().map(QuadRef::from)).into_nquads(); - eprintln!("to_jws_payload_v2: sigopts hash 3"); payload.sigopts_digest = sha256(sigopts_normalized.as_bytes()); - eprintln!("to_jws_payload_v2: begin doc to n-quads 1"); let doc_dataset = document .to_dataset_for_signing(None, context_loader) .await?; - eprintln!("to_jws_payload_v2: begin doc to n-quads 2"); let doc_normalized = urdna2015::normalize(doc_dataset.quads().map(QuadRef::from)).into_nquads_vec(); - eprintln!("to_jws_payload_v2: begin doc to n-quads 3"); - payload.messages = doc_normalized; + payload.messages = rename_blank_node_labels(&doc_normalized); + + /* + for message in payload.messages.iter() { + eprintln!("[message] {}", message); + }*/ Ok(payload) } @@ -586,6 +686,7 @@ async fn sign( algorithm: Algorithm, extra_proof_properties: Option>, ) -> Result { + eprintln!("ssi-ldp, sign"); if let Some(key_algorithm) = key.algorithm { if key_algorithm != algorithm { return Err(Error::JWS(ssi_jws::Error::AlgorithmMismatch)); @@ -595,6 +696,7 @@ async fn sign( .with_options(options) .with_properties(extra_proof_properties); sign_proof_v2(document, proof, key, algorithm, context_loader).await + //sign_proof(document, proof, key, algorithm, context_loader).await } async fn sign_proof( @@ -604,6 +706,7 @@ async fn sign_proof( algorithm: Algorithm, context_loader: &mut ContextLoader, ) -> Result { + eprintln!("sign_proof_v1"); let message = to_jws_payload(document, &proof, context_loader).await?; let jws = ssi_jws::detached_sign_unencoded_payload(algorithm, &message, key)?; proof.jws = Some(jws); @@ -617,6 +720,7 @@ async fn sign_proof_v2( algorithm: Algorithm, context_loader: &mut ContextLoader, ) -> Result { + eprintln!("sign_proof_v2"); let mut jws_payload = to_jws_payload_v2(document, &proof, context_loader).await?; let jws = ssi_jws::detached_sign_unencoded_payload_v2(algorithm, &mut jws_payload, key)?; proof.jws = Some(jws); diff --git a/ssi-vc/src/lib.rs b/ssi-vc/src/lib.rs index a9380a094..c54055d29 100644 --- a/ssi-vc/src/lib.rs +++ b/ssi-vc/src/lib.rs @@ -1123,6 +1123,7 @@ impl LinkedDataDocument for Credential { parent: Option<&(dyn LinkedDataDocument + Sync)>, context_loader: &mut ContextLoader, ) -> Result { + eprintln!("to_dataset_for_signing, impl LinkedDataDocument for Credential"); let mut copy = self.clone(); copy.proof = None;