1#[cfg(target_arch = "wasm32")]
2use serde::{Deserialize, Serialize};
3#[cfg(target_arch = "wasm32")]
4use serde_json::Value;
5#[cfg(target_arch = "wasm32")]
6use serde_wasm_bindgen::to_value;
7#[cfg(target_arch = "wasm32")]
8use wasm_bindgen::prelude::*;
9
10#[cfg(target_arch = "wasm32")]
18#[wasm_bindgen]
19pub struct SdJwtIssuer {}
20
21#[cfg(target_arch = "wasm32")]
22#[wasm_bindgen]
23impl SdJwtIssuer {
24 #[wasm_bindgen(constructor)]
25 pub fn new() -> SdJwtIssuer {
26 SdJwtIssuer {}
27 }
28
29 pub fn encode(
30 &self,
31 claims: &str,
32 signing_key: &str,
33 algorithm: &str,
34 ) -> Result<String, JsValue> {
35 let (claims, tagged_paths) = parse_yaml(claims)?;
36 let encoding_key = match algorithm {
37 "RS256" | "RS384" | "RS512" | "PS256" | "PS384" | "PS512" => {
38 KeyForEncoding::from_rsa_pem(signing_key.as_bytes())?
39 }
40 "ES256" | "ES384" | "ES512" => KeyForEncoding::from_ec_pem(signing_key.as_bytes())?,
41 _ => return Err(JsValue::from_str("Unsupported algorithm")),
42 };
43 let issuer_sd_jwt = crate::issuer::Issuer::new(claims.clone())?
44 .iter_disclosable(tagged_paths.iter())
45 .encode(&encoding_key)?;
46 Ok(issuer_sd_jwt)
47 }
48}
49
50#[cfg(target_arch = "wasm32")]
51impl Default for SdJwtIssuer {
52 fn default() -> Self {
53 Self::new()
54 }
55}
56
57#[cfg(target_arch = "wasm32")]
58#[derive(Serialize, Deserialize)]
59pub struct DecodedIssuerJwt {
60 pub header: Value,
61 pub updated_claims: Value,
62 pub disclosure_paths: Vec<DisclosurePath>,
63}
64
65#[cfg(target_arch = "wasm32")]
66#[wasm_bindgen]
67pub struct SdJwtHolder {}
68
69#[cfg(target_arch = "wasm32")]
70#[wasm_bindgen]
71impl SdJwtHolder {
72 #[wasm_bindgen(constructor)]
73 pub fn new() -> Self {
74 SdJwtHolder {}
75 }
76
77 #[wasm_bindgen]
78 pub fn verify(
79 &self,
80 encoded_issuer_jwt: &str,
81 public_key: &str,
82 algorithm: &str,
83 ) -> Result<JsValue, JsValue> {
84 let decoding_key = match algorithm {
85 "RS256" | "RS384" | "RS512" => KeyForDecoding::from_rsa_pem(public_key.as_bytes())?,
86 "ES256" | "ES384" | "ES512" => KeyForDecoding::from_ec_pem(public_key.as_bytes())?,
87 _ => return Err(JsValue::from_str("Unsupported algorithm")),
88 };
89 let validation = Validation::default().without_expiry();
90 let (header, decoded_claims, disclosure_paths) =
91 Holder::verify(encoded_issuer_jwt, &decoding_key, &validation)?;
92 let decoded_issuer_jwt = DecodedIssuerJwt {
93 header,
94 updated_claims: decoded_claims,
95 disclosure_paths,
96 };
97 Ok(to_value(&decoded_issuer_jwt)?)
98 }
99
100 #[wasm_bindgen]
101 pub fn presentation(
102 &self,
103 encoded_issuer_jwt: &str,
104 redacted_paths: Vec<String>,
105 ) -> Result<String, JsValue> {
106 let mut presentation = Holder::presentation(encoded_issuer_jwt)?;
107 let _ = redacted_paths
108 .iter()
109 .try_for_each::<_, Result<(), Error>>(|path| {
110 presentation.redact(path)?;
111 Ok(())
112 });
113
114 Ok(presentation.build()?)
115 }
116}
117
118#[cfg(target_arch = "wasm32")]
119impl Default for SdJwtHolder {
120 fn default() -> Self {
121 Self::new()
122 }
123}
124
125#[cfg(target_arch = "wasm32")]
126#[derive(Debug, Serialize, Deserialize)]
127pub struct DecodedHolderJwt {
128 pub header: Value,
129 pub restored_claims: Value,
130}
131
132#[cfg(target_arch = "wasm32")]
133#[wasm_bindgen]
134pub struct SdJwtVerifier {}
135
136#[cfg(target_arch = "wasm32")]
137#[wasm_bindgen]
138impl SdJwtVerifier {
139 #[wasm_bindgen(constructor)]
140 pub fn new() -> Self {
141 SdJwtVerifier {}
142 }
143
144 #[wasm_bindgen]
145 pub fn verify(
146 &self,
147 holder_presentation_sdjwt: &str,
148 public_key: &str,
149 algorithm: &str,
150 ) -> Result<JsValue, JsValue> {
151 let decoding_key = match algorithm {
152 "RS256" | "RS384" | "RS512" => KeyForDecoding::from_rsa_pem(public_key.as_bytes())?,
153 "ES256" | "ES384" | "ES512" => KeyForDecoding::from_ec_pem(public_key.as_bytes())?,
154 _ => return Err(JsValue::from_str("Unsupported algorithm")),
155 };
156 let validation = Validation::default().without_expiry();
157 let (header, restored_claims) =
158 Verifier::verify(holder_presentation_sdjwt, &decoding_key, &validation, &None)?;
159 let decoded_holder_jwt = DecodedHolderJwt {
160 header,
161 restored_claims,
162 };
163 Ok(to_value(&decoded_holder_jwt)?)
164 }
165}
166
167#[cfg(target_arch = "wasm32")]
168impl Default for SdJwtVerifier {
169 fn default() -> Self {
170 Self::new()
171 }
172}
173
174pub mod algorithm;
175pub mod decoding;
176pub(crate) mod decoy;
177pub mod disclosure;
178pub mod disclosure_path;
179pub mod encoding;
180pub mod error;
181pub mod header;
182pub mod holder;
183pub mod issuer;
184pub mod jwk;
185mod parser;
186mod utils;
187pub mod validation;
188pub mod verifier;
189
190#[cfg(test)]
191mod test_utils;
192
193pub use algorithm::*;
194pub use decoding::*;
195pub use disclosure::Disclosure;
196pub use disclosure_path::*;
197pub use encoding::*;
198pub use error::*;
199pub use header::*;
200pub use holder::*;
201pub use issuer::*;
202pub use jwk::*;
203pub use parser::parse_yaml;
204pub use validation::*;
205pub use verifier::*;