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)]
104pub struct DefaultVerifier;
105
106impl JwsVerifier for DefaultVerifier {
107 fn verify(
108 &self,
109 alg: JwsAlgorithm,
110 signing_input: &[u8],
111 signature: &[u8],
112 key: &Jwk,
113 ) -> Result<(), VerificationError> {
114 check_key_restrictions(alg, key)?;
115 match alg {
116 JwsAlgorithm::EdDSA => {
117 let verifying_key = key.ed25519_verifying_key()?;
118 let signature = ed25519_dalek::Signature::from_bytes(fixed_size::<64>(signature)?);
119 verifying_key
120 .verify_strict(signing_input, &signature)
121 .map_err(|_| VerificationError::InvalidSignature)
122 }
123 JwsAlgorithm::ES256 => {
124 use p256::ecdsa::signature::Verifier as _;
125 let verifying_key = p256::ecdsa::VerifyingKey::from(&key.p256_public_key()?);
126 let signature = p256::ecdsa::Signature::from_slice(ecdsa_raw::<64>(signature)?)
127 .map_err(|_| VerificationError::InvalidSignature)?;
128 verifying_key
129 .verify(signing_input, &signature)
130 .map_err(|_| VerificationError::InvalidSignature)
131 }
132 #[cfg(feature = "secp256k1")]
133 JwsAlgorithm::ES256K => {
134 use k256::ecdsa::signature::Verifier as _;
135 let verifying_key = k256::ecdsa::VerifyingKey::from(&key.secp256k1_public_key()?);
136 let signature = k256::ecdsa::Signature::from_slice(ecdsa_raw::<64>(signature)?)
137 .map_err(|_| VerificationError::InvalidSignature)?;
138 verifying_key
139 .verify(signing_input, &signature)
140 .map_err(|_| VerificationError::InvalidSignature)
141 }
142 #[cfg(feature = "rsa")]
143 JwsAlgorithm::RS256 => {
144 use rsa::signature::Verifier as _;
145 let public_key = key.rsa_public_key()?;
146 let signature =
147 rsa::pkcs1v15::Signature::try_from(rsa_sized(&public_key, signature)?)
148 .map_err(|_| VerificationError::InvalidSignature)?;
149 rsa::pkcs1v15::VerifyingKey::<sha2::Sha256>::new(public_key)
150 .verify(signing_input, &signature)
151 .map_err(|_| VerificationError::InvalidSignature)
152 }
153 #[cfg(feature = "rsa")]
154 JwsAlgorithm::PS256 => {
155 use rsa::signature::Verifier as _;
156 let public_key = key.rsa_public_key()?;
157 let signature = rsa::pss::Signature::try_from(rsa_sized(&public_key, signature)?)
158 .map_err(|_| VerificationError::InvalidSignature)?;
159 rsa::pss::VerifyingKey::<sha2::Sha256>::new(public_key)
160 .verify(signing_input, &signature)
161 .map_err(|_| VerificationError::InvalidSignature)
162 }
163 other => Err(VerificationError::UnsupportedAlgorithm(other)),
164 }
165 }
166}
167
168fn check_key_restrictions(alg: JwsAlgorithm, key: &Jwk) -> Result<(), VerificationError> {
170 match key.alg() {
171 Some(key_alg) if key_alg != alg.as_str() => {
172 return Err(VerificationError::AlgorithmMismatch {
173 alg,
174 key_alg: key_alg.to_owned(),
175 });
176 }
177 _ => {}
178 }
179 if key.key_use().is_some_and(|key_use| key_use != "sig") {
180 return Err(VerificationError::KeyUse("`use` is not `sig`"));
181 }
182 if key
183 .key_ops()
184 .is_some_and(|key_ops| !key_ops.iter().any(|op| op == "verify"))
185 {
186 return Err(VerificationError::KeyUse("`key_ops` lacks `verify`"));
187 }
188 Ok(())
189}
190
191fn fixed_size<const N: usize>(signature: &[u8]) -> Result<&[u8; N], VerificationError> {
193 signature
194 .try_into()
195 .map_err(|_| VerificationError::InvalidSignatureLength {
196 expected: N,
197 actual: signature.len(),
198 })
199}
200
201#[cfg(feature = "rsa")]
205fn rsa_sized<'a>(
206 key: &rsa::RsaPublicKey,
207 signature: &'a [u8],
208) -> Result<&'a [u8], VerificationError> {
209 use rsa::traits::PublicKeyParts as _;
210 let expected = key.size();
211 if signature.len() != expected {
212 return Err(VerificationError::InvalidSignatureLength {
213 expected,
214 actual: signature.len(),
215 });
216 }
217 Ok(signature)
218}
219
220fn ecdsa_raw<const N: usize>(signature: &[u8]) -> Result<&[u8; N], VerificationError> {
223 if signature.len() != N && signature.first() == Some(&0x30) {
226 return Err(VerificationError::DerEncodedSignature);
227 }
228 fixed_size::<N>(signature)
229}