1//! Message signatures.
2//!
3//! The `Signer` allows for the computation of cryptographic signatures of
4//! data given a private key. The `Verifier` can then be used with the
5//! corresponding public key to verify the integrity and authenticity of that
6//! data given the signature.
7//!
8//! # Examples
9//!
10//! Sign and verify data given an RSA keypair:
11//!
12//! ```rust
13//! use openssl::sign::{Signer, Verifier};
14//! use openssl::rsa::Rsa;
15//! use openssl::pkey::PKey;
16//! use openssl::hash::MessageDigest;
17//!
18//! // Generate a keypair
19//! let keypair = Rsa::generate(2048).unwrap();
20//! let keypair = PKey::from_rsa(keypair).unwrap();
21//!
22//! let data = b"hello, world!";
23//! let data2 = b"hola, mundo!";
24//!
25//! // Sign the data
26//! let mut signer = Signer::new(MessageDigest::sha256(), &keypair).unwrap();
27//! signer.update(data).unwrap();
28//! signer.update(data2).unwrap();
29//! let signature = signer.sign_to_vec().unwrap();
30//!
31//! // Verify the data
32//! let mut verifier = Verifier::new(MessageDigest::sha256(), &keypair).unwrap();
33//! verifier.update(data).unwrap();
34//! verifier.update(data2).unwrap();
35//! assert!(verifier.verify(&signature).unwrap());
36//! ```
37
38#![cfg_attr(
39 not(boringssl),
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};
82
83cfg_if! {
84 if #[cfg(any(ossl110, libressl382))] {
85 use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
86 } else {
87 use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
88 }
89}
90
91/// Salt lengths that must be used with `set_rsa_pss_saltlen`.
92pub struct RsaPssSaltlen(c_int);
93
94impl RsaPssSaltlen {
95 /// Returns the integer representation of `RsaPssSaltlen`.
96 pub(crate) fn as_raw(&self) -> c_int {
97 self.0
98 }
99
100 /// Sets the salt length to the given value.
101 pub fn custom(val: c_int) -> RsaPssSaltlen {
102 RsaPssSaltlen(val)
103 }
104
105 /// The salt length is set to the digest length.
106 /// Corresponds to the special value `-1`.
107 pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1);
108 /// The salt length is set to the maximum permissible value.
109 /// Corresponds to the special value `-2`.
110 pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2);
111}
112
113/// A type which computes cryptographic signatures of data.
114pub struct Signer<'a> {
115 md_ctx: *mut ffi::EVP_MD_CTX,
116 pctx: *mut ffi::EVP_PKEY_CTX,
117 _p: PhantomData<&'a ()>,
118}
119
120unsafe impl Sync for Signer<'_> {}
121unsafe impl Send for Signer<'_> {}
122
123impl Drop for Signer<'_> {
124 fn drop(&mut self) {
125 // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
126 unsafe {
127 EVP_MD_CTX_free(self.md_ctx);
128 }
129 }
130}
131
132#[allow(clippy::len_without_is_empty)]
133impl Signer<'_> {
134 /// Creates a new `Signer`.
135 ///
136 /// This cannot be used with Ed25519 or Ed448 keys. Please refer to
137 /// `new_without_digest`.
138 ///
139 /// OpenSSL documentation at [`EVP_DigestSignInit`].
140 ///
141 /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html
142 pub fn new<'a, T>(type_: MessageDigest, pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
143 where
144 T: HasPrivate,
145 {
146 Self::new_intern(Some(type_), pkey)
147 }
148
149 /// Creates a new `Signer` without a digest.
150 ///
151 /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys.
152 /// It can also be used to create a CMAC.
153 ///
154 /// OpenSSL documentation at [`EVP_DigestSignInit`].
155 ///
156 /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html
157 pub fn new_without_digest<'a, T>(pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
158 where
159 T: HasPrivate,
160 {
161 Self::new_intern(None, pkey)
162 }
163
164 fn new_intern<'a, T>(
165 type_: Option<MessageDigest>,
166 pkey: &PKeyRef<T>,
167 ) -> Result<Signer<'a>, ErrorStack>
168 where
169 T: HasPrivate,
170 {
171 unsafe {
172 ffi::init();
173
174 let ctx = cvt_p(EVP_MD_CTX_new())?;
175 let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
176 let r = ffi::EVP_DigestSignInit(
177 ctx,
178 &mut pctx,
179 type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
180 ptr::null_mut(),
181 pkey.as_ptr(),
182 );
183 if r != 1 {
184 EVP_MD_CTX_free(ctx);
185 return Err(ErrorStack::get());
186 }
187
188 assert!(!pctx.is_null());
189
190 Ok(Signer {
191 md_ctx: ctx,
192 pctx,
193 _p: PhantomData,
194 })
195 }
196 }
197
198 /// Returns the RSA padding mode in use.
199 ///
200 /// This is only useful for RSA keys.
201 ///
202 /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
203 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
204 unsafe {
205 let mut pad = 0;
206 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
207 .map(|_| Padding::from_raw(pad))
208 }
209 }
210
211 /// Sets the RSA padding mode.
212 ///
213 /// This is only useful for RSA keys.
214 ///
215 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`].
216 ///
217 /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html
218 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
219 unsafe {
220 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
221 self.pctx,
222 padding.as_raw(),
223 ))
224 .map(|_| ())
225 }
226 }
227
228 /// Sets the RSA PSS salt length.
229 ///
230 /// This is only useful for RSA keys.
231 ///
232 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`].
233 ///
234 /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html
235 pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
236 unsafe {
237 cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
238 self.pctx,
239 len.as_raw(),
240 ))
241 .map(|_| ())
242 }
243 }
244
245 /// Sets the RSA MGF1 algorithm.
246 ///
247 /// This is only useful for RSA keys.
248 ///
249 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`].
250 ///
251 /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html
252 pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
253 unsafe {
254 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
255 self.pctx,
256 md.as_ptr() as *mut _,
257 ))
258 .map(|_| ())
259 }
260 }
261
262 /// Feeds more data into the `Signer`.
263 ///
264 /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming.
265 /// Use `sign_oneshot` instead.
266 ///
267 /// OpenSSL documentation at [`EVP_DigestUpdate`].
268 ///
269 /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html
270 pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
271 unsafe {
272 cvt(ffi::EVP_DigestUpdate(
273 self.md_ctx,
274 buf.as_ptr() as *const _,
275 buf.len(),
276 ))
277 .map(|_| ())
278 }
279 }
280
281 /// Computes an upper bound on the signature length.
282 ///
283 /// The actual signature may be shorter than this value. Check the return value of
284 /// `sign` to get the exact length.
285 ///
286 /// OpenSSL documentation at [`EVP_DigestSignFinal`].
287 ///
288 /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/manmaster/crypto/EVP_DigestSignFinal.html
289 pub fn len(&self) -> Result<usize, ErrorStack> {
290 self.len_intern()
291 }
292
293 #[cfg(all(not(ossl111), not(boringssl), not(libressl370)))]
294 fn len_intern(&self) -> Result<usize, ErrorStack> {
295 unsafe {
296 let mut len = 0;
297 cvt(ffi::EVP_DigestSignFinal(
298 self.md_ctx,
299 ptr::null_mut(),
300 &mut len,
301 ))?;
302 Ok(len)
303 }
304 }
305
306 #[cfg(any(ossl111, boringssl, libressl370))]
307 fn len_intern(&self) -> Result<usize, ErrorStack> {
308 unsafe {
309 let mut len = 0;
310 cvt(ffi::EVP_DigestSign(
311 self.md_ctx,
312 ptr::null_mut(),
313 &mut len,
314 ptr::null(),
315 0,
316 ))?;
317 Ok(len)
318 }
319 }
320
321 /// Writes the signature into the provided buffer, returning the number of bytes written.
322 ///
323 /// This method will fail if the buffer is not large enough for the signature. Use the `len`
324 /// method to get an upper bound on the required size.
325 ///
326 /// OpenSSL documentation at [`EVP_DigestSignFinal`].
327 ///
328 /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/manmaster/crypto/EVP_DigestSignFinal.html
329 pub fn sign(&self, buf: &mut [u8]) -> Result<usize, ErrorStack> {
330 unsafe {
331 let mut len = buf.len();
332 cvt(ffi::EVP_DigestSignFinal(
333 self.md_ctx,
334 buf.as_mut_ptr() as *mut _,
335 &mut len,
336 ))?;
337 Ok(len)
338 }
339 }
340
341 /// Returns the signature.
342 ///
343 /// This is a simple convenience wrapper over `len` and `sign`.
344 pub fn sign_to_vec(&self) -> Result<Vec<u8>, ErrorStack> {
345 let mut buf = vec![0; self.len()?];
346 let len = self.sign(&mut buf)?;
347 // The advertised length is not always equal to the real length for things like DSA
348 buf.truncate(len);
349 Ok(buf)
350 }
351
352 /// Signs the data in `data_buf` and writes the signature into the buffer `sig_buf`, returning the
353 /// number of bytes written.
354 ///
355 /// For PureEdDSA (Ed25519 and Ed448 keys), this is the only way to sign data.
356 ///
357 /// This method will fail if the buffer is not large enough for the signature. Use the `len`
358 /// method to get an upper bound on the required size.
359 ///
360 /// OpenSSL documentation at [`EVP_DigestSign`].
361 ///
362 /// [`EVP_DigestSign`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestSign.html
363 #[cfg(any(ossl111, boringssl, libressl370))]
364 pub fn sign_oneshot(
365 &mut self,
366 sig_buf: &mut [u8],
367 data_buf: &[u8],
368 ) -> Result<usize, ErrorStack> {
369 unsafe {
370 let mut sig_len = sig_buf.len();
371 cvt(ffi::EVP_DigestSign(
372 self.md_ctx,
373 sig_buf.as_mut_ptr() as *mut _,
374 &mut sig_len,
375 data_buf.as_ptr() as *const _,
376 data_buf.len(),
377 ))?;
378 Ok(sig_len)
379 }
380 }
381
382 /// Returns the signature.
383 ///
384 /// This is a simple convenience wrapper over `len` and `sign_oneshot`.
385 #[cfg(any(ossl111, boringssl, libressl370))]
386 pub fn sign_oneshot_to_vec(&mut self, data_buf: &[u8]) -> Result<Vec<u8>, ErrorStack> {
387 let mut sig_buf = vec![0; self.len()?];
388 let len = self.sign_oneshot(&mut sig_buf, data_buf)?;
389 // The advertised length is not always equal to the real length for things like DSA
390 sig_buf.truncate(len);
391 Ok(sig_buf)
392 }
393}
394
395impl<'a> Write for Signer<'a> {
396 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
397 self.update(buf)?;
398 Ok(buf.len())
399 }
400
401 fn flush(&mut self) -> io::Result<()> {
402 Ok(())
403 }
404}
405
406/// A type which can be used to verify the integrity and authenticity
407/// of data given the signature.
408pub struct Verifier<'a> {
409 md_ctx: *mut ffi::EVP_MD_CTX,
410 pctx: *mut ffi::EVP_PKEY_CTX,
411 pkey_pd: PhantomData<&'a ()>,
412}
413
414unsafe impl<'a> Sync for Verifier<'a> {}
415unsafe impl<'a> Send for Verifier<'a> {}
416
417impl<'a> Drop for Verifier<'a> {
418 fn drop(&mut self) {
419 // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
420 unsafe {
421 EVP_MD_CTX_free(self.md_ctx);
422 }
423 }
424}
425
426/// A type which verifies cryptographic signatures of data.
427impl<'a> Verifier<'a> {
428 /// Creates a new `Verifier`.
429 ///
430 /// This cannot be used with Ed25519 or Ed448 keys. Please refer to
431 /// [`Verifier::new_without_digest`].
432 ///
433 /// OpenSSL documentation at [`EVP_DigestVerifyInit`].
434 ///
435 /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html
436 pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
437 where
438 T: HasPublic,
439 {
440 Verifier::new_intern(Some(type_), pkey)
441 }
442
443 /// Creates a new `Verifier` without a digest.
444 ///
445 /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys.
446 ///
447 /// OpenSSL documentation at [`EVP_DigestVerifyInit`].
448 ///
449 /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html
450 pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
451 where
452 T: HasPublic,
453 {
454 Verifier::new_intern(None, pkey)
455 }
456
457 fn new_intern<T>(
458 type_: Option<MessageDigest>,
459 pkey: &'a PKeyRef<T>,
460 ) -> Result<Verifier<'a>, ErrorStack>
461 where
462 T: HasPublic,
463 {
464 unsafe {
465 ffi::init();
466
467 let ctx = cvt_p(EVP_MD_CTX_new())?;
468 let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
469 let r = ffi::EVP_DigestVerifyInit(
470 ctx,
471 &mut pctx,
472 type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
473 ptr::null_mut(),
474 pkey.as_ptr(),
475 );
476 if r != 1 {
477 EVP_MD_CTX_free(ctx);
478 return Err(ErrorStack::get());
479 }
480
481 assert!(!pctx.is_null());
482
483 Ok(Verifier {
484 md_ctx: ctx,
485 pctx,
486 pkey_pd: PhantomData,
487 })
488 }
489 }
490
491 /// Returns the RSA padding mode in use.
492 ///
493 /// This is only useful for RSA keys.
494 ///
495 /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
496 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
497 unsafe {
498 let mut pad = 0;
499 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
500 .map(|_| Padding::from_raw(pad))
501 }
502 }
503
504 /// Sets the RSA padding mode.
505 ///
506 /// This is only useful for RSA keys.
507 ///
508 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`].
509 ///
510 /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html
511 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
512 unsafe {
513 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
514 self.pctx,
515 padding.as_raw(),
516 ))
517 .map(|_| ())
518 }
519 }
520
521 /// Sets the RSA PSS salt length.
522 ///
523 /// This is only useful for RSA keys.
524 ///
525 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`].
526 ///
527 /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html
528 pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
529 unsafe {
530 cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
531 self.pctx,
532 len.as_raw(),
533 ))
534 .map(|_| ())
535 }
536 }
537
538 /// Sets the RSA MGF1 algorithm.
539 ///
540 /// This is only useful for RSA keys.
541 ///
542 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`].
543 ///
544 /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html
545 pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
546 unsafe {
547 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
548 self.pctx,
549 md.as_ptr() as *mut _,
550 ))
551 .map(|_| ())
552 }
553 }
554
555 /// Feeds more data into the `Verifier`.
556 ///
557 /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming.
558 /// Use [`Verifier::verify_oneshot`] instead.
559 ///
560 /// OpenSSL documentation at [`EVP_DigestUpdate`].
561 ///
562 /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html
563 pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
564 unsafe {
565 cvt(ffi::EVP_DigestUpdate(
566 self.md_ctx,
567 buf.as_ptr() as *const _,
568 buf.len(),
569 ))
570 .map(|_| ())
571 }
572 }
573
574 /// Determines if the data fed into the `Verifier` matches the provided signature.
575 ///
576 /// OpenSSL documentation at [`EVP_DigestVerifyFinal`].
577 ///
578 /// [`EVP_DigestVerifyFinal`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyFinal.html
579 pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
580 unsafe {
581 let r =
582 EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len());
583 match r {
584 1 => Ok(true),
585 0 => {
586 ErrorStack::get(); // discard error stack
587 Ok(false)
588 }
589 _ => Err(ErrorStack::get()),
590 }
591 }
592 }
593
594 /// Determines if the data given in `buf` matches the provided signature.
595 ///
596 /// OpenSSL documentation at [`EVP_DigestVerify`].
597 ///
598 /// [`EVP_DigestVerify`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestVerify.html
599 #[cfg(any(ossl111, boringssl, libressl370))]
600 pub fn verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> {
601 unsafe {
602 let r = ffi::EVP_DigestVerify(
603 self.md_ctx,
604 signature.as_ptr() as *const _,
605 signature.len(),
606 buf.as_ptr() as *const _,
607 buf.len(),
608 );
609 match r {
610 1 => Ok(true),
611 0 => {
612 ErrorStack::get();
613 Ok(false)
614 }
615 _ => Err(ErrorStack::get()),
616 }
617 }
618 }
619}
620
621impl<'a> Write for Verifier<'a> {
622 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
623 self.update(buf)?;
624 Ok(buf.len())
625 }
626
627 fn flush(&mut self) -> io::Result<()> {
628 Ok(())
629 }
630}
631
632#[cfg(not(ossl101))]
633use ffi::EVP_DigestVerifyFinal;
634
635#[cfg(ossl101)]
636#[allow(bad_style)]
637unsafe fn EVP_DigestVerifyFinal(
638 ctx: *mut ffi::EVP_MD_CTX,
639 sigret: *const ::libc::c_uchar,
640 siglen: ::libc::size_t,
641) -> ::libc::c_int {
642 ffi::EVP_DigestVerifyFinal(ctx, sigret as *mut _, siglen)
643}
644
645#[cfg(test)]
646mod test {
647 use hex::{self, FromHex};
648 #[cfg(not(boringssl))]
649 use std::iter;
650
651 use crate::ec::{EcGroup, EcKey};
652 use crate::hash::MessageDigest;
653 use crate::nid::Nid;
654 use crate::pkey::PKey;
655 use crate::rsa::{Padding, Rsa};
656 #[cfg(ossl111)]
657 use crate::sign::RsaPssSaltlen;
658 use crate::sign::{Signer, Verifier};
659
660 const INPUT: &str =
661 "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
662 654841694f6a457a4d4441344d546b7a4f44417344516f67496d6830644841364c79396c654746746347786c4c\
663 6d4e76625339706331397962323930496a7030636e566c6651";
664
665 const SIGNATURE: &str =
666 "702e218943e88fd11eb5d82dbf7845f34106ae1b81fff7731116add1717d83656d420afd3c96eedd73a2663e51\
667 66687b000b87226e0187ed1073f945e582adfcef16d85a798ee8c66ddb3db8975b17d09402beedd5d9d9700710\
668 8db28160d5f8040ca7445762b81fbe7ff9d92e0ae76f24f25b33bbe6f44ae61eb1040acb20044d3ef9128ed401\
669 30795bd4bd3b41eecad066ab651981fde48df77f372dc38b9fafdd3befb18b5da3cc3c2eb02f9e3a41d612caad\
670 15911273a05f23b9e838faaf849d698429ef5a1e88798236c3d40e604522a544c8f27a7a2db80663d16cf7caea\
671 56de405cb2215a45b2c25566b55ac1a748a070dfc8a32a469543d019eefb47";
672
673 #[test]
674 fn rsa_sign() {
675 let key = include_bytes!("../test/rsa.pem");
676 let private_key = Rsa::private_key_from_pem(key).unwrap();
677 let pkey = PKey::from_rsa(private_key).unwrap();
678
679 let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
680 assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1);
681 signer.set_rsa_padding(Padding::PKCS1).unwrap();
682 signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
683 let result = signer.sign_to_vec().unwrap();
684
685 assert_eq!(hex::encode(result), SIGNATURE);
686 }
687
688 #[test]
689 fn rsa_verify_ok() {
690 let key = include_bytes!("../test/rsa.pem");
691 let private_key = Rsa::private_key_from_pem(key).unwrap();
692 let pkey = PKey::from_rsa(private_key).unwrap();
693
694 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
695 assert_eq!(verifier.rsa_padding().unwrap(), Padding::PKCS1);
696 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
697 assert!(verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
698 }
699
700 #[test]
701 fn rsa_verify_invalid() {
702 let key = include_bytes!("../test/rsa.pem");
703 let private_key = Rsa::private_key_from_pem(key).unwrap();
704 let pkey = PKey::from_rsa(private_key).unwrap();
705
706 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
707 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
708 verifier.update(b"foobar").unwrap();
709 assert!(!verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
710 }
711
712 #[cfg(not(boringssl))]
713 fn test_hmac(ty: MessageDigest, tests: &[(Vec<u8>, Vec<u8>, Vec<u8>)]) {
714 for (key, data, res) in tests.iter() {
715 let pkey = PKey::hmac(key).unwrap();
716 let mut signer = Signer::new(ty, &pkey).unwrap();
717 signer.update(data).unwrap();
718 assert_eq!(signer.sign_to_vec().unwrap(), *res);
719 }
720 }
721
722 #[test]
723 #[cfg(not(boringssl))]
724 fn hmac_md5() {
725 // test vectors from RFC 2202
726 let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] = [
727 (
728 iter::repeat(0x0b_u8).take(16).collect(),
729 b"Hi There".to_vec(),
730 Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap(),
731 ),
732 (
733 b"Jefe".to_vec(),
734 b"what do ya want for nothing?".to_vec(),
735 Vec::from_hex("750c783e6ab0b503eaa86e310a5db738").unwrap(),
736 ),
737 (
738 iter::repeat(0xaa_u8).take(16).collect(),
739 iter::repeat(0xdd_u8).take(50).collect(),
740 Vec::from_hex("56be34521d144c88dbb8c733f0e8b3f6").unwrap(),
741 ),
742 (
743 Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(),
744 iter::repeat(0xcd_u8).take(50).collect(),
745 Vec::from_hex("697eaf0aca3a3aea3a75164746ffaa79").unwrap(),
746 ),
747 (
748 iter::repeat(0x0c_u8).take(16).collect(),
749 b"Test With Truncation".to_vec(),
750 Vec::from_hex("56461ef2342edc00f9bab995690efd4c").unwrap(),
751 ),
752 (
753 iter::repeat(0xaa_u8).take(80).collect(),
754 b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(),
755 Vec::from_hex("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd").unwrap(),
756 ),
757 (
758 iter::repeat(0xaa_u8).take(80).collect(),
759 b"Test Using Larger Than Block-Size Key \
760 and Larger Than One Block-Size Data"
761 .to_vec(),
762 Vec::from_hex("6f630fad67cda0ee1fb1f562db3aa53e").unwrap(),
763 ),
764 ];
765
766 test_hmac(MessageDigest::md5(), &tests);
767 }
768
769 #[test]
770 #[cfg(not(boringssl))]
771 fn hmac_sha1() {
772 // test vectors from RFC 2202
773 let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] = [
774 (
775 iter::repeat(0x0b_u8).take(20).collect(),
776 b"Hi There".to_vec(),
777 Vec::from_hex("b617318655057264e28bc0b6fb378c8ef146be00").unwrap(),
778 ),
779 (
780 b"Jefe".to_vec(),
781 b"what do ya want for nothing?".to_vec(),
782 Vec::from_hex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79").unwrap(),
783 ),
784 (
785 iter::repeat(0xaa_u8).take(20).collect(),
786 iter::repeat(0xdd_u8).take(50).collect(),
787 Vec::from_hex("125d7342b9ac11cd91a39af48aa17b4f63f175d3").unwrap(),
788 ),
789 (
790 Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(),
791 iter::repeat(0xcd_u8).take(50).collect(),
792 Vec::from_hex("4c9007f4026250c6bc8414f9bf50c86c2d7235da").unwrap(),
793 ),
794 (
795 iter::repeat(0x0c_u8).take(20).collect(),
796 b"Test With Truncation".to_vec(),
797 Vec::from_hex("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04").unwrap(),
798 ),
799 (
800 iter::repeat(0xaa_u8).take(80).collect(),
801 b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(),
802 Vec::from_hex("aa4ae5e15272d00e95705637ce8a3b55ed402112").unwrap(),
803 ),
804 (
805 iter::repeat(0xaa_u8).take(80).collect(),
806 b"Test Using Larger Than Block-Size Key \
807 and Larger Than One Block-Size Data"
808 .to_vec(),
809 Vec::from_hex("e8e99d0f45237d786d6bbaa7965c7808bbff1a91").unwrap(),
810 ),
811 ];
812
813 test_hmac(MessageDigest::sha1(), &tests);
814 }
815
816 #[test]
817 #[cfg(ossl110)]
818 fn test_cmac() {
819 let cipher = crate::symm::Cipher::aes_128_cbc();
820 let key = Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap();
821 let pkey = PKey::cmac(&cipher, &key).unwrap();
822 let mut signer = Signer::new_without_digest(&pkey).unwrap();
823
824 let data = b"Hi There";
825 signer.update(data as &[u8]).unwrap();
826
827 let expected = vec![
828 136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19,
829 ];
830 assert_eq!(signer.sign_to_vec().unwrap(), expected);
831 }
832
833 #[test]
834 fn ec() {
835 let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
836 let key = EcKey::generate(&group).unwrap();
837 let key = PKey::from_ec_key(key).unwrap();
838
839 let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
840 signer.update(b"hello world").unwrap();
841 let signature = signer.sign_to_vec().unwrap();
842
843 let mut verifier = Verifier::new(MessageDigest::sha256(), &key).unwrap();
844 verifier.update(b"hello world").unwrap();
845 assert!(verifier.verify(&signature).unwrap());
846 }
847
848 #[test]
849 #[cfg(any(ossl111, boringssl, libressl370))]
850 fn eddsa() {
851 let key = PKey::generate_ed25519().unwrap();
852
853 let mut signer = Signer::new_without_digest(&key).unwrap();
854 let signature = signer.sign_oneshot_to_vec(b"hello world").unwrap();
855
856 let mut verifier = Verifier::new_without_digest(&key).unwrap();
857 assert!(verifier.verify_oneshot(&signature, b"hello world").unwrap());
858 }
859
860 #[test]
861 #[cfg(ossl111)]
862 fn rsa_sign_verify() {
863 let key = include_bytes!("../test/rsa.pem");
864 let private_key = Rsa::private_key_from_pem(key).unwrap();
865 let pkey = PKey::from_rsa(private_key).unwrap();
866
867 let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
868 signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
869 assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS);
870 signer
871 .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
872 .unwrap();
873 signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
874 signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
875 let signature = signer.sign_to_vec().unwrap();
876
877 let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
878 verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
879 verifier
880 .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
881 .unwrap();
882 verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
883 verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
884 assert!(verifier.verify(&signature).unwrap());
885 }
886}
887