From e03caa8a858e5f53e73535daa322362d9275b57b Mon Sep 17 00:00:00 2001 From: Abdulrahim Al Methiab Date: Tue, 5 Dec 2023 23:28:51 +0100 Subject: [PATCH] add test for decoy/decode --- src/api_test.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/api_test.rs b/src/api_test.rs index 908cd67..8539d10 100644 --- a/src/api_test.rs +++ b/src/api_test.rs @@ -1,11 +1,14 @@ // Copyright 2020-2023 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +use josekit::jws::JwsAlgorithm; use josekit::jws::JwsHeader; +use josekit::jws::JwsVerifier; use josekit::jws::HS256; use josekit::jwt::JwtPayload; use josekit::jwt::{self}; use serde_json::json; +use serde_json::Map; use serde_json::Value; use crate::Disclosure; @@ -160,3 +163,60 @@ fn concealed_object_in_array() { let decoded = decoder.decode(encoder.object(), &disclosures).unwrap(); assert_eq!(Value::Object(decoded), expected); } + +#[test] +fn decode() { + // Values taken from https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-06.html#name-example-2-handling-structur + let sd_jwt = "eyJhbGciOiAiRVMyNTYifQ.eyJfc2QiOiBbIkM5aW5wNllvUmFFWFI0Mjd6WUpQN1FyazFXSF84YmR3T0FfWVVyVW5HUVUiLCAiS3VldDF5QWEwSElRdlluT1ZkNTloY1ZpTzlVZzZKMmtTZnFZUkJlb3d2RSIsICJNTWxkT0ZGekIyZDB1bWxtcFRJYUdlcmhXZFVfUHBZZkx2S2hoX2ZfOWFZIiwgIlg2WkFZT0lJMnZQTjQwVjd4RXhad1Z3ejd5Um1MTmNWd3Q1REw4Ukx2NGciLCAiWTM0em1JbzBRTExPdGRNcFhHd2pCZ0x2cjE3eUVoaFlUMEZHb2ZSLWFJRSIsICJmeUdwMFdUd3dQdjJKRFFsbjFsU2lhZW9iWnNNV0ExMGJRNTk4OS05RFRzIiwgIm9tbUZBaWNWVDhMR0hDQjB1eXd4N2ZZdW8zTUhZS08xNWN6LVJaRVlNNVEiLCAiczBCS1lzTFd4UVFlVTh0VmxsdE03TUtzSVJUckVJYTFQa0ptcXhCQmY1VSJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAwMDAsICJleHAiOiAxODgzMDAwMDAwLCAiYWRkcmVzcyI6IHsiX3NkIjogWyI2YVVoelloWjdTSjFrVm1hZ1FBTzN1MkVUTjJDQzFhSGhlWnBLbmFGMF9FIiwgIkF6TGxGb2JrSjJ4aWF1cFJFUHlvSnotOS1OU2xkQjZDZ2pyN2ZVeW9IemciLCAiUHp6Y1Z1MHFiTXVCR1NqdWxmZXd6a2VzRDl6dXRPRXhuNUVXTndrclEtayIsICJiMkRrdzBqY0lGOXJHZzhfUEY4WmN2bmNXN3p3Wmo1cnlCV3ZYZnJwemVrIiwgImNQWUpISVo4VnUtZjlDQ3lWdWIyVWZnRWs4anZ2WGV6d0sxcF9KbmVlWFEiLCAiZ2xUM2hyU1U3ZlNXZ3dGNVVEWm1Xd0JUdzMyZ25VbGRJaGk4aEdWQ2FWNCIsICJydkpkNmlxNlQ1ZWptc0JNb0d3dU5YaDlxQUFGQVRBY2k0MG9pZEVlVnNBIiwgInVOSG9XWWhYc1poVkpDTkUyRHF5LXpxdDd0NjlnSkt5NVFhRnY3R3JNWDQiXX0sICJfc2RfYWxnIjogInNoYS0yNTYifQ.IjE4EfnYu1RZ1uz6yqtFh5Lppq36VC4VeSr-hLDFpZ9zqBNmMrT5JHLLXTuMJqKQp3NIzDsLaft4GK5bYyfqhg~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgInJlZ2lvbiIsICJcdTZlMmZcdTUzM2EiXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgImNvdW50cnkiLCAiSlAiXQ~"; + let sd_jwt: SdJwt = SdJwt::parse(&sd_jwt).unwrap(); + let (payload, _header) = jwt::decode_with_verifier(&sd_jwt.jwt, &DeocyJwsVerifier {}).unwrap(); + let decoder = SdObjectDecoder::new_with_sha256(); + let decoded: Map = decoder.decode(payload.claims_set(), &sd_jwt.disclosures).unwrap(); + let expected_object = json!({ + "address": { + "country": "JP", + "region": "港区" + }, + "iss": "https://issuer.example.com", + "iat": 1683000000, + "exp": 1883000000 + } + ) + .as_object() + .unwrap() + .clone(); + assert_eq!(expected_object, decoded); +} + +// Boilerplate to allow extracting JWS payload without verifying the signature. +#[derive(Debug, Clone)] +struct DecoyJwsAlgorithm; +impl JwsAlgorithm for DecoyJwsAlgorithm { + fn name(&self) -> &str { + "ES256" + } + + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } +} + +#[derive(Debug, Clone)] +struct DeocyJwsVerifier; +impl JwsVerifier for DeocyJwsVerifier { + fn algorithm(&self) -> &dyn josekit::jws::JwsAlgorithm { + &DecoyJwsAlgorithm {} + } + + fn key_id(&self) -> Option<&str> { + None + } + + fn verify(&self, _message: &[u8], _signature: &[u8]) -> Result<(), josekit::JoseError> { + Ok(()) + } + + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } +}