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