boring_imp/
sign.rs

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 boring::sign::{Signer, Verifier};
14//! use boring::rsa::Rsa;
15//! use boring::pkey::PKey;
16//! use boring::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//! ```
37use 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
52/// Salt lengths that must be used with `set_rsa_pss_saltlen`.
53pub struct RsaPssSaltlen(c_int);
54
55impl RsaPssSaltlen {
56    /// Returns the integer representation of `RsaPssSaltlen`.
57    fn as_raw(&self) -> c_int {
58        self.0
59    }
60
61    /// Sets the salt length to the given value.
62    pub fn custom(val: c_int) -> RsaPssSaltlen {
63        RsaPssSaltlen(val)
64    }
65
66    /// The salt length is set to the digest length.
67    /// Corresponds to the special value `-1`.
68    pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1);
69    /// The salt length is set to the maximum permissible value.
70    /// Corresponds to the special value `-2`.
71    pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2);
72}
73
74/// A type which computes cryptographic signatures of data.
75pub 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        // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
87        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    /// Creates a new `Signer`.
96    ///
97    /// This cannot be used with Ed25519 or Ed448 keys. Please refer to
98    /// `new_without_digest`.
99    ///
100    /// OpenSSL documentation at [`EVP_DigestSignInit`].
101    ///
102    /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html
103    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    /// Creates a new `Signer` without a digest.
111    ///
112    /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys.
113    /// It can also be used to create a CMAC.
114    ///
115    /// OpenSSL documentation at [`EVP_DigestSignInit`].
116    ///
117    /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html
118    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    /// Returns the RSA padding mode in use.
160    ///
161    /// This is only useful for RSA keys.
162    ///
163    /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
164    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    /// Sets the RSA padding mode.
173    ///
174    /// This is only useful for RSA keys.
175    ///
176    /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`].
177    ///
178    /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_padding.html
179    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    /// Sets the RSA PSS salt length.
190    ///
191    /// This is only useful for RSA keys.
192    ///
193    /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`].
194    ///
195    /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html
196    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    /// Sets the RSA MGF1 algorithm.
207    ///
208    /// This is only useful for RSA keys.
209    ///
210    /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`].
211    ///
212    /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html
213    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    /// Feeds more data into the `Signer`.
224    ///
225    /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming.
226    /// Use `sign_oneshot` instead.
227    ///
228    /// OpenSSL documentation at [`EVP_DigestUpdate`].
229    ///
230    /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html
231    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    /// Computes an upper bound on the signature length.
243    ///
244    /// The actual signature may be shorter than this value. Check the return value of
245    /// `sign` to get the exact length.
246    ///
247    /// OpenSSL documentation at [`EVP_DigestSignFinal`].
248    ///
249    /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestSignFinal.html
250    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    /// Writes the signature into the provided buffer, returning the number of bytes written.
269    ///
270    /// This method will fail if the buffer is not large enough for the signature. Use the `len`
271    /// method to get an upper bound on the required size.
272    ///
273    /// OpenSSL documentation at [`EVP_DigestSignFinal`].
274    ///
275    /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestSignFinal.html
276    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    /// Returns the signature.
289    ///
290    /// This is a simple convenience wrapper over `len` and `sign`.
291    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        // The advertised length is not always equal to the real length for things like DSA
295        buf.truncate(len);
296        Ok(buf)
297    }
298
299    /// Signs the data in data_buf and writes the signature into the buffer sig_buf, returning the
300    /// number of bytes written.
301    ///
302    /// For PureEdDSA (Ed25519 and Ed448 keys) this is the only way to sign data.
303    ///
304    /// This method will fail if the buffer is not large enough for the signature. Use the `len`
305    /// method to get an upper bound on the required size.
306    ///
307    /// OpenSSL documentation at [`EVP_DigestSign`].
308    ///
309    /// [`EVP_DigestSign`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestSign.html
310    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    /// Returns the signature.
329    ///
330    /// This is a simple convenience wrapper over `len` and `sign_oneshot`.
331    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        // The advertised length is not always equal to the real length for things like DSA
335        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        // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
363        unsafe {
364            EVP_MD_CTX_free(self.md_ctx);
365        }
366    }
367}
368
369/// A type which verifies cryptographic signatures of data.
370impl<'a> Verifier<'a> {
371    /// Creates a new `Verifier`.
372    ///
373    /// This cannot be used with Ed25519 or Ed448 keys. Please refer to
374    /// `new_without_digest`.
375    ///
376    /// OpenSSL documentation at [`EVP_DigestVerifyInit`].
377    ///
378    /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html
379    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    /// Creates a new `Verifier` without a digest.
387    ///
388    /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys.
389    ///
390    /// OpenSSL documentation at [`EVP_DigestVerifyInit`].
391    ///
392    /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html
393    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    /// Returns the RSA padding mode in use.
435    ///
436    /// This is only useful for RSA keys.
437    ///
438    /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
439    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    /// Sets the RSA padding mode.
448    ///
449    /// This is only useful for RSA keys.
450    ///
451    /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`].
452    ///
453    /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_padding.html
454    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    /// Sets the RSA PSS salt length.
465    ///
466    /// This is only useful for RSA keys.
467    ///
468    /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`].
469    ///
470    /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html
471    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    /// Sets the RSA MGF1 algorithm.
482    ///
483    /// This is only useful for RSA keys.
484    ///
485    /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`].
486    ///
487    /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html
488    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    /// Feeds more data into the `Verifier`.
499    ///
500    /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming.
501    /// Use `verify_oneshot` instead.
502    ///
503    /// OpenSSL documentation at [`EVP_DigestUpdate`].
504    ///
505    /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html
506    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    /// Determines if the data fed into the `Verifier` matches the provided signature.
518    ///
519    /// OpenSSL documentation at [`EVP_DigestVerifyFinal`].
520    ///
521    /// [`EVP_DigestVerifyFinal`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyFinal.html
522    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(); // discard error stack
530                    Ok(false)
531                }
532                _ => Err(ErrorStack::get()),
533            }
534        }
535    }
536
537    /// Determines if the data given in buf matches the provided signature.
538    ///
539    /// OpenSSL documentation at [`EVP_DigestVerify`].
540    ///
541    /// [`EVP_DigestVerify`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestVerify.html
542    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}