identity_kit/jose/
verifier.rs1use super::{Jwk, JwsAlgorithm, VerificationError};
4
5pub trait JwsVerifier: Send + Sync {
12 fn verify(
21 &self,
22 alg: JwsAlgorithm,
23 signing_input: &[u8],
24 signature: &[u8],
25 key: &Jwk,
26 ) -> Result<(), VerificationError>;
27}
28
29impl<T: JwsVerifier + ?Sized> JwsVerifier for &T {
30 fn verify(
31 &self,
32 alg: JwsAlgorithm,
33 signing_input: &[u8],
34 signature: &[u8],
35 key: &Jwk,
36 ) -> Result<(), VerificationError> {
37 (**self).verify(alg, signing_input, signature, key)
38 }
39}
40
41impl<T: JwsVerifier + ?Sized> JwsVerifier for Box<T> {
42 fn verify(
43 &self,
44 alg: JwsAlgorithm,
45 signing_input: &[u8],
46 signature: &[u8],
47 key: &Jwk,
48 ) -> Result<(), VerificationError> {
49 (**self).verify(alg, signing_input, signature, key)
50 }
51}
52
53impl<T: JwsVerifier + ?Sized> JwsVerifier for std::sync::Arc<T> {
54 fn verify(
55 &self,
56 alg: JwsAlgorithm,
57 signing_input: &[u8],
58 signature: &[u8],
59 key: &Jwk,
60 ) -> Result<(), VerificationError> {
61 (**self).verify(alg, signing_input, signature, key)
62 }
63}
64
65#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
90pub struct DefaultVerifier;
91
92impl JwsVerifier for DefaultVerifier {
93 fn verify(
94 &self,
95 alg: JwsAlgorithm,
96 signing_input: &[u8],
97 signature: &[u8],
98 key: &Jwk,
99 ) -> Result<(), VerificationError> {
100 check_key_restrictions(alg, key)?;
101 match alg {
102 JwsAlgorithm::EdDSA => {
103 let verifying_key = key.ed25519_verifying_key()?;
104 let signature = ed25519_dalek::Signature::from_bytes(fixed_size::<64>(signature)?);
105 verifying_key
106 .verify_strict(signing_input, &signature)
107 .map_err(|_| VerificationError::InvalidSignature)
108 }
109 JwsAlgorithm::ES256 => {
110 use p256::ecdsa::signature::Verifier as _;
111 let verifying_key = p256::ecdsa::VerifyingKey::from(&key.p256_public_key()?);
112 let signature = p256::ecdsa::Signature::from_slice(ecdsa_raw::<64>(signature)?)
113 .map_err(|_| VerificationError::InvalidSignature)?;
114 verifying_key
115 .verify(signing_input, &signature)
116 .map_err(|_| VerificationError::InvalidSignature)
117 }
118 #[cfg(feature = "secp256k1")]
119 JwsAlgorithm::ES256K => {
120 use k256::ecdsa::signature::Verifier as _;
121 let verifying_key = k256::ecdsa::VerifyingKey::from(&key.secp256k1_public_key()?);
122 let signature = k256::ecdsa::Signature::from_slice(ecdsa_raw::<64>(signature)?)
123 .map_err(|_| VerificationError::InvalidSignature)?;
124 verifying_key
125 .verify(signing_input, &signature)
126 .map_err(|_| VerificationError::InvalidSignature)
127 }
128 #[cfg(feature = "rsa")]
129 JwsAlgorithm::RS256 => {
130 use rsa::signature::Verifier as _;
131 let public_key = key.rsa_public_key()?;
132 let signature =
133 rsa::pkcs1v15::Signature::try_from(rsa_sized(&public_key, signature)?)
134 .map_err(|_| VerificationError::InvalidSignature)?;
135 rsa::pkcs1v15::VerifyingKey::<sha2::Sha256>::new(public_key)
136 .verify(signing_input, &signature)
137 .map_err(|_| VerificationError::InvalidSignature)
138 }
139 #[cfg(feature = "rsa")]
140 JwsAlgorithm::PS256 => {
141 use rsa::signature::Verifier as _;
142 let public_key = key.rsa_public_key()?;
143 let signature = rsa::pss::Signature::try_from(rsa_sized(&public_key, signature)?)
144 .map_err(|_| VerificationError::InvalidSignature)?;
145 rsa::pss::VerifyingKey::<sha2::Sha256>::new(public_key)
146 .verify(signing_input, &signature)
147 .map_err(|_| VerificationError::InvalidSignature)
148 }
149 other => Err(VerificationError::UnsupportedAlgorithm(other)),
150 }
151 }
152}
153
154fn check_key_restrictions(alg: JwsAlgorithm, key: &Jwk) -> Result<(), VerificationError> {
156 match key.alg() {
157 Some(key_alg) if key_alg != alg.as_str() => {
158 return Err(VerificationError::AlgorithmMismatch {
159 alg,
160 key_alg: key_alg.to_owned(),
161 });
162 }
163 _ => {}
164 }
165 if key.key_use().is_some_and(|key_use| key_use != "sig") {
166 return Err(VerificationError::KeyUse("`use` is not `sig`"));
167 }
168 if key
169 .key_ops()
170 .is_some_and(|key_ops| !key_ops.iter().any(|op| op == "verify"))
171 {
172 return Err(VerificationError::KeyUse("`key_ops` lacks `verify`"));
173 }
174 Ok(())
175}
176
177fn fixed_size<const N: usize>(signature: &[u8]) -> Result<&[u8; N], VerificationError> {
179 signature
180 .try_into()
181 .map_err(|_| VerificationError::InvalidSignatureLength {
182 expected: N,
183 actual: signature.len(),
184 })
185}
186
187#[cfg(feature = "rsa")]
191fn rsa_sized<'a>(
192 key: &rsa::RsaPublicKey,
193 signature: &'a [u8],
194) -> Result<&'a [u8], VerificationError> {
195 use rsa::traits::PublicKeyParts as _;
196 let expected = key.size();
197 if signature.len() != expected {
198 return Err(VerificationError::InvalidSignatureLength {
199 expected,
200 actual: signature.len(),
201 });
202 }
203 Ok(signature)
204}
205
206fn ecdsa_raw<const N: usize>(signature: &[u8]) -> Result<&[u8; N], VerificationError> {
209 if signature.len() != N && signature.first() == Some(&0x30) {
212 return Err(VerificationError::DerEncodedSignature);
213 }
214 fixed_size::<N>(signature)
215}