Coverage Report

Created: 2026-08-08 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/openssl-0.10.62/src/sign.rs
Line
Count
Source
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`.
96
0
    pub(crate) fn as_raw(&self) -> c_int {
97
0
        self.0
98
0
    }
99
100
    /// Sets the salt length to the given value.
101
0
    pub fn custom(val: c_int) -> RsaPssSaltlen {
102
0
        RsaPssSaltlen(val)
103
0
    }
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<'_> {
124
0
    fn drop(&mut self) {
125
        // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
126
0
        unsafe {
127
0
            EVP_MD_CTX_free(self.md_ctx);
128
0
        }
129
0
    }
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
142
0
    pub fn new<'a, T>(type_: MessageDigest, pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
143
0
    where
144
0
        T: HasPrivate,
145
    {
146
0
        Self::new_intern(Some(type_), pkey)
147
0
    }
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
0
    pub fn new_without_digest<'a, T>(pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
158
0
    where
159
0
        T: HasPrivate,
160
    {
161
0
        Self::new_intern(None, pkey)
162
0
    }
163
164
0
    fn new_intern<'a, T>(
165
0
        type_: Option<MessageDigest>,
166
0
        pkey: &PKeyRef<T>,
167
0
    ) -> Result<Signer<'a>, ErrorStack>
168
0
    where
169
0
        T: HasPrivate,
170
    {
171
        unsafe {
172
0
            ffi::init();
173
174
0
            let ctx = cvt_p(EVP_MD_CTX_new())?;
175
0
            let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
176
0
            let r = ffi::EVP_DigestSignInit(
177
0
                ctx,
178
0
                &mut pctx,
179
0
                type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
180
0
                ptr::null_mut(),
181
0
                pkey.as_ptr(),
182
            );
183
0
            if r != 1 {
184
0
                EVP_MD_CTX_free(ctx);
185
0
                return Err(ErrorStack::get());
186
0
            }
187
188
0
            assert!(!pctx.is_null());
189
190
0
            Ok(Signer {
191
0
                md_ctx: ctx,
192
0
                pctx,
193
0
                _p: PhantomData,
194
0
            })
195
        }
196
0
    }
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
0
    pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
204
        unsafe {
205
0
            let mut pad = 0;
206
0
            cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
207
0
                .map(|_| Padding::from_raw(pad))
208
        }
209
0
    }
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
0
    pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
219
        unsafe {
220
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
221
0
                self.pctx,
222
0
                padding.as_raw(),
223
            ))
224
0
            .map(|_| ())
225
        }
226
0
    }
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
0
    pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
236
        unsafe {
237
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
238
0
                self.pctx,
239
0
                len.as_raw(),
240
            ))
241
0
            .map(|_| ())
242
        }
243
0
    }
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
0
    pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
253
        unsafe {
254
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
255
0
                self.pctx,
256
0
                md.as_ptr() as *mut _,
257
            ))
258
0
            .map(|_| ())
259
        }
260
0
    }
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
0
    pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
271
        unsafe {
272
0
            cvt(ffi::EVP_DigestUpdate(
273
0
                self.md_ctx,
274
0
                buf.as_ptr() as *const _,
275
0
                buf.len(),
276
            ))
277
0
            .map(|_| ())
278
        }
279
0
    }
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
0
    pub fn len(&self) -> Result<usize, ErrorStack> {
290
0
        self.len_intern()
291
0
    }
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
0
    fn len_intern(&self) -> Result<usize, ErrorStack> {
308
        unsafe {
309
0
            let mut len = 0;
310
0
            cvt(ffi::EVP_DigestSign(
311
0
                self.md_ctx,
312
0
                ptr::null_mut(),
313
0
                &mut len,
314
0
                ptr::null(),
315
                0,
316
0
            ))?;
317
0
            Ok(len)
318
        }
319
0
    }
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
0
    pub fn sign(&self, buf: &mut [u8]) -> Result<usize, ErrorStack> {
330
        unsafe {
331
0
            let mut len = buf.len();
332
0
            cvt(ffi::EVP_DigestSignFinal(
333
0
                self.md_ctx,
334
0
                buf.as_mut_ptr() as *mut _,
335
0
                &mut len,
336
0
            ))?;
337
0
            Ok(len)
338
        }
339
0
    }
340
341
    /// Returns the signature.
342
    ///
343
    /// This is a simple convenience wrapper over `len` and `sign`.
344
0
    pub fn sign_to_vec(&self) -> Result<Vec<u8>, ErrorStack> {
345
0
        let mut buf = vec![0; self.len()?];
346
0
        let len = self.sign(&mut buf)?;
347
        // The advertised length is not always equal to the real length for things like DSA
348
0
        buf.truncate(len);
349
0
        Ok(buf)
350
0
    }
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
0
    pub fn sign_oneshot(
365
0
        &mut self,
366
0
        sig_buf: &mut [u8],
367
0
        data_buf: &[u8],
368
0
    ) -> Result<usize, ErrorStack> {
369
        unsafe {
370
0
            let mut sig_len = sig_buf.len();
371
0
            cvt(ffi::EVP_DigestSign(
372
0
                self.md_ctx,
373
0
                sig_buf.as_mut_ptr() as *mut _,
374
0
                &mut sig_len,
375
0
                data_buf.as_ptr() as *const _,
376
0
                data_buf.len(),
377
0
            ))?;
378
0
            Ok(sig_len)
379
        }
380
0
    }
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
0
    pub fn sign_oneshot_to_vec(&mut self, data_buf: &[u8]) -> Result<Vec<u8>, ErrorStack> {
387
0
        let mut sig_buf = vec![0; self.len()?];
388
0
        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
0
        sig_buf.truncate(len);
391
0
        Ok(sig_buf)
392
0
    }
393
}
394
395
impl<'a> Write for Signer<'a> {
396
0
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
397
0
        self.update(buf)?;
398
0
        Ok(buf.len())
399
0
    }
400
401
0
    fn flush(&mut self) -> io::Result<()> {
402
0
        Ok(())
403
0
    }
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> {
418
0
    fn drop(&mut self) {
419
        // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
420
0
        unsafe {
421
0
            EVP_MD_CTX_free(self.md_ctx);
422
0
        }
423
0
    }
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
436
0
    pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
437
0
    where
438
0
        T: HasPublic,
439
    {
440
0
        Verifier::new_intern(Some(type_), pkey)
441
0
    }
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
0
    pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
451
0
    where
452
0
        T: HasPublic,
453
    {
454
0
        Verifier::new_intern(None, pkey)
455
0
    }
456
457
0
    fn new_intern<T>(
458
0
        type_: Option<MessageDigest>,
459
0
        pkey: &'a PKeyRef<T>,
460
0
    ) -> Result<Verifier<'a>, ErrorStack>
461
0
    where
462
0
        T: HasPublic,
463
    {
464
        unsafe {
465
0
            ffi::init();
466
467
0
            let ctx = cvt_p(EVP_MD_CTX_new())?;
468
0
            let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
469
0
            let r = ffi::EVP_DigestVerifyInit(
470
0
                ctx,
471
0
                &mut pctx,
472
0
                type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
473
0
                ptr::null_mut(),
474
0
                pkey.as_ptr(),
475
            );
476
0
            if r != 1 {
477
0
                EVP_MD_CTX_free(ctx);
478
0
                return Err(ErrorStack::get());
479
0
            }
480
481
0
            assert!(!pctx.is_null());
482
483
0
            Ok(Verifier {
484
0
                md_ctx: ctx,
485
0
                pctx,
486
0
                pkey_pd: PhantomData,
487
0
            })
488
        }
489
0
    }
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
0
    pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
497
        unsafe {
498
0
            let mut pad = 0;
499
0
            cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
500
0
                .map(|_| Padding::from_raw(pad))
501
        }
502
0
    }
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
0
    pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
512
        unsafe {
513
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
514
0
                self.pctx,
515
0
                padding.as_raw(),
516
            ))
517
0
            .map(|_| ())
518
        }
519
0
    }
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
0
    pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
529
        unsafe {
530
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
531
0
                self.pctx,
532
0
                len.as_raw(),
533
            ))
534
0
            .map(|_| ())
535
        }
536
0
    }
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
0
    pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
546
        unsafe {
547
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
548
0
                self.pctx,
549
0
                md.as_ptr() as *mut _,
550
            ))
551
0
            .map(|_| ())
552
        }
553
0
    }
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
0
    pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
564
        unsafe {
565
0
            cvt(ffi::EVP_DigestUpdate(
566
0
                self.md_ctx,
567
0
                buf.as_ptr() as *const _,
568
0
                buf.len(),
569
            ))
570
0
            .map(|_| ())
571
        }
572
0
    }
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
0
    pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
580
        unsafe {
581
0
            let r =
582
0
                EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len());
583
0
            match r {
584
0
                1 => Ok(true),
585
                0 => {
586
0
                    ErrorStack::get(); // discard error stack
587
0
                    Ok(false)
588
                }
589
0
                _ => Err(ErrorStack::get()),
590
            }
591
        }
592
0
    }
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
0
    pub fn verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> {
601
        unsafe {
602
0
            let r = ffi::EVP_DigestVerify(
603
0
                self.md_ctx,
604
0
                signature.as_ptr() as *const _,
605
0
                signature.len(),
606
0
                buf.as_ptr() as *const _,
607
0
                buf.len(),
608
            );
609
0
            match r {
610
0
                1 => Ok(true),
611
                0 => {
612
0
                    ErrorStack::get();
613
0
                    Ok(false)
614
                }
615
0
                _ => Err(ErrorStack::get()),
616
            }
617
        }
618
0
    }
619
}
620
621
impl<'a> Write for Verifier<'a> {
622
0
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
623
0
        self.update(buf)?;
624
0
        Ok(buf.len())
625
0
    }
626
627
0
    fn flush(&mut self) -> io::Result<()> {
628
0
        Ok(())
629
0
    }
630
}
631
632
#[cfg(not(ossl101))]
633
use ffi::EVP_DigestVerifyFinal;
634
635
#[cfg(ossl101)]
636
#[allow(bad_style)]
637
0
unsafe fn EVP_DigestVerifyFinal(
638
0
    ctx: *mut ffi::EVP_MD_CTX,
639
0
    sigret: *const ::libc::c_uchar,
640
0
    siglen: ::libc::size_t,
641
0
) -> ::libc::c_int {
642
0
    ffi::EVP_DigestVerifyFinal(ctx, sigret as *mut _, siglen)
643
0
}
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]
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
}