From da43e65d8e2bec69fb48c15d52656776e1c50316 Mon Sep 17 00:00:00 2001 From: Jacob Date: Fri, 13 Oct 2023 12:15:54 +0100 Subject: [PATCH] Remove didkit, rename crate, add missing metadata. --- Cargo.toml | 6 +- .../authorization_request/verification/did.rs | 25 +-------- .../authorization_request/verification/mod.rs | 7 +-- .../verification/x509_san_dns.rs | 2 +- .../verification/x509_san_uri.rs | 2 +- src/core/metadata/parameters/verifier.rs | 56 +++++++++++++++++++ src/core/verifier/builder/mod.rs | 16 +----- src/core/verifier/request_signer.rs | 2 +- src/mdl_request.rs | 2 +- src/utils.rs | 6 +- 10 files changed, 74 insertions(+), 50 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8dae754..b213e0a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,19 +1,18 @@ [package] -name = "oidc4vp" +name = "oid4vp" version = "0.1.0" edition = "2021" authors = ["Spruce Systems, Inc."] license = "MIT OR Apache-2.0" description = "OpenID Connect for Verifiable Presentations" repository = "https://github.com/spruceid/oidc4vp-rs/" -documentation = "https://docs.rs/oidc4vp/" +documentation = "https://docs.rs/oid4vp/" [dependencies] anyhow = "1.0.75" async-trait = "0.1.73" base64 = "0.21.4" did-web = "0.2.2" -didkit = "0.6.0" isomdl = { git = "https://git@github.com/spruceid/isomdl", rev = "b2324b7" } josekit = { git = "https://github.com/cobward/josekit-rs", rev = "635c8a7" } p256 = { version = "0.13.2", features = ["jwk"] } @@ -23,6 +22,7 @@ serde_cbor = "0.11.2" serde_json = "1.0.107" serde_qs = "0.12.0" serde_urlencoded = "0.7.1" +ssi = "0.7.0" thiserror = "1.0.49" tracing = "0.1.37" url = { version = "2.4.1", features = ["serde"] } diff --git a/src/core/authorization_request/verification/did.rs b/src/core/authorization_request/verification/did.rs index 68c6639..8b14607 100644 --- a/src/core/authorization_request/verification/did.rs +++ b/src/core/authorization_request/verification/did.rs @@ -5,27 +5,8 @@ use crate::core::{ }; use anyhow::{bail, Context, Result}; use base64::prelude::*; -use didkit::{resolve_key, DIDResolver}; use serde_json::{Map, Value as Json}; - -/// Default implementation of request verification for `client_id_scheme` `did`. -/// -/// Uses the default didkit [DIDResolver]. -pub async fn verify( - wallet_metadata: &WalletMetadata, - request_object: &AuthorizationRequestObject, - request_jwt: String, - trusted_dids: Option<&[String]>, -) -> Result<()> { - verify_with_resolver( - wallet_metadata, - request_object, - request_jwt, - trusted_dids, - didkit::DID_METHODS.to_resolver(), - ) - .await -} +use ssi::did_resolve::{resolve_key, DIDResolver}; /// Default implementation of request validation for `client_id_scheme` `did`. pub async fn verify_with_resolver( @@ -35,7 +16,7 @@ pub async fn verify_with_resolver( trusted_dids: Option<&[String]>, resolver: &dyn DIDResolver, ) -> Result<()> { - let (headers_b64, _, _) = didkit::ssi::jws::split_jws(&request_jwt)?; + let (headers_b64, _, _) = ssi::jws::split_jws(&request_jwt)?; let headers_json_bytes = BASE64_URL_SAFE_NO_PAD .decode(headers_b64) @@ -87,7 +68,7 @@ pub async fn verify_with_resolver( .await .context("unable to resolve verification method from 'kid' header")?; - let _: Json = didkit::ssi::jwt::decode_verify(&request_jwt, &jwk) + let _: Json = ssi::jwt::decode_verify(&request_jwt, &jwk) .context("request signature could not be verified")?; Ok(()) diff --git a/src/core/authorization_request/verification/mod.rs b/src/core/authorization_request/verification/mod.rs index 43fac7b..6c725c2 100644 --- a/src/core/authorization_request/verification/mod.rs +++ b/src/core/authorization_request/verification/mod.rs @@ -74,10 +74,9 @@ pub(crate) async fn verify_request( profile: &WP, jwt: String, ) -> Result { - let request: AuthorizationRequestObject = - didkit::ssi::jwt::decode_unverified::(&jwt) - .context("unable to decode Authorization Request Object JWT")? - .try_into()?; + let request: AuthorizationRequestObject = ssi::jwt::decode_unverified::(&jwt) + .context("unable to decode Authorization Request Object JWT")? + .try_into()?; let client_id_scheme = request.client_id_scheme(); diff --git a/src/core/authorization_request/verification/x509_san_dns.rs b/src/core/authorization_request/verification/x509_san_dns.rs index 615a356..90432db 100644 --- a/src/core/authorization_request/verification/x509_san_dns.rs +++ b/src/core/authorization_request/verification/x509_san_dns.rs @@ -24,7 +24,7 @@ pub fn validate( trusted_roots: Option<&[Certificate]>, ) -> Result<()> { let client_id = request_object.client_id().0.as_str(); - let (headers_b64, body_b64, sig_b64) = didkit::ssi::jws::split_jws(&request_jwt)?; + let (headers_b64, body_b64, sig_b64) = ssi::jws::split_jws(&request_jwt)?; let headers_json_bytes = BASE64_URL_SAFE_NO_PAD .decode(headers_b64) diff --git a/src/core/authorization_request/verification/x509_san_uri.rs b/src/core/authorization_request/verification/x509_san_uri.rs index 16e09ff..1c61833 100644 --- a/src/core/authorization_request/verification/x509_san_uri.rs +++ b/src/core/authorization_request/verification/x509_san_uri.rs @@ -24,7 +24,7 @@ pub fn validate( trusted_roots: Option<&[Certificate]>, ) -> Result<()> { let client_id = request_object.client_id().0.as_str(); - let (headers_b64, body_b64, sig_b64) = didkit::ssi::jws::split_jws(&request_jwt)?; + let (headers_b64, body_b64, sig_b64) = ssi::jws::split_jws(&request_jwt)?; let headers_json_bytes = BASE64_URL_SAFE_NO_PAD .decode(headers_b64) diff --git a/src/core/metadata/parameters/verifier.rs b/src/core/metadata/parameters/verifier.rs index 365d0f5..5d09a13 100644 --- a/src/core/metadata/parameters/verifier.rs +++ b/src/core/metadata/parameters/verifier.rs @@ -51,6 +51,48 @@ impl From for Json { } } +#[derive(Debug, Clone)] +pub struct AuthorizationEncryptedResponseAlg(pub String); + +impl TypedParameter for AuthorizationEncryptedResponseAlg { + const KEY: &'static str = "authorization_encrypted_response_alg"; +} + +impl TryFrom for AuthorizationEncryptedResponseAlg { + type Error = Error; + + fn try_from(value: Json) -> Result { + Ok(Self(serde_json::from_value(value)?)) + } +} + +impl From for Json { + fn from(value: AuthorizationEncryptedResponseAlg) -> Json { + Json::String(value.0) + } +} + +#[derive(Debug, Clone)] +pub struct AuthorizationEncryptedResponseEnc(pub String); + +impl TypedParameter for AuthorizationEncryptedResponseEnc { + const KEY: &'static str = "authorization_encrypted_response_enc"; +} + +impl TryFrom for AuthorizationEncryptedResponseEnc { + type Error = Error; + + fn try_from(value: Json) -> Result { + Ok(Self(serde_json::from_value(value)?)) + } +} + +impl From for Json { + fn from(value: AuthorizationEncryptedResponseEnc) -> Json { + Json::String(value.0) + } +} + #[cfg(test)] mod test { use serde_json::json; @@ -109,4 +151,18 @@ mod test { let RequireSignedRequestObject(b) = metadata().get().unwrap().unwrap(); assert_eq!(b, exp); } + + #[test] + fn authorization_encrypted_response_alg() { + let exp = "ECDH-ES"; + let AuthorizationEncryptedResponseAlg(s) = metadata().get().unwrap().unwrap(); + assert_eq!(s, exp); + } + + #[test] + fn authorization_encrypted_response_enc() { + let exp = "A256GCM"; + let AuthorizationEncryptedResponseEnc(s) = metadata().get().unwrap().unwrap(); + assert_eq!(s, exp); + } } diff --git a/src/core/verifier/builder/mod.rs b/src/core/verifier/builder/mod.rs index 6b5f6bb..d80ee5b 100644 --- a/src/core/verifier/builder/mod.rs +++ b/src/core/verifier/builder/mod.rs @@ -1,5 +1,5 @@ use anyhow::{bail, Context, Result}; -use didkit::{DIDResolver, DID_METHODS}; +use ssi::did_resolve::DIDResolver; use tracing::{debug, warn}; use url::Url; use x509_cert::{ @@ -117,18 +117,6 @@ impl SessionBuilder { self } - /// Configure the [ClientId] and set the [ClientIdScheme] to `did`. - /// - /// Uses the default didkit [DIDResolver]. - pub async fn with_did_client_id( - self, - vm: String, - signer: T, - ) -> Result> { - self.with_did_client_id_and_resolver(vm, signer, DID_METHODS.to_resolver()) - .await - } - /// Configure the [ClientId] and set the [ClientIdScheme] to `did`. pub async fn with_did_client_id_and_resolver( self, @@ -140,7 +128,7 @@ impl SessionBuilder { "expected a DID verification method, received '{vm}'" ))?; - let key = didkit::resolve_key(&vm, resolver) + let key = ssi::did_resolve::resolve_key(&vm, resolver) .await .context("unable to resolve key from verification method")?; diff --git a/src/core/verifier/request_signer.rs b/src/core/verifier/request_signer.rs index e4265a5..0684da7 100644 --- a/src/core/verifier/request_signer.rs +++ b/src/core/verifier/request_signer.rs @@ -1,7 +1,7 @@ use anyhow::Result; use async_trait::async_trait; -use didkit::JWK; use p256::ecdsa::{signature::Signer, Signature, SigningKey}; +use ssi::jwk::JWK; #[async_trait] pub trait RequestSigner { diff --git a/src/mdl_request.rs b/src/mdl_request.rs index 5a4cac2..ea9753c 100644 --- a/src/mdl_request.rs +++ b/src/mdl_request.rs @@ -5,10 +5,10 @@ use crate::{ }, utils::NonEmptyVec, }; -use didkit::ssi::jwk::JWK; use isomdl::definitions::helpers::NonEmptyMap; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; +use ssi::jwk::JWK; use std::collections::BTreeMap; use x509_cert::der::referenced::OwnedToRef; use x509_cert::der::Decode; diff --git a/src/utils.rs b/src/utils.rs index c884d74..4f30afb 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,5 +1,4 @@ use anyhow; -use didkit::ssi::jws::Error as JwsError; use isomdl::definitions::helpers::non_empty_map::Error as NonEmptyMapError; use isomdl::definitions::Error as IsomdlDefinitionError; use isomdl::presentation::reader::oid4vp::Error as IsomdlError; @@ -8,6 +7,7 @@ use josekit::JoseError; use reqwest::Error as ReqwestError; use serde::{Deserialize, Serialize}; use serde_cbor::Error as CborError; +use ssi::jws::Error as JwsError; use std::ops::Deref; // #[derive(Clone)] @@ -200,8 +200,8 @@ impl From for Openid4vpError { } } -impl From for Openid4vpError { - fn from(_value: didkit::ssi::jwk::Error) -> Self { +impl From for Openid4vpError { + fn from(_value: ssi::jwk::Error) -> Self { Openid4vpError::InvalidRequest } }