identity_jose/jwk/
jwk_ext.rs

1// Copyright 2020-2024 IOTA Stiftung, Fondazione Links
2// SPDX-License-Identifier: Apache-2.0
3
4use super::Jwk;
5use super::JwkOperation;
6use super::JwkParams;
7use super::JwkParamsEc;
8use super::JwkType;
9use super::JwkUse;
10use identity_core::common::Url;
11use jsonprooftoken::jpa::algs::ProofAlgorithm;
12use jsonprooftoken::jwk::alg_parameters::Algorithm;
13use jsonprooftoken::jwk::alg_parameters::JwkAlgorithmParameters;
14use jsonprooftoken::jwk::alg_parameters::JwkEllipticCurveKeyParameters;
15use jsonprooftoken::jwk::curves::EllipticCurveTypes;
16use jsonprooftoken::jwk::key::Jwk as JwkExt;
17use jsonprooftoken::jwk::key::KeyOps;
18use jsonprooftoken::jwk::key::PKUse;
19use jsonprooftoken::jwk::types::KeyType;
20use std::str::FromStr;
21
22impl From<KeyOps> for JwkOperation {
23  fn from(value: KeyOps) -> Self {
24    match value {
25      KeyOps::Sign => Self::Sign,
26      KeyOps::Verify => Self::Verify,
27      KeyOps::Encrypt => Self::Encrypt,
28      KeyOps::Decrypt => Self::Decrypt,
29      KeyOps::WrapKey => Self::WrapKey,
30      KeyOps::UnwrapKey => Self::UnwrapKey,
31      KeyOps::DeriveKey => Self::DeriveKey,
32      KeyOps::DeriveBits => Self::DeriveBits,
33      KeyOps::ProofGeneration => Self::ProofGeneration,
34      KeyOps::ProofVerification => Self::ProofVerification,
35    }
36  }
37}
38
39impl From<JwkOperation> for KeyOps {
40  fn from(value: JwkOperation) -> Self {
41    match value {
42      JwkOperation::Sign => Self::Sign,
43      JwkOperation::Verify => Self::Verify,
44      JwkOperation::Encrypt => Self::Encrypt,
45      JwkOperation::Decrypt => Self::Decrypt,
46      JwkOperation::WrapKey => Self::WrapKey,
47      JwkOperation::UnwrapKey => Self::UnwrapKey,
48      JwkOperation::DeriveKey => Self::DeriveKey,
49      JwkOperation::DeriveBits => Self::DeriveBits,
50      JwkOperation::ProofGeneration => Self::ProofGeneration,
51      JwkOperation::ProofVerification => Self::ProofVerification,
52    }
53  }
54}
55
56impl From<PKUse> for JwkUse {
57  fn from(value: PKUse) -> Self {
58    match value {
59      PKUse::Signature => Self::Signature,
60      PKUse::Encryption => Self::Encryption,
61      PKUse::Proof => Self::Proof,
62    }
63  }
64}
65
66impl From<JwkUse> for PKUse {
67  fn from(value: JwkUse) -> Self {
68    match value {
69      JwkUse::Signature => Self::Signature,
70      JwkUse::Encryption => Self::Encryption,
71      JwkUse::Proof => Self::Proof,
72    }
73  }
74}
75
76impl From<JwkEllipticCurveKeyParameters> for JwkParamsEc {
77  fn from(value: JwkEllipticCurveKeyParameters) -> Self {
78    Self {
79      crv: value.crv.to_string(),
80      x: value.x,
81      y: value.y,
82      d: value.d,
83    }
84  }
85}
86
87impl TryInto<JwkEllipticCurveKeyParameters> for &JwkParamsEc {
88  type Error = crate::error::Error;
89
90  fn try_into(self) -> Result<JwkEllipticCurveKeyParameters, Self::Error> {
91    Ok(JwkEllipticCurveKeyParameters {
92      kty: KeyType::EllipticCurve,
93      crv: EllipticCurveTypes::from_str(&self.crv).map_err(|_| Self::Error::KeyError("crv not supported!"))?,
94      x: self.x.clone(),
95      y: self.y.clone(),
96      d: self.d.clone(),
97    })
98  }
99}
100
101impl TryFrom<JwkExt> for Jwk {
102  type Error = crate::error::Error;
103
104  fn try_from(value: JwkExt) -> Result<Self, Self::Error> {
105    let x5u = match value.x5u {
106      Some(v) => Some(Url::from_str(&v).map_err(|_| Self::Error::InvalidClaim("x5u"))?),
107      None => None,
108    };
109
110    let (kty, params) = match value.key_params {
111      JwkAlgorithmParameters::EllipticCurve(p) => (JwkType::Ec, JwkParams::Ec(JwkParamsEc::from(p))),
112      _ => unreachable!(),
113    };
114
115    Ok(Self {
116      kty,
117      use_: value.pk_use.map(JwkUse::from),
118      key_ops: value
119        .key_ops
120        .map(|vec_key_ops| vec_key_ops.into_iter().map(JwkOperation::from).collect()),
121      alg: value.alg.map(|a| a.to_string()),
122      kid: value.kid,
123      x5u,
124      x5c: value.x5c,
125      x5t: value.x5t,
126      x5t_s256: None,
127      params,
128    })
129  }
130}
131
132impl TryInto<JwkExt> for &Jwk {
133  type Error = crate::error::Error;
134
135  fn try_into(self) -> Result<JwkExt, Self::Error> {
136    let params = match &self.params {
137      JwkParams::Ec(p) => JwkAlgorithmParameters::EllipticCurve(p.try_into()?),
138      _ => return Err(Self::Error::InvalidParam("Parameters not supported!")),
139    };
140
141    let alg = match &self.alg {
142      Some(a) => Some(Algorithm::Proof(
143        ProofAlgorithm::from_str(a).map_err(|_| Self::Error::KeyError("Invalid alg"))?,
144      )),
145      None => None,
146    };
147
148    Ok(JwkExt {
149      kid: self.kid.clone(),
150      pk_use: self.use_.map(|u| u.into()),
151      key_ops: self
152        .key_ops
153        .as_deref()
154        .and_then(|vec_key_ops| vec_key_ops.iter().map(|o| Some((*o).into())).collect()),
155      alg,
156      x5u: self.x5u.as_ref().map(|v| v.as_str().to_string()),
157      x5c: self.x5c.clone(),
158      x5t: self.x5t.clone(),
159      key_params: params,
160    })
161  }
162}