1use alloc::collections::BTreeMap;
13use alloc::vec::Vec;
14
15use ed25519_dalek::{Signer as _, SigningKey, VerifyingKey};
16use p256::ecdsa::signature::Verifier as _;
17use p256::ecdsa::{
18 Signature as P256Signature, SigningKey as P256SigningKey, VerifyingKey as P256VerifyingKey,
19};
20use x25519_dalek::{PublicKey, StaticSecret};
21use zeroize::Zeroizing;
22
23use crate::alg::SignatureAlgorithm;
24use crate::codec;
25use crate::error::{OpenError, SignError, VerifyError};
26use crate::kdf;
27use crate::traits::{OpenRequest, Recipient, Signer, Verifier};
28use crate::types::{KeyId, Signature};
29
30pub struct Ed25519Signer {
32 key: SigningKey,
33 key_id: KeyId,
34}
35
36impl Ed25519Signer {
37 #[must_use]
39 pub fn from_secret_bytes(key_id: KeyId, secret: &Zeroizing<[u8; 32]>) -> Self {
40 Self {
41 key: SigningKey::from_bytes(secret),
42 key_id,
43 }
44 }
45
46 #[must_use]
48 pub fn public_key_bytes(&self) -> [u8; 32] {
49 self.key.verifying_key().to_bytes()
50 }
51}
52
53impl Signer for Ed25519Signer {
54 fn key_id(&self) -> &KeyId {
55 &self.key_id
56 }
57
58 fn algorithm(&self) -> SignatureAlgorithm {
59 SignatureAlgorithm::EdDsa
60 }
61
62 async fn sign(&self, sig_structure: &[u8]) -> Result<Signature, SignError> {
63 let sig = self.key.sign(sig_structure);
64 Signature::from_bytes(sig.to_bytes().to_vec()).map_err(|_| SignError::Provider {
65 message: alloc::string::String::from("empty signature"),
66 })
67 }
68}
69
70pub struct Ed25519Verifier {
73 keys: BTreeMap<KeyId, VerifyingKey>,
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
78pub enum KeyError {
79 InvalidPublicKey,
81 InvalidPrivateKey,
83}
84
85impl core::fmt::Display for KeyError {
86 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
87 match self {
88 Self::InvalidPublicKey => write!(f, "invalid public key"),
89 Self::InvalidPrivateKey => write!(f, "invalid private key"),
90 }
91 }
92}
93
94impl core::error::Error for KeyError {}
95
96impl Ed25519Verifier {
97 pub fn from_key(key_id: KeyId, public: &[u8; 32]) -> Result<Self, KeyError> {
102 let mut keys = BTreeMap::new();
103 keys.insert(
104 key_id,
105 VerifyingKey::from_bytes(public).map_err(|_| KeyError::InvalidPublicKey)?,
106 );
107 Ok(Self { keys })
108 }
109
110 pub fn add_key(&mut self, key_id: KeyId, public: &[u8; 32]) -> Result<(), KeyError> {
115 self.keys.insert(
116 key_id,
117 VerifyingKey::from_bytes(public).map_err(|_| KeyError::InvalidPublicKey)?,
118 );
119 Ok(())
120 }
121}
122
123impl Verifier for Ed25519Verifier {
124 async fn verify(
125 &self,
126 key_id: &KeyId,
127 algorithm: SignatureAlgorithm,
128 _protected_headers: &crate::claims::ProtectedHeaders,
129 sig_structure: &[u8],
130 signature: &Signature,
131 ) -> Result<(), VerifyError> {
132 if algorithm != SignatureAlgorithm::EdDsa {
133 return Err(VerifyError::AlgorithmMismatch);
134 }
135 let key = self.keys.get(key_id).ok_or(VerifyError::UnknownKeyId)?;
136 let sig_bytes: [u8; 64] = signature
137 .as_bytes()
138 .try_into()
139 .map_err(|_| VerifyError::SignatureInvalid)?;
140 let sig = ed25519_dalek::Signature::from_bytes(&sig_bytes);
141 key.verify_strict(sig_structure, &sig)
143 .map_err(|_| VerifyError::SignatureInvalid)
144 }
145}
146
147pub struct Es256Signer {
153 key: P256SigningKey,
154 key_id: KeyId,
155}
156
157impl Es256Signer {
158 pub fn from_secret_bytes(
164 key_id: KeyId,
165 secret: &Zeroizing<[u8; 32]>,
166 ) -> Result<Self, KeyError> {
167 let key = P256SigningKey::from_slice(secret.as_slice())
168 .map_err(|_| KeyError::InvalidPrivateKey)?;
169 Ok(Self { key, key_id })
170 }
171
172 #[must_use]
175 pub fn public_key_sec1(&self) -> Vec<u8> {
176 self.key
177 .verifying_key()
178 .to_encoded_point(false)
179 .as_bytes()
180 .to_vec()
181 }
182}
183
184impl Signer for Es256Signer {
185 fn key_id(&self) -> &KeyId {
186 &self.key_id
187 }
188
189 fn algorithm(&self) -> SignatureAlgorithm {
190 SignatureAlgorithm::Es256
191 }
192
193 async fn sign(&self, sig_structure: &[u8]) -> Result<Signature, SignError> {
194 let sig: P256Signature =
197 self.key
198 .try_sign(sig_structure)
199 .map_err(|_| SignError::Provider {
200 message: alloc::string::String::from("ecdsa signing failed"),
201 })?;
202 let sig = sig.normalize_s().unwrap_or(sig);
203 Signature::from_bytes(sig.to_bytes().to_vec()).map_err(|_| SignError::Provider {
204 message: alloc::string::String::from("empty signature"),
205 })
206 }
207}
208
209pub struct P256Verifier {
212 keys: BTreeMap<KeyId, P256VerifyingKey>,
213}
214
215impl P256Verifier {
216 pub fn from_sec1(key_id: KeyId, public: &[u8]) -> Result<Self, KeyError> {
222 let mut keys = BTreeMap::new();
223 keys.insert(
224 key_id,
225 P256VerifyingKey::from_sec1_bytes(public).map_err(|_| KeyError::InvalidPublicKey)?,
226 );
227 Ok(Self { keys })
228 }
229
230 pub fn add_key(&mut self, key_id: KeyId, public: &[u8]) -> Result<(), KeyError> {
235 self.keys.insert(
236 key_id,
237 P256VerifyingKey::from_sec1_bytes(public).map_err(|_| KeyError::InvalidPublicKey)?,
238 );
239 Ok(())
240 }
241}
242
243impl Verifier for P256Verifier {
244 async fn verify(
245 &self,
246 key_id: &KeyId,
247 algorithm: SignatureAlgorithm,
248 _protected_headers: &crate::claims::ProtectedHeaders,
249 sig_structure: &[u8],
250 signature: &Signature,
251 ) -> Result<(), VerifyError> {
252 if algorithm != SignatureAlgorithm::Es256 {
253 return Err(VerifyError::AlgorithmMismatch);
254 }
255 let key = self.keys.get(key_id).ok_or(VerifyError::UnknownKeyId)?;
256 let sig = P256Signature::from_slice(signature.as_bytes())
259 .map_err(|_| VerifyError::SignatureInvalid)?;
260 if sig.normalize_s().is_some() {
261 return Err(VerifyError::SignatureInvalid);
262 }
263 key.verify(sig_structure, &sig)
264 .map_err(|_| VerifyError::SignatureInvalid)
265 }
266}
267
268#[derive(Debug, Clone, PartialEq, Eq)]
270pub struct X25519RecipientPublic {
271 pub key_id: KeyId,
273 pub public: [u8; 32],
275}
276
277pub struct X25519Recipient {
280 private: Zeroizing<[u8; 32]>,
281 key_id: KeyId,
282}
283
284impl X25519Recipient {
285 #[must_use]
287 pub const fn new(key_id: KeyId, private: Zeroizing<[u8; 32]>) -> Self {
288 Self { private, key_id }
289 }
290
291 pub fn from_private_slice(key_id: KeyId, bytes: &[u8]) -> Result<Self, KeyLengthError> {
298 let arr: [u8; 32] = bytes.try_into().map_err(|_| KeyLengthError {
299 actual: bytes.len(),
300 })?;
301 Ok(Self::new(key_id, Zeroizing::new(arr)))
302 }
303
304 #[must_use]
306 pub fn public(&self) -> X25519RecipientPublic {
307 let secret = StaticSecret::from(*self.private);
308 X25519RecipientPublic {
309 key_id: self.key_id.clone(),
310 public: PublicKey::from(&secret).to_bytes(),
311 }
312 }
313}
314
315#[derive(Debug, Clone, Copy, PartialEq, Eq)]
317pub struct KeyLengthError {
318 pub actual: usize,
320}
321
322impl core::fmt::Display for KeyLengthError {
323 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
324 write!(
325 f,
326 "X25519 private key must be 32 bytes, got {}",
327 self.actual
328 )
329 }
330}
331
332impl core::error::Error for KeyLengthError {}
333
334impl Recipient for X25519Recipient {
335 fn key_id(&self) -> &KeyId {
336 &self.key_id
337 }
338
339 async fn open(&self, request: &OpenRequest<'_>) -> Result<Zeroizing<Vec<u8>>, OpenError> {
340 open_local(self, request)
341 }
342}
343
344fn open_local(
347 recipient: &X25519Recipient,
348 request: &OpenRequest<'_>,
349) -> Result<Zeroizing<Vec<u8>>, OpenError> {
350 let decoded = decode_any_encrypt(request.cose_encrypt)?;
355
356 if decoded.recipient_kid != recipient.key_id {
357 return Err(OpenError::RecipientKeyMismatch);
358 }
359 if let Some(expected) = request.expected_parties
360 && *expected != decoded.parties
361 {
362 return Err(OpenError::PartyMismatch);
363 }
364
365 let secret = StaticSecret::from(*recipient.private);
366 let ephemeral = PublicKey::from(decoded.ephemeral_x);
367 let shared_secret = secret.diffie_hellman(&ephemeral);
368 if !shared_secret.was_contributory() {
373 return Err(OpenError::OpenFailed);
374 }
375 let shared = Zeroizing::new(shared_secret.to_bytes());
376
377 let info = codec::kdf_context(
378 decoded.content_algorithm,
379 &decoded.parties,
380 &decoded.recipient_protected,
381 )
382 .map_err(|codec::CodecError| OpenError::OpenFailed)?;
383 let cek = kdf::derive_cek(&shared, &info).map_err(|kdf::KdfFailed| OpenError::OpenFailed)?;
384
385 let aad = codec::enc_structure(&decoded.protected, request.external_aad.as_bytes())
386 .map_err(|codec::CodecError| OpenError::OpenFailed)?;
387
388 crate::encrypt::aead_open(
389 decoded.content_algorithm,
390 &cek,
391 &decoded.iv,
392 &decoded.ciphertext,
393 &aad,
394 )
395}
396
397fn decode_any_encrypt(bytes: &[u8]) -> Result<codec::DecodedEncrypt, OpenError> {
401 match codec::decode_encrypt_strict(bytes, codec::ClaimsExpectation::Optional) {
402 Ok(d) => Ok(d),
403 Err(e) => Err(OpenError::Decode(e)),
404 }
405}