Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the presentation submission in the oid4vp-rs e2e test. #8

Conversation

Ryanmtate
Copy link
Contributor

@Ryanmtate Ryanmtate commented Aug 8, 2024

As part of this fix, upgrading ssi dependency to 0.8.1;

NOTE: Saving the following for another PR:

  • Handle JWT encoded authorization request.

src/verifier/client.rs Outdated Show resolved Hide resolved
src/verifier/client.rs Outdated Show resolved Hide resolved
tests/jwt_vc.rs Outdated Show resolved Hide resolved
Ryanmtate and others added 5 commits August 8, 2024 14:32
Signed-off-by: Ryan Tate <[email protected]>
add implementation methods for Presentation Definition.

WIP: Need to continue work for Presentation Submission and the rest
of the structs used in the presentation exchange flow.

Signed-off-by: Ryan Tate <[email protected]>

Co-authored-by: Todd Showalter <[email protected]>
@Ryanmtate
Copy link
Contributor Author

Merge #9 before this.

Cargo.toml Outdated Show resolved Hide resolved
src/core/authorization_request/verification/did.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@cobward cobward left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great progress so far!

src/core/authorization_request/verification/did.rs Outdated Show resolved Hide resolved
src/presentation_exchange.rs Outdated Show resolved Hide resolved
src/verifier/client.rs Outdated Show resolved Hide resolved
src/verifier/client.rs Outdated Show resolved Hide resolved
src/core/credential_format/mod.rs Outdated Show resolved Hide resolved
src/core/credential_format/mod.rs Outdated Show resolved Hide resolved
src/core/input_descriptor.rs Show resolved Hide resolved
src/core/presentation_definition.rs Outdated Show resolved Hide resolved
src/core/presentation_definition.rs Outdated Show resolved Hide resolved
src/core/presentation_definition.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep let's yank then.

src/lib.rs Show resolved Hide resolved
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to point out: OID4VP is a framework specification. The semantics are not well defined, and it's down to the "profile" to define how a request is interpreted, and what kind of response to be built.

src/core/metadata/mod.rs Outdated Show resolved Hide resolved
src/tests.rs Outdated Show resolved Hide resolved
tests/e2e.rs Outdated Show resolved Hide resolved
tests/e2e.rs Outdated Show resolved Hide resolved
tests/jwt_vc.rs Outdated Show resolved Hide resolved
Cargo.toml Outdated Show resolved Hide resolved
},
#[serde(rename = "mso_mdoc")]
MsoMDoc(serde_json::Value),
Other(serde_json::Value),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this Other case needs #[serde(untagged)] otherwise it will only capture:

{
  ...
  "Other": { ... }
  ...
}

Could you add a little unit test for deserializing and the designation fn for this case?

/// Other claim format designations not covered by the above.
///
/// The value of this variant is the name of the claim format designation.
Other(String),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above I think this needs a #[serde(untagged)]. Please add a test.

Comment on lines 257 to 271
pub enum CredentialType {
/// an ISO 18013-5:2021 mobile driving license (mDL) Credential
#[serde(rename = "org.iso.18013.5.1.mDL")]
Iso18013_5_1mDl,
/// A vehicle title credential
///
/// Given there is no universal standard for how to present a vehicle title credential,
/// the inner String provides a dynamic way to represent a vehicle title credential.
// TODO: is there a standard identifier for a vehicle title credential instead of `vehicle_title`?
#[serde(rename = "vehicle_title")]
VehicleTitle(String),
// TODO: Add additional credential types here. Fallback to a string for any other credential type.
/// Other credential types not covered by the above.
Other(String),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will never be able to enumerate all credential types, so I think a string is the most reasonable representation.

Comment on lines +8 to +9
/// A Json object of claim formats.
pub type ClaimFormatMap = HashMap<ClaimFormatDesignation, ClaimFormatPayload>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed in addition to ClaimFormat? Isn't ClaimFormatMap equivalent to Vec<ClaimFormat>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The presentation exchange presentation definition test suite test case format_example shows format property as a map. I tried with the Vec<ClaimFormat> but encountered errors in the test case.

{
  "presentation_definition": {
    "id": "32f54163-7166-48f1-93d8-ff217bdb0653",
    "input_descriptors": [],
    "format": {
      "jwt": {
        "alg": ["EdDSA", "ES256K", "ES384"]
      },
      "jwt_vc": {
        "alg": ["ES256K", "ES384"]
      },
      "jwt_vp": {
        "alg": ["EdDSA", "ES256K"]
      },
      "ldp_vc": {
        "proof_type": [
          "JsonWebSignature2020",
          "Ed25519Signature2018",
          "EcdsaSecp256k1Signature2019",
          "RsaSignature2018"
        ]
      },
      "ldp_vp": {
        "proof_type": ["Ed25519Signature2018"]
      },
      "ldp": {
        "proof_type": ["RsaSignature2018"]
      }
    }
  }
}

src/core/input_descriptor.rs Outdated Show resolved Hide resolved
Comment on lines 281 to 282
#[serde(skip_serializing_if = "Option::is_none")]
fields: Option<Vec<ConstraintsField>>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, may not be important to distinguish between None and an empty vec.

src/core/input_descriptor.rs Outdated Show resolved Hide resolved
src/core/presentation_definition.rs Outdated Show resolved Hide resolved
src/core/response/mod.rs Outdated Show resolved Hide resolved
Comment on lines 56 to 76
/// Parse the VP Token as a JSON object.
///
/// This will attempt to decode the token as base64, and if that fails, it
/// will attempt to parse the token as a JSON object.
///
/// See: https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#section-6.1-2.2
///
/// If you want to check for decode errors, use [VpToken::decode_base64].
pub fn parse(&self) -> Result<Json, Error> {
match self.decode_base64() {
Ok(decoded) => Ok(decoded),
Err(_) => Ok(serde_json::from_str(&self.0)?),
}
}

/// Return the Verifiable Presentation Token as a JSON object from a base64
/// encoded string.
pub fn decode_base64(&self) -> Result<Json, Error> {
let decoded = BASE64_STANDARD.decode(&self.0)?;
Ok(serde_json::from_slice(&decoded)?)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These methods are inaccurate:

JSON String or JSON object that MUST contain a single Verifiable Presentation or an array of JSON Strings and JSON objects each of them containing a Verifiable Presentations. Each Verifiable Presentation MUST be represented as a JSON string (that is a Base64url encoded value) or a JSON object depending on a format as defined in Annex E of [OpenID.VCI]

We have a bug in our definition of VpToken. It should be something like:

enum VpToken {
    Single(String),
    SingleAsMap(Map<String, Value>),
    Many(Vec<VpToken>),
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a TODO in the code to update the VpToken. Maybe we can do this in another PR.

/// the requirements of the presentation definition.
///
///
pub fn validate_unencoded(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, this is making an assumption that the VpToken is a VCDM VP. There's also some confusion here about encoded as a JWT vs unencoded. Encoded as a JWT refers to the authorization response (see direct_post.jwt), not the VP token. The VP token is never encoded directly as a JWT. It's either a String, a JSON object, or an array of VP tokens.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method has been removed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we said this should be removed from this library and added to SSI?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay to remove in another PR once added to SSI?

Ryanmtate and others added 4 commits September 12, 2024 14:29
Co-authored-by: Jacob <[email protected]>
…elds

This commit also removes validation logic from vp token response struct.

Signed-off-by: Ryan Tate <[email protected]>
@Ryanmtate Ryanmtate merged commit 13c4733 into spruceid:main Sep 16, 2024
1 check passed
Copy link
Contributor

@timothee-haudebourg timothee-haudebourg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a late review of this to clarify some stuff about ssi.

use std::time::{SystemTime, UNIX_EPOCH};

use serde::{Deserialize, Serialize};
use ssi_claims::jwt::{VerifiableCredential, VerifiablePresentation};
Copy link
Contributor

@timothee-haudebourg timothee-haudebourg Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a confusion here, probably because of the lack of documentation in ssi I'll admit. Those two types are wrappers around the JWT registered claims vc and vp to be used with ssi_claims::jwt::ClaimSet.

If you want to represent VCs and VPs, the appropriate types are defined in ssi_claims::vc.


#[derive(Debug, Clone)]
pub struct VerifiablePresentationBuilderOptions {
pub issuer: DIDURLBuf,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it a requirement of OID4VP that we use DIDs? I know this is not a requirement of VPs.

///
/// This will set the issuance date to the current time and the expiration
/// date to the expiration secs from the issuance date.
pub fn from_options(options: VerifiablePresentationBuilderOptions) -> VerifiablePresentation {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds like a re-implementation of VCDM1.0 JWT VP encoding. This is already implemented in ssi here.

// Create the presentation.
let presentation: ssi::claims::vc::v1::JsonPresentation = ...;

// Encode the JWT claims according to VCDM1.0 JWT VP format.
let jwt_claims = presentation.to_jwt_claims();

// Sign the claims into a JWT.
let jwt = jwt_claims.sign(signer).await.unwrap();

#[serde(rename = "jwt_vp")]
JwtVp,
#[serde(rename = "jwt_vc_json")]
JwtVcJson,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this format?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants