1use crate::{
4 checked::CheckedSum, decode::Decode, encode::Encode, private, public, reader::Reader,
5 writer::Writer, Algorithm, Error, MPInt, PrivateKey, PublicKey, Result,
6};
7use alloc::vec::Vec;
8use core::fmt;
9use signature::{Signer, Verifier};
10
11#[cfg(feature = "ed25519")]
12use crate::{private::Ed25519Keypair, public::Ed25519PublicKey};
13
14#[cfg(feature = "p256")]
15use crate::{
16 private::{EcdsaKeypair, EcdsaPrivateKey},
17 public::EcdsaPublicKey,
18 EcdsaCurve,
19};
20
21#[cfg(feature = "rsa")]
22use {
23 crate::{private::RsaKeypair, public::RsaPublicKey, HashAlg},
24 rsa::PublicKey as _,
25 sha2::{Digest, Sha256, Sha512},
26};
27
28const DSA_SIGNATURE_SIZE: usize = 40;
29const ED25519_SIGNATURE_SIZE: usize = 64;
30
31#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
51#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
52pub struct Signature {
53 algorithm: Algorithm,
55
56 data: Vec<u8>,
58}
59
60impl Signature {
61 pub fn new(algorithm: Algorithm, data: impl Into<Vec<u8>>) -> Result<Self> {
69 let data = data.into();
70
71 match algorithm {
73 Algorithm::Dsa if data.len() == DSA_SIGNATURE_SIZE => (),
74 Algorithm::Ecdsa { curve } => {
75 let reader = &mut data.as_slice();
76
77 for _ in 0..2 {
78 let component = MPInt::decode(reader)?;
79
80 if component.as_positive_bytes().ok_or(Error::Crypto)?.len()
81 != curve.field_size()
82 {
83 return Err(Error::Length);
84 }
85 }
86
87 if !reader.is_finished() {
88 return Err(Error::Length);
89 }
90 }
91 Algorithm::Ed25519 if data.len() == ED25519_SIGNATURE_SIZE => (),
92 Algorithm::Rsa { hash: Some(_) } => (),
93 _ => return Err(Error::Length),
94 }
95
96 Ok(Self { algorithm, data })
97 }
98
99 pub(crate) fn placeholder() -> Self {
103 Self {
104 algorithm: Algorithm::default(),
105 data: Vec::new(),
106 }
107 }
108
109 pub(crate) fn is_placeholder(&self) -> bool {
111 self.algorithm == Algorithm::default() && self.data.is_empty()
112 }
113}
114
115impl Signature {
116 pub fn algorithm(&self) -> Algorithm {
118 self.algorithm
119 }
120
121 pub fn as_bytes(&self) -> &[u8] {
123 &self.data
124 }
125}
126
127impl AsRef<[u8]> for Signature {
128 fn as_ref(&self) -> &[u8] {
129 self.as_bytes()
130 }
131}
132
133impl Decode for Signature {
134 fn decode(reader: &mut impl Reader) -> Result<Self> {
135 let algorithm = Algorithm::decode(reader)?;
136 let data = Vec::decode(reader)?;
137 Self::new(algorithm, data)
138 }
139}
140
141impl Encode for Signature {
142 fn encoded_len(&self) -> Result<usize> {
143 [
144 self.algorithm().encoded_len()?,
145 4, self.as_bytes().len(),
147 ]
148 .checked_sum()
149 }
150
151 fn encode(&self, writer: &mut impl Writer) -> Result<()> {
152 if self.is_placeholder() {
153 return Err(Error::Length);
154 }
155
156 self.algorithm().encode(writer)?;
157 self.as_bytes().encode(writer)
158 }
159}
160
161impl signature::Signature for Signature {
162 fn from_bytes(bytes: &[u8]) -> signature::Result<Self> {
163 Self::try_from(bytes).map_err(|_| signature::Error::new())
164 }
165}
166
167impl TryFrom<&[u8]> for Signature {
169 type Error = Error;
170
171 fn try_from(mut bytes: &[u8]) -> Result<Self> {
172 Self::decode(&mut bytes)
173 }
174}
175
176impl fmt::Debug for Signature {
177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178 write!(
179 f,
180 "Signature {{ algorithm: {:?}, data: {:X} }}",
181 self.algorithm, self
182 )
183 }
184}
185
186impl fmt::LowerHex for Signature {
187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188 for byte in self.as_ref() {
189 write!(f, "{:02x}", byte)?;
190 }
191 Ok(())
192 }
193}
194
195impl fmt::UpperHex for Signature {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 for byte in self.as_ref() {
198 write!(f, "{:02X}", byte)?;
199 }
200 Ok(())
201 }
202}
203
204impl Signer<Signature> for PrivateKey {
205 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
206 self.key_data().try_sign(message)
207 }
208}
209
210impl Signer<Signature> for private::KeypairData {
211 #[allow(unused_variables)]
212 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
213 match self {
214 #[cfg(feature = "p256")]
215 Self::Ecdsa(keypair) => keypair.try_sign(message),
216 #[cfg(feature = "ed25519")]
217 Self::Ed25519(keypair) => keypair.try_sign(message),
218 #[cfg(feature = "rsa")]
219 Self::Rsa(keypair) => keypair.try_sign(message),
220 _ => Err(signature::Error::new()),
221 }
222 }
223}
224
225impl Verifier<Signature> for PublicKey {
226 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
227 self.key_data().verify(message, signature)
228 }
229}
230
231impl Verifier<Signature> for public::KeyData {
232 #[allow(unused_variables)]
233 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
234 match self {
235 #[cfg(feature = "p256")]
236 Self::Ecdsa(pk) => pk.verify(message, signature),
237 #[cfg(feature = "ed25519")]
238 Self::Ed25519(pk) => pk.verify(message, signature),
239 #[cfg(feature = "rsa")]
240 Self::Rsa(pk) => pk.verify(message, signature),
241 _ => Err(signature::Error::new()),
242 }
243 }
244}
245
246#[cfg(feature = "ed25519")]
247#[cfg_attr(docsrs, doc(cfg(feature = "ed25519")))]
248impl TryFrom<Signature> for ed25519_dalek::Signature {
249 type Error = Error;
250
251 fn try_from(signature: Signature) -> Result<ed25519_dalek::Signature> {
252 ed25519_dalek::Signature::try_from(&signature)
253 }
254}
255
256#[cfg(feature = "ed25519")]
257#[cfg_attr(docsrs, doc(cfg(feature = "ed25519")))]
258impl TryFrom<&Signature> for ed25519_dalek::Signature {
259 type Error = Error;
260
261 fn try_from(signature: &Signature) -> Result<ed25519_dalek::Signature> {
262 match signature.algorithm {
263 Algorithm::Ed25519 => Ok(ed25519_dalek::Signature::try_from(signature.as_bytes())?),
264 _ => Err(Error::Algorithm),
265 }
266 }
267}
268
269#[cfg(feature = "ed25519")]
270#[cfg_attr(docsrs, doc(cfg(feature = "ed25519")))]
271impl Signer<Signature> for Ed25519Keypair {
272 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
273 let signature = ed25519_dalek::Keypair::try_from(self)?.sign(message);
274
275 Ok(Signature {
276 algorithm: Algorithm::Ed25519,
277 data: signature.as_ref().to_vec(),
278 })
279 }
280}
281
282#[cfg(feature = "ed25519")]
283#[cfg_attr(docsrs, doc(cfg(feature = "ed25519")))]
284impl Verifier<Signature> for Ed25519PublicKey {
285 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
286 let signature = ed25519_dalek::Signature::try_from(signature)?;
287 ed25519_dalek::PublicKey::try_from(self)?.verify(message, &signature)
288 }
289}
290
291#[cfg(feature = "p256")]
292#[cfg_attr(docsrs, doc(cfg(feature = "p256")))]
293impl TryFrom<p256::ecdsa::Signature> for Signature {
294 type Error = Error;
295
296 fn try_from(signature: p256::ecdsa::Signature) -> Result<Signature> {
297 Signature::try_from(&signature)
298 }
299}
300
301#[cfg(feature = "p256")]
302#[cfg_attr(docsrs, doc(cfg(feature = "p256")))]
303impl TryFrom<&p256::ecdsa::Signature> for Signature {
304 type Error = Error;
305
306 fn try_from(signature: &p256::ecdsa::Signature) -> Result<Signature> {
307 let (r, s) = signature.as_ref().split_at(32);
308 let mut data = Vec::with_capacity(74); MPInt::from_positive_bytes(r)?.encode(&mut data)?;
310 MPInt::from_positive_bytes(s)?.encode(&mut data)?;
311
312 Ok(Signature {
313 algorithm: Algorithm::Ecdsa {
314 curve: EcdsaCurve::NistP256,
315 },
316 data,
317 })
318 }
319}
320
321#[cfg(feature = "p256")]
322#[cfg_attr(docsrs, doc(cfg(feature = "p256")))]
323impl TryFrom<Signature> for p256::ecdsa::Signature {
324 type Error = Error;
325
326 fn try_from(signature: Signature) -> Result<p256::ecdsa::Signature> {
327 p256::ecdsa::Signature::try_from(&signature)
328 }
329}
330
331#[cfg(feature = "p256")]
332#[cfg_attr(docsrs, doc(cfg(feature = "p256")))]
333impl TryFrom<&Signature> for p256::ecdsa::Signature {
334 type Error = Error;
335
336 fn try_from(signature: &Signature) -> Result<p256::ecdsa::Signature> {
337 match signature.algorithm {
338 Algorithm::Ecdsa {
339 curve: EcdsaCurve::NistP256,
340 } => {
341 let reader = &mut signature.as_bytes();
342 let r = MPInt::decode(reader)?;
343 let s = MPInt::decode(reader)?;
344
345 match (r.as_positive_bytes(), s.as_positive_bytes()) {
346 (Some(r), Some(s)) if r.len() == 32 && s.len() == 32 => {
347 Ok(p256::ecdsa::Signature::from_scalars(
348 *p256::FieldBytes::from_slice(r),
349 *p256::FieldBytes::from_slice(s),
350 )?)
351 }
352 _ => Err(Error::Crypto),
353 }
354 }
355 _ => Err(Error::Algorithm),
356 }
357 }
358}
359
360#[cfg(feature = "p256")]
361#[cfg_attr(docsrs, doc(cfg(feature = "p256")))]
362impl Signer<Signature> for EcdsaKeypair {
363 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
364 match self {
365 Self::NistP256 { private, .. } => private.try_sign(message),
366 _ => Err(signature::Error::new()),
367 }
368 }
369}
370
371#[cfg(feature = "p256")]
372#[cfg_attr(docsrs, doc(cfg(feature = "p256")))]
373impl Signer<Signature> for EcdsaPrivateKey<32> {
374 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
375 Ok(p256::ecdsa::SigningKey::from_bytes(self.as_ref())?
376 .try_sign(message)?
377 .try_into()?)
378 }
379}
380
381#[cfg(feature = "p256")]
382#[cfg_attr(docsrs, doc(cfg(feature = "p256")))]
383impl Verifier<Signature> for EcdsaPublicKey {
384 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
385 match signature.algorithm {
386 Algorithm::Ecdsa {
387 curve: EcdsaCurve::NistP256,
388 } => {
389 let verifying_key = p256::ecdsa::VerifyingKey::try_from(self)?;
390 let signature = p256::ecdsa::Signature::try_from(signature)?;
391 verifying_key.verify(message, &signature)
392 }
393 _ => Err(signature::Error::new()),
394 }
395 }
396}
397
398#[cfg(feature = "rsa")]
399#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))]
400impl Signer<Signature> for RsaKeypair {
401 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
402 let padding = rsa::padding::PaddingScheme::PKCS1v15Sign {
403 hash: Some(rsa::hash::Hash::SHA2_512),
404 };
405 let digest = sha2::Sha512::digest(message);
406 let data = rsa::RsaPrivateKey::try_from(self)?
407 .sign(padding, digest.as_ref())
408 .map_err(|_| signature::Error::new())?;
409
410 Ok(Signature {
411 algorithm: Algorithm::Rsa {
412 hash: Some(HashAlg::Sha512),
413 },
414 data,
415 })
416 }
417}
418
419#[cfg(feature = "rsa")]
420#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))]
421impl Verifier<Signature> for RsaPublicKey {
422 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
423 let key = rsa::RsaPublicKey::try_from(self)?;
424
425 match signature.algorithm {
426 Algorithm::Rsa {
427 hash: Some(HashAlg::Sha256),
428 } => {
429 let digest = Sha256::digest(message);
430 let padding = rsa::padding::PaddingScheme::PKCS1v15Sign {
431 hash: Some(rsa::hash::Hash::SHA2_256),
432 };
433 key.verify(padding, digest.as_ref(), signature.as_bytes())
434 .map_err(|_| signature::Error::new())
435 }
436 Algorithm::Rsa {
437 hash: Some(HashAlg::Sha512),
438 } => {
439 let padding = rsa::padding::PaddingScheme::PKCS1v15Sign {
440 hash: Some(rsa::hash::Hash::SHA2_512),
441 };
442 let digest = Sha512::digest(message);
443 key.verify(padding, digest.as_ref(), signature.as_bytes())
444 .map_err(|_| signature::Error::new())
445 }
446 _ => Err(signature::Error::new()),
447 }
448 }
449}
450
451#[cfg(test)]
452mod tests {
453 use super::Signature;
454 use crate::{encode::Encode, Algorithm, EcdsaCurve, Error, HashAlg};
455 use alloc::vec::Vec;
456 use hex_literal::hex;
457
458 #[cfg(feature = "ed25519")]
459 use {
460 super::Ed25519Keypair,
461 signature::{Signer, Verifier},
462 };
463
464 const DSA_SIGNATURE: &[u8] = &hex!("000000077373682d6473730000002866725bf3c56100e975e21fff28a60f73717534d285ea3e1beefc2891f7189d00bd4d94627e84c55c");
465 const ECDSA_SHA2_P256_SIGNATURE: &[u8] = &hex!("0000001365636473612d736861322d6e6973747032353600000048000000201298ab320720a32139cda8a40c97a13dc54ce032ea3c6f09ea9e87501e48fa1d0000002046e4ac697a6424a9870b9ef04ca1182cd741965f989bd1f1f4a26fd83cf70348");
466 const ED25519_SIGNATURE: &[u8] = &hex!("0000000b7373682d65643235353139000000403d6b9906b76875aef1e7b2f1e02078a94f439aebb9a4734da1a851a81e22ce0199bbf820387a8de9c834c9c3cc778d9972dcbe70f68d53cc6bc9e26b02b46d04");
467 const RSA_SHA512_SIGNATURE: &[u8] = &hex!("0000000c7273612d736861322d3531320000018085a4ad1a91a62c00c85de7bb511f38088ff2bce763d76f4786febbe55d47624f9e2cffce58a680183b9ad162c7f0191ea26cab001ac5f5055743eced58e9981789305c208fc98d2657954e38eb28c7e7f3fbe92393a14324ed77aebb772a41aa7a107b38cb9bd1d9ad79b275135d1d7e019bb1d56d74f2450be6db0771f48f6707d3fcf9789592ca2e55595acc16b6e8d0139b56c5d1360b3a1e060f4151a3d7841df2c2a8c94d6f8a1bf633165ee0bcadac5642763df0dd79d3235ae5506595145f199d8abe8f9980411bf70a16e30f273736324d047043317044c36374d6a5ed34cac251e01c6795e4578393f9090bf4ae3e74a0009275a197315fc9c62f1c9aec1ba3b2d37c3b207e5500df19e090e7097ebc038fb9c9e35aea9161479ba6b5190f48e89e1abe51e8ec0e120ef89776e129687ca52d1892c8e88e6ef062a7d96b8a87682ca6a42ff1df0cdf5815c3645aeed7267ca7093043db0565e0f109b796bf117b9d2bb6d6debc0c67a4c9fb3aae3e29b00c7bd70f6c11cf53c295ff");
468
469 #[cfg(feature = "ed25519")]
471 const EXAMPLE_MSG: &[u8] = b"Hello, world!";
472
473 #[test]
474 fn decode_dsa() {
475 let signature = Signature::try_from(DSA_SIGNATURE).unwrap();
476 assert_eq!(Algorithm::Dsa, signature.algorithm());
477 }
478
479 #[test]
480 fn decode_ecdsa_sha2_p256() {
481 let signature = Signature::try_from(ECDSA_SHA2_P256_SIGNATURE).unwrap();
482 assert_eq!(
483 Algorithm::Ecdsa {
484 curve: EcdsaCurve::NistP256
485 },
486 signature.algorithm()
487 );
488 }
489
490 #[test]
491 fn decode_ed25519() {
492 let signature = Signature::try_from(ED25519_SIGNATURE).unwrap();
493 assert_eq!(Algorithm::Ed25519, signature.algorithm());
494 }
495
496 #[test]
497 fn decode_rsa() {
498 let signature = Signature::try_from(RSA_SHA512_SIGNATURE).unwrap();
499 assert_eq!(
500 Algorithm::Rsa {
501 hash: Some(HashAlg::Sha512)
502 },
503 signature.algorithm()
504 );
505 }
506
507 #[test]
508 fn encode_dsa() {
509 let signature = Signature::try_from(DSA_SIGNATURE).unwrap();
510
511 let mut result = Vec::new();
512 signature.encode(&mut result).unwrap();
513 assert_eq!(DSA_SIGNATURE, &result);
514 }
515
516 #[test]
517 fn encode_ecdsa_sha2_p256() {
518 let signature = Signature::try_from(ECDSA_SHA2_P256_SIGNATURE).unwrap();
519
520 let mut result = Vec::new();
521 signature.encode(&mut result).unwrap();
522 assert_eq!(ECDSA_SHA2_P256_SIGNATURE, &result);
523 }
524
525 #[test]
526 fn encode_ed25519() {
527 let signature = Signature::try_from(ED25519_SIGNATURE).unwrap();
528
529 let mut result = Vec::new();
530 signature.encode(&mut result).unwrap();
531 assert_eq!(ED25519_SIGNATURE, &result);
532 }
533
534 #[cfg(feature = "ed25519")]
535 #[test]
536 fn sign_and_verify_ed25519() {
537 let keypair = Ed25519Keypair::from_seed(&[42; 32]);
538 let signature = keypair.sign(EXAMPLE_MSG);
539 assert!(keypair.public.verify(EXAMPLE_MSG, &signature).is_ok());
540 }
541
542 #[test]
543 fn placeholder() {
544 assert!(!Signature::try_from(ED25519_SIGNATURE)
545 .unwrap()
546 .is_placeholder());
547
548 let placeholder = Signature::placeholder();
549 assert!(placeholder.is_placeholder());
550
551 let mut writer = Vec::new();
552 assert_eq!(placeholder.encode(&mut writer), Err(Error::Length));
553 }
554}