identity_credential/sd_jwt_vc/metadata/
issuer.rs1use identity_core::common::Url;
5use identity_verification::jwk::JwkSet;
6use serde::Deserialize;
7use serde::Serialize;
8
9use crate::sd_jwt_vc::Error;
10use crate::sd_jwt_vc::SdJwtVc;
11
12pub const WELL_KNOWN_VC_ISSUER: &str = "/.well-known/jwt-vc-issuer";
14
15#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
21pub struct IssuerMetadata {
22 pub issuer: Url,
24 #[serde(flatten)]
26 pub jwks: Jwks,
27}
28
29impl IssuerMetadata {
30 pub fn validate(&self, sd_jwt_vc: &SdJwtVc) -> Result<(), Error> {
33 let expected_issuer = sd_jwt_vc.claims().iss.as_ref().ok_or_else(|| {
34 Error::InvalidIssuerMetadata(anyhow::anyhow!(
35 "SD-JWT VC is missing 'iss' claim required for issuer metadata validation"
36 ))
37 })?;
38 let actual_issuer = &self.issuer;
39 if actual_issuer != expected_issuer {
40 Err(Error::InvalidIssuerMetadata(anyhow::anyhow!(
41 "expected issuer \"{expected_issuer}\", but found \"{actual_issuer}\""
42 )))
43 } else {
44 Ok(())
45 }
46 }
47}
48
49#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
51pub enum Jwks {
52 #[serde(rename = "jwks_uri")]
54 Uri(Url),
55 #[serde(rename = "jwks")]
57 Object(JwkSet),
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 const EXAMPLE_URI_ISSUER_METADATA: &str = r#"
65{
66 "issuer":"https://example.com",
67 "jwks_uri":"https://jwt-vc-issuer.example.org/my_public_keys.jwks"
68}
69 "#;
70 const EXAMPLE_JWKS_ISSUER_METADATA: &str = r#"
71{
72 "issuer":"https://example.com",
73 "jwks":{
74 "keys":[
75 {
76 "kid":"doc-signer-05-25-2022",
77 "e":"AQAB",
78 "n":"nj3YJwsLUFl9BmpAbkOswCNVx17Eh9wMO-_AReZwBqfaWFcfGHrZXsIV2VMCNVNU8Tpb4obUaSXcRcQ-VMsfQPJm9IzgtRdAY8NN8Xb7PEcYyklBjvTtuPbpzIaqyiUepzUXNDFuAOOkrIol3WmflPUUgMKULBN0EUd1fpOD70pRM0rlp_gg_WNUKoW1V-3keYUJoXH9NztEDm_D2MQXj9eGOJJ8yPgGL8PAZMLe2R7jb9TxOCPDED7tY_TU4nFPlxptw59A42mldEmViXsKQt60s1SLboazxFKveqXC_jpLUt22OC6GUG63p-REw-ZOr3r845z50wMuzifQrMI9bQ",
79 "kty":"RSA"
80 }
81 ]
82 }
83}
84 "#;
85
86 #[test]
87 fn deserializing_uri_metadata_works() {
88 let issuer_metadata: IssuerMetadata = serde_json::from_str(EXAMPLE_URI_ISSUER_METADATA).unwrap();
89 assert!(matches!(issuer_metadata.jwks, Jwks::Uri(_)));
90 }
91
92 #[test]
93 fn deserializing_jwks_metadata_works() {
94 let issuer_metadata: IssuerMetadata = serde_json::from_str(EXAMPLE_JWKS_ISSUER_METADATA).unwrap();
95 assert!(matches!(issuer_metadata.jwks, Jwks::Object { .. }));
96 }
97}