Skip to main content

rama_boring/
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 rama_boring::sign::{Signer, Verifier};
14//! use rama_boring::rsa::Rsa;
15//! use rama_boring::pkey::PKey;
16//! use rama_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 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
53/// Salt lengths that must be used with `set_rsa_pss_saltlen`.
54pub struct RsaPssSaltlen(c_int);
55
56impl RsaPssSaltlen {
57    /// Returns the integer representation of `RsaPssSaltlen`.
58    fn as_raw(&self) -> c_int {
59        self.0
60    }
61
62    /// Sets the salt length to the given value.
63    #[must_use]
64    pub fn custom(val: c_int) -> RsaPssSaltlen {
65        RsaPssSaltlen(val)
66    }
67
68    /// The salt length is set to the digest length.
69    /// Corresponds to the special value `-1`.
70    pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1);
71    /// The salt length is set to the maximum permissible value.
72    /// Corresponds to the special value `-2`.
73    pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2);
74}
75
76/// A type which computes cryptographic signatures of data.
77pub 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        // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
89        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    /// Creates a new `Signer`.
98    ///
99    /// This cannot be used with Ed25519 or Ed448 keys. Please refer to
100    /// `new_without_digest`.
101    #[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    /// Creates a new `Signer` without a digest.
110    ///
111    /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys.
112    /// It can also be used to create a CMAC.
113    #[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    /// Returns the RSA padding mode in use.
156    ///
157    /// This is only useful for RSA keys.
158    #[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    /// Sets the RSA padding mode.
168    ///
169    /// This is only useful for RSA keys.
170    #[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    /// Sets the RSA PSS salt length.
181    ///
182    /// This is only useful for RSA keys.
183    #[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    /// Sets the RSA MGF1 algorithm.
194    ///
195    /// This is only useful for RSA keys.
196    #[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    /// Feeds more data into the `Signer`.
207    ///
208    /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming.
209    /// Use `sign_oneshot` instead.
210    #[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    /// Computes an upper bound on the signature length.
222    ///
223    /// The actual signature may be shorter than this value. Check the return value of
224    /// `sign` to get the exact length.
225    #[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    /// Writes the signature into the provided buffer, returning the number of bytes written.
245    ///
246    /// This method will fail if the buffer is not large enough for the signature. Use the `len`
247    /// method to get an upper bound on the required size.
248    #[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    /// Returns the signature.
262    ///
263    /// This is a simple convenience wrapper over `len` and `sign`.
264    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        // The advertised length is not always equal to the real length for things like DSA
268        buf.truncate(len);
269        Ok(buf)
270    }
271
272    /// Signs the data in data_buf and writes the signature into the buffer sig_buf, returning the
273    /// number of bytes written.
274    ///
275    /// For PureEdDSA (Ed25519 and Ed448 keys) this is the only way to sign data.
276    ///
277    /// This method will fail if the buffer is not large enough for the signature. Use the `len`
278    /// method to get an upper bound on the required size.
279    #[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    /// Returns the signature.
299    ///
300    /// This is a simple convenience wrapper over `len` and `sign_oneshot`.
301    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        // The advertised length is not always equal to the real length for things like DSA
305        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        // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
333        unsafe {
334            EVP_MD_CTX_free(self.md_ctx);
335        }
336    }
337}
338
339/// A type which verifies cryptographic signatures of data.
340impl<'a> Verifier<'a> {
341    /// Creates a new `Verifier`.
342    ///
343    /// This cannot be used with Ed25519 or Ed448 keys. Please refer to
344    /// `new_without_digest`.
345    #[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    /// Creates a new `Verifier` without a digest.
354    ///
355    /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys.
356    #[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    /// Returns the RSA padding mode in use.
399    ///
400    /// This is only useful for RSA keys.
401    #[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    /// Sets the RSA padding mode.
411    ///
412    /// This is only useful for RSA keys.
413    #[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    /// Sets the RSA PSS salt length.
424    ///
425    /// This is only useful for RSA keys.
426    #[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    /// Sets the RSA MGF1 algorithm.
437    ///
438    /// This is only useful for RSA keys.
439    #[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    /// Feeds more data into the `Verifier`.
450    ///
451    /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming.
452    /// Use `verify_oneshot` instead.
453    #[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    /// Determines if the data fed into the `Verifier` matches the provided signature.
465    #[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(); // discard error stack
474                    Ok(false)
475                }
476                _ => Err(ErrorStack::get()),
477            }
478        }
479    }
480
481    /// Determines if the data given in buf matches the provided signature.
482    #[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}