mas_jose/jwa/
asymmetric.rs

1// Copyright 2024 New Vector Ltd.
2// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
3//
4// SPDX-License-Identifier: AGPL-3.0-only
5// Please see LICENSE in the repository root for full details.
6
7use digest::Digest;
8use mas_iana::jose::{JsonWebKeyEcEllipticCurve, JsonWebSignatureAlg};
9use sha2::{Sha256, Sha384, Sha512};
10use signature::rand_core::CryptoRngCore;
11use thiserror::Error;
12
13use super::signature::Signature;
14use crate::jwk::{JsonWebKeyPrivateParameters, JsonWebKeyPublicParameters};
15
16#[derive(Debug, Error)]
17pub enum AsymmetricKeyFromJwkError {
18    #[error("Invalid RSA parameters")]
19    Rsa {
20        #[from]
21        inner: rsa::errors::Error,
22    },
23
24    #[error("Invalid Elliptic Curve parameters")]
25    EllipticCurve {
26        #[from]
27        inner: elliptic_curve::Error,
28    },
29
30    #[error("Unsupported algorithm {alg}")]
31    UnsupportedAlgorithm { alg: JsonWebSignatureAlg },
32
33    #[error("Key not suitable for algorithm {alg}")]
34    KeyNotSuitable { alg: JsonWebSignatureAlg },
35}
36
37/// An enum of all supported asymmetric signature algorithms verifying keys
38#[non_exhaustive]
39pub enum AsymmetricSigningKey {
40    Rs256(super::Rs256SigningKey),
41    Rs384(super::Rs384SigningKey),
42    Rs512(super::Rs512SigningKey),
43    Ps256(super::Ps256SigningKey),
44    Ps384(super::Ps384SigningKey),
45    Ps512(super::Ps512SigningKey),
46    Es256(super::Es256SigningKey),
47    Es384(super::Es384SigningKey),
48    Es256K(super::Es256KSigningKey),
49}
50
51impl AsymmetricSigningKey {
52    /// Create a new signing key with the RS256 algorithm from the given RSA
53    /// private key.
54    #[must_use]
55    pub fn rs256(key: rsa::RsaPrivateKey) -> Self {
56        Self::Rs256(rsa::pkcs1v15::SigningKey::new(key))
57    }
58
59    /// Create a new signing key with the RS384 algorithm from the given RSA
60    /// private key.
61    #[must_use]
62    pub fn rs384(key: rsa::RsaPrivateKey) -> Self {
63        Self::Rs384(rsa::pkcs1v15::SigningKey::new(key))
64    }
65
66    /// Create a new signing key with the RS512 algorithm from the given RSA
67    /// private key.
68    #[must_use]
69    pub fn rs512(key: rsa::RsaPrivateKey) -> Self {
70        Self::Rs512(rsa::pkcs1v15::SigningKey::new(key))
71    }
72
73    /// Create a new signing key with the PS256 algorithm from the given RSA
74    /// private key.
75    #[must_use]
76    pub fn ps256(key: rsa::RsaPrivateKey) -> Self {
77        Self::Ps256(rsa::pss::SigningKey::new_with_salt_len(
78            key,
79            Sha256::output_size(),
80        ))
81    }
82
83    /// Create a new signing key with the PS384 algorithm from the given RSA
84    /// private key.
85    #[must_use]
86    pub fn ps384(key: rsa::RsaPrivateKey) -> Self {
87        Self::Ps384(rsa::pss::SigningKey::new_with_salt_len(
88            key,
89            Sha384::output_size(),
90        ))
91    }
92
93    /// Create a new signing key with the PS512 algorithm from the given RSA
94    /// private key.
95    #[must_use]
96    pub fn ps512(key: rsa::RsaPrivateKey) -> Self {
97        Self::Ps512(rsa::pss::SigningKey::new_with_salt_len(
98            key,
99            Sha512::output_size(),
100        ))
101    }
102
103    /// Create a new signing key with the ES256 algorithm from the given ECDSA
104    /// private key.
105    #[must_use]
106    pub fn es256(key: elliptic_curve::SecretKey<p256::NistP256>) -> Self {
107        Self::Es256(ecdsa::SigningKey::from(key))
108    }
109
110    /// Create a new signing key with the ES384 algorithm from the given ECDSA
111    /// private key.
112    #[must_use]
113    pub fn es384(key: elliptic_curve::SecretKey<p384::NistP384>) -> Self {
114        Self::Es384(ecdsa::SigningKey::from(key))
115    }
116
117    /// Create a new signing key with the ES256K algorithm from the given ECDSA
118    /// private key.
119    #[must_use]
120    pub fn es256k(key: elliptic_curve::SecretKey<k256::Secp256k1>) -> Self {
121        Self::Es256K(ecdsa::SigningKey::from(key))
122    }
123
124    /// Create a new signing key for the given algorithm from the given private
125    /// JWK parameters.
126    ///
127    /// # Errors
128    ///
129    /// Returns an error if the key parameters are not suitable for the given
130    /// algorithm.
131    pub fn from_jwk_and_alg(
132        params: &JsonWebKeyPrivateParameters,
133        alg: &JsonWebSignatureAlg,
134    ) -> Result<Self, AsymmetricKeyFromJwkError> {
135        match (params, alg) {
136            (JsonWebKeyPrivateParameters::Rsa(params), alg) => match alg {
137                JsonWebSignatureAlg::Rs256 => Ok(Self::rs256(params.try_into()?)),
138                JsonWebSignatureAlg::Rs384 => Ok(Self::rs384(params.try_into()?)),
139                JsonWebSignatureAlg::Rs512 => Ok(Self::rs512(params.try_into()?)),
140                JsonWebSignatureAlg::Ps256 => Ok(Self::ps256(params.try_into()?)),
141                JsonWebSignatureAlg::Ps384 => Ok(Self::ps384(params.try_into()?)),
142                JsonWebSignatureAlg::Ps512 => Ok(Self::ps512(params.try_into()?)),
143                _ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg: alg.clone() }),
144            },
145
146            (JsonWebKeyPrivateParameters::Ec(params), JsonWebSignatureAlg::Es256)
147                if params.crv == JsonWebKeyEcEllipticCurve::P256 =>
148            {
149                Ok(Self::es256(params.try_into()?))
150            }
151
152            (JsonWebKeyPrivateParameters::Ec(params), JsonWebSignatureAlg::Es384)
153                if params.crv == JsonWebKeyEcEllipticCurve::P384 =>
154            {
155                Ok(Self::es384(params.try_into()?))
156            }
157
158            (JsonWebKeyPrivateParameters::Ec(params), JsonWebSignatureAlg::Es512)
159                if params.crv == JsonWebKeyEcEllipticCurve::P521 =>
160            {
161                Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg: alg.clone() })
162            }
163
164            (JsonWebKeyPrivateParameters::Ec(params), JsonWebSignatureAlg::Es256K)
165                if params.crv == JsonWebKeyEcEllipticCurve::Secp256K1 =>
166            {
167                Ok(Self::es256k(params.try_into()?))
168            }
169
170            (JsonWebKeyPrivateParameters::Okp(_params), JsonWebSignatureAlg::EdDsa) => {
171                Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg: alg.clone() })
172            }
173
174            _ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg: alg.clone() }),
175        }
176    }
177}
178
179impl From<super::Rs256SigningKey> for AsymmetricSigningKey {
180    fn from(key: super::Rs256SigningKey) -> Self {
181        Self::Rs256(key)
182    }
183}
184
185impl From<super::Rs384SigningKey> for AsymmetricSigningKey {
186    fn from(key: super::Rs384SigningKey) -> Self {
187        Self::Rs384(key)
188    }
189}
190
191impl From<super::Rs512SigningKey> for AsymmetricSigningKey {
192    fn from(key: super::Rs512SigningKey) -> Self {
193        Self::Rs512(key)
194    }
195}
196
197impl From<super::Ps256SigningKey> for AsymmetricSigningKey {
198    fn from(key: super::Ps256SigningKey) -> Self {
199        Self::Ps256(key)
200    }
201}
202
203impl From<super::Ps384SigningKey> for AsymmetricSigningKey {
204    fn from(key: super::Ps384SigningKey) -> Self {
205        Self::Ps384(key)
206    }
207}
208
209impl From<super::Ps512SigningKey> for AsymmetricSigningKey {
210    fn from(key: super::Ps512SigningKey) -> Self {
211        Self::Ps512(key)
212    }
213}
214
215impl From<super::Es256SigningKey> for AsymmetricSigningKey {
216    fn from(key: super::Es256SigningKey) -> Self {
217        Self::Es256(key)
218    }
219}
220
221impl From<super::Es384SigningKey> for AsymmetricSigningKey {
222    fn from(key: super::Es384SigningKey) -> Self {
223        Self::Es384(key)
224    }
225}
226
227impl From<super::Es256KSigningKey> for AsymmetricSigningKey {
228    fn from(key: super::Es256KSigningKey) -> Self {
229        Self::Es256K(key)
230    }
231}
232
233impl signature::RandomizedSigner<Signature> for AsymmetricSigningKey {
234    fn try_sign_with_rng(
235        &self,
236        rng: &mut impl CryptoRngCore,
237        msg: &[u8],
238    ) -> Result<Signature, signature::Error> {
239        match self {
240            Self::Rs256(key) => {
241                let signature = key.try_sign_with_rng(rng, msg)?;
242                Ok(Signature::from_signature(&signature))
243            }
244            Self::Rs384(key) => {
245                let signature = key.try_sign_with_rng(rng, msg)?;
246                Ok(Signature::from_signature(&signature))
247            }
248            Self::Rs512(key) => {
249                let signature = key.try_sign_with_rng(rng, msg)?;
250                Ok(Signature::from_signature(&signature))
251            }
252            Self::Ps256(key) => {
253                let signature = key.try_sign_with_rng(rng, msg)?;
254                Ok(Signature::from_signature(&signature))
255            }
256            Self::Ps384(key) => {
257                let signature = key.try_sign_with_rng(rng, msg)?;
258                Ok(Signature::from_signature(&signature))
259            }
260            Self::Ps512(key) => {
261                let signature = key.try_sign_with_rng(rng, msg)?;
262                Ok(Signature::from_signature(&signature))
263            }
264            Self::Es256(key) => {
265                let signature: ecdsa::Signature<_> = key.try_sign_with_rng(rng, msg)?;
266                Ok(Signature::from_signature(&signature))
267            }
268            Self::Es384(key) => {
269                let signature: ecdsa::Signature<_> = key.try_sign_with_rng(rng, msg)?;
270                Ok(Signature::from_signature(&signature))
271            }
272            Self::Es256K(key) => {
273                let signature: ecdsa::Signature<_> = key.try_sign_with_rng(rng, msg)?;
274                Ok(Signature::from_signature(&signature))
275            }
276        }
277    }
278}
279
280/// An enum of all supported asymmetric signature algorithms signing keys
281#[non_exhaustive]
282pub enum AsymmetricVerifyingKey {
283    Rs256(super::Rs256VerifyingKey),
284    Rs384(super::Rs384VerifyingKey),
285    Rs512(super::Rs512VerifyingKey),
286    Ps256(super::Ps256VerifyingKey),
287    Ps384(super::Ps384VerifyingKey),
288    Ps512(super::Ps512VerifyingKey),
289    Es256(super::Es256VerifyingKey),
290    Es384(super::Es384VerifyingKey),
291    Es256K(super::Es256KVerifyingKey),
292}
293
294impl AsymmetricVerifyingKey {
295    /// Create a new verifying key with the RS256 algorithm from the given RSA
296    /// public key.
297    #[must_use]
298    pub fn rs256(key: rsa::RsaPublicKey) -> Self {
299        Self::Rs256(rsa::pkcs1v15::VerifyingKey::new(key))
300    }
301
302    /// Create a new verifying key with the RS384 algorithm from the given RSA
303    /// public key.
304    #[must_use]
305    pub fn rs384(key: rsa::RsaPublicKey) -> Self {
306        Self::Rs384(rsa::pkcs1v15::VerifyingKey::new(key))
307    }
308
309    /// Create a new verifying key with the RS512 algorithm from the given RSA
310    /// public key.
311    #[must_use]
312    pub fn rs512(key: rsa::RsaPublicKey) -> Self {
313        Self::Rs512(rsa::pkcs1v15::VerifyingKey::new(key))
314    }
315
316    /// Create a new verifying key with the PS256 algorithm from the given RSA
317    /// public key.
318    #[must_use]
319    pub fn ps256(key: rsa::RsaPublicKey) -> Self {
320        Self::Ps256(rsa::pss::VerifyingKey::new(key))
321    }
322
323    /// Create a new verifying key with the PS384 algorithm from the given RSA
324    /// public key.
325    #[must_use]
326    pub fn ps384(key: rsa::RsaPublicKey) -> Self {
327        Self::Ps384(rsa::pss::VerifyingKey::new(key))
328    }
329
330    /// Create a new verifying key with the PS512 algorithm from the given RSA
331    /// public key.
332    #[must_use]
333    pub fn ps512(key: rsa::RsaPublicKey) -> Self {
334        Self::Ps512(rsa::pss::VerifyingKey::new(key))
335    }
336
337    /// Create a new verifying key with the ES256 algorithm from the given ECDSA
338    /// public key.
339    #[must_use]
340    pub fn es256(key: elliptic_curve::PublicKey<p256::NistP256>) -> Self {
341        Self::Es256(ecdsa::VerifyingKey::from(key))
342    }
343
344    /// Create a new verifying key with the ES384 algorithm from the given ECDSA
345    /// public key.
346    #[must_use]
347    pub fn es384(key: elliptic_curve::PublicKey<p384::NistP384>) -> Self {
348        Self::Es384(ecdsa::VerifyingKey::from(key))
349    }
350
351    /// Create a new verifying key with the ES256K algorithm from the given
352    /// ECDSA public key.
353    #[must_use]
354    pub fn es256k(key: elliptic_curve::PublicKey<k256::Secp256k1>) -> Self {
355        Self::Es256K(ecdsa::VerifyingKey::from(key))
356    }
357
358    /// Create a new verifying key for the given algorithm from the given public
359    /// JWK parameters.
360    ///
361    /// # Errors
362    ///
363    /// Returns an error if the key parameters are not suitable for the given
364    /// algorithm.
365    pub fn from_jwk_and_alg(
366        params: &JsonWebKeyPublicParameters,
367        alg: &JsonWebSignatureAlg,
368    ) -> Result<Self, AsymmetricKeyFromJwkError> {
369        match (params, alg) {
370            (JsonWebKeyPublicParameters::Rsa(params), alg) => match alg {
371                JsonWebSignatureAlg::Rs256 => Ok(Self::rs256(params.try_into()?)),
372                JsonWebSignatureAlg::Rs384 => Ok(Self::rs384(params.try_into()?)),
373                JsonWebSignatureAlg::Rs512 => Ok(Self::rs512(params.try_into()?)),
374                JsonWebSignatureAlg::Ps256 => Ok(Self::ps256(params.try_into()?)),
375                JsonWebSignatureAlg::Ps384 => Ok(Self::ps384(params.try_into()?)),
376                JsonWebSignatureAlg::Ps512 => Ok(Self::ps512(params.try_into()?)),
377                _ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg: alg.clone() }),
378            },
379
380            (JsonWebKeyPublicParameters::Ec(params), JsonWebSignatureAlg::Es256)
381                if params.crv == JsonWebKeyEcEllipticCurve::P256 =>
382            {
383                Ok(Self::es256(params.try_into()?))
384            }
385
386            (JsonWebKeyPublicParameters::Ec(params), JsonWebSignatureAlg::Es384)
387                if params.crv == JsonWebKeyEcEllipticCurve::P384 =>
388            {
389                Ok(Self::es384(params.try_into()?))
390            }
391
392            (JsonWebKeyPublicParameters::Ec(params), JsonWebSignatureAlg::Es512)
393                if params.crv == JsonWebKeyEcEllipticCurve::P521 =>
394            {
395                Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg: alg.clone() })
396            }
397
398            (JsonWebKeyPublicParameters::Ec(params), JsonWebSignatureAlg::Es256K)
399                if params.crv == JsonWebKeyEcEllipticCurve::Secp256K1 =>
400            {
401                Ok(Self::es256k(params.try_into()?))
402            }
403
404            (JsonWebKeyPublicParameters::Okp(_params), JsonWebSignatureAlg::EdDsa) => {
405                Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg: alg.clone() })
406            }
407
408            _ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg: alg.clone() }),
409        }
410    }
411}
412
413impl From<super::Rs256VerifyingKey> for AsymmetricVerifyingKey {
414    fn from(key: super::Rs256VerifyingKey) -> Self {
415        Self::Rs256(key)
416    }
417}
418
419impl From<super::Rs384VerifyingKey> for AsymmetricVerifyingKey {
420    fn from(key: super::Rs384VerifyingKey) -> Self {
421        Self::Rs384(key)
422    }
423}
424
425impl From<super::Rs512VerifyingKey> for AsymmetricVerifyingKey {
426    fn from(key: super::Rs512VerifyingKey) -> Self {
427        Self::Rs512(key)
428    }
429}
430
431impl From<super::Ps256VerifyingKey> for AsymmetricVerifyingKey {
432    fn from(key: super::Ps256VerifyingKey) -> Self {
433        Self::Ps256(key)
434    }
435}
436
437impl From<super::Ps384VerifyingKey> for AsymmetricVerifyingKey {
438    fn from(key: super::Ps384VerifyingKey) -> Self {
439        Self::Ps384(key)
440    }
441}
442
443impl From<super::Ps512VerifyingKey> for AsymmetricVerifyingKey {
444    fn from(key: super::Ps512VerifyingKey) -> Self {
445        Self::Ps512(key)
446    }
447}
448
449impl From<super::Es256VerifyingKey> for AsymmetricVerifyingKey {
450    fn from(key: super::Es256VerifyingKey) -> Self {
451        Self::Es256(key)
452    }
453}
454
455impl From<super::Es384VerifyingKey> for AsymmetricVerifyingKey {
456    fn from(key: super::Es384VerifyingKey) -> Self {
457        Self::Es384(key)
458    }
459}
460
461impl From<super::Es256KVerifyingKey> for AsymmetricVerifyingKey {
462    fn from(key: super::Es256KVerifyingKey) -> Self {
463        Self::Es256K(key)
464    }
465}
466
467impl signature::Verifier<Signature> for AsymmetricVerifyingKey {
468    fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), ecdsa::Error> {
469        match self {
470            Self::Rs256(key) => {
471                let signature = signature.to_signature()?;
472                key.verify(msg, &signature)
473            }
474            Self::Rs384(key) => {
475                let signature = signature.to_signature()?;
476                key.verify(msg, &signature)
477            }
478            Self::Rs512(key) => {
479                let signature = signature.to_signature()?;
480                key.verify(msg, &signature)
481            }
482            Self::Ps256(key) => {
483                let signature = signature.to_signature()?;
484                key.verify(msg, &signature)
485            }
486            Self::Ps384(key) => {
487                let signature = signature.to_signature()?;
488                key.verify(msg, &signature)
489            }
490            Self::Ps512(key) => {
491                let signature = signature.to_signature()?;
492                key.verify(msg, &signature)
493            }
494            Self::Es256(key) => {
495                let signature: ecdsa::Signature<_> = signature.to_signature()?;
496                key.verify(msg, &signature)
497            }
498            Self::Es384(key) => {
499                let signature: ecdsa::Signature<_> = signature.to_signature()?;
500                key.verify(msg, &signature)
501            }
502            Self::Es256K(key) => {
503                let signature: ecdsa::Signature<_> = signature.to_signature()?;
504                key.verify(msg, &signature)
505            }
506        }
507    }
508}