1#![cfg_attr(
39 not(any(boringssl, awslc)),
40 doc = r#"\
41
42Compute an HMAC:
43
44```rust
45use openssl::hash::MessageDigest;
46use openssl::memcmp;
47use openssl::pkey::PKey;
48use openssl::sign::Signer;
49
50// Create a PKey
51let key = PKey::hmac(b"my secret").unwrap();
52
53let data = b"hello, world!";
54let data2 = b"hola, mundo!";
55
56// Compute the HMAC
57let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
58signer.update(data).unwrap();
59signer.update(data2).unwrap();
60let hmac = signer.sign_to_vec().unwrap();
61
62// `Verifier` cannot be used with HMACs; use the `memcmp::eq` function instead
63//
64// Do not simply check for equality with `==`!
65# let target = hmac.clone();
66assert!(memcmp::eq(&hmac, &target));
67```"#
68)]
69
70use cfg_if::cfg_if;
71use foreign_types::ForeignTypeRef;
72use libc::c_int;
73use std::io::{self, Write};
74use std::marker::PhantomData;
75use std::ptr;
76
77use crate::error::ErrorStack;
78use crate::hash::MessageDigest;
79use crate::pkey::{HasPrivate, HasPublic, PKeyRef};
80use crate::rsa::Padding;
81use crate::{cvt, cvt_p};
82use openssl_macros::corresponds;
83
84cfg_if! {
85 if #[cfg(any(ossl110, libressl382))] {
86 use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
87 } else {
88 use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
89 }
90}
91
92pub struct RsaPssSaltlen(c_int);
94
95impl RsaPssSaltlen {
96 pub(crate) fn as_raw(&self) -> c_int {
98 self.0
99 }
100
101 pub fn custom(val: c_int) -> RsaPssSaltlen {
103 RsaPssSaltlen(val)
104 }
105
106 pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1);
109 pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2);
112}
113
114pub struct Signer<'a> {
116 md_ctx: *mut ffi::EVP_MD_CTX,
117 pctx: *mut ffi::EVP_PKEY_CTX,
118 _p: PhantomData<&'a ()>,
119}
120
121unsafe impl Sync for Signer<'_> {}
122unsafe impl Send for Signer<'_> {}
123
124impl Drop for Signer<'_> {
125 fn drop(&mut self) {
126 unsafe {
128 EVP_MD_CTX_free(self.md_ctx);
129 }
130 }
131}
132
133#[allow(clippy::len_without_is_empty)]
134impl Signer<'_> {
135 #[corresponds(EVP_DigestSignInit)]
140 pub fn new<'a, T>(type_: MessageDigest, pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
141 where
142 T: HasPrivate,
143 {
144 Self::new_intern(Some(type_), pkey)
145 }
146
147 #[corresponds(EVP_DigestSignInit)]
152 pub fn new_without_digest<'a, T>(pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
153 where
154 T: HasPrivate,
155 {
156 Self::new_intern(None, pkey)
157 }
158
159 fn new_intern<'a, T>(
160 type_: Option<MessageDigest>,
161 pkey: &PKeyRef<T>,
162 ) -> Result<Signer<'a>, ErrorStack>
163 where
164 T: HasPrivate,
165 {
166 unsafe {
167 ffi::init();
168
169 let ctx = cvt_p(EVP_MD_CTX_new())?;
170 let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
171 let r = ffi::EVP_DigestSignInit(
172 ctx,
173 &mut pctx,
174 type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
175 ptr::null_mut(),
176 pkey.as_ptr(),
177 );
178 if r != 1 {
179 EVP_MD_CTX_free(ctx);
180 return Err(ErrorStack::get());
181 }
182
183 assert!(!pctx.is_null());
184
185 Ok(Signer {
186 md_ctx: ctx,
187 pctx,
188 _p: PhantomData,
189 })
190 }
191 }
192
193 #[corresponds(EVP_PKEY_CTX_get_rsa_padding)]
197 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
198 unsafe {
199 let mut pad = 0;
200 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
201 .map(|_| Padding::from_raw(pad))
202 }
203 }
204
205 #[corresponds(EVP_PKEY_CTX_set_rsa_padding)]
209 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
210 unsafe {
211 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
212 self.pctx,
213 padding.as_raw(),
214 ))
215 .map(|_| ())
216 }
217 }
218
219 #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)]
223 pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
224 unsafe {
225 cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
226 self.pctx,
227 len.as_raw(),
228 ))
229 .map(|_| ())
230 }
231 }
232
233 #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)]
237 pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
238 unsafe {
239 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
240 self.pctx,
241 md.as_ptr() as *mut _,
242 ))
243 .map(|_| ())
244 }
245 }
246
247 #[corresponds(EVP_DigestUpdate)]
252 pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
253 unsafe {
254 cvt(ffi::EVP_DigestUpdate(
255 self.md_ctx,
256 buf.as_ptr() as *const _,
257 buf.len(),
258 ))
259 .map(|_| ())
260 }
261 }
262
263 #[corresponds(EVP_DigestSignFinal)]
268 pub fn len(&self) -> Result<usize, ErrorStack> {
269 self.len_intern()
270 }
271
272 #[cfg(not(any(ossl111, boringssl, libressl370, awslc)))]
273 fn len_intern(&self) -> Result<usize, ErrorStack> {
274 unsafe {
275 let mut len = 0;
276 cvt(ffi::EVP_DigestSignFinal(
277 self.md_ctx,
278 ptr::null_mut(),
279 &mut len,
280 ))?;
281 Ok(len)
282 }
283 }
284
285 #[cfg(any(ossl111, boringssl, libressl370, awslc))]
286 fn len_intern(&self) -> Result<usize, ErrorStack> {
287 unsafe {
288 let mut len = 0;
289 cvt(ffi::EVP_DigestSign(
290 self.md_ctx,
291 ptr::null_mut(),
292 &mut len,
293 ptr::null(),
294 0,
295 ))?;
296 Ok(len)
297 }
298 }
299
300 #[corresponds(EVP_DigestSignFinal)]
305 pub fn sign(&self, buf: &mut [u8]) -> Result<usize, ErrorStack> {
306 unsafe {
307 let mut len = buf.len();
308 cvt(ffi::EVP_DigestSignFinal(
309 self.md_ctx,
310 buf.as_mut_ptr() as *mut _,
311 &mut len,
312 ))?;
313 Ok(len)
314 }
315 }
316
317 pub fn sign_to_vec(&self) -> Result<Vec<u8>, ErrorStack> {
321 let mut buf = vec![0; self.len()?];
322 let len = self.sign(&mut buf)?;
323 buf.truncate(len);
325 Ok(buf)
326 }
327
328 #[corresponds(EVP_DigestSign)]
336 #[cfg(any(ossl111, boringssl, libressl370, awslc))]
337 pub fn sign_oneshot(
338 &mut self,
339 sig_buf: &mut [u8],
340 data_buf: &[u8],
341 ) -> Result<usize, ErrorStack> {
342 unsafe {
343 let mut sig_len = sig_buf.len();
344 cvt(ffi::EVP_DigestSign(
345 self.md_ctx,
346 sig_buf.as_mut_ptr() as *mut _,
347 &mut sig_len,
348 data_buf.as_ptr() as *const _,
349 data_buf.len(),
350 ))?;
351 Ok(sig_len)
352 }
353 }
354
355 #[cfg(any(ossl111, boringssl, libressl370, awslc))]
359 pub fn sign_oneshot_to_vec(&mut self, data_buf: &[u8]) -> Result<Vec<u8>, ErrorStack> {
360 let mut sig_buf = vec![0; self.len()?];
361 let len = self.sign_oneshot(&mut sig_buf, data_buf)?;
362 sig_buf.truncate(len);
364 Ok(sig_buf)
365 }
366}
367
368impl Write for Signer<'_> {
369 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
370 self.update(buf)?;
371 Ok(buf.len())
372 }
373
374 fn flush(&mut self) -> io::Result<()> {
375 Ok(())
376 }
377}
378
379pub struct Verifier<'a> {
382 md_ctx: *mut ffi::EVP_MD_CTX,
383 pctx: *mut ffi::EVP_PKEY_CTX,
384 pkey_pd: PhantomData<&'a ()>,
385}
386
387unsafe impl Sync for Verifier<'_> {}
388unsafe impl Send for Verifier<'_> {}
389
390impl Drop for Verifier<'_> {
391 fn drop(&mut self) {
392 unsafe {
394 EVP_MD_CTX_free(self.md_ctx);
395 }
396 }
397}
398
399impl<'a> Verifier<'a> {
401 #[corresponds(EVP_DigestVerifyInit)]
406 pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
407 where
408 T: HasPublic,
409 {
410 Verifier::new_intern(Some(type_), pkey)
411 }
412
413 #[corresponds(EVP_DigestVerifyInit)]
417 pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
418 where
419 T: HasPublic,
420 {
421 Verifier::new_intern(None, pkey)
422 }
423
424 fn new_intern<T>(
425 type_: Option<MessageDigest>,
426 pkey: &'a PKeyRef<T>,
427 ) -> Result<Verifier<'a>, ErrorStack>
428 where
429 T: HasPublic,
430 {
431 unsafe {
432 ffi::init();
433
434 let ctx = cvt_p(EVP_MD_CTX_new())?;
435 let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
436 let r = ffi::EVP_DigestVerifyInit(
437 ctx,
438 &mut pctx,
439 type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
440 ptr::null_mut(),
441 pkey.as_ptr(),
442 );
443 if r != 1 {
444 EVP_MD_CTX_free(ctx);
445 return Err(ErrorStack::get());
446 }
447
448 assert!(!pctx.is_null());
449
450 Ok(Verifier {
451 md_ctx: ctx,
452 pctx,
453 pkey_pd: PhantomData,
454 })
455 }
456 }
457
458 #[corresponds(EVP_PKEY_CTX_get_rsa_padding)]
462 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
463 unsafe {
464 let mut pad = 0;
465 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
466 .map(|_| Padding::from_raw(pad))
467 }
468 }
469
470 #[corresponds(EVP_PKEY_CTX_set_rsa_padding)]
474 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
475 unsafe {
476 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
477 self.pctx,
478 padding.as_raw(),
479 ))
480 .map(|_| ())
481 }
482 }
483
484 #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)]
488 pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
489 unsafe {
490 cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
491 self.pctx,
492 len.as_raw(),
493 ))
494 .map(|_| ())
495 }
496 }
497
498 #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)]
502 pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
503 unsafe {
504 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
505 self.pctx,
506 md.as_ptr() as *mut _,
507 ))
508 .map(|_| ())
509 }
510 }
511
512 #[corresponds(EVP_DigestUpdate)]
517 pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
518 unsafe {
519 cvt(ffi::EVP_DigestUpdate(
520 self.md_ctx,
521 buf.as_ptr() as *const _,
522 buf.len(),
523 ))
524 .map(|_| ())
525 }
526 }
527
528 #[corresponds(EVP_DigestVerifyFinal)]
530 pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
531 unsafe {
532 let r =
533 EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len());
534 match r {
535 1 => Ok(true),
536 0 => {
537 ErrorStack::get(); Ok(false)
539 }
540 _ => Err(ErrorStack::get()),
541 }
542 }
543 }
544
545 #[corresponds(EVP_DigestVerify)]
547 #[cfg(any(ossl111, boringssl, libressl370, awslc))]
548 pub fn verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> {
549 unsafe {
550 let r = ffi::EVP_DigestVerify(
551 self.md_ctx,
552 signature.as_ptr() as *const _,
553 signature.len(),
554 buf.as_ptr() as *const _,
555 buf.len(),
556 );
557 match r {
558 1 => Ok(true),
559 0 => {
560 ErrorStack::get();
561 Ok(false)
562 }
563 _ => Err(ErrorStack::get()),
564 }
565 }
566 }
567}
568
569impl Write for Verifier<'_> {
570 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
571 self.update(buf)?;
572 Ok(buf.len())
573 }
574
575 fn flush(&mut self) -> io::Result<()> {
576 Ok(())
577 }
578}
579
580#[cfg(not(ossl101))]
581use ffi::EVP_DigestVerifyFinal;
582
583#[cfg(ossl101)]
584#[allow(bad_style)]
585unsafe fn EVP_DigestVerifyFinal(
586 ctx: *mut ffi::EVP_MD_CTX,
587 sigret: *const ::libc::c_uchar,
588 siglen: ::libc::size_t,
589) -> ::libc::c_int {
590 ffi::EVP_DigestVerifyFinal(ctx, sigret as *mut _, siglen)
591}
592
593#[cfg(test)]
594mod test {
595 use hex::{self, FromHex};
596 #[cfg(not(boringssl))]
597 use std::iter;
598
599 use crate::ec::{EcGroup, EcKey};
600 use crate::hash::MessageDigest;
601 use crate::nid::Nid;
602 use crate::pkey::PKey;
603 use crate::rsa::{Padding, Rsa};
604 #[cfg(any(ossl111, awslc))]
605 use crate::sign::RsaPssSaltlen;
606 use crate::sign::{Signer, Verifier};
607
608 const INPUT: &str =
609 "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
610 654841694f6a457a4d4441344d546b7a4f44417344516f67496d6830644841364c79396c654746746347786c4c\
611 6d4e76625339706331397962323930496a7030636e566c6651";
612
613 const SIGNATURE: &str =
614 "702e218943e88fd11eb5d82dbf7845f34106ae1b81fff7731116add1717d83656d420afd3c96eedd73a2663e51\
615 66687b000b87226e0187ed1073f945e582adfcef16d85a798ee8c66ddb3db8975b17d09402beedd5d9d9700710\
616 8db28160d5f8040ca7445762b81fbe7ff9d92e0ae76f24f25b33bbe6f44ae61eb1040acb20044d3ef9128ed401\
617 30795bd4bd3b41eecad066ab651981fde48df77f372dc38b9fafdd3befb18b5da3cc3c2eb02f9e3a41d612caad\
618 15911273a05f23b9e838faaf849d698429ef5a1e88798236c3d40e604522a544c8f27a7a2db80663d16cf7caea\
619 56de405cb2215a45b2c25566b55ac1a748a070dfc8a32a469543d019eefb47";
620
621 #[test]
622 fn rsa_sign() {
623 let key = include_bytes!("../test/rsa.pem");
624 let private_key = Rsa::private_key_from_pem(key).unwrap();
625 let pkey = PKey::from_rsa(private_key).unwrap();
626
627 let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
628 assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1);
629 signer.set_rsa_padding(Padding::PKCS1).unwrap();
630 signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
631 let result = signer.sign_to_vec().unwrap();
632
633 assert_eq!(hex::encode(result), SIGNATURE);
634 }
635
636 #[test]
637 fn rsa_verify_ok() {
638 let key = include_bytes!("../test/rsa.pem");
639 let private_key = Rsa::private_key_from_pem(key).unwrap();
640 let pkey = PKey::from_rsa(private_key).unwrap();
641
642 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
643 assert_eq!(verifier.rsa_padding().unwrap(), Padding::PKCS1);
644 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
645 assert!(verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
646 }
647
648 #[test]
649 fn rsa_verify_invalid() {
650 let key = include_bytes!("../test/rsa.pem");
651 let private_key = Rsa::private_key_from_pem(key).unwrap();
652 let pkey = PKey::from_rsa(private_key).unwrap();
653
654 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
655 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
656 verifier.update(b"foobar").unwrap();
657 assert!(!verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
658 }
659
660 #[cfg(not(boringssl))]
661 fn test_hmac(ty: MessageDigest, tests: &[(Vec<u8>, Vec<u8>, Vec<u8>)]) {
662 for (key, data, res) in tests.iter() {
663 let pkey = PKey::hmac(key).unwrap();
664 let mut signer = Signer::new(ty, &pkey).unwrap();
665 signer.update(data).unwrap();
666 assert_eq!(signer.sign_to_vec().unwrap(), *res);
667 }
668 }
669
670 #[test]
671 #[cfg(not(boringssl))]
672 fn hmac_md5() {
673 let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] = [
675 (
676 iter::repeat(0x0b_u8).take(16).collect(),
677 b"Hi There".to_vec(),
678 Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap(),
679 ),
680 (
681 b"Jefe".to_vec(),
682 b"what do ya want for nothing?".to_vec(),
683 Vec::from_hex("750c783e6ab0b503eaa86e310a5db738").unwrap(),
684 ),
685 (
686 iter::repeat(0xaa_u8).take(16).collect(),
687 iter::repeat(0xdd_u8).take(50).collect(),
688 Vec::from_hex("56be34521d144c88dbb8c733f0e8b3f6").unwrap(),
689 ),
690 (
691 Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(),
692 iter::repeat(0xcd_u8).take(50).collect(),
693 Vec::from_hex("697eaf0aca3a3aea3a75164746ffaa79").unwrap(),
694 ),
695 (
696 iter::repeat(0x0c_u8).take(16).collect(),
697 b"Test With Truncation".to_vec(),
698 Vec::from_hex("56461ef2342edc00f9bab995690efd4c").unwrap(),
699 ),
700 (
701 iter::repeat(0xaa_u8).take(80).collect(),
702 b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(),
703 Vec::from_hex("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd").unwrap(),
704 ),
705 (
706 iter::repeat(0xaa_u8).take(80).collect(),
707 b"Test Using Larger Than Block-Size Key \
708 and Larger Than One Block-Size Data"
709 .to_vec(),
710 Vec::from_hex("6f630fad67cda0ee1fb1f562db3aa53e").unwrap(),
711 ),
712 ];
713
714 test_hmac(MessageDigest::md5(), &tests);
715 }
716
717 #[test]
718 #[cfg(not(boringssl))]
719 fn hmac_sha1() {
720 let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] = [
722 (
723 iter::repeat(0x0b_u8).take(20).collect(),
724 b"Hi There".to_vec(),
725 Vec::from_hex("b617318655057264e28bc0b6fb378c8ef146be00").unwrap(),
726 ),
727 (
728 b"Jefe".to_vec(),
729 b"what do ya want for nothing?".to_vec(),
730 Vec::from_hex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79").unwrap(),
731 ),
732 (
733 iter::repeat(0xaa_u8).take(20).collect(),
734 iter::repeat(0xdd_u8).take(50).collect(),
735 Vec::from_hex("125d7342b9ac11cd91a39af48aa17b4f63f175d3").unwrap(),
736 ),
737 (
738 Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(),
739 iter::repeat(0xcd_u8).take(50).collect(),
740 Vec::from_hex("4c9007f4026250c6bc8414f9bf50c86c2d7235da").unwrap(),
741 ),
742 (
743 iter::repeat(0x0c_u8).take(20).collect(),
744 b"Test With Truncation".to_vec(),
745 Vec::from_hex("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04").unwrap(),
746 ),
747 (
748 iter::repeat(0xaa_u8).take(80).collect(),
749 b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(),
750 Vec::from_hex("aa4ae5e15272d00e95705637ce8a3b55ed402112").unwrap(),
751 ),
752 (
753 iter::repeat(0xaa_u8).take(80).collect(),
754 b"Test Using Larger Than Block-Size Key \
755 and Larger Than One Block-Size Data"
756 .to_vec(),
757 Vec::from_hex("e8e99d0f45237d786d6bbaa7965c7808bbff1a91").unwrap(),
758 ),
759 ];
760
761 test_hmac(MessageDigest::sha1(), &tests);
762 }
763
764 #[test]
765 #[cfg(ossl110)]
766 fn test_cmac() {
767 let cipher = crate::symm::Cipher::aes_128_cbc();
768 let key = Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap();
769 let pkey = PKey::cmac(&cipher, &key).unwrap();
770 let mut signer = Signer::new_without_digest(&pkey).unwrap();
771
772 let data = b"Hi There";
773 signer.update(data as &[u8]).unwrap();
774
775 let expected = vec![
776 136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19,
777 ];
778 assert_eq!(signer.sign_to_vec().unwrap(), expected);
779 }
780
781 #[test]
782 fn ec() {
783 let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
784 let key = EcKey::generate(&group).unwrap();
785 let key = PKey::from_ec_key(key).unwrap();
786
787 let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
788 signer.update(b"hello world").unwrap();
789 let signature = signer.sign_to_vec().unwrap();
790
791 let mut verifier = Verifier::new(MessageDigest::sha256(), &key).unwrap();
792 verifier.update(b"hello world").unwrap();
793 assert!(verifier.verify(&signature).unwrap());
794 }
795
796 #[test]
797 #[cfg(any(ossl111, boringssl, libressl370, awslc))]
798 fn eddsa() {
799 let key = PKey::generate_ed25519().unwrap();
800
801 let mut signer = Signer::new_without_digest(&key).unwrap();
802 let signature = signer.sign_oneshot_to_vec(b"hello world").unwrap();
803
804 let mut verifier = Verifier::new_without_digest(&key).unwrap();
805 assert!(verifier.verify_oneshot(&signature, b"hello world").unwrap());
806 }
807
808 #[test]
809 #[cfg(any(ossl111, awslc))]
810 fn rsa_sign_verify() {
811 let key = include_bytes!("../test/rsa.pem");
812 let private_key = Rsa::private_key_from_pem(key).unwrap();
813 let pkey = PKey::from_rsa(private_key).unwrap();
814
815 let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
816 signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
817 assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS);
818 signer
819 .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
820 .unwrap();
821 signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
822 signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
823 let signature = signer.sign_to_vec().unwrap();
824
825 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
826 verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
827 verifier
828 .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
829 .unwrap();
830 verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
831 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
832 assert!(verifier.verify(&signature).unwrap());
833 }
834}