identity_credential/validator/jwt_presentation_validation/
jwt_presentation_validator_utils.rs1use identity_core::common::Object;
5use identity_core::convert::FromJson;
6use identity_did::DID;
7use identity_verification::jws::Decoder;
8use serde_json::Value;
9use std::str::FromStr;
10
11use crate::credential::Jwt;
12use crate::presentation::JwtPresentationV2Claims;
13use crate::presentation::Presentation;
14use crate::presentation::PresentationJwtClaims;
15use crate::validator::jwt_credential_validation::JwtValidationError;
16use crate::validator::jwt_credential_validation::SignerContext;
17
18#[non_exhaustive]
20pub struct JwtPresentationValidatorUtils;
21
22impl JwtPresentationValidatorUtils {
23 pub fn extract_holder<H: DID>(presentation: &Jwt) -> std::result::Result<H, JwtValidationError>
29 where
30 <H as FromStr>::Err: std::error::Error + Send + Sync + 'static,
31 {
32 let validation_item = Decoder::new()
33 .decode_compact_serialization(presentation.as_str().as_bytes(), None)
34 .map_err(JwtValidationError::JwsDecodingError)?;
35
36 let maybe_holder =
38 if let Ok(claims) = PresentationJwtClaims::<Value, Object>::from_json_slice(&validation_item.claims()) {
39 H::from_str(claims.iss.as_str())
40 } else if let Ok(claims) = JwtPresentationV2Claims::<Value, Object>::from_json_slice(&validation_item.claims()) {
41 H::from_str(claims.vp.holder.as_str())
42 } else {
43 return Err(JwtValidationError::PresentationStructure(
44 crate::error::Error::JwtClaimsSetDeserializationError(
45 "Failed to deserialize JWT presentation claims to either a v1 or v2 Verifiable Presentation".into(),
46 ),
47 ));
48 };
49
50 maybe_holder.map_err(|err| JwtValidationError::SignerUrl {
51 signer_ctx: SignerContext::Holder,
52 source: err.into(),
53 })
54 }
55
56 pub fn check_structure<U>(presentation: &Presentation<U>) -> Result<(), JwtValidationError> {
58 presentation
59 .check_structure()
60 .map_err(JwtValidationError::PresentationStructure)
61 }
62}