1use crate::ffi;
38use crate::libc_types::c_int;
39use foreign_types::ForeignTypeRef;
40use openssl_macros::corresponds;
41use std::io::{self, Write};
42use std::marker::PhantomData;
43use std::ptr;
44
45use crate::error::ErrorStack;
46use crate::hash::MessageDigest;
47use crate::pkey::{HasPrivate, HasPublic, PKeyRef};
48use crate::rsa::Padding;
49use crate::{cvt, cvt_p};
50
51use crate::ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
52
53pub struct RsaPssSaltlen(c_int);
55
56impl RsaPssSaltlen {
57 fn as_raw(&self) -> c_int {
59 self.0
60 }
61
62 #[must_use]
64 pub fn custom(val: c_int) -> RsaPssSaltlen {
65 RsaPssSaltlen(val)
66 }
67
68 pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1);
71 pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2);
74}
75
76pub struct Signer<'a> {
78 md_ctx: *mut ffi::EVP_MD_CTX,
79 pctx: *mut ffi::EVP_PKEY_CTX,
80 _p: PhantomData<&'a ()>,
81}
82
83unsafe impl Sync for Signer<'_> {}
84unsafe impl Send for Signer<'_> {}
85
86impl Drop for Signer<'_> {
87 fn drop(&mut self) {
88 unsafe {
90 EVP_MD_CTX_free(self.md_ctx);
91 }
92 }
93}
94
95#[allow(clippy::len_without_is_empty)]
96impl<'a> Signer<'a> {
97 #[corresponds(EVP_DigestSignInit)]
102 pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
103 where
104 T: HasPrivate,
105 {
106 Self::new_intern(Some(type_), pkey)
107 }
108
109 #[corresponds(EVP_DigestSignInit)]
114 pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
115 where
116 T: HasPrivate,
117 {
118 Self::new_intern(None, pkey)
119 }
120
121 fn new_intern<T>(
122 type_: Option<MessageDigest>,
123 pkey: &'a PKeyRef<T>,
124 ) -> Result<Signer<'a>, ErrorStack>
125 where
126 T: HasPrivate,
127 {
128 unsafe {
129 ffi::init();
130
131 let ctx = cvt_p(EVP_MD_CTX_new())?;
132 let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
133 let r = ffi::EVP_DigestSignInit(
134 ctx,
135 &mut pctx,
136 type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
137 ptr::null_mut(),
138 pkey.as_ptr(),
139 );
140 if r != 1 {
141 EVP_MD_CTX_free(ctx);
142 return Err(ErrorStack::get());
143 }
144
145 assert!(!pctx.is_null());
146
147 Ok(Signer {
148 md_ctx: ctx,
149 pctx,
150 _p: PhantomData,
151 })
152 }
153 }
154
155 #[corresponds(EVP_PKEY_CTX_get_rsa_padding)]
159 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
160 unsafe {
161 let mut pad = 0;
162 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
163 .map(|_| Padding::from_raw(pad))
164 }
165 }
166
167 #[corresponds(EVP_PKEY_CTX_set_rsa_padding)]
171 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
172 unsafe {
173 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
174 self.pctx,
175 padding.as_raw(),
176 ))
177 }
178 }
179
180 #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)]
184 pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
185 unsafe {
186 cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
187 self.pctx,
188 len.as_raw(),
189 ))
190 }
191 }
192
193 #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)]
197 pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
198 unsafe {
199 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
200 self.pctx,
201 md.as_ptr().cast_mut(),
202 ))
203 }
204 }
205
206 #[corresponds(EVP_DigestUpdate)]
211 pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
212 unsafe {
213 cvt(ffi::EVP_DigestUpdate(
214 self.md_ctx,
215 buf.as_ptr().cast(),
216 buf.len(),
217 ))
218 }
219 }
220
221 #[corresponds(EVP_DigestSignFinal)]
226 pub fn len(&self) -> Result<usize, ErrorStack> {
227 self.len_intern()
228 }
229
230 fn len_intern(&self) -> Result<usize, ErrorStack> {
231 unsafe {
232 let mut len = 0;
233 cvt(ffi::EVP_DigestSign(
234 self.md_ctx,
235 ptr::null_mut(),
236 &mut len,
237 ptr::null(),
238 0,
239 ))?;
240 Ok(len)
241 }
242 }
243
244 #[corresponds(EVP_DigestSignFinal)]
249 pub fn sign(&self, buf: &mut [u8]) -> Result<usize, ErrorStack> {
250 unsafe {
251 let mut len = buf.len();
252 cvt(ffi::EVP_DigestSignFinal(
253 self.md_ctx,
254 buf.as_mut_ptr().cast(),
255 &mut len,
256 ))?;
257 Ok(len)
258 }
259 }
260
261 pub fn sign_to_vec(&self) -> Result<Vec<u8>, ErrorStack> {
265 let mut buf = vec![0; self.len()?];
266 let len = self.sign(&mut buf)?;
267 buf.truncate(len);
269 Ok(buf)
270 }
271
272 #[corresponds(EVP_DigestSign)]
280 pub fn sign_oneshot(
281 &mut self,
282 sig_buf: &mut [u8],
283 data_buf: &[u8],
284 ) -> Result<usize, ErrorStack> {
285 unsafe {
286 let mut sig_len = sig_buf.len();
287 cvt(ffi::EVP_DigestSign(
288 self.md_ctx,
289 sig_buf.as_mut_ptr(),
290 &mut sig_len,
291 data_buf.as_ptr(),
292 data_buf.len(),
293 ))?;
294 Ok(sig_len)
295 }
296 }
297
298 pub fn sign_oneshot_to_vec(&mut self, data_buf: &[u8]) -> Result<Vec<u8>, ErrorStack> {
302 let mut sig_buf = vec![0; self.len()?];
303 let len = self.sign_oneshot(&mut sig_buf, data_buf)?;
304 sig_buf.truncate(len);
306 Ok(sig_buf)
307 }
308}
309
310impl Write for Signer<'_> {
311 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
312 self.update(buf)?;
313 Ok(buf.len())
314 }
315
316 fn flush(&mut self) -> io::Result<()> {
317 Ok(())
318 }
319}
320
321pub struct Verifier<'a> {
322 md_ctx: *mut ffi::EVP_MD_CTX,
323 pctx: *mut ffi::EVP_PKEY_CTX,
324 pkey_pd: PhantomData<&'a ()>,
325}
326
327unsafe impl Sync for Verifier<'_> {}
328unsafe impl Send for Verifier<'_> {}
329
330impl Drop for Verifier<'_> {
331 fn drop(&mut self) {
332 unsafe {
334 EVP_MD_CTX_free(self.md_ctx);
335 }
336 }
337}
338
339impl<'a> Verifier<'a> {
341 #[corresponds(EVP_DigestVerifyInit)]
346 pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
347 where
348 T: HasPublic,
349 {
350 Verifier::new_intern(Some(type_), pkey)
351 }
352
353 #[corresponds(EVP_DigestVerifyInit)]
357 pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
358 where
359 T: HasPublic,
360 {
361 Verifier::new_intern(None, pkey)
362 }
363
364 fn new_intern<T>(
365 type_: Option<MessageDigest>,
366 pkey: &'a PKeyRef<T>,
367 ) -> Result<Verifier<'a>, ErrorStack>
368 where
369 T: HasPublic,
370 {
371 unsafe {
372 ffi::init();
373
374 let ctx = cvt_p(EVP_MD_CTX_new())?;
375 let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
376 let r = ffi::EVP_DigestVerifyInit(
377 ctx,
378 &mut pctx,
379 type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
380 ptr::null_mut(),
381 pkey.as_ptr(),
382 );
383 if r != 1 {
384 EVP_MD_CTX_free(ctx);
385 return Err(ErrorStack::get());
386 }
387
388 assert!(!pctx.is_null());
389
390 Ok(Verifier {
391 md_ctx: ctx,
392 pctx,
393 pkey_pd: PhantomData,
394 })
395 }
396 }
397
398 #[corresponds(EVP_PKEY_CTX_get_rsa_padding)]
402 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
403 unsafe {
404 let mut pad = 0;
405 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
406 .map(|_| Padding::from_raw(pad))
407 }
408 }
409
410 #[corresponds(EVP_PKEY_CTX_set_rsa_padding)]
414 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
415 unsafe {
416 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
417 self.pctx,
418 padding.as_raw(),
419 ))
420 }
421 }
422
423 #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)]
427 pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
428 unsafe {
429 cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
430 self.pctx,
431 len.as_raw(),
432 ))
433 }
434 }
435
436 #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)]
440 pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
441 unsafe {
442 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
443 self.pctx,
444 md.as_ptr().cast_mut(),
445 ))
446 }
447 }
448
449 #[corresponds(EVP_DigestUpdate)]
454 pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
455 unsafe {
456 cvt(ffi::EVP_DigestUpdate(
457 self.md_ctx,
458 buf.as_ptr().cast(),
459 buf.len(),
460 ))
461 }
462 }
463
464 #[corresponds(EVP_DigestVerifyFinal)]
466 pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
467 unsafe {
468 let r =
469 EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr().cast_mut(), signature.len());
470 match r {
471 1 => Ok(true),
472 0 => {
473 ErrorStack::clear(); Ok(false)
475 }
476 _ => Err(ErrorStack::get()),
477 }
478 }
479 }
480
481 #[corresponds(EVP_DigestVerify)]
483 pub fn verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> {
484 unsafe {
485 let r = ffi::EVP_DigestVerify(
486 self.md_ctx,
487 signature.as_ptr().cast(),
488 signature.len(),
489 buf.as_ptr().cast(),
490 buf.len(),
491 );
492 match r {
493 1 => Ok(true),
494 0 => {
495 ErrorStack::clear();
496 Ok(false)
497 }
498 _ => Err(ErrorStack::get()),
499 }
500 }
501 }
502}
503
504impl Write for Verifier<'_> {
505 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
506 self.update(buf)?;
507 Ok(buf.len())
508 }
509
510 fn flush(&mut self) -> io::Result<()> {
511 Ok(())
512 }
513}
514
515use crate::ffi::EVP_DigestVerifyFinal;
516
517#[cfg(test)]
518mod test {
519 use super::RsaPssSaltlen;
520 use hex::{self, FromHex};
521
522 use crate::ec::{EcGroup, EcKey};
523 use crate::hash::MessageDigest;
524 use crate::nid::Nid;
525 use crate::pkey::PKey;
526 use crate::rsa::{Padding, Rsa};
527 use crate::sign::{Signer, Verifier};
528
529 const INPUT: &str = "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
530 654841694f6a457a4d4441344d546b7a4f44417344516f67496d6830644841364c79396c654746746347786c4c\
531 6d4e76625339706331397962323930496a7030636e566c6651";
532
533 const SIGNATURE: &str = "702e218943e88fd11eb5d82dbf7845f34106ae1b81fff7731116add1717d83656d420afd3c96eedd73a2663e51\
534 66687b000b87226e0187ed1073f945e582adfcef16d85a798ee8c66ddb3db8975b17d09402beedd5d9d9700710\
535 8db28160d5f8040ca7445762b81fbe7ff9d92e0ae76f24f25b33bbe6f44ae61eb1040acb20044d3ef9128ed401\
536 30795bd4bd3b41eecad066ab651981fde48df77f372dc38b9fafdd3befb18b5da3cc3c2eb02f9e3a41d612caad\
537 15911273a05f23b9e838faaf849d698429ef5a1e88798236c3d40e604522a544c8f27a7a2db80663d16cf7caea\
538 56de405cb2215a45b2c25566b55ac1a748a070dfc8a32a469543d019eefb47";
539
540 #[test]
541 fn rsa_sign() {
542 let key = include_bytes!("../test/rsa.pem");
543 let private_key = Rsa::private_key_from_pem(key).unwrap();
544 let pkey = PKey::from_rsa(private_key).unwrap();
545
546 let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
547 assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1);
548 signer.set_rsa_padding(Padding::PKCS1).unwrap();
549 signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
550 let result = signer.sign_to_vec().unwrap();
551
552 assert_eq!(hex::encode(result), SIGNATURE);
553 }
554
555 #[test]
556 fn rsa_verify_ok() {
557 let key = include_bytes!("../test/rsa.pem");
558 let private_key = Rsa::private_key_from_pem(key).unwrap();
559 let pkey = PKey::from_rsa(private_key).unwrap();
560
561 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
562 assert_eq!(verifier.rsa_padding().unwrap(), Padding::PKCS1);
563 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
564 assert!(verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
565 }
566
567 #[test]
568 fn rsa_verify_invalid() {
569 let key = include_bytes!("../test/rsa.pem");
570 let private_key = Rsa::private_key_from_pem(key).unwrap();
571 let pkey = PKey::from_rsa(private_key).unwrap();
572
573 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
574 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
575 verifier.update(b"foobar").unwrap();
576 assert!(!verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
577 }
578
579 #[test]
580 fn ec() {
581 let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
582 let key = EcKey::generate(&group).unwrap();
583 let key = PKey::from_ec_key(key).unwrap();
584
585 let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
586 signer.update(b"hello world").unwrap();
587 let signature = signer.sign_to_vec().unwrap();
588
589 let mut verifier = Verifier::new(MessageDigest::sha256(), &key).unwrap();
590 verifier.update(b"hello world").unwrap();
591 assert!(verifier.verify(&signature).unwrap());
592 }
593
594 #[test]
595 fn rsa_sign_verify() {
596 let key = include_bytes!("../test/rsa.pem");
597 let private_key = Rsa::private_key_from_pem(key).unwrap();
598 let pkey = PKey::from_rsa(private_key).unwrap();
599
600 let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
601 signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
602 assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS);
603 signer
604 .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
605 .unwrap();
606 signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
607 signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
608 let signature = signer.sign_to_vec().unwrap();
609
610 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
611 verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
612 verifier
613 .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
614 .unwrap();
615 verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
616 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
617 assert!(verifier.verify(&signature).unwrap());
618 }
619}