From 96fb56c7f87dcd487cd077cb43a16fb76322872c Mon Sep 17 00:00:00 2001 From: "Charles E. Lehner" Date: Mon, 4 Apr 2022 17:35:02 -0400 Subject: [PATCH 1/4] Update for cacao-rs with libipld --- .github/workflows/ci.yml | 2 +- Cargo.toml | 1 + src/lib.rs | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4043b6a..32f22a4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ jobs: repository: spruceid/cacao-rs token: ${{ secrets.SPRUCE_CEL_PRIVATE_REPOS_2022 }} path: cacao-rs - ref: c48b68faccb885f270b0e34f37b61c1b66d48c6a + ref: 61b02a7b0eb0b4b75c04553cbf4f045066d4f1ad - name: Checkout ssi uses: actions/checkout@v2 diff --git a/Cargo.toml b/Cargo.toml index c886d75..78f3caf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ hex = "0.4" anyhow = "1.0" iri-string = { version = "0.4", features = ["serde", "serde-std"] } percent-encoding = "2.1" +libipld = "0.12" [dev-dependencies] pretty_assertions = "1.2" diff --git a/src/lib.rs b/src/lib.rs index ab42e57..4953e0f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ use cacao::siwe_cacao::SignInWithEthereum; use cacao::{Header, Payload, SignatureScheme, Version as CacaoVersion, CACAO}; use chrono::prelude::DateTime; use iri_string::types::UriString; +use libipld::cbor::DagCbor; use serde::{Deserialize, Serialize}; use serde_json::Value; use siwe::TimeStamp; @@ -269,7 +270,7 @@ pub fn cacao_to_zcap( cacao: &CACAO, ) -> Result, CacaoToZcapError> where - S::Signature: AsRef<[u8]>, + S::Signature: AsRef<[u8]> + DagCbor, { let header = cacao.header(); let Payload { @@ -585,7 +586,7 @@ pub fn zcap_to_cacao( zcap: &Delegation<(), CacaoZcapExtraProps>, ) -> Result, ZcapToCacaoError> where - S::Signature: TryFrom>, + S::Signature: TryFrom> + DagCbor, { let Delegation { context: contexts, From 6550beb9e86ca569d199d8eea84b38dc6caffae9 Mon Sep 17 00:00:00 2001 From: "Charles E. Lehner" Date: Mon, 4 Apr 2022 17:35:51 -0400 Subject: [PATCH 2/4] Remove unused imports --- src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4953e0f..5664abd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -896,14 +896,12 @@ mod tests { use cacao::BasicSignature; use pretty_assertions::assert_eq; use siwe::Message; - use ssi::ldp::resolve_vm; pub struct ExampleDIDPKH; use async_trait::async_trait; use ssi::did::{DIDMethod, Document}; use ssi::did_resolve::{ - DIDResolver, DocumentMetadata, ResolutionInputMetadata, ResolutionMetadata, - ERROR_NOT_FOUND, TYPE_DID_LD_JSON, + DIDResolver, DocumentMetadata, ResolutionInputMetadata, ResolutionMetadata, ERROR_NOT_FOUND, }; const EXAMPLE_DID: &str = "did:pkh:eip155:1:0x6da01670d8fc844e736095918bbe11fe8d564163"; const DOC_JSON: &str = r#" From eeb5309ab861d9bae5b860edb2dd25473d525add Mon Sep 17 00:00:00 2001 From: "Charles E. Lehner" Date: Mon, 4 Apr 2022 17:36:01 -0400 Subject: [PATCH 3/4] Test parent capability in resources --- src/lib.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 5664abd..5d1e29e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1055,6 +1055,15 @@ Issued At: 2021-12-07T18:28:18.807Z"#, let cacao = CACAO::::new(message, sig); let zcap = cacao_to_zcap(&cacao).unwrap(); let zcap_json = serde_json::to_value(&zcap).unwrap(); + + // Ensure last resource matches parent + let parent_expected_str = include_str!("../tests/delegation0-zcap.jsonld"); + let parent_expected_json: Value = serde_json::from_str(parent_expected_str).unwrap(); + let last_resource = cacao.payload().resources.iter().next_back().unwrap(); + let parent_capability = CapabilityChainItem::from_resource_uri(&last_resource).unwrap(); + let parent_zcap_json = serde_json::to_value(parent_capability).unwrap(); + assert_eq!(parent_zcap_json, parent_expected_json); + let zcap_json_expected: Value = serde_json::from_str(include_str!("../tests/delegation1-zcap.jsonld")).unwrap(); assert_eq!(zcap_json, zcap_json_expected); From ea3df6cd671443dd77b8254614ecec21e5293e6e Mon Sep 17 00:00:00 2001 From: "Charles E. Lehner" Date: Mon, 4 Apr 2022 17:36:43 -0400 Subject: [PATCH 4/4] Add script to regenerate test vectors --- examples/regenerate-test-vectors.rs | 75 +++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 examples/regenerate-test-vectors.rs diff --git a/examples/regenerate-test-vectors.rs b/examples/regenerate-test-vectors.rs new file mode 100644 index 0000000..8bd7644 --- /dev/null +++ b/examples/regenerate-test-vectors.rs @@ -0,0 +1,75 @@ +use anyhow::{Context, Result}; +use cacao::siwe_cacao::SignInWithEthereum; +use cacao::BasicSignature; +use cacao::{Payload, CACAO}; +use cacao_zcap::{cacao_to_zcap, CapabilityChainItem}; +use siwe::Message; +use std::fs::File; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; +use std::str::FromStr; + +fn read_siwe(path: &PathBuf) -> Result { + let mut file = File::open(path)?; + let mut string = String::new(); + file.read_to_string(&mut string)?; + Message::from_str(&string).context("Unable to parse message") +} + +fn read_siwe_sig(path: &PathBuf) -> Result> { + let mut file = File::open(path)?; + let mut string = String::new(); + file.read_to_string(&mut string)?; + let (_base, sig) = multibase::decode(&format!("f{}", &string)).unwrap(); + Ok(sig) +} + +fn main() { + let crate_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + let siwe0_path = crate_dir.join("tests/delegation0.siwe"); + let siwe1_path = crate_dir.join("tests/delegation1.siwe"); + let siwe0_sig_path = crate_dir.join("tests/delegation0.siwe.sig"); + let siwe1_sig_path = crate_dir.join("tests/delegation1.siwe.sig"); + let zcap0_path = crate_dir.join("tests/delegation0-zcap.jsonld"); + let zcap1_path = crate_dir.join("tests/delegation1-zcap.jsonld"); + + let siwe0 = read_siwe(&siwe0_path).unwrap(); + let siwe1 = read_siwe(&siwe1_path).unwrap(); + + // Build zcap0 from siwe0 + let payload0 = Payload::from(siwe0); + let sigbytes0 = read_siwe_sig(&siwe0_sig_path).unwrap(); + let sig0 = BasicSignature { + s: sigbytes0.try_into().unwrap(), + }; + let cacao0 = CACAO::::new(payload0, sig0); + let zcap0 = cacao_to_zcap(&cacao0).unwrap(); + let zcap0_json = serde_json::to_value(&zcap0).unwrap(); + let mut zcap0_out = File::create(zcap0_path).unwrap(); + serde_json::to_writer_pretty(&mut zcap0_out, &zcap0_json).unwrap(); + write!(zcap0_out, "\n").unwrap(); + + // Update siwe1 to embed zcap0. + // Update previous delegation in resources array + let parent_capability = CapabilityChainItem::Object(zcap0); + let mut payload1 = Payload::from(siwe1); + payload1.resources.pop(); + payload1 + .resources + .push(parent_capability.as_resource_uri().unwrap()); + let siwe1: Message = payload1.clone().try_into().unwrap(); + let mut siwe1_out = File::create(siwe1_path).unwrap(); + write!(siwe1_out, "{}", siwe1).unwrap(); + + // Build zcap1 from siwe1 + let sigbytes1 = read_siwe_sig(&siwe1_sig_path).unwrap(); + let sig1 = BasicSignature { + s: sigbytes1.try_into().unwrap(), + }; + let cacao1 = CACAO::::new(payload1, sig1); + let zcap1 = cacao_to_zcap(&cacao1).unwrap(); + let zcap1_json = serde_json::to_value(&zcap1).unwrap(); + let mut zcap1_out = File::create(zcap1_path).unwrap(); + serde_json::to_writer_pretty(&mut zcap1_out, &zcap1_json).unwrap(); + write!(zcap1_out, "\n").unwrap(); +}