diff --git a/crates/teddybear-crypto/src/lib.rs b/crates/teddybear-crypto/src/lib.rs index d370156..eee8781 100644 --- a/crates/teddybear-crypto/src/lib.rs +++ b/crates/teddybear-crypto/src/lib.rs @@ -8,8 +8,7 @@ use rand::rngs::OsRng; use serde::{Deserialize, Serialize}; use ssi_dids_core::{ document::{verification_method::ValueOrReference, DIDVerificationMethod, ResourceRef}, - ssi_json_ld::Iri, - DIDBuf, DIDURLReference, DIDURLReferenceBuf, InvalidDIDURL, VerificationMethodDIDResolver, + DIDURLReference, DIDURLReferenceBuf, InvalidDIDURL, VerificationMethodDIDResolver, }; use ssi_jwk::{Algorithm, Params}; use ssi_jws::{ @@ -26,11 +25,14 @@ use teddybear_high_assurance::DnsError; use crate::okp_encoder::OKPEncoder; pub use ssi_dids_core::{ - ssi_json_ld::{iref::UriBuf, IriBuf}, - DIDURLBuf, DID, DIDURL, + ssi_json_ld::{ + iref::{Uri, UriBuf}, + Iri, IriBuf, + }, + DIDBuf, DIDURLBuf, PrimaryDIDURL, PrimaryDIDURLBuf, DID, DIDURL, }; pub use ssi_jwk::JWK; -pub use ssi_verification_methods::{Ed25519VerificationKey2020, JwkVerificationMethod}; +pub use ssi_verification_methods::{Controller, Ed25519VerificationKey2020, JwkVerificationMethod}; pub use crate::x25519::X25519KeyAgreementKey2020; @@ -68,6 +70,9 @@ pub enum Ed25519Error { #[error("high assurance verification failed")] HighAssuranceVerificationFailed, + #[error("DID subject mismatch")] + SubjectMismatch, + #[error("{0}")] ControllerError(String), @@ -147,11 +152,11 @@ impl Document { } pub async fn resolve( - id: &Iri, + id: &DID, options: DocumentResolveOptions<'_>, ) -> Result { let inner = CustomVerificationMethodDIDResolver::new(default_did_method()) - .require_controller(id) + .require_controller(id.as_iri()) .await .map_err(|e| match e { ControllerError::NotFound(e) => Ed25519Error::ControllerError(e), @@ -162,6 +167,12 @@ impl Document { ControllerError::InternalError(e) => Ed25519Error::ControllerError(e), })?; + // Additionally enforce DID subject to be the same as the + // DID used to request the DID document. + if inner.id != id { + return Err(Ed25519Error::SubjectMismatch); + } + if options.require_high_assurance_verification { // FIXME: Implement other parts of the RFC. if let Some(vm) = id.strip_prefix("did:web:") { diff --git a/crates/teddybear-js/src/lib.rs b/crates/teddybear-js/src/lib.rs index 16face3..bccab6a 100644 --- a/crates/teddybear-js/src/lib.rs +++ b/crates/teddybear-js/src/lib.rs @@ -15,14 +15,14 @@ use ssi_status::bitstring_status_list::{ use teddybear_c2pa::{Builder, Ed25519Signer, Reader}; use teddybear_crypto::{ DIDURLBuf, Ed25519VerificationKey2020, IriBuf, JwkVerificationMethod, SignOptions, UriBuf, - X25519KeyAgreementKey2020, + X25519KeyAgreementKey2020, DID, }; use teddybear_jwe::{A256Gcm, XC20P}; use wasm_bindgen::prelude::*; use teddybear_vc::{ - issue_vc, present_vp, verify, ContextLoader as InnerContextLoader, JsonCredential, - JsonPresentation, DI, + issue_vc, present_vp, verify, ContextLoader as InnerContextLoader, JsonPresentation, + SpecializedJsonCredential, DI, }; const OBJECT_SERIALIZER: Serializer = Serializer::new().serialize_maps_as_objects(true); @@ -118,7 +118,7 @@ impl Document { .unwrap_or_default(); Ok(Document( - teddybear_crypto::Document::resolve(&IriBuf::from_str(did)?, options).await?, + teddybear_crypto::Document::resolve(DID::new(did)?, options).await?, )) } @@ -236,7 +236,7 @@ impl PrivateEd25519 { vc: Object, context_loader: &mut ContextLoader, ) -> Result { - let credential = serde_wasm_bindgen::from_value(vc.into())?; + let credential: SpecializedJsonCredential = serde_wasm_bindgen::from_value(vc.into())?; let vm = IriBuf::from_str(verification_method)?; Ok(issue_vc( @@ -260,7 +260,8 @@ impl PrivateEd25519 { domain: Option, challenge: Option, ) -> Result { - let presentation = serde_wasm_bindgen::from_value(vp.into())?; + let presentation: JsonPresentation = + serde_wasm_bindgen::from_value(vp.into())?; let vm = IriBuf::from_str(verification_method)?; Ok(present_vp( @@ -491,7 +492,8 @@ pub async fn js_verify_credential( document: Object, context_loader: &mut ContextLoader, ) -> Result { - let credential: DI = serde_wasm_bindgen::from_value(document.into())?; + let credential: DI = + serde_wasm_bindgen::from_value(document.into())?; let (key, challenge) = verify(&credential, &mut context_loader.0).await?; diff --git a/crates/teddybear-vc/src/lib.rs b/crates/teddybear-vc/src/lib.rs index 4d323c1..4374493 100644 --- a/crates/teddybear-vc/src/lib.rs +++ b/crates/teddybear-vc/src/lib.rs @@ -2,15 +2,15 @@ mod credential_ref; use ed25519_dalek::SigningKey; use itertools::Itertools; +use serde::Serialize; use ssi_claims::{ data_integrity::{ suites::Ed25519Signature2020, CryptographicSuite, DataIntegrity, ProofOptions, }, Invalid, InvalidClaims, ProofValidationError, SignatureEnvironment, SignatureError, - ValidateClaims, ValidateProof, VerifiableClaims, VerificationParameters, + ValidateProof, VerificationParameters, }; use ssi_json_ld::IriBuf; -use ssi_vc::v2::{Credential, Presentation}; use ssi_verification_methods::{ Ed25519VerificationKey2020, ProofPurpose, ReferenceOrOwned, SingleSecretSigner, }; @@ -18,12 +18,20 @@ use teddybear_crypto::{default_did_method, CustomVerificationMethodDIDResolver}; use crate::credential_ref::CredentialRef; -pub use ssi_json_ld::ContextLoader; -pub use ssi_vc::v2::syntax::{JsonCredential, JsonPresentation}; +pub use ssi_claims::{ValidateClaims, VerifiableClaims}; +pub use ssi_json_ld::{ContextLoader, Expand, Expandable, JsonLdNodeObject, ValidId}; +pub use ssi_vc::{ + syntax::{RequiredContext, RequiredContextList, RequiredType, RequiredTypeSet}, + v2::{ + syntax::{JsonPresentation, SpecializedJsonCredential}, + Credential, Presentation, + }, + Identified, +}; pub type DI = DataIntegrity; -type CustomVerificationParameters<'a> = +pub type CustomVerificationParameters<'a> = VerificationParameters; #[derive(thiserror::Error, Debug)] @@ -44,14 +52,17 @@ pub enum Error { ProofValidationError(#[from] ProofValidationError), } -type SignedEd25519Credential<'a> = DI>; +pub type SignedEd25519Credential<'a, C> = DI>; -pub async fn issue_vc<'a>( +pub async fn issue_vc<'a, C>( key: SigningKey, verification_method: IriBuf, - credential: &'a JsonCredential, + credential: &'a C, context_loader: &mut ContextLoader, -) -> Result, Error> { +) -> Result, Error> +where + C: Credential + JsonLdNodeObject + Expandable, +{ let resolver = CustomVerificationMethodDIDResolver::new(default_did_method()); let params = @@ -77,16 +88,19 @@ pub async fn issue_vc<'a>( .await?) } -type SignedEd25519Presentation<'a> = DI>; +pub type SignedEd25519Presentation<'a, C> = DI>>; -pub async fn present_vp<'a>( +pub async fn present_vp<'a, C>( key: SigningKey, verification_method: IriBuf, - presentation: &'a JsonPresentation, + presentation: &'a JsonPresentation, domain: Option, challenge: Option, context_loader: &mut ContextLoader, -) -> Result, Error> { +) -> Result, Error> +where + C: Credential + JsonLdNodeObject + Expandable + Serialize, +{ let resolver = CustomVerificationMethodDIDResolver::new(default_did_method()); let params =