identity_jose/jwk/key_params.rs
1// Copyright 2020-2023 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use zeroize::Zeroize;
5
6use crate::error::Error;
7use crate::error::Result;
8use crate::jwk::EcCurve;
9use crate::jwk::EcxCurve;
10use crate::jwk::EdCurve;
11use crate::jwk::JwkType;
12
13use super::BlsCurve;
14
15/// Algorithm-specific parameters for JSON Web Keys.
16///
17/// [More Info](https://tools.ietf.org/html/rfc7518#section-6)
18#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize, serde::Serialize)]
19#[serde(untagged)]
20#[derive(Zeroize)]
21#[zeroize(drop)]
22pub enum JwkParams {
23 /// Elliptic Curve parameters.
24 Ec(JwkParamsEc),
25 /// RSA parameters.
26 Rsa(JwkParamsRsa),
27 /// Octet Sequence parameters used to represent symmetric keys.
28 Oct(JwkParamsOct),
29 /// Octet Key Pairs parameters.
30 Okp(JwkParamsOkp),
31}
32
33impl JwkParams {
34 /// Creates new `JwkParams` with the given `kty` parameter.
35 pub const fn new(kty: JwkType) -> Self {
36 match kty {
37 JwkType::Ec => Self::Ec(JwkParamsEc::new()),
38 JwkType::Rsa => Self::Rsa(JwkParamsRsa::new()),
39 JwkType::Oct => Self::Oct(JwkParamsOct::new()),
40 JwkType::Okp => Self::Okp(JwkParamsOkp::new()),
41 }
42 }
43
44 /// Returns the key type `kty`.
45 pub const fn kty(&self) -> JwkType {
46 match self {
47 Self::Ec(inner) => inner.kty(),
48 Self::Rsa(inner) => inner.kty(),
49 Self::Oct(inner) => inner.kty(),
50 Self::Okp(inner) => inner.kty(),
51 }
52 }
53
54 /// Returns a clone with _all_ private key components unset. The `None` variant is returned
55 /// in the case of [`JwkParams::Oct`] as such keys are not considered public by
56 /// this library.
57 pub fn to_public(&self) -> Option<Self> {
58 match self {
59 Self::Okp(inner) => Some(Self::Okp(inner.to_public())),
60 Self::Ec(inner) => Some(Self::Ec(inner.to_public())),
61 Self::Rsa(inner) => Some(Self::Rsa(inner.to_public())),
62 Self::Oct(_) => None,
63 }
64 }
65
66 /// Returns `true` if _all_ private key components are unset, `false` otherwise.
67 pub fn is_public(&self) -> bool {
68 match self {
69 Self::Okp(value) => value.is_public(),
70 Self::Ec(value) => value.is_public(),
71 Self::Rsa(value) => value.is_public(),
72 Self::Oct(value) => value.is_public(),
73 }
74 }
75}
76
77// =============================================================================
78// Jwk Params Ec
79// =============================================================================
80
81/// Parameters for Elliptic Curve Keys.
82///
83/// [More Info](https://tools.ietf.org/html/rfc7518#section-6.2)
84#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize, serde::Serialize, Zeroize)]
85#[zeroize(drop)]
86pub struct JwkParamsEc {
87 /// Identifies the cryptographic curve used with the key.
88 ///
89 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.2.1.1)
90 pub crv: String, // Curve
91 /// The `x` coordinate for the Elliptic Curve point as a base64url-encoded
92 /// value.
93 ///
94 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.2.1.2)
95 pub x: String, // X Coordinate
96 /// The `y` coordinate for the Elliptic Curve point as a base64url-encoded
97 /// value.
98 ///
99 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.2.1.3)
100 pub y: String, // Y Coordinate
101 /// The Elliptic Curve private key as a base64url-encoded value.
102 ///
103 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.2.2.1)
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub d: Option<String>, // ECC Private Key
106}
107
108impl Default for JwkParamsEc {
109 fn default() -> Self {
110 Self::new()
111 }
112}
113
114impl JwkParamsEc {
115 /// Creates new JWK EC Params.
116 pub const fn new() -> Self {
117 Self {
118 crv: String::new(),
119 x: String::new(),
120 y: String::new(),
121 d: None,
122 }
123 }
124
125 /// Returns the key type `kty`.
126 pub const fn kty(&self) -> JwkType {
127 JwkType::Ec
128 }
129
130 /// Returns a clone with _all_ private key components unset.
131 pub fn to_public(&self) -> Self {
132 Self {
133 crv: self.crv.clone(),
134 x: self.x.clone(),
135 y: self.y.clone(),
136 d: None,
137 }
138 }
139
140 /// Returns `true` if _all_ private key components of the key are unset, `false` otherwise.
141 pub fn is_public(&self) -> bool {
142 self.d.is_none()
143 }
144
145 /// Returns `true` if _all_ private key components of the key are set, `false` otherwise.
146 pub fn is_private(&self) -> bool {
147 self.d.is_some()
148 }
149
150 /// Returns the [`EcCurve`] if it is of a supported type.
151 pub fn try_ec_curve(&self) -> Result<EcCurve> {
152 match &*self.crv {
153 "P-256" => Ok(EcCurve::P256),
154 "P-384" => Ok(EcCurve::P384),
155 "P-521" => Ok(EcCurve::P521),
156 "secp256k1" => Ok(EcCurve::Secp256K1),
157 _ => Err(Error::KeyError("Ec Curve")),
158 }
159 }
160
161 /// Returns the [`BlsCurve`] if it is of a supported type.
162 pub fn try_bls_curve(&self) -> Result<BlsCurve> {
163 match &*self.crv {
164 "BLS12381G1" => Ok(BlsCurve::BLS12381G1),
165 "BLS12381G2" => Ok(BlsCurve::BLS12381G2),
166 "BLS48581G1" => Ok(BlsCurve::BLS48581G1),
167 "BLS48581G2" => Ok(BlsCurve::BLS48581G2),
168 _ => Err(Error::KeyError("BLS Curve")),
169 }
170 }
171}
172
173impl From<JwkParamsEc> for JwkParams {
174 fn from(other: JwkParamsEc) -> Self {
175 Self::Ec(other)
176 }
177}
178
179// =============================================================================
180// Jwk Params Rsa
181// =============================================================================
182
183/// Parameters for RSA Keys.
184///
185/// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3)
186#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize, serde::Serialize, Zeroize)]
187#[zeroize(drop)]
188pub struct JwkParamsRsa {
189 /// The modulus value for the RSA public key as a base64urlUInt-encoded value.
190 ///
191 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.1.1)
192 pub n: String, // Modulus
193 /// The exponent value for the RSA public key as a base64urlUInt-encoded
194 /// value.
195 ///
196 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.1.2)
197 pub e: String, // Exponent
198 /// The private exponent value for the RSA private key as a
199 /// base64urlUInt-encoded value.
200 ///
201 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.2.1)
202 #[serde(skip_serializing_if = "Option::is_none")]
203 pub d: Option<String>, // Private Exponent
204 /// The first prime factor as a base64urlUInt-encoded value.
205 ///
206 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.2.2)
207 #[serde(skip_serializing_if = "Option::is_none")]
208 pub p: Option<String>, // First Prime Factor
209 /// The second prime factor as a base64urlUInt-encoded value.
210 ///
211 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.2.3)
212 #[serde(skip_serializing_if = "Option::is_none")]
213 pub q: Option<String>, // Second Prime Factor
214 /// The Chinese Remainder Theorem (CRT) exponent of the first factor as a
215 /// base64urlUInt-encoded value.
216 ///
217 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.2.4)
218 #[serde(skip_serializing_if = "Option::is_none")]
219 pub dp: Option<String>, // First Factor CRT Exponent
220 /// The CRT exponent of the second factor as a base64urlUInt-encoded value.
221 ///
222 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.2.5)
223 #[serde(skip_serializing_if = "Option::is_none")]
224 pub dq: Option<String>, // Second Factor CRT Exponent
225 /// The CRT coefficient of the second factor as a base64urlUInt-encoded value.
226 ///
227 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.2.6)
228 #[serde(skip_serializing_if = "Option::is_none")]
229 pub qi: Option<String>, // First CRT Coefficient
230 /// An array of information about any third and subsequent primes, should they
231 /// exist.
232 ///
233 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.2.7)
234 #[serde(skip_serializing_if = "Option::is_none")]
235 pub oth: Option<Vec<JwkParamsRsaPrime>>, // Other Primes Info
236}
237
238/// Parameters for RSA Primes
239///
240/// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.2.7)
241#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize, serde::Serialize, Zeroize)]
242#[zeroize(drop)]
243pub struct JwkParamsRsaPrime {
244 /// The value of a subsequent prime factor as a base64urlUInt-encoded value.
245 ///
246 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.2.7.1)
247 pub r: String, // Prime Factor
248 /// The CRT exponent of the corresponding prime factor as a
249 /// base64urlUInt-encoded value.
250 ///
251 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.2.7.2)
252 pub d: String, // Factor CRT Exponent
253 /// The CRT coefficient of the corresponding prime factor as a
254 /// base64urlUInt-encoded value.
255 ///
256 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.3.2.7.3)
257 pub t: String, // Factor CRT Coefficient
258}
259
260impl Default for JwkParamsRsa {
261 fn default() -> Self {
262 Self::new()
263 }
264}
265
266impl JwkParamsRsa {
267 /// Creates new JWK RSA Params.
268 pub const fn new() -> Self {
269 Self {
270 n: String::new(),
271 e: String::new(),
272 d: None,
273 p: None,
274 q: None,
275 dp: None,
276 dq: None,
277 qi: None,
278 oth: None,
279 }
280 }
281
282 /// Returns the key type `kty`.
283 pub const fn kty(&self) -> JwkType {
284 JwkType::Rsa
285 }
286
287 /// Returns a clone with _all_ private key components unset.
288 pub fn to_public(&self) -> Self {
289 Self {
290 n: self.n.clone(),
291 e: self.e.clone(),
292 d: None,
293 p: None,
294 q: None,
295 dp: None,
296 dq: None,
297 qi: None,
298 oth: None,
299 }
300 }
301
302 /// Returns `true` if _all_ private key components of the key are unset, `false` otherwise.
303 pub fn is_public(&self) -> bool {
304 self.d.is_none()
305 && self.p.is_none()
306 && self.q.is_none()
307 && self.dp.is_none()
308 && self.dq.is_none()
309 && self.qi.is_none()
310 && self.oth.is_none()
311 }
312
313 /// Returns `true` if _all_ private key components of the key are set, `false` otherwise.
314 ///
315 /// Since the `oth` parameter is optional in a private key, its presence is not checked.
316 pub fn is_private(&self) -> bool {
317 self.d.is_some()
318 && self.p.is_some()
319 && self.q.is_some()
320 && self.dp.is_some()
321 && self.dq.is_some()
322 && self.qi.is_some()
323 }
324}
325
326impl From<JwkParamsRsa> for JwkParams {
327 fn from(other: JwkParamsRsa) -> Self {
328 Self::Rsa(other)
329 }
330}
331
332// =============================================================================
333// Jwk Params Oct
334// =============================================================================
335
336/// Parameters for Symmetric Keys.
337///
338/// [More Info](https://tools.ietf.org/html/rfc7518#section-6.4)
339#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize, serde::Serialize, Zeroize)]
340#[zeroize(drop)]
341pub struct JwkParamsOct {
342 /// The symmetric key as a base64url-encoded value.
343 ///
344 /// [More Info](https://tools.ietf.org/html/rfc7518#section-6.4.1)
345 pub k: String, // Key Value
346}
347
348impl Default for JwkParamsOct {
349 fn default() -> Self {
350 Self::new()
351 }
352}
353
354impl JwkParamsOct {
355 /// Creates new JWK Oct Params.
356 pub const fn new() -> Self {
357 Self { k: String::new() }
358 }
359
360 /// Returns the key type `kty`.
361 pub const fn kty(&self) -> JwkType {
362 JwkType::Oct
363 }
364
365 /// Always returns `false`. Octet sequence keys
366 /// are not considered public by this library.
367 pub fn is_public(&self) -> bool {
368 false
369 }
370}
371
372impl From<JwkParamsOct> for JwkParams {
373 fn from(other: JwkParamsOct) -> Self {
374 Self::Oct(other)
375 }
376}
377
378// =============================================================================
379// Jwk Params Okp
380// =============================================================================
381
382/// Parameters for Octet Key Pairs.
383///
384/// [More Info](https://tools.ietf.org/html/rfc8037#section-2)
385#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize, serde::Serialize, Zeroize)]
386#[zeroize(drop)]
387pub struct JwkParamsOkp {
388 /// The subtype of the key pair.
389 ///
390 /// [More Info](https://tools.ietf.org/html/rfc8037#section-2)
391 pub crv: String, // Key SubType
392 /// The public key as a base64url-encoded value.
393 ///
394 /// [More Info](https://tools.ietf.org/html/rfc8037#section-2)
395 pub x: String, // Public Key
396 /// The private key as a base64url-encoded value.
397 ///
398 /// [More Info](https://tools.ietf.org/html/rfc8037#section-2)
399 #[serde(skip_serializing_if = "Option::is_none")]
400 pub d: Option<String>, // Private Key
401}
402
403impl Default for JwkParamsOkp {
404 fn default() -> Self {
405 Self::new()
406 }
407}
408
409impl JwkParamsOkp {
410 /// Creates new JWK OKP Params.
411 pub const fn new() -> Self {
412 Self {
413 crv: String::new(),
414 x: String::new(),
415 d: None,
416 }
417 }
418
419 /// Returns the key type `kty`.
420 pub const fn kty(&self) -> JwkType {
421 JwkType::Okp
422 }
423
424 /// Returns a clone with _all_ private key components unset.
425 pub fn to_public(&self) -> Self {
426 Self {
427 crv: self.crv.clone(),
428 x: self.x.clone(),
429 d: None,
430 }
431 }
432
433 /// Returns `true` if _all_ private key components of the key are unset, `false` otherwise.
434 pub fn is_public(&self) -> bool {
435 self.d.is_none()
436 }
437
438 /// Returns `true` if _all_ private key components of the key are set, `false` otherwise.
439 pub fn is_private(&self) -> bool {
440 self.d.is_some()
441 }
442
443 /// Returns the [`EdCurve`] if it is of a supported type.
444 pub fn try_ed_curve(&self) -> Result<EdCurve> {
445 match &*self.crv {
446 "Ed25519" => Ok(EdCurve::Ed25519),
447 "Ed448" => Ok(EdCurve::Ed448),
448 _ => Err(Error::KeyError("Ed Curve")),
449 }
450 }
451
452 /// Returns the [`EcxCurve`] if it is of a supported type.
453 pub fn try_ecx_curve(&self) -> Result<EcxCurve> {
454 match &*self.crv {
455 "X25519" => Ok(EcxCurve::X25519),
456 "X448" => Ok(EcxCurve::X448),
457 _ => Err(Error::KeyError("Ecx Curve")),
458 }
459 }
460}
461
462impl From<JwkParamsOkp> for JwkParams {
463 fn from(other: JwkParamsOkp) -> Self {
464 Self::Okp(other)
465 }
466}