Coverage Report

Created: 2025-12-28 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/openssl-0.10.62/src/dsa.rs
Line
Count
Source
1
//! Digital Signatures
2
//!
3
//! DSA ensures a message originated from a known sender, and was not modified.
4
//! DSA uses asymmetrical keys and an algorithm to output a signature of the message
5
//! using the private key that can be validated with the public key but not be generated
6
//! without the private key.
7
8
use cfg_if::cfg_if;
9
use foreign_types::{ForeignType, ForeignTypeRef};
10
#[cfg(not(boringssl))]
11
use libc::c_int;
12
use std::fmt;
13
use std::mem;
14
use std::ptr;
15
16
use crate::bn::{BigNum, BigNumRef};
17
use crate::error::ErrorStack;
18
use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
19
use crate::util::ForeignTypeRefExt;
20
use crate::{cvt, cvt_p};
21
use openssl_macros::corresponds;
22
23
generic_foreign_type_and_impl_send_sync! {
24
    type CType = ffi::DSA;
25
    fn drop = ffi::DSA_free;
26
27
    /// Object representing DSA keys.
28
    ///
29
    /// A DSA object contains the parameters p, q, and g.  There is a private
30
    /// and public key.  The values p, g, and q are:
31
    ///
32
    /// * `p`: DSA prime parameter
33
    /// * `q`: DSA sub-prime parameter
34
    /// * `g`: DSA base parameter
35
    ///
36
    /// These values are used to calculate a pair of asymmetrical keys used for
37
    /// signing.
38
    ///
39
    /// OpenSSL documentation at [`DSA_new`]
40
    ///
41
    /// [`DSA_new`]: https://www.openssl.org/docs/manmaster/crypto/DSA_new.html
42
    ///
43
    /// # Examples
44
    ///
45
    /// ```
46
    /// use openssl::dsa::Dsa;
47
    /// use openssl::error::ErrorStack;
48
    /// use openssl::pkey::Private;
49
    ///
50
    /// fn create_dsa() -> Result<Dsa<Private>, ErrorStack> {
51
    ///     let sign = Dsa::generate(2048)?;
52
    ///     Ok(sign)
53
    /// }
54
    /// # fn main() {
55
    /// #    create_dsa();
56
    /// # }
57
    /// ```
58
    pub struct Dsa<T>;
59
    /// Reference to [`Dsa`].
60
    ///
61
    /// [`Dsa`]: struct.Dsa.html
62
    pub struct DsaRef<T>;
63
}
64
65
impl<T> Clone for Dsa<T> {
66
0
    fn clone(&self) -> Dsa<T> {
67
0
        (**self).to_owned()
68
0
    }
69
}
70
71
impl<T> ToOwned for DsaRef<T> {
72
    type Owned = Dsa<T>;
73
74
0
    fn to_owned(&self) -> Dsa<T> {
75
        unsafe {
76
0
            ffi::DSA_up_ref(self.as_ptr());
77
0
            Dsa::from_ptr(self.as_ptr())
78
        }
79
0
    }
80
}
81
82
impl<T> DsaRef<T>
83
where
84
    T: HasPublic,
85
{
86
    to_pem! {
87
        /// Serializes the public key into a PEM-encoded SubjectPublicKeyInfo structure.
88
        ///
89
        /// The output will have a header of `-----BEGIN PUBLIC KEY-----`.
90
        #[corresponds(PEM_write_bio_DSA_PUBKEY)]
91
        public_key_to_pem,
92
        ffi::PEM_write_bio_DSA_PUBKEY
93
    }
94
95
    to_der! {
96
        /// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure.
97
        #[corresponds(i2d_DSA_PUBKEY)]
98
        public_key_to_der,
99
        ffi::i2d_DSA_PUBKEY
100
    }
101
102
    /// Returns a reference to the public key component of `self`.
103
    #[corresponds(DSA_get0_key)]
104
0
    pub fn pub_key(&self) -> &BigNumRef {
105
        unsafe {
106
0
            let mut pub_key = ptr::null();
107
0
            DSA_get0_key(self.as_ptr(), &mut pub_key, ptr::null_mut());
108
0
            BigNumRef::from_const_ptr(pub_key)
109
        }
110
0
    }
111
}
112
113
impl<T> DsaRef<T>
114
where
115
    T: HasPrivate,
116
{
117
    private_key_to_pem! {
118
        /// Serializes the private key to a PEM-encoded DSAPrivateKey structure.
119
        ///
120
        /// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`.
121
        #[corresponds(PEM_write_bio_DSAPrivateKey)]
122
        private_key_to_pem,
123
        /// Serializes the private key to a PEM-encoded encrypted DSAPrivateKey structure.
124
        ///
125
        /// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`.
126
        #[corresponds(PEM_write_bio_DSAPrivateKey)]
127
        private_key_to_pem_passphrase,
128
        ffi::PEM_write_bio_DSAPrivateKey
129
    }
130
131
    to_der! {
132
        /// Serializes the private_key to a DER-encoded `DSAPrivateKey` structure.
133
        #[corresponds(i2d_DSAPrivateKey)]
134
        private_key_to_der,
135
        ffi::i2d_DSAPrivateKey
136
    }
137
138
    /// Returns a reference to the private key component of `self`.
139
    #[corresponds(DSA_get0_key)]
140
0
    pub fn priv_key(&self) -> &BigNumRef {
141
        unsafe {
142
0
            let mut priv_key = ptr::null();
143
0
            DSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut priv_key);
144
0
            BigNumRef::from_const_ptr(priv_key)
145
        }
146
0
    }
147
}
148
149
impl<T> DsaRef<T>
150
where
151
    T: HasParams,
152
{
153
    /// Returns the maximum size of the signature output by `self` in bytes.
154
    #[corresponds(DSA_size)]
155
0
    pub fn size(&self) -> u32 {
156
0
        unsafe { ffi::DSA_size(self.as_ptr()) as u32 }
157
0
    }
158
159
    /// Returns the DSA prime parameter of `self`.
160
    #[corresponds(DSA_get0_pqg)]
161
0
    pub fn p(&self) -> &BigNumRef {
162
        unsafe {
163
0
            let mut p = ptr::null();
164
0
            DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut());
165
0
            BigNumRef::from_const_ptr(p)
166
        }
167
0
    }
168
169
    /// Returns the DSA sub-prime parameter of `self`.
170
    #[corresponds(DSA_get0_pqg)]
171
0
    pub fn q(&self) -> &BigNumRef {
172
        unsafe {
173
0
            let mut q = ptr::null();
174
0
            DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut());
175
0
            BigNumRef::from_const_ptr(q)
176
        }
177
0
    }
178
179
    /// Returns the DSA base parameter of `self`.
180
    #[corresponds(DSA_get0_pqg)]
181
0
    pub fn g(&self) -> &BigNumRef {
182
        unsafe {
183
0
            let mut g = ptr::null();
184
0
            DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g);
185
0
            BigNumRef::from_const_ptr(g)
186
        }
187
0
    }
188
}
189
#[cfg(boringssl)]
190
type BitType = libc::c_uint;
191
#[cfg(not(boringssl))]
192
type BitType = c_int;
193
194
impl Dsa<Params> {
195
    /// Creates a DSA params based upon the given parameters.
196
    #[corresponds(DSA_set0_pqg)]
197
0
    pub fn from_pqg(p: BigNum, q: BigNum, g: BigNum) -> Result<Dsa<Params>, ErrorStack> {
198
        unsafe {
199
0
            let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
200
0
            cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
201
0
            mem::forget((p, q, g));
202
0
            Ok(dsa)
203
        }
204
0
    }
205
206
    /// Generates DSA params based on the given number of bits.
207
    #[corresponds(DSA_generate_parameters_ex)]
208
0
    pub fn generate_params(bits: u32) -> Result<Dsa<Params>, ErrorStack> {
209
0
        ffi::init();
210
        unsafe {
211
0
            let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
212
0
            cvt(ffi::DSA_generate_parameters_ex(
213
0
                dsa.0,
214
0
                bits as BitType,
215
0
                ptr::null(),
216
                0,
217
0
                ptr::null_mut(),
218
0
                ptr::null_mut(),
219
0
                ptr::null_mut(),
220
0
            ))?;
221
0
            Ok(dsa)
222
        }
223
0
    }
224
225
    /// Generates a private key based on the DSA params.
226
    #[corresponds(DSA_generate_key)]
227
0
    pub fn generate_key(self) -> Result<Dsa<Private>, ErrorStack> {
228
        unsafe {
229
0
            let dsa_ptr = self.0;
230
0
            cvt(ffi::DSA_generate_key(dsa_ptr))?;
231
0
            mem::forget(self);
232
0
            Ok(Dsa::from_ptr(dsa_ptr))
233
        }
234
0
    }
235
}
236
237
impl Dsa<Private> {
238
    /// Generate a DSA key pair.
239
    ///
240
    /// The `bits` parameter corresponds to the length of the prime `p`.
241
0
    pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
242
0
        let params = Dsa::generate_params(bits)?;
243
0
        params.generate_key()
244
0
    }
245
246
    /// Create a DSA key pair with the given parameters
247
    ///
248
    /// `p`, `q` and `g` are the common parameters.
249
    /// `priv_key` is the private component of the key pair.
250
    /// `pub_key` is the public component of the key. Can be computed via `g^(priv_key) mod p`
251
0
    pub fn from_private_components(
252
0
        p: BigNum,
253
0
        q: BigNum,
254
0
        g: BigNum,
255
0
        priv_key: BigNum,
256
0
        pub_key: BigNum,
257
0
    ) -> Result<Dsa<Private>, ErrorStack> {
258
0
        ffi::init();
259
        unsafe {
260
0
            let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
261
0
            cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
262
0
            mem::forget((p, q, g));
263
0
            cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), priv_key.as_ptr()))?;
264
0
            mem::forget((pub_key, priv_key));
265
0
            Ok(dsa)
266
        }
267
0
    }
268
}
269
270
impl Dsa<Public> {
271
    from_pem! {
272
        /// Decodes a PEM-encoded SubjectPublicKeyInfo structure containing a DSA key.
273
        ///
274
        /// The input should have a header of `-----BEGIN PUBLIC KEY-----`.
275
        #[corresponds(PEM_read_bio_DSA_PUBKEY)]
276
        public_key_from_pem,
277
        Dsa<Public>,
278
        ffi::PEM_read_bio_DSA_PUBKEY
279
    }
280
281
    from_der! {
282
        /// Decodes a DER-encoded SubjectPublicKeyInfo structure containing a DSA key.
283
        #[corresponds(d2i_DSA_PUBKEY)]
284
        public_key_from_der,
285
        Dsa<Public>,
286
        ffi::d2i_DSA_PUBKEY
287
    }
288
289
    /// Create a new DSA key with only public components.
290
    ///
291
    /// `p`, `q` and `g` are the common parameters.
292
    /// `pub_key` is the public component of the key.
293
0
    pub fn from_public_components(
294
0
        p: BigNum,
295
0
        q: BigNum,
296
0
        g: BigNum,
297
0
        pub_key: BigNum,
298
0
    ) -> Result<Dsa<Public>, ErrorStack> {
299
0
        ffi::init();
300
        unsafe {
301
0
            let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
302
0
            cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
303
0
            mem::forget((p, q, g));
304
0
            cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), ptr::null_mut()))?;
305
0
            mem::forget(pub_key);
306
0
            Ok(dsa)
307
        }
308
0
    }
309
}
310
311
impl<T> fmt::Debug for Dsa<T> {
312
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
313
0
        write!(f, "DSA")
314
0
    }
315
}
316
317
cfg_if! {
318
    if #[cfg(any(ossl110, libressl273, boringssl))] {
319
        use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg};
320
    } else {
321
        #[allow(bad_style)]
322
        unsafe fn DSA_get0_pqg(
323
            d: *mut ffi::DSA,
324
            p: *mut *const ffi::BIGNUM,
325
            q: *mut *const ffi::BIGNUM,
326
            g: *mut *const ffi::BIGNUM)
327
        {
328
            if !p.is_null() {
329
                *p = (*d).p;
330
            }
331
            if !q.is_null() {
332
                *q = (*d).q;
333
            }
334
            if !g.is_null() {
335
                *g = (*d).g;
336
            }
337
        }
338
339
        #[allow(bad_style)]
340
        unsafe fn DSA_get0_key(
341
            d: *mut ffi::DSA,
342
            pub_key: *mut *const ffi::BIGNUM,
343
            priv_key: *mut *const ffi::BIGNUM)
344
        {
345
            if !pub_key.is_null() {
346
                *pub_key = (*d).pub_key;
347
            }
348
            if !priv_key.is_null() {
349
                *priv_key = (*d).priv_key;
350
            }
351
        }
352
353
        #[allow(bad_style)]
354
        unsafe fn DSA_set0_key(
355
            d: *mut ffi::DSA,
356
            pub_key: *mut ffi::BIGNUM,
357
            priv_key: *mut ffi::BIGNUM) -> c_int
358
        {
359
            (*d).pub_key = pub_key;
360
            (*d).priv_key = priv_key;
361
            1
362
        }
363
364
        #[allow(bad_style)]
365
        unsafe fn DSA_set0_pqg(
366
            d: *mut ffi::DSA,
367
            p: *mut ffi::BIGNUM,
368
            q: *mut ffi::BIGNUM,
369
            g: *mut ffi::BIGNUM) -> c_int
370
        {
371
            (*d).p = p;
372
            (*d).q = q;
373
            (*d).g = g;
374
            1
375
        }
376
    }
377
}
378
379
foreign_type_and_impl_send_sync! {
380
    type CType = ffi::DSA_SIG;
381
    fn drop = ffi::DSA_SIG_free;
382
383
    /// Object representing DSA signature.
384
    ///
385
    /// DSA signatures consist of two components: `r` and `s`.
386
    ///
387
    /// # Examples
388
    ///
389
    /// ```
390
    /// use std::convert::TryInto;
391
    ///
392
    /// use openssl::bn::BigNum;
393
    /// use openssl::dsa::{Dsa, DsaSig};
394
    /// use openssl::hash::MessageDigest;
395
    /// use openssl::pkey::PKey;
396
    /// use openssl::sign::{Signer, Verifier};
397
    ///
398
    /// const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
399
    /// let dsa_ref = Dsa::generate(1024).unwrap();
400
    ///
401
    /// let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap();
402
    /// let priv_key: PKey<_> = dsa_ref.try_into().unwrap();
403
    ///
404
    /// let mut signer = if let Ok(signer) = Signer::new(MessageDigest::sha256(), &priv_key) {
405
    ///     signer
406
    /// } else {
407
    ///     // DSA signing is not supported (eg. BoringSSL)
408
    ///     return;
409
    /// };
410
    ///
411
    /// signer.update(TEST_DATA).unwrap();
412
    ///
413
    /// let signature = signer.sign_to_vec().unwrap();
414
    /// // Parse DER-encoded DSA signature
415
    /// let signature = DsaSig::from_der(&signature).unwrap();
416
    ///
417
    /// // Extract components `r` and `s`
418
    /// let r = BigNum::from_slice(&signature.r().to_vec()).unwrap();
419
    /// let s = BigNum::from_slice(&signature.s().to_vec()).unwrap();
420
    ///
421
    /// // Construct new DSA signature from components
422
    /// let signature = DsaSig::from_private_components(r, s).unwrap();
423
    ///
424
    /// // Serialize DSA signature to DER
425
    /// let signature = signature.to_der().unwrap();
426
    ///
427
    /// let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
428
    /// verifier.update(TEST_DATA).unwrap();
429
    /// assert!(verifier.verify(&signature[..]).unwrap());
430
    /// ```
431
    pub struct DsaSig;
432
433
    /// Reference to a [`DsaSig`].
434
    pub struct DsaSigRef;
435
}
436
437
impl DsaSig {
438
    /// Returns a new `DsaSig` by setting the `r` and `s` values associated with an DSA signature.
439
    #[corresponds(DSA_SIG_set0)]
440
0
    pub fn from_private_components(r: BigNum, s: BigNum) -> Result<Self, ErrorStack> {
441
        unsafe {
442
0
            let sig = cvt_p(ffi::DSA_SIG_new())?;
443
0
            DSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
444
0
            mem::forget((r, s));
445
0
            Ok(DsaSig::from_ptr(sig))
446
        }
447
0
    }
448
449
    from_der! {
450
        /// Decodes a DER-encoded DSA signature.
451
        #[corresponds(d2i_DSA_SIG)]
452
        from_der,
453
        DsaSig,
454
        ffi::d2i_DSA_SIG
455
    }
456
}
457
458
impl fmt::Debug for DsaSig {
459
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
460
0
        f.debug_struct("DsaSig")
461
0
            .field("r", self.r())
462
0
            .field("s", self.s())
463
0
            .finish()
464
0
    }
465
}
466
467
impl DsaSigRef {
468
    to_der! {
469
        /// Serializes the DSA signature into a DER-encoded `DSASignature` structure.
470
        #[corresponds(i2d_DSA_SIG)]
471
        to_der,
472
        ffi::i2d_DSA_SIG
473
    }
474
475
    /// Returns internal component `r` of an `DsaSig`.
476
    #[corresponds(DSA_SIG_get0)]
477
0
    pub fn r(&self) -> &BigNumRef {
478
        unsafe {
479
0
            let mut r = ptr::null();
480
0
            DSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
481
0
            BigNumRef::from_const_ptr(r)
482
        }
483
0
    }
484
485
    /// Returns internal component `s` of an `DsaSig`.
486
    #[corresponds(DSA_SIG_get0)]
487
0
    pub fn s(&self) -> &BigNumRef {
488
        unsafe {
489
0
            let mut s = ptr::null();
490
0
            DSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
491
0
            BigNumRef::from_const_ptr(s)
492
        }
493
0
    }
494
}
495
496
cfg_if! {
497
    if #[cfg(any(ossl110, libressl273, boringssl))] {
498
        use ffi::{DSA_SIG_set0, DSA_SIG_get0};
499
    } else {
500
        #[allow(bad_style)]
501
        unsafe fn DSA_SIG_set0(
502
            sig: *mut ffi::DSA_SIG,
503
            r: *mut ffi::BIGNUM,
504
            s: *mut ffi::BIGNUM,
505
        ) -> c_int {
506
            if r.is_null() || s.is_null() {
507
                return 0;
508
            }
509
            ffi::BN_clear_free((*sig).r);
510
            ffi::BN_clear_free((*sig).s);
511
            (*sig).r = r;
512
            (*sig).s = s;
513
            1
514
        }
515
516
        #[allow(bad_style)]
517
        unsafe fn DSA_SIG_get0(
518
            sig: *const ffi::DSA_SIG,
519
            pr: *mut *const ffi::BIGNUM,
520
            ps: *mut *const ffi::BIGNUM)
521
        {
522
            if !pr.is_null() {
523
                (*pr) = (*sig).r;
524
            }
525
            if !ps.is_null() {
526
                (*ps) = (*sig).s;
527
            }
528
        }
529
    }
530
}
531
532
#[cfg(test)]
533
mod test {
534
    use super::*;
535
    use crate::bn::BigNumContext;
536
    #[cfg(not(boringssl))]
537
    use crate::hash::MessageDigest;
538
    #[cfg(not(boringssl))]
539
    use crate::pkey::PKey;
540
    #[cfg(not(boringssl))]
541
    use crate::sign::{Signer, Verifier};
542
543
    #[test]
544
    pub fn test_generate() {
545
        Dsa::generate(1024).unwrap();
546
    }
547
548
    #[test]
549
    fn test_pubkey_generation() {
550
        let dsa = Dsa::generate(1024).unwrap();
551
        let p = dsa.p();
552
        let g = dsa.g();
553
        let priv_key = dsa.priv_key();
554
        let pub_key = dsa.pub_key();
555
        let mut ctx = BigNumContext::new().unwrap();
556
        let mut calc = BigNum::new().unwrap();
557
        calc.mod_exp(g, priv_key, p, &mut ctx).unwrap();
558
        assert_eq!(&calc, pub_key)
559
    }
560
561
    #[test]
562
    fn test_priv_key_from_parts() {
563
        let p = BigNum::from_u32(283).unwrap();
564
        let q = BigNum::from_u32(47).unwrap();
565
        let g = BigNum::from_u32(60).unwrap();
566
        let priv_key = BigNum::from_u32(15).unwrap();
567
        let pub_key = BigNum::from_u32(207).unwrap();
568
569
        let dsa = Dsa::from_private_components(p, q, g, priv_key, pub_key).unwrap();
570
        assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
571
        assert_eq!(dsa.priv_key(), &BigNum::from_u32(15).unwrap());
572
        assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
573
        assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
574
        assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
575
    }
576
577
    #[test]
578
    fn test_pub_key_from_parts() {
579
        let p = BigNum::from_u32(283).unwrap();
580
        let q = BigNum::from_u32(47).unwrap();
581
        let g = BigNum::from_u32(60).unwrap();
582
        let pub_key = BigNum::from_u32(207).unwrap();
583
584
        let dsa = Dsa::from_public_components(p, q, g, pub_key).unwrap();
585
        assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
586
        assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
587
        assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
588
        assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
589
    }
590
591
    #[test]
592
    fn test_params() {
593
        let params = Dsa::generate_params(1024).unwrap();
594
        let p = params.p().to_owned().unwrap();
595
        let q = params.q().to_owned().unwrap();
596
        let g = params.g().to_owned().unwrap();
597
        let key = params.generate_key().unwrap();
598
        let params2 = Dsa::from_pqg(
599
            key.p().to_owned().unwrap(),
600
            key.q().to_owned().unwrap(),
601
            key.g().to_owned().unwrap(),
602
        )
603
        .unwrap();
604
        assert_eq!(p, *params2.p());
605
        assert_eq!(q, *params2.q());
606
        assert_eq!(g, *params2.g());
607
    }
608
609
    #[test]
610
    #[cfg(not(boringssl))]
611
    fn test_signature() {
612
        const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
613
        let dsa_ref = Dsa::generate(1024).unwrap();
614
615
        let p = dsa_ref.p();
616
        let q = dsa_ref.q();
617
        let g = dsa_ref.g();
618
619
        let pub_key = dsa_ref.pub_key();
620
        let priv_key = dsa_ref.priv_key();
621
622
        let priv_key = Dsa::from_private_components(
623
            BigNumRef::to_owned(p).unwrap(),
624
            BigNumRef::to_owned(q).unwrap(),
625
            BigNumRef::to_owned(g).unwrap(),
626
            BigNumRef::to_owned(priv_key).unwrap(),
627
            BigNumRef::to_owned(pub_key).unwrap(),
628
        )
629
        .unwrap();
630
        let priv_key = PKey::from_dsa(priv_key).unwrap();
631
632
        let pub_key = Dsa::from_public_components(
633
            BigNumRef::to_owned(p).unwrap(),
634
            BigNumRef::to_owned(q).unwrap(),
635
            BigNumRef::to_owned(g).unwrap(),
636
            BigNumRef::to_owned(pub_key).unwrap(),
637
        )
638
        .unwrap();
639
        let pub_key = PKey::from_dsa(pub_key).unwrap();
640
641
        let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
642
        signer.update(TEST_DATA).unwrap();
643
644
        let signature = signer.sign_to_vec().unwrap();
645
        let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
646
        verifier.update(TEST_DATA).unwrap();
647
        assert!(verifier.verify(&signature[..]).unwrap());
648
    }
649
650
    #[test]
651
    #[cfg(not(boringssl))]
652
    fn test_signature_der() {
653
        use std::convert::TryInto;
654
655
        const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
656
        let dsa_ref = Dsa::generate(1024).unwrap();
657
658
        let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap();
659
        let priv_key: PKey<_> = dsa_ref.try_into().unwrap();
660
661
        let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
662
        signer.update(TEST_DATA).unwrap();
663
664
        let signature = signer.sign_to_vec().unwrap();
665
        eprintln!("{:?}", signature);
666
        let signature = DsaSig::from_der(&signature).unwrap();
667
668
        let r = BigNum::from_slice(&signature.r().to_vec()).unwrap();
669
        let s = BigNum::from_slice(&signature.s().to_vec()).unwrap();
670
671
        let signature = DsaSig::from_private_components(r, s).unwrap();
672
        let signature = signature.to_der().unwrap();
673
674
        let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
675
        verifier.update(TEST_DATA).unwrap();
676
        assert!(verifier.verify(&signature[..]).unwrap());
677
    }
678
679
    #[test]
680
    #[allow(clippy::redundant_clone)]
681
    fn clone() {
682
        let key = Dsa::generate(2048).unwrap();
683
        drop(key.clone());
684
    }
685
686
    #[test]
687
    fn dsa_sig_debug() {
688
        let sig = DsaSig::from_der(&[
689
            48, 46, 2, 21, 0, 135, 169, 24, 58, 153, 37, 175, 248, 200, 45, 251, 112, 238, 238, 89,
690
            172, 177, 182, 166, 237, 2, 21, 0, 159, 146, 151, 237, 187, 8, 82, 115, 14, 183, 103,
691
            12, 203, 46, 161, 208, 251, 167, 123, 131,
692
        ])
693
        .unwrap();
694
        let s = format!("{:?}", sig);
695
        assert_eq!(s, "DsaSig { r: 774484690634577222213819810519929266740561094381, s: 910998676210681457251421818099943952372231273347 }");
696
    }
697
}