1use crate::ffi;
38use foreign_types::ForeignTypeRef;
39use libc::c_int;
40use std::io::{self, Write};
41use std::marker::PhantomData;
42use std::ptr;
43
44use crate::error::ErrorStack;
45use crate::hash::MessageDigest;
46use crate::pkey::{HasPrivate, HasPublic, PKeyRef};
47use crate::rsa::Padding;
48use crate::{cvt, cvt_p};
49
50use crate::ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
51
52pub struct RsaPssSaltlen(c_int);
54
55impl RsaPssSaltlen {
56 fn as_raw(&self) -> c_int {
58 self.0
59 }
60
61 pub fn custom(val: c_int) -> RsaPssSaltlen {
63 RsaPssSaltlen(val)
64 }
65
66 pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1);
69 pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2);
72}
73
74pub struct Signer<'a> {
76 md_ctx: *mut ffi::EVP_MD_CTX,
77 pctx: *mut ffi::EVP_PKEY_CTX,
78 _p: PhantomData<&'a ()>,
79}
80
81unsafe impl<'a> Sync for Signer<'a> {}
82unsafe impl<'a> Send for Signer<'a> {}
83
84impl<'a> Drop for Signer<'a> {
85 fn drop(&mut self) {
86 unsafe {
88 EVP_MD_CTX_free(self.md_ctx);
89 }
90 }
91}
92
93#[allow(clippy::len_without_is_empty)]
94impl<'a> Signer<'a> {
95 pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
104 where
105 T: HasPrivate,
106 {
107 Self::new_intern(Some(type_), pkey)
108 }
109
110 pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
119 where
120 T: HasPrivate,
121 {
122 Self::new_intern(None, pkey)
123 }
124
125 fn new_intern<T>(
126 type_: Option<MessageDigest>,
127 pkey: &'a PKeyRef<T>,
128 ) -> Result<Signer<'a>, ErrorStack>
129 where
130 T: HasPrivate,
131 {
132 unsafe {
133 ffi::init();
134
135 let ctx = cvt_p(EVP_MD_CTX_new())?;
136 let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
137 let r = ffi::EVP_DigestSignInit(
138 ctx,
139 &mut pctx,
140 type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
141 ptr::null_mut(),
142 pkey.as_ptr(),
143 );
144 if r != 1 {
145 EVP_MD_CTX_free(ctx);
146 return Err(ErrorStack::get());
147 }
148
149 assert!(!pctx.is_null());
150
151 Ok(Signer {
152 md_ctx: ctx,
153 pctx,
154 _p: PhantomData,
155 })
156 }
157 }
158
159 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
165 unsafe {
166 let mut pad = 0;
167 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
168 .map(|_| Padding::from_raw(pad))
169 }
170 }
171
172 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
180 unsafe {
181 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
182 self.pctx,
183 padding.as_raw(),
184 ))
185 .map(|_| ())
186 }
187 }
188
189 pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
197 unsafe {
198 cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
199 self.pctx,
200 len.as_raw(),
201 ))
202 .map(|_| ())
203 }
204 }
205
206 pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
214 unsafe {
215 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
216 self.pctx,
217 md.as_ptr() as *mut _,
218 ))
219 .map(|_| ())
220 }
221 }
222
223 pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
232 unsafe {
233 cvt(ffi::EVP_DigestUpdate(
234 self.md_ctx,
235 buf.as_ptr() as *const _,
236 buf.len(),
237 ))
238 .map(|_| ())
239 }
240 }
241
242 pub fn len(&self) -> Result<usize, ErrorStack> {
251 self.len_intern()
252 }
253
254 fn len_intern(&self) -> Result<usize, ErrorStack> {
255 unsafe {
256 let mut len = 0;
257 cvt(ffi::EVP_DigestSign(
258 self.md_ctx,
259 ptr::null_mut(),
260 &mut len,
261 ptr::null(),
262 0,
263 ))?;
264 Ok(len)
265 }
266 }
267
268 pub fn sign(&self, buf: &mut [u8]) -> Result<usize, ErrorStack> {
277 unsafe {
278 let mut len = buf.len();
279 cvt(ffi::EVP_DigestSignFinal(
280 self.md_ctx,
281 buf.as_mut_ptr() as *mut _,
282 &mut len,
283 ))?;
284 Ok(len)
285 }
286 }
287
288 pub fn sign_to_vec(&self) -> Result<Vec<u8>, ErrorStack> {
292 let mut buf = vec![0; self.len()?];
293 let len = self.sign(&mut buf)?;
294 buf.truncate(len);
296 Ok(buf)
297 }
298
299 pub fn sign_oneshot(
311 &mut self,
312 sig_buf: &mut [u8],
313 data_buf: &[u8],
314 ) -> Result<usize, ErrorStack> {
315 unsafe {
316 let mut sig_len = sig_buf.len();
317 cvt(ffi::EVP_DigestSign(
318 self.md_ctx,
319 sig_buf.as_mut_ptr() as *mut _,
320 &mut sig_len,
321 data_buf.as_ptr() as *const _,
322 data_buf.len(),
323 ))?;
324 Ok(sig_len)
325 }
326 }
327
328 pub fn sign_oneshot_to_vec(&mut self, data_buf: &[u8]) -> Result<Vec<u8>, ErrorStack> {
332 let mut sig_buf = vec![0; self.len()?];
333 let len = self.sign_oneshot(&mut sig_buf, data_buf)?;
334 sig_buf.truncate(len);
336 Ok(sig_buf)
337 }
338}
339
340impl<'a> Write for Signer<'a> {
341 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
342 self.update(buf)?;
343 Ok(buf.len())
344 }
345
346 fn flush(&mut self) -> io::Result<()> {
347 Ok(())
348 }
349}
350
351pub struct Verifier<'a> {
352 md_ctx: *mut ffi::EVP_MD_CTX,
353 pctx: *mut ffi::EVP_PKEY_CTX,
354 pkey_pd: PhantomData<&'a ()>,
355}
356
357unsafe impl<'a> Sync for Verifier<'a> {}
358unsafe impl<'a> Send for Verifier<'a> {}
359
360impl<'a> Drop for Verifier<'a> {
361 fn drop(&mut self) {
362 unsafe {
364 EVP_MD_CTX_free(self.md_ctx);
365 }
366 }
367}
368
369impl<'a> Verifier<'a> {
371 pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
380 where
381 T: HasPublic,
382 {
383 Verifier::new_intern(Some(type_), pkey)
384 }
385
386 pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
394 where
395 T: HasPublic,
396 {
397 Verifier::new_intern(None, pkey)
398 }
399
400 fn new_intern<T>(
401 type_: Option<MessageDigest>,
402 pkey: &'a PKeyRef<T>,
403 ) -> Result<Verifier<'a>, ErrorStack>
404 where
405 T: HasPublic,
406 {
407 unsafe {
408 ffi::init();
409
410 let ctx = cvt_p(EVP_MD_CTX_new())?;
411 let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
412 let r = ffi::EVP_DigestVerifyInit(
413 ctx,
414 &mut pctx,
415 type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
416 ptr::null_mut(),
417 pkey.as_ptr(),
418 );
419 if r != 1 {
420 EVP_MD_CTX_free(ctx);
421 return Err(ErrorStack::get());
422 }
423
424 assert!(!pctx.is_null());
425
426 Ok(Verifier {
427 md_ctx: ctx,
428 pctx,
429 pkey_pd: PhantomData,
430 })
431 }
432 }
433
434 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
440 unsafe {
441 let mut pad = 0;
442 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
443 .map(|_| Padding::from_raw(pad))
444 }
445 }
446
447 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
455 unsafe {
456 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
457 self.pctx,
458 padding.as_raw(),
459 ))
460 .map(|_| ())
461 }
462 }
463
464 pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
472 unsafe {
473 cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
474 self.pctx,
475 len.as_raw(),
476 ))
477 .map(|_| ())
478 }
479 }
480
481 pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
489 unsafe {
490 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
491 self.pctx,
492 md.as_ptr() as *mut _,
493 ))
494 .map(|_| ())
495 }
496 }
497
498 pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
507 unsafe {
508 cvt(ffi::EVP_DigestUpdate(
509 self.md_ctx,
510 buf.as_ptr() as *const _,
511 buf.len(),
512 ))
513 .map(|_| ())
514 }
515 }
516
517 pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
523 unsafe {
524 let r =
525 EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len());
526 match r {
527 1 => Ok(true),
528 0 => {
529 ErrorStack::get(); Ok(false)
531 }
532 _ => Err(ErrorStack::get()),
533 }
534 }
535 }
536
537 pub fn verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> {
543 unsafe {
544 let r = ffi::EVP_DigestVerify(
545 self.md_ctx,
546 signature.as_ptr() as *const _,
547 signature.len(),
548 buf.as_ptr() as *const _,
549 buf.len(),
550 );
551 match r {
552 1 => Ok(true),
553 0 => {
554 ErrorStack::get();
555 Ok(false)
556 }
557 _ => Err(ErrorStack::get()),
558 }
559 }
560 }
561}
562
563impl<'a> Write for Verifier<'a> {
564 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
565 self.update(buf)?;
566 Ok(buf.len())
567 }
568
569 fn flush(&mut self) -> io::Result<()> {
570 Ok(())
571 }
572}
573
574use crate::ffi::EVP_DigestVerifyFinal;
575
576#[cfg(test)]
577mod test {
578 use super::RsaPssSaltlen;
579 use hex::{self, FromHex};
580
581 use crate::ec::{EcGroup, EcKey};
582 use crate::hash::MessageDigest;
583 use crate::nid::Nid;
584 use crate::pkey::PKey;
585 use crate::rsa::{Padding, Rsa};
586 use crate::sign::{Signer, Verifier};
587
588 const INPUT: &str =
589 "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
590 654841694f6a457a4d4441344d546b7a4f44417344516f67496d6830644841364c79396c654746746347786c4c\
591 6d4e76625339706331397962323930496a7030636e566c6651";
592
593 const SIGNATURE: &str =
594 "702e218943e88fd11eb5d82dbf7845f34106ae1b81fff7731116add1717d83656d420afd3c96eedd73a2663e51\
595 66687b000b87226e0187ed1073f945e582adfcef16d85a798ee8c66ddb3db8975b17d09402beedd5d9d9700710\
596 8db28160d5f8040ca7445762b81fbe7ff9d92e0ae76f24f25b33bbe6f44ae61eb1040acb20044d3ef9128ed401\
597 30795bd4bd3b41eecad066ab651981fde48df77f372dc38b9fafdd3befb18b5da3cc3c2eb02f9e3a41d612caad\
598 15911273a05f23b9e838faaf849d698429ef5a1e88798236c3d40e604522a544c8f27a7a2db80663d16cf7caea\
599 56de405cb2215a45b2c25566b55ac1a748a070dfc8a32a469543d019eefb47";
600
601 #[test]
602 fn rsa_sign() {
603 let key = include_bytes!("../test/rsa.pem");
604 let private_key = Rsa::private_key_from_pem(key).unwrap();
605 let pkey = PKey::from_rsa(private_key).unwrap();
606
607 let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
608 assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1);
609 signer.set_rsa_padding(Padding::PKCS1).unwrap();
610 signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
611 let result = signer.sign_to_vec().unwrap();
612
613 assert_eq!(hex::encode(result), SIGNATURE);
614 }
615
616 #[test]
617 fn rsa_verify_ok() {
618 let key = include_bytes!("../test/rsa.pem");
619 let private_key = Rsa::private_key_from_pem(key).unwrap();
620 let pkey = PKey::from_rsa(private_key).unwrap();
621
622 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
623 assert_eq!(verifier.rsa_padding().unwrap(), Padding::PKCS1);
624 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
625 assert!(verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
626 }
627
628 #[test]
629 fn rsa_verify_invalid() {
630 let key = include_bytes!("../test/rsa.pem");
631 let private_key = Rsa::private_key_from_pem(key).unwrap();
632 let pkey = PKey::from_rsa(private_key).unwrap();
633
634 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
635 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
636 verifier.update(b"foobar").unwrap();
637 assert!(!verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
638 }
639
640 #[test]
641 fn ec() {
642 let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
643 let key = EcKey::generate(&group).unwrap();
644 let key = PKey::from_ec_key(key).unwrap();
645
646 let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
647 signer.update(b"hello world").unwrap();
648 let signature = signer.sign_to_vec().unwrap();
649
650 let mut verifier = Verifier::new(MessageDigest::sha256(), &key).unwrap();
651 verifier.update(b"hello world").unwrap();
652 assert!(verifier.verify(&signature).unwrap());
653 }
654
655 #[test]
656 fn rsa_sign_verify() {
657 let key = include_bytes!("../test/rsa.pem");
658 let private_key = Rsa::private_key_from_pem(key).unwrap();
659 let pkey = PKey::from_rsa(private_key).unwrap();
660
661 let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
662 signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
663 assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS);
664 signer
665 .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
666 .unwrap();
667 signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
668 signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
669 let signature = signer.sign_to_vec().unwrap();
670
671 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
672 verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
673 verifier
674 .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
675 .unwrap();
676 verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
677 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
678 assert!(verifier.verify(&signature).unwrap());
679 }
680}