Skip to content

Commit

Permalink
add data integrity conversion for vp token
Browse files Browse the repository at this point in the history
Additionally adds a check for authorization request
vp formats supported to check cryptosuite against
expected response formats.

Signed-off-by: Ryan Tate <[email protected]>
  • Loading branch information
Ryanmtate committed Nov 13, 2024
1 parent cab7fac commit 453c31d
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 2 deletions.
17 changes: 17 additions & 0 deletions src/core/authorization_request/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::ops::{Deref, DerefMut};

use anyhow::{anyhow, bail, Context, Error, Result};
use parameters::ClientMetadata;
use serde::{Deserialize, Serialize};
use serde_json::Value as Json;
use url::Url;
Expand All @@ -16,6 +17,7 @@ use self::{
};

use super::{
metadata::parameters::verifier::VpFormats,
object::{ParsingErrorContext, UntypedObject},
util::{base_request, AsyncHttpClient},
};
Expand Down Expand Up @@ -263,6 +265,21 @@ impl AuthorizationRequestObject {
pub fn nonce(&self) -> &Nonce {
&self.7
}

/// Return the `client_metadata` field from the authorization request.
pub fn client_metadata(&self) -> Result<ClientMetadata> {
self.0
.get()
.ok_or(anyhow!("missing `client_metadata` object"))?
}

/// Return the `VpFormats` from the `client_metadata` field.
pub fn vp_formats(&self) -> Result<VpFormats> {
self.client_metadata()?
.0
.get()
.ok_or(anyhow!("missing vp_formats"))?
}
}

impl From<AuthorizationRequestObject> for UntypedObject {
Expand Down
1 change: 1 addition & 0 deletions src/core/credential_format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ pub enum ClaimFormatPayload {
/// claim presentation algorithm types supported by a wallet.
#[serde(rename = "alg_values_supported")]
AlgValuesSupported(Vec<String>),
/// This variant is primarily used for `ldp`, `ldp_vc`, `ldp_vp`, `ac_vc`, and `ac_vp`
#[serde(rename = "proof_type")]
ProofType(Vec<String>),
#[serde(untagged)]
Expand Down
5 changes: 5 additions & 0 deletions src/core/input_descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,11 @@ impl Constraints {
self.fields.as_ref()
}

/// Returns the fields of the constraints object as a mutable reference.
pub fn fields_mut(&mut self) -> &mut Vec<ConstraintsField> {
self.fields.as_mut()
}

/// Set the limit disclosure value.
///
/// For all [Claims](https://identity.foundation/presentation-exchange/spec/v2.0.0/#term:claims) submitted in relation to [InputDescriptor] Objects that include a `constraints`
Expand Down
28 changes: 27 additions & 1 deletion src/core/metadata/parameters/verifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::core::credential_format::ClaimFormatMap;
use crate::core::metadata::ClaimFormatPayload;
use crate::core::object::TypedParameter;
use crate::core::{credential_format::ClaimFormatMap, metadata::ClaimFormatDesignation};

use anyhow::{Context, Error};
use serde::{Deserialize, Serialize};
Expand All @@ -8,6 +9,31 @@ use serde_json::{Map, Value as Json};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VpFormats(pub ClaimFormatMap);

impl VpFormats {
/// Returns a boolean to denote whether the format and cryptosuite provided
/// are supported in the VP formats.
///
/// NOTE: This method is interested in the cryptosuite of the claim format
/// payload and not the claim format designation.
///
/// For example, the cryptosuite would need to match one of the `alg`
/// values in the claim format payload.
pub fn supports_cryptosuite(
&self,
format: &ClaimFormatDesignation,
cryptosuite: &String,
) -> bool {
match self.0.get(format) {
Some(ClaimFormatPayload::Alg(alg_values))
| Some(ClaimFormatPayload::AlgValuesSupported(alg_values)) => {
alg_values.contains(cryptosuite)
}
Some(ClaimFormatPayload::ProofType(proof_types)) => proof_types.contains(cryptosuite),
_ => false,
}
}
}

impl TypedParameter for VpFormats {
const KEY: &'static str = "vp_formats";
}
Expand Down
22 changes: 21 additions & 1 deletion src/core/response/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use ssi::{
claims::vc::{self, v2::SpecializedJsonCredential},
json_ld::syntax::Object,
one_or_many::OneOrManyRef,
prelude::AnyJsonPresentation,
prelude::{AnyDataIntegrity, AnyJsonPresentation},
OneOrMany,
};

Expand Down Expand Up @@ -112,6 +112,12 @@ impl From<vc::v2::syntax::JsonPresentation> for VpToken {
}
}

impl From<vc::v2::syntax::JsonPresentation<SpecializedJsonCredential<Object>>> for VpToken {
fn from(value: vc::v2::syntax::JsonPresentation<SpecializedJsonCredential<Object>>) -> Self {
Self(vec![value.into()])
}
}

impl From<AnyJsonPresentation> for VpToken {
fn from(value: AnyJsonPresentation) -> Self {
Self(vec![value.into()])
Expand Down Expand Up @@ -165,6 +171,20 @@ impl From<String> for VpTokenItem {
}
}

impl From<AnyDataIntegrity> for VpTokenItem {
fn from(value: AnyDataIntegrity) -> Self {
let serde_json::Value::Object(obj) = serde_json::to_value(&value)
// SAFETY: by definition a Data Integrity Object is a Json LD Node and is a JSON object.
.unwrap()
else {
// SAFETY: by definition a Data Integrity Object is a Json LD Node and is a JSON object.
unreachable!()
};

Self::JsonObject(obj)
}
}

impl From<vc::v1::syntax::JsonPresentation> for VpTokenItem {
fn from(value: vc::v1::syntax::JsonPresentation) -> Self {
let serde_json::Value::Object(obj) = serde_json::to_value(value)
Expand Down

0 comments on commit 453c31d

Please sign in to comment.