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 
42 Compute an HMAC:
43 
44 ```rust
45 use openssl::hash::MessageDigest;
46 use openssl::memcmp;
47 use openssl::pkey::PKey;
48 use openssl::sign::Signer;
49 
50 // Create a PKey
51 let key = PKey::hmac(b"my secret").unwrap();
52 
53 let data = b"hello, world!";
54 let data2 = b"hola, mundo!";
55 
56 // Compute the HMAC
57 let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
58 signer.update(data).unwrap();
59 signer.update(data2).unwrap();
60 let 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();
66 assert!(memcmp::eq(&hmac, &target));
67 ```"#
68 )]
69 
70 use cfg_if::cfg_if;
71 use foreign_types::ForeignTypeRef;
72 use libc::c_int;
73 use std::io::{self, Write};
74 use std::marker::PhantomData;
75 use std::ptr;
76 
77 use crate::error::ErrorStack;
78 use crate::hash::MessageDigest;
79 use crate::pkey::{HasPrivate, HasPublic, PKeyRef};
80 use crate::rsa::Padding;
81 use crate::{cvt, cvt_p};
82 
83 cfg_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`.
92 pub struct RsaPssSaltlen(c_int);
93 
94 impl RsaPssSaltlen {
95     /// Returns the integer representation of `RsaPssSaltlen`.
as_raw(&self) -> c_int96     pub(crate) fn as_raw(&self) -> c_int {
97         self.0
98     }
99 
100     /// Sets the salt length to the given value.
custom(val: c_int) -> RsaPssSaltlen101     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.
114 pub struct Signer<'a> {
115     md_ctx: *mut ffi::EVP_MD_CTX,
116     pctx: *mut ffi::EVP_PKEY_CTX,
117     _p: PhantomData<&'a ()>,
118 }
119 
120 unsafe impl Sync for Signer<'_> {}
121 unsafe impl Send for Signer<'_> {}
122 
123 impl Drop for Signer<'_> {
drop(&mut self)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)]
133 impl 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
new<'a, T>(type_: MessageDigest, pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack> where T: HasPrivate,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
new_without_digest<'a, T>(pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack> where T: HasPrivate,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 
new_intern<'a, T>( type_: Option<MessageDigest>, pkey: &PKeyRef<T>, ) -> Result<Signer<'a>, ErrorStack> where T: HasPrivate,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`.
rsa_padding(&self) -> Result<Padding, ErrorStack>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
set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack>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
set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack>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
set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack>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
update(&mut self, buf: &[u8]) -> Result<(), ErrorStack>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
len(&self) -> Result<usize, ErrorStack>289     pub fn len(&self) -> Result<usize, ErrorStack> {
290         self.len_intern()
291     }
292 
293     #[cfg(all(not(ossl111), not(boringssl), not(libressl370)))]
len_intern(&self) -> Result<usize, ErrorStack>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))]
len_intern(&self) -> Result<usize, ErrorStack>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
sign(&self, buf: &mut [u8]) -> Result<usize, ErrorStack>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`.
sign_to_vec(&self) -> Result<Vec<u8>, ErrorStack>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))]
sign_oneshot( &mut self, sig_buf: &mut [u8], data_buf: &[u8], ) -> Result<usize, ErrorStack>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))]
sign_oneshot_to_vec(&mut self, data_buf: &[u8]) -> Result<Vec<u8>, ErrorStack>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 
395 impl<'a> Write for Signer<'a> {
write(&mut self, buf: &[u8]) -> io::Result<usize>396     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
397         self.update(buf)?;
398         Ok(buf.len())
399     }
400 
flush(&mut self) -> io::Result<()>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.
408 pub 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 
414 unsafe impl<'a> Sync for Verifier<'a> {}
415 unsafe impl<'a> Send for Verifier<'a> {}
416 
417 impl<'a> Drop for Verifier<'a> {
drop(&mut self)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.
427 impl<'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
new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack> where T: HasPublic,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
new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack> where T: HasPublic,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 
new_intern<T>( type_: Option<MessageDigest>, pkey: &'a PKeyRef<T>, ) -> Result<Verifier<'a>, ErrorStack> where T: HasPublic,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`.
rsa_padding(&self) -> Result<Padding, ErrorStack>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
set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack>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
set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack>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
set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack>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
update(&mut self, buf: &[u8]) -> Result<(), ErrorStack>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
verify(&self, signature: &[u8]) -> Result<bool, ErrorStack>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))]
verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack>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 
621 impl<'a> Write for Verifier<'a> {
write(&mut self, buf: &[u8]) -> io::Result<usize>622     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
623         self.update(buf)?;
624         Ok(buf.len())
625     }
626 
flush(&mut self) -> io::Result<()>627     fn flush(&mut self) -> io::Result<()> {
628         Ok(())
629     }
630 }
631 
632 #[cfg(not(ossl101))]
633 use ffi::EVP_DigestVerifyFinal;
634 
635 #[cfg(ossl101)]
636 #[allow(bad_style)]
EVP_DigestVerifyFinal( ctx: *mut ffi::EVP_MD_CTX, sigret: *const ::libc::c_uchar, siglen: ::libc::size_t, ) -> ::libc::c_int637 unsafe 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)]
646 mod 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]
rsa_sign()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]
rsa_verify_ok()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]
rsa_verify_invalid()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))]
test_hmac(ty: MessageDigest, tests: &[(Vec<u8>, Vec<u8>, Vec<u8>)])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))]
hmac_md5()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))]
hmac_sha1()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)]
test_cmac()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]
ec()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))]
eddsa()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)]
rsa_sign_verify()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