identity_credential/validator/jwt_presentation_validation/
jwt_presentation_validator_utils.rs

1// Copyright 2020-2023 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use identity_core::common::Object;
5use identity_core::convert::FromJson;
6use identity_did::DID;
7use identity_verification::jws::Decoder;
8use std::str::FromStr;
9
10use crate::credential::Jwt;
11use crate::presentation::Presentation;
12use crate::presentation::PresentationJwtClaims;
13use crate::validator::jwt_credential_validation::JwtValidationError;
14use crate::validator::jwt_credential_validation::SignerContext;
15
16/// Utility functions for verifying JWT presentations.
17#[non_exhaustive]
18pub struct JwtPresentationValidatorUtils;
19
20impl JwtPresentationValidatorUtils {
21  /// Attempt to extract the holder of the presentation.
22  ///
23  /// # Errors:
24  /// * If deserialization/decoding of the presentation fails.
25  /// * If the holder can't be parsed as DIDs.
26  pub fn extract_holder<H: DID>(presentation: &Jwt) -> std::result::Result<H, JwtValidationError>
27  where
28    <H as FromStr>::Err: std::error::Error + Send + Sync + 'static,
29  {
30    let validation_item = Decoder::new()
31      .decode_compact_serialization(presentation.as_str().as_bytes(), None)
32      .map_err(JwtValidationError::JwsDecodingError)?;
33
34    let claims: PresentationJwtClaims<'_, identity_core::common::Value, Object> =
35      PresentationJwtClaims::from_json_slice(&validation_item.claims()).map_err(|err| {
36        JwtValidationError::PresentationStructure(crate::Error::JwtClaimsSetDeserializationError(err.into()))
37      })?;
38
39    let holder: H = H::from_str(claims.iss.as_str()).map_err(|err| JwtValidationError::SignerUrl {
40      signer_ctx: SignerContext::Holder,
41      source: err.into(),
42    })?;
43    Ok(holder)
44  }
45
46  /// Validates the semantic structure of the `Presentation`.
47  pub fn check_structure<U>(presentation: &Presentation<U>) -> Result<(), JwtValidationError> {
48    presentation
49      .check_structure()
50      .map_err(JwtValidationError::PresentationStructure)
51  }
52}