1use crate::{Algorithm, EcdsaCurve, Error, Mpint, PrivateKey, PublicKey, Result, private, public};
4use alloc::vec::Vec;
5use core::fmt;
6use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
7use signature::{SignatureEncoding, Signer, Verifier};
8
9#[cfg(feature = "ed25519")]
10use crate::{private::Ed25519Keypair, public::Ed25519PublicKey};
11
12#[cfg(feature = "dsa")]
13use {
14 crate::{private::DsaKeypair, public::DsaPublicKey},
15 encoding::Uint,
16 signature::{DigestSigner, DigestVerifier},
17};
18
19#[cfg(any(feature = "p256", feature = "p384", feature = "p521"))]
20use crate::{
21 private::{EcdsaKeypair, EcdsaPrivateKey},
22 public::EcdsaPublicKey,
23};
24
25#[cfg(any(feature = "dsa", feature = "p256", feature = "p384", feature = "p521"))]
26use core::iter;
27
28#[cfg(feature = "rsa")]
29use {
30 crate::{HashAlg, private::RsaKeypair, public::RsaPublicKey},
31 sha2::Sha512,
32};
33
34#[cfg(any(all(feature = "sha1", feature = "rsa"), feature = "dsa"))]
35use sha1::Sha1;
36
37#[cfg(any(feature = "ed25519", feature = "rsa", feature = "p256"))]
38use sha2::Sha256;
39
40#[cfg(any(feature = "dsa", feature = "ed25519", feature = "p256"))]
41use sha2::Digest;
42
43const DSA_SIGNATURE_SIZE: usize = 40;
44const ED25519_SIGNATURE_SIZE: usize = 64;
45const SK_SIGNATURE_TRAILER_SIZE: usize = 5; const SK_ED25519_SIGNATURE_SIZE: usize = ED25519_SIGNATURE_SIZE + SK_SIGNATURE_TRAILER_SIZE;
47
48pub trait SigningKey: Signer<Signature> {
54 fn public_key(&self) -> public::KeyData;
56}
57
58impl<T> SigningKey for T
59where
60 T: Signer<Signature>,
61 public::KeyData: for<'a> From<&'a T>,
62{
63 fn public_key(&self) -> public::KeyData {
64 self.into()
65 }
66}
67
68#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
90pub struct Signature {
91 algorithm: Algorithm,
93
94 data: Vec<u8>,
96}
97
98impl Signature {
99 pub fn new(algorithm: Algorithm, data: impl Into<Vec<u8>>) -> Result<Self> {
107 let data = data.into();
108
109 match algorithm {
111 Algorithm::Dsa if data.len() == DSA_SIGNATURE_SIZE => (),
112 Algorithm::Ecdsa { curve } => ecdsa_sig_size(&data, curve, false)?,
113 Algorithm::Ed25519 if data.len() == ED25519_SIGNATURE_SIZE => (),
114 Algorithm::SkEd25519 if data.len() == SK_ED25519_SIGNATURE_SIZE => (),
115 Algorithm::SkEcdsaSha2NistP256 => ecdsa_sig_size(&data, EcdsaCurve::NistP256, true)?,
116 Algorithm::Rsa { .. } => (),
117 Algorithm::Other(_) if !data.is_empty() => (),
118 _ => return Err(encoding::Error::Length.into()),
119 }
120
121 Ok(Self { algorithm, data })
122 }
123
124 pub fn algorithm(&self) -> Algorithm {
126 self.algorithm.clone()
127 }
128
129 pub fn as_bytes(&self) -> &[u8] {
131 &self.data
132 }
133
134 pub(crate) fn placeholder() -> Self {
138 Self {
139 algorithm: Algorithm::default(),
140 data: Vec::new(),
141 }
142 }
143
144 pub(crate) fn is_placeholder(&self) -> bool {
146 self.algorithm == Algorithm::default() && self.data.is_empty()
147 }
148}
149
150fn ecdsa_sig_size(mut data: &[u8], curve: EcdsaCurve, sk_trailer: bool) -> Result<()> {
153 let reader = &mut data;
154
155 for _ in 0..2 {
156 let component = Mpint::decode(reader)?;
157 let bytes = component.as_positive_bytes().ok_or(Error::FormatEncoding)?;
158 if bytes.len() > curve.field_size() {
159 return Err(encoding::Error::Length.into());
160 }
161 }
162
163 if sk_trailer {
164 reader.drain(SK_SIGNATURE_TRAILER_SIZE)?;
165 }
166
167 Ok(reader.finish(())?)
168}
169
170impl AsRef<[u8]> for Signature {
171 fn as_ref(&self) -> &[u8] {
172 self.as_bytes()
173 }
174}
175
176impl Decode for Signature {
177 type Error = Error;
178
179 fn decode(reader: &mut impl Reader) -> Result<Self> {
180 let algorithm = Algorithm::decode(reader)?;
181 let mut data = Vec::decode(reader)?;
182
183 if algorithm == Algorithm::SkEd25519 || algorithm == Algorithm::SkEcdsaSha2NistP256 {
184 let flags = u8::decode(reader)?;
185 let counter = u32::decode(reader)?;
186
187 data.push(flags);
188 data.extend(counter.to_be_bytes());
189 }
190 Self::new(algorithm, data)
191 }
192}
193
194impl Encode for Signature {
195 fn encoded_len(&self) -> encoding::Result<usize> {
196 [
197 self.algorithm().encoded_len()?,
198 self.as_bytes().encoded_len()?,
199 ]
200 .checked_sum()
201 }
202
203 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
204 if self.is_placeholder() {
205 return Err(encoding::Error::Length);
206 }
207
208 self.algorithm().encode(writer)?;
209
210 if self.algorithm == Algorithm::SkEd25519 {
211 let signature_length = self
212 .as_bytes()
213 .len()
214 .checked_sub(SK_SIGNATURE_TRAILER_SIZE)
215 .ok_or(encoding::Error::Length)?;
216 self.as_bytes()[..signature_length].encode(writer)?;
217 writer.write(&self.as_bytes()[signature_length..])?;
218 } else {
219 self.as_bytes().encode(writer)?;
220 }
221
222 Ok(())
223 }
224}
225
226impl SignatureEncoding for Signature {
227 type Repr = Vec<u8>;
228}
229
230impl TryFrom<&[u8]> for Signature {
232 type Error = Error;
233
234 fn try_from(mut bytes: &[u8]) -> Result<Self> {
235 Self::decode(&mut bytes)
236 }
237}
238
239impl TryFrom<Signature> for Vec<u8> {
240 type Error = Error;
241
242 fn try_from(signature: Signature) -> Result<Vec<u8>> {
243 Ok(signature.encode_vec()?)
244 }
245}
246
247impl fmt::Debug for Signature {
248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249 write!(
250 f,
251 "Signature {{ algorithm: {:?}, data: {:X} }}",
252 self.algorithm, self
253 )
254 }
255}
256
257impl fmt::LowerHex for Signature {
258 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
259 for byte in self.as_ref() {
260 write!(f, "{byte:02x}")?;
261 }
262 Ok(())
263 }
264}
265
266impl fmt::UpperHex for Signature {
267 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
268 for byte in self.as_ref() {
269 write!(f, "{byte:02X}")?;
270 }
271 Ok(())
272 }
273}
274
275impl Signer<Signature> for PrivateKey {
276 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
277 self.key_data().try_sign(message)
278 }
279}
280
281impl Signer<Signature> for private::KeypairData {
282 #[allow(unused_variables)]
283 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
284 match self {
285 #[cfg(feature = "dsa")]
286 Self::Dsa(keypair) => keypair.try_sign(message),
287 #[cfg(any(feature = "p256", feature = "p384", feature = "p521"))]
288 Self::Ecdsa(keypair) => keypair.try_sign(message),
289 #[cfg(feature = "ed25519")]
290 Self::Ed25519(keypair) => keypair.try_sign(message),
291 #[cfg(feature = "rsa")]
292 Self::Rsa(keypair) => keypair.try_sign(message),
293 _ => Err(self.algorithm()?.unsupported_error().into()),
294 }
295 }
296}
297
298impl Verifier<Signature> for PublicKey {
299 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
300 self.key_data().verify(message, signature)
301 }
302}
303
304impl Verifier<Signature> for public::KeyData {
305 #[allow(unused_variables)]
306 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
307 match self {
308 #[cfg(feature = "dsa")]
309 Self::Dsa(pk) => pk.verify(message, signature),
310 #[cfg(any(feature = "p256", feature = "p384", feature = "p521"))]
311 Self::Ecdsa(pk) => pk.verify(message, signature),
312 #[cfg(feature = "ed25519")]
313 Self::Ed25519(pk) => pk.verify(message, signature),
314 #[cfg(feature = "ed25519")]
315 Self::SkEd25519(pk) => pk.verify(message, signature),
316 #[cfg(feature = "p256")]
317 Self::SkEcdsaSha2NistP256(pk) => pk.verify(message, signature),
318 #[cfg(feature = "rsa")]
319 Self::Rsa(pk) => pk.verify(message, signature),
320 #[allow(unreachable_patterns)]
321 _ => Err(self.algorithm().unsupported_error().into()),
322 }
323 }
324}
325
326#[cfg(feature = "dsa")]
327impl Signer<Signature> for DsaKeypair {
328 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
329 let signature = dsa::SigningKey::try_from(self)?
330 .try_sign_digest(Sha1::new_with_prefix(message))
331 .map_err(|_| signature::Error::new())?;
332
333 let mut data = Vec::with_capacity(DSA_SIGNATURE_SIZE);
335
336 for component in [signature.r(), signature.s()] {
337 let bytes = component.to_be_bytes_trimmed_vartime();
338 let pad_len = (DSA_SIGNATURE_SIZE / 2).saturating_sub(bytes.len());
339 data.extend(iter::repeat(0).take(pad_len));
340 data.extend_from_slice(&bytes);
341 }
342
343 debug_assert_eq!(data.len(), DSA_SIGNATURE_SIZE);
344
345 Ok(Signature {
346 algorithm: Algorithm::Dsa,
347 data,
348 })
349 }
350}
351
352#[cfg(feature = "dsa")]
353impl Verifier<Signature> for DsaPublicKey {
354 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
355 match signature.algorithm {
356 Algorithm::Dsa => {
357 let signature = dsa::Signature::try_from(signature)?;
358 dsa::VerifyingKey::try_from(self)?
359 .verify_digest(Sha1::new_with_prefix(message), &signature)
360 .map_err(|_| signature::Error::new())
361 }
362 _ => Err(signature.algorithm().unsupported_error().into()),
363 }
364 }
365}
366
367#[cfg(feature = "dsa")]
368impl TryFrom<Signature> for dsa::Signature {
369 type Error = Error;
370
371 fn try_from(signature: Signature) -> Result<Self> {
372 dsa::Signature::try_from(&signature)
373 }
374}
375
376#[cfg(feature = "dsa")]
377impl TryFrom<&Signature> for dsa::Signature {
378 type Error = Error;
379
380 fn try_from(signature: &Signature) -> Result<Self> {
381 let data = signature.data.as_slice();
382 if data.len() != DSA_SIGNATURE_SIZE {
383 return Err(encoding::Error::Length.into());
384 }
385
386 let component_size = DSA_SIGNATURE_SIZE / 2;
387 let component_bits = component_size.saturating_mul(8) as u32;
388 let components = data.split_at(component_size);
389
390 let r = Uint::from_be_slice(components.0, component_bits)?;
391 let s = Uint::from_be_slice(components.1, component_bits)?;
392 Ok(Self::from_components(r, s).ok_or(encoding::Error::MpintEncoding)?)
393 }
394}
395
396#[cfg(feature = "ed25519")]
397impl TryFrom<Signature> for ed25519_dalek::Signature {
398 type Error = Error;
399
400 fn try_from(signature: Signature) -> Result<ed25519_dalek::Signature> {
401 ed25519_dalek::Signature::try_from(&signature)
402 }
403}
404
405#[cfg(feature = "ed25519")]
406impl TryFrom<&Signature> for ed25519_dalek::Signature {
407 type Error = Error;
408
409 fn try_from(signature: &Signature) -> Result<ed25519_dalek::Signature> {
410 match signature.algorithm {
411 Algorithm::Ed25519 | Algorithm::SkEd25519 => {
412 Ok(ed25519_dalek::Signature::try_from(signature.as_bytes())?)
413 }
414 _ => Err(Error::AlgorithmUnknown),
415 }
416 }
417}
418
419#[cfg(feature = "ed25519")]
420impl Signer<Signature> for Ed25519Keypair {
421 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
422 let signature = ed25519_dalek::SigningKey::try_from(self)?.sign(message);
423
424 Ok(Signature {
425 algorithm: Algorithm::Ed25519,
426 data: signature.to_vec(),
427 })
428 }
429}
430
431#[cfg(feature = "ed25519")]
432impl Verifier<Signature> for Ed25519PublicKey {
433 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
434 let signature = ed25519_dalek::Signature::try_from(signature)?;
435 ed25519_dalek::VerifyingKey::try_from(self)?.verify(message, &signature)
436 }
437}
438
439#[cfg(feature = "ed25519")]
440impl Verifier<Signature> for public::SkEd25519 {
441 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
442 let (signature, flags_and_counter) = split_sk_signature(signature)?;
443 let signature = ed25519_dalek::Signature::try_from(signature)?;
444 ed25519_dalek::VerifyingKey::try_from(self.public_key())?.verify(
445 &make_sk_signed_data(self.application(), flags_and_counter, message),
446 &signature,
447 )
448 }
449}
450
451#[cfg(feature = "p256")]
452impl Verifier<Signature> for public::SkEcdsaSha2NistP256 {
453 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
454 let (signature_bytes, flags_and_counter) = split_sk_signature(signature)?;
455 let signature = p256_signature_from_openssh_bytes(signature_bytes)?;
456 p256::ecdsa::VerifyingKey::from_encoded_point(self.ec_point())?.verify(
457 &make_sk_signed_data(self.application(), flags_and_counter, message),
458 &signature,
459 )
460 }
461}
462
463#[cfg(any(feature = "p256", feature = "ed25519"))]
464fn make_sk_signed_data(application: &str, flags_and_counter: &[u8], message: &[u8]) -> Vec<u8> {
465 const SHA256_OUTPUT_LENGTH: usize = 32;
466 const SIGNED_SK_DATA_LENGTH: usize = 2 * SHA256_OUTPUT_LENGTH + SK_SIGNATURE_TRAILER_SIZE;
467
468 let mut signed_data = Vec::with_capacity(SIGNED_SK_DATA_LENGTH);
469 signed_data.extend(Sha256::digest(application));
470 signed_data.extend(flags_and_counter);
471 signed_data.extend(Sha256::digest(message));
472 signed_data
473}
474
475#[cfg(any(feature = "p256", feature = "ed25519"))]
476fn split_sk_signature(signature: &Signature) -> Result<(&[u8], &[u8])> {
477 let signature_bytes = signature.as_bytes();
478 let signature_len = signature_bytes
479 .len()
480 .checked_sub(SK_SIGNATURE_TRAILER_SIZE)
481 .ok_or(Error::Encoding(encoding::Error::Length))?;
482 Ok((
483 &signature_bytes[..signature_len],
484 &signature_bytes[signature_len..],
485 ))
486}
487
488macro_rules! impl_signature_for_curve {
489 ($krate:ident, $feature:expr, $curve:ident, $size:expr) => {
490 #[cfg(feature = $feature)]
491 impl TryFrom<$krate::ecdsa::Signature> for Signature {
492 type Error = Error;
493
494 fn try_from(signature: $krate::ecdsa::Signature) -> Result<Signature> {
495 Signature::try_from(&signature)
496 }
497 }
498
499 #[cfg(feature = $feature)]
500 impl TryFrom<&$krate::ecdsa::Signature> for Signature {
501 type Error = Error;
502
503 fn try_from(signature: &$krate::ecdsa::Signature) -> Result<Signature> {
504 let (r, s) = signature.split_bytes();
505
506 #[allow(clippy::arithmetic_side_effects)]
507 let mut data = Vec::with_capacity($size * 2 + 4 * 2 + 2);
508
509 Mpint::from_positive_bytes(&r)?.encode(&mut data)?;
510 Mpint::from_positive_bytes(&s)?.encode(&mut data)?;
511
512 Ok(Signature {
513 algorithm: Algorithm::Ecdsa {
514 curve: EcdsaCurve::$curve,
515 },
516 data,
517 })
518 }
519 }
520
521 #[cfg(feature = $feature)]
522 impl TryFrom<Signature> for $krate::ecdsa::Signature {
523 type Error = Error;
524
525 fn try_from(signature: Signature) -> Result<$krate::ecdsa::Signature> {
526 $krate::ecdsa::Signature::try_from(&signature)
527 }
528 }
529
530 #[cfg(feature = $feature)]
531 impl Signer<Signature> for EcdsaPrivateKey<$size> {
532 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
533 let signing_key = $krate::ecdsa::SigningKey::from_slice(self.as_ref())?;
534 let signature: $krate::ecdsa::Signature = signing_key.try_sign(message)?;
535 Ok(signature.try_into()?)
536 }
537 }
538 };
539}
540
541impl_signature_for_curve!(p256, "p256", NistP256, 32);
542impl_signature_for_curve!(p384, "p384", NistP384, 48);
543impl_signature_for_curve!(p521, "p521", NistP521, 66);
544
545#[cfg(any(feature = "p256", feature = "p384", feature = "p521"))]
547fn zero_pad_field_bytes<B: FromIterator<u8> + Copy>(m: Mpint) -> Option<B> {
548 use core::mem::size_of;
549
550 let bytes = m.as_positive_bytes()?;
551 size_of::<B>()
552 .checked_sub(bytes.len())
553 .map(|i| B::from_iter(iter::repeat(0u8).take(i).chain(bytes.iter().cloned())))
554}
555
556#[cfg(feature = "p256")]
557impl TryFrom<&Signature> for p256::ecdsa::Signature {
558 type Error = Error;
559
560 fn try_from(signature: &Signature) -> Result<p256::ecdsa::Signature> {
561 match signature.algorithm {
562 Algorithm::Ecdsa {
563 curve: EcdsaCurve::NistP256,
564 } => p256_signature_from_openssh_bytes(signature.as_bytes()),
565 _ => Err(signature.algorithm.clone().unsupported_error()),
566 }
567 }
568}
569#[cfg(feature = "p256")]
570fn p256_signature_from_openssh_bytes(mut signature_bytes: &[u8]) -> Result<p256::ecdsa::Signature> {
571 let reader = &mut signature_bytes;
572 let r = Mpint::decode(reader)?;
573 let s = Mpint::decode(reader)?;
574
575 match (
576 zero_pad_field_bytes::<p256::FieldBytes>(r),
577 zero_pad_field_bytes::<p256::FieldBytes>(s),
578 ) {
579 (Some(r), Some(s)) => Ok(p256::ecdsa::Signature::from_scalars(r, s)?),
580 _ => Err(Error::Crypto),
581 }
582}
583
584#[cfg(feature = "p384")]
585impl TryFrom<&Signature> for p384::ecdsa::Signature {
586 type Error = Error;
587
588 fn try_from(signature: &Signature) -> Result<p384::ecdsa::Signature> {
589 match signature.algorithm {
590 Algorithm::Ecdsa {
591 curve: EcdsaCurve::NistP384,
592 } => {
593 let reader = &mut signature.as_bytes();
594 let r = Mpint::decode(reader)?;
595 let s = Mpint::decode(reader)?;
596
597 match (
598 zero_pad_field_bytes::<p384::FieldBytes>(r),
599 zero_pad_field_bytes::<p384::FieldBytes>(s),
600 ) {
601 (Some(r), Some(s)) => Ok(p384::ecdsa::Signature::from_scalars(r, s)?),
602 _ => Err(Error::Crypto),
603 }
604 }
605 _ => Err(signature.algorithm.clone().unsupported_error()),
606 }
607 }
608}
609
610#[cfg(feature = "p521")]
611impl TryFrom<&Signature> for p521::ecdsa::Signature {
612 type Error = Error;
613
614 fn try_from(signature: &Signature) -> Result<p521::ecdsa::Signature> {
615 match signature.algorithm {
616 Algorithm::Ecdsa {
617 curve: EcdsaCurve::NistP521,
618 } => {
619 let reader = &mut signature.as_bytes();
620 let r = Mpint::decode(reader)?;
621 let s = Mpint::decode(reader)?;
622
623 match (
624 zero_pad_field_bytes::<p521::FieldBytes>(r),
625 zero_pad_field_bytes::<p521::FieldBytes>(s),
626 ) {
627 (Some(r), Some(s)) => Ok(p521::ecdsa::Signature::from_scalars(r, s)?),
628 _ => Err(Error::Crypto),
629 }
630 }
631 _ => Err(signature.algorithm.clone().unsupported_error()),
632 }
633 }
634}
635
636#[cfg(any(feature = "p256", feature = "p384", feature = "p521"))]
637impl Signer<Signature> for EcdsaKeypair {
638 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
639 match self {
640 #[cfg(feature = "p256")]
641 Self::NistP256 { private, .. } => private.try_sign(message),
642 #[cfg(feature = "p384")]
643 Self::NistP384 { private, .. } => private.try_sign(message),
644 #[cfg(feature = "p521")]
645 Self::NistP521 { private, .. } => private.try_sign(message),
646 #[cfg(not(all(feature = "p256", feature = "p384", feature = "p521")))]
647 _ => Err(self.algorithm().unsupported_error().into()),
648 }
649 }
650}
651
652#[cfg(any(feature = "p256", feature = "p384", feature = "p521"))]
653impl Verifier<Signature> for EcdsaPublicKey {
654 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
655 match signature.algorithm {
656 Algorithm::Ecdsa { curve } => match curve {
657 #[cfg(feature = "p256")]
658 EcdsaCurve::NistP256 => {
659 let verifying_key = p256::ecdsa::VerifyingKey::try_from(self)?;
660 let signature = p256::ecdsa::Signature::try_from(signature)?;
661 verifying_key.verify(message, &signature)
662 }
663
664 #[cfg(feature = "p384")]
665 EcdsaCurve::NistP384 => {
666 let verifying_key = p384::ecdsa::VerifyingKey::try_from(self)?;
667 let signature = p384::ecdsa::Signature::try_from(signature)?;
668 verifying_key.verify(message, &signature)
669 }
670
671 #[cfg(feature = "p521")]
672 EcdsaCurve::NistP521 => {
673 let verifying_key = p521::ecdsa::VerifyingKey::try_from(self)?;
674 let signature = p521::ecdsa::Signature::try_from(signature)?;
675 verifying_key.verify(message, &signature)
676 }
677
678 #[cfg(not(all(feature = "p256", feature = "p384", feature = "p521")))]
679 _ => Err(signature.algorithm().unsupported_error().into()),
680 },
681 _ => Err(signature.algorithm().unsupported_error().into()),
682 }
683 }
684}
685
686#[cfg(feature = "rsa")]
687impl Signer<Signature> for (&RsaKeypair, Option<HashAlg>) {
688 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
689 let data = match self.1 {
690 Some(HashAlg::Sha512) => {
691 rsa::pkcs1v15::SigningKey::<Sha512>::try_from(self.0)?.try_sign(message)
692 }
693 Some(HashAlg::Sha256) => {
694 rsa::pkcs1v15::SigningKey::<Sha256>::try_from(self.0)?.try_sign(message)
695 }
696 #[cfg(all(feature = "rsa", feature = "sha1"))]
697 None => rsa::pkcs1v15::SigningKey::<Sha1>::try_from(self.0)?.try_sign(message),
698 #[cfg(not(all(feature = "rsa", feature = "sha1")))]
699 None => return Err(Algorithm::Rsa { hash: None }.unsupported_error().into()),
700 }
701 .map_err(|_| signature::Error::new())?;
702
703 Ok(Signature {
704 algorithm: Algorithm::Rsa { hash: self.1 },
705 data: data.to_vec(),
706 })
707 }
708}
709
710#[cfg(feature = "rsa")]
711impl Signer<Signature> for RsaKeypair {
712 fn try_sign(&self, message: &[u8]) -> signature::Result<Signature> {
713 (self, Some(HashAlg::Sha512)).try_sign(message)
714 }
715}
716
717#[cfg(feature = "rsa")]
718impl Verifier<Signature> for RsaPublicKey {
719 fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> {
720 match signature.algorithm {
721 Algorithm::Rsa { hash } => {
722 let signature = rsa::pkcs1v15::Signature::try_from(signature.data.as_ref())?;
723
724 match hash {
725 #[cfg(not(all(feature = "rsa", feature = "sha1")))]
726 None => Err(Algorithm::Rsa { hash: None }.unsupported_error().into()),
727 #[cfg(all(feature = "rsa", feature = "sha1"))]
728 None => rsa::pkcs1v15::VerifyingKey::<Sha1>::try_from(self)?
729 .verify(message, &signature)
730 .map_err(|_| signature::Error::new()),
731 Some(HashAlg::Sha256) => rsa::pkcs1v15::VerifyingKey::<Sha256>::try_from(self)?
732 .verify(message, &signature)
733 .map_err(|_| signature::Error::new()),
734 Some(HashAlg::Sha512) => rsa::pkcs1v15::VerifyingKey::<Sha512>::try_from(self)?
735 .verify(message, &signature)
736 .map_err(|_| signature::Error::new()),
737 }
738 }
739 _ => Err(signature.algorithm().unsupported_error().into()),
740 }
741 }
742}
743
744#[cfg(test)]
745mod tests {
746 use super::Signature;
747 use crate::{Algorithm, EcdsaCurve, HashAlg};
748 use alloc::vec::Vec;
749 use encoding::Encode;
750 use hex_literal::hex;
751
752 #[cfg(any(feature = "ed25519", all(feature = "rsa", feature = "sha1")))]
753 use signature::Verifier;
754 #[cfg(feature = "ed25519")]
755 use {super::Ed25519Keypair, signature::Signer};
756
757 #[cfg(feature = "p256")]
758 use super::{Mpint, zero_pad_field_bytes};
759
760 const DSA_SIGNATURE: &[u8] = &hex!(
761 "000000077373682d6473730000002866725bf3c56100e975e21fff28a60f73717534d285ea3e1beefc2891f7189d00bd4d94627e84c55c"
762 );
763 const ECDSA_SHA2_P256_SIGNATURE: &[u8] = &hex!(
764 "0000001365636473612d736861322d6e6973747032353600000048000000201298ab320720a32139cda8a40c97a13dc54ce032ea3c6f09ea9e87501e48fa1d0000002046e4ac697a6424a9870b9ef04ca1182cd741965f989bd1f1f4a26fd83cf70348"
765 );
766 const ED25519_SIGNATURE: &[u8] = &hex!(
767 "0000000b7373682d65643235353139000000403d6b9906b76875aef1e7b2f1e02078a94f439aebb9a4734da1a851a81e22ce0199bbf820387a8de9c834c9c3cc778d9972dcbe70f68d53cc6bc9e26b02b46d04"
768 );
769 const SK_ED25519_SIGNATURE: &[u8] = &hex!(
770 "0000001a736b2d7373682d65643235353139406f70656e7373682e636f6d000000402f5670b6f93465d17423878a74084bf331767031ed240c627c8eb79ab8fa1b935a1fd993f52f5a13fec1797f8a434f943a6096246aea8dd5c8aa922cba3d95060100000009"
771 );
772 const RSA_SHA512_SIGNATURE: &[u8] = &hex!(
773 "0000000c7273612d736861322d3531320000018085a4ad1a91a62c00c85de7bb511f38088ff2bce763d76f4786febbe55d47624f9e2cffce58a680183b9ad162c7f0191ea26cab001ac5f5055743eced58e9981789305c208fc98d2657954e38eb28c7e7f3fbe92393a14324ed77aebb772a41aa7a107b38cb9bd1d9ad79b275135d1d7e019bb1d56d74f2450be6db0771f48f6707d3fcf9789592ca2e55595acc16b6e8d0139b56c5d1360b3a1e060f4151a3d7841df2c2a8c94d6f8a1bf633165ee0bcadac5642763df0dd79d3235ae5506595145f199d8abe8f9980411bf70a16e30f273736324d047043317044c36374d6a5ed34cac251e01c6795e4578393f9090bf4ae3e74a0009275a197315fc9c62f1c9aec1ba3b2d37c3b207e5500df19e090e7097ebc038fb9c9e35aea9161479ba6b5190f48e89e1abe51e8ec0e120ef89776e129687ca52d1892c8e88e6ef062a7d96b8a87682ca6a42ff1df0cdf5815c3645aeed7267ca7093043db0565e0f109b796bf117b9d2bb6d6debc0c67a4c9fb3aae3e29b00c7bd70f6c11cf53c295ff"
774 );
775
776 #[cfg(any(feature = "ed25519", all(feature = "rsa", feature = "sha1")))]
778 const EXAMPLE_MSG: &[u8] = b"Hello, world!";
779
780 #[cfg(feature = "p256")]
781 #[test]
782 fn convert_ecdsa_sha2_p256() {
783 let p256_signature = p256::ecdsa::Signature::try_from(&hex!("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001")[..]).unwrap();
784 let _ssh_signature = Signature::try_from(p256_signature).unwrap();
785 }
786
787 #[cfg(feature = "p256")]
788 #[test]
789 fn zero_pad_field_bytes_p256() {
790 let i = Mpint::from_bytes(&hex!(
791 "1122334455667788112233445566778811223344556677881122334455667788"
792 ))
793 .unwrap();
794 let fb = zero_pad_field_bytes::<p256::FieldBytes>(i);
795 assert!(fb.is_some());
796
797 let i = Mpint::from_bytes(&hex!(
799 "991122334455667788112233445566778811223344556677881122334455667788"
800 ))
801 .unwrap();
802 let fb = zero_pad_field_bytes::<p256::FieldBytes>(i);
803 assert!(fb.is_none());
804
805 let i = Mpint::from_bytes(&hex!(
807 "22334455667788112233445566778811223344556677881122334455667788"
808 ))
809 .unwrap();
810 let fb = zero_pad_field_bytes::<p256::FieldBytes>(i)
811 .expect("failed to build FieldBytes from short hex string");
812 assert_eq!(fb[0], 0x00);
813 assert_eq!(fb[1], 0x22);
814 }
815
816 #[test]
817 fn decode_dsa() {
818 let signature = Signature::try_from(DSA_SIGNATURE).unwrap();
819 assert_eq!(Algorithm::Dsa, signature.algorithm());
820 }
821
822 #[test]
823 fn decode_ecdsa_sha2_p256() {
824 let signature = Signature::try_from(ECDSA_SHA2_P256_SIGNATURE).unwrap();
825 assert_eq!(
826 Algorithm::Ecdsa {
827 curve: EcdsaCurve::NistP256
828 },
829 signature.algorithm()
830 );
831 }
832
833 #[test]
834 fn decode_ed25519() {
835 let signature = Signature::try_from(ED25519_SIGNATURE).unwrap();
836 assert_eq!(Algorithm::Ed25519, signature.algorithm());
837 }
838
839 #[test]
840 fn decode_sk_ed25519() {
841 let signature = Signature::try_from(SK_ED25519_SIGNATURE).unwrap();
842 assert_eq!(Algorithm::SkEd25519, signature.algorithm());
843 }
844
845 #[test]
846 fn decode_rsa() {
847 let signature = Signature::try_from(RSA_SHA512_SIGNATURE).unwrap();
848 assert_eq!(
849 Algorithm::Rsa {
850 hash: Some(HashAlg::Sha512)
851 },
852 signature.algorithm()
853 );
854 }
855
856 #[test]
857 fn encode_dsa() {
858 let signature = Signature::try_from(DSA_SIGNATURE).unwrap();
859 let result = signature.encode_vec().unwrap();
860 assert_eq!(DSA_SIGNATURE, &result);
861 }
862
863 #[test]
864 fn encode_ecdsa_sha2_p256() {
865 let signature = Signature::try_from(ECDSA_SHA2_P256_SIGNATURE).unwrap();
866 let result = signature.encode_vec().unwrap();
867 assert_eq!(ECDSA_SHA2_P256_SIGNATURE, &result);
868 }
869
870 #[test]
871 fn encode_ed25519() {
872 let signature = Signature::try_from(ED25519_SIGNATURE).unwrap();
873 let result = signature.encode_vec().unwrap();
874 assert_eq!(ED25519_SIGNATURE, &result);
875 }
876
877 #[test]
878 fn encode_sk_ed25519() {
879 let signature = Signature::try_from(SK_ED25519_SIGNATURE).unwrap();
880 let result = signature.encode_vec().unwrap();
881 assert_eq!(SK_ED25519_SIGNATURE, &result);
882 }
883
884 #[cfg(feature = "dsa")]
885 #[test]
886 fn try_sign_and_verify_dsa() {
887 use super::{DSA_SIGNATURE_SIZE, DsaKeypair};
888 use encoding::Decode as _;
889 use signature::{Signer as _, Verifier as _};
890
891 fn check_signature_component_lengths(
892 keypair: &DsaKeypair,
893 data: &[u8],
894 r_len: usize,
895 s_len: usize,
896 ) {
897 use sha1::{Digest as _, Sha1};
898 use signature::DigestSigner as _;
899
900 let signature = dsa::SigningKey::try_from(keypair)
901 .expect("valid DSA signing key")
902 .try_sign_digest(Sha1::new_with_prefix(data))
903 .expect("valid DSA signature");
904
905 let r = signature.r().to_be_bytes_trimmed_vartime();
906 assert_eq!(
907 r.len(),
908 r_len,
909 "dsa signature component `r` has len {} != {}",
910 r.len(),
911 r_len
912 );
913 let s = signature.s().to_be_bytes_trimmed_vartime();
914 assert_eq!(
915 s.len(),
916 s_len,
917 "dsa signature component `s` has len {} != {}",
918 s.len(),
919 s_len
920 );
921 }
922
923 let keypair = hex!(
924 "0000008100c161fb30c9e4e3602c8510f93bbd48d813da845dfcc75f3696e440cd019d609809608cd592b8430db901d7b43740740045b547c60fb035d69f9c64d3dfbfb13bb3edd8ccfdd44705739a639eb70f4aed16b0b8355de1b21cd9d442eff250895573a8af7ce2fb71fb062e887482dab5c68139845fb8afafc5f3819dc782920d510000001500f3fb6762430332bd5950edc5cd1ae6f17b88514f0000008061ef1394d864905e8efec3b610b7288a6522893af2a475f910796e0de47c8b065d365e942e80e471d1e6d4abdee1d3d3ede7103c6996432f1a9f9a671a31388672d63555077911fc69e641a997087260d22cdbf4965aa64bb382204f88987890ec225a5a7723a977dc1ecc5e04cf678f994692b20470adbf697489f800817b920000008100a9a6f1b65fc724d65df7441908b34af66489a4a3872cbbba25ea1bcfc83f25c4af1a62e339eefc814907cfaf0cb6d2d16996212a32a27a63013f01c57d0630f0be16c8c69d16fc25438e613b904b98aeb3e7c356fa8e75ee1d474c9f82f1280c5a6c18e9e607fcf7586eefb75ea9399da893b807375ac1396fd586bf277161980000001500ced95f1c7bbb39be4987837ad1f71be31bb7b0d9"
925 );
926 let keypair = DsaKeypair::decode(&mut &keypair[..]).expect("properly encoded DSA keypair");
927
928 let data = hex!(
929 "F0000040713d5f6fffe0000e6421ab0b3a69774d3da02fd72b107d6b32b6dad7c1660bbf507bf3eac3304cc5058f7e6f81b04239b8471459b1f3b387e2626f7eb8f6bcdd3200000006626c616465320000000e7373682d636f6e6e656374696f6e00000009686f73746261736564000000077373682d647373000001b2000000077373682d6473730000008100c161fb30c9e4e3602c8510f93bbd48d813da845dfcc75f3696e440cd019d609809608cd592b8430db901d7b43740740045b547c60fb035d69f9c64d3dfbfb13bb3edd8ccfdd44705739a639eb70f4aed16b0b8355de1b21cd9d442eff250895573a8af7ce2fb71fb062e887482dab5c68139845fb8afafc5f3819dc782920d510000001500f3fb6762430332bd5950edc5cd1ae6f17b88514f0000008061ef1394d864905e8efec3b610b7288a6522893af2a475f910796e0de47c8b065d365e942e80e471d1e6d4abdee1d3d3ede7103c6996432f1a9f9a671a31388672d63555077911fc69e641a997087260d22cdbf4965aa64bb382204f88987890ec225a5a7723a977dc1ecc5e04cf678f994692b20470adbf697489f800817b920000008100a9a6f1b65fc724d65df7441908b34af66489a4a3872cbbba25ea1bcfc83f25c4af1a62e339eefc814907cfaf0cb6d2d16996212a32a27a63013f01c57d0630f0be16c8c69d16fc25438e613b904b98aeb3e7c356fa8e75ee1d474c9f82f1280c5a6c18e9e607fcf7586eefb75ea9399da893b807375ac1396fd586bf2771619800000015746f6d61746f7373682e6c6f63616c646f6d61696e00000009746f6d61746f737368"
930 );
931 check_signature_component_lengths(
932 &keypair,
933 &data,
934 DSA_SIGNATURE_SIZE / 2,
935 DSA_SIGNATURE_SIZE / 2,
936 );
937 let signature = keypair.try_sign(&data[..]).expect("dsa try_sign is ok");
938 keypair
939 .public()
940 .verify(&data[..], &signature)
941 .expect("dsa verify is ok");
942
943 let data = hex!(
944 "00000040713d5f6fffe0000e6421ab0b3a69774d3da02fd72b107d6b32b6dad7c1660bbf507bf3eac3304cc5058f7e6f81b04239b8471459b1f3b387e2626f7eb8f6bcdd3200000006626c616465320000000e7373682d636f6e6e656374696f6e00000009686f73746261736564000000077373682d647373000001b2000000077373682d6473730000008100c161fb30c9e4e3602c8510f93bbd48d813da845dfcc75f3696e440cd019d609809608cd592b8430db901d7b43740740045b547c60fb035d69f9c64d3dfbfb13bb3edd8ccfdd44705739a639eb70f4aed16b0b8355de1b21cd9d442eff250895573a8af7ce2fb71fb062e887482dab5c68139845fb8afafc5f3819dc782920d510000001500f3fb6762430332bd5950edc5cd1ae6f17b88514f0000008061ef1394d864905e8efec3b610b7288a6522893af2a475f910796e0de47c8b065d365e942e80e471d1e6d4abdee1d3d3ede7103c6996432f1a9f9a671a31388672d63555077911fc69e641a997087260d22cdbf4965aa64bb382204f88987890ec225a5a7723a977dc1ecc5e04cf678f994692b20470adbf697489f800817b920000008100a9a6f1b65fc724d65df7441908b34af66489a4a3872cbbba25ea1bcfc83f25c4af1a62e339eefc814907cfaf0cb6d2d16996212a32a27a63013f01c57d0630f0be16c8c69d16fc25438e613b904b98aeb3e7c356fa8e75ee1d474c9f82f1280c5a6c18e9e607fcf7586eefb75ea9399da893b807375ac1396fd586bf2771619800000015746f6d61746f7373682e6c6f63616c646f6d61696e00000009746f6d61746f737368"
945 );
946 check_signature_component_lengths(
948 &keypair,
949 &data,
950 DSA_SIGNATURE_SIZE / 2 - 1,
951 DSA_SIGNATURE_SIZE / 2,
952 );
953 let signature = keypair
954 .try_sign(&data[..])
955 .expect("dsa try_sign for r.len() == 19 is ok");
956 keypair
957 .public()
958 .verify(&data[..], &signature)
959 .expect("dsa verify is ok");
960 }
961
962 #[cfg(feature = "ed25519")]
963 #[test]
964 fn sign_and_verify_ed25519() {
965 let keypair = Ed25519Keypair::from_seed(&[42; 32]);
966 let signature = keypair.sign(EXAMPLE_MSG);
967 assert!(keypair.public.verify(EXAMPLE_MSG, &signature).is_ok());
968 }
969
970 #[test]
971 fn placeholder() {
972 assert!(
973 !Signature::try_from(ED25519_SIGNATURE)
974 .unwrap()
975 .is_placeholder()
976 );
977
978 let placeholder = Signature::placeholder();
979 assert!(placeholder.is_placeholder());
980
981 let mut writer = Vec::new();
982 assert_eq!(
983 placeholder.encode(&mut writer),
984 Err(encoding::Error::Length)
985 );
986 }
987
988 #[cfg(all(feature = "rsa", feature = "sha1"))]
989 #[test]
990 fn sign_and_verify_rsa_sha1() {
991 use encoding::Decode;
992
993 use crate::PrivateKey;
994
995 let key = PrivateKey::from_openssh(include_str!("../tests/examples/id_rsa_3072")).unwrap();
996 let key = key.key_data().rsa().unwrap();
997 let encoded = hex!(
998 "000000077373682d727361000001809485247d72bf853272c86dd8c1c3fa0d2bebcdea9d91a376525a4bcc4a9ca2b19d31af48cfc07da086b244c65b37f3eb8fcab9661ccf777ed2f45404dd602b405526e19323f065b44d19f1bbda3eaf87b922b01049fcd8b82f08ffab6582e8427b0af3305f32961816d499d7b4925c1293b2d658dc6ca7cfb2d47c203c7d9512c0ee33e3d74f362d339a112fc94a74e8f388fc7fd1e9b95c7dd94e62ff16c9463476b7cf0e42af0f17fd2b9e325a50fc40ffd02b4a39e692727186b47c8ce9d7037de7e94615966df462238e214e7440bedabc5fbf79cfa93b96be5f27268da7c1ae2246bcabcc18a0d2c507be8727d04e41ed38686e5c455c159ee371f477668e89720191a72fbdb4eef86f1aa5c3596cefad12b20b1a1220accf6145f8583d7559751b2d0445e2e8a8fda85bf30f24b446ac6d0b943f7c519e5a021b1468cf120ed565d95ed8ddf022f97537ec5491226198ec58dd96c6bd218ddb237aa80785ceafa7722f1d2ba3e39dce2a9fdb0038f4124e2aa27d28eef927d87c8708f6"
999 );
1000
1001 let decoded = Signature::decode(&mut &encoded[..]).unwrap();
1002
1003 assert!(Verifier::verify(key.public(), EXAMPLE_MSG, &decoded).is_ok());
1004 }
1005}