openssl/
dsa.rs

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
8use cfg_if::cfg_if;
9use foreign_types::{ForeignType, ForeignTypeRef};
10#[cfg(not(any(boringssl, awslc)))]
11use libc::c_int;
12use std::fmt;
13use std::mem;
14use std::ptr;
15
16use crate::bn::{BigNum, BigNumRef};
17use crate::error::ErrorStack;
18use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
19use crate::util::ForeignTypeRefExt;
20use crate::{cvt, cvt_p};
21use openssl_macros::corresponds;
22
23generic_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
65impl<T> Clone for Dsa<T> {
66    fn clone(&self) -> Dsa<T> {
67        (**self).to_owned()
68    }
69}
70
71impl<T> ToOwned for DsaRef<T> {
72    type Owned = Dsa<T>;
73
74    fn to_owned(&self) -> Dsa<T> {
75        unsafe {
76            ffi::DSA_up_ref(self.as_ptr());
77            Dsa::from_ptr(self.as_ptr())
78        }
79    }
80}
81
82impl<T> DsaRef<T>
83where
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    pub fn pub_key(&self) -> &BigNumRef {
105        unsafe {
106            let mut pub_key = ptr::null();
107            DSA_get0_key(self.as_ptr(), &mut pub_key, ptr::null_mut());
108            BigNumRef::from_const_ptr(pub_key)
109        }
110    }
111}
112
113impl<T> DsaRef<T>
114where
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    pub fn priv_key(&self) -> &BigNumRef {
141        unsafe {
142            let mut priv_key = ptr::null();
143            DSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut priv_key);
144            BigNumRef::from_const_ptr(priv_key)
145        }
146    }
147}
148
149impl<T> DsaRef<T>
150where
151    T: HasParams,
152{
153    /// Returns the maximum size of the signature output by `self` in bytes.
154    #[corresponds(DSA_size)]
155    pub fn size(&self) -> u32 {
156        unsafe { ffi::DSA_size(self.as_ptr()) as u32 }
157    }
158
159    /// Returns the DSA prime parameter of `self`.
160    #[corresponds(DSA_get0_pqg)]
161    pub fn p(&self) -> &BigNumRef {
162        unsafe {
163            let mut p = ptr::null();
164            DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut());
165            BigNumRef::from_const_ptr(p)
166        }
167    }
168
169    /// Returns the DSA sub-prime parameter of `self`.
170    #[corresponds(DSA_get0_pqg)]
171    pub fn q(&self) -> &BigNumRef {
172        unsafe {
173            let mut q = ptr::null();
174            DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut());
175            BigNumRef::from_const_ptr(q)
176        }
177    }
178
179    /// Returns the DSA base parameter of `self`.
180    #[corresponds(DSA_get0_pqg)]
181    pub fn g(&self) -> &BigNumRef {
182        unsafe {
183            let mut g = ptr::null();
184            DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g);
185            BigNumRef::from_const_ptr(g)
186        }
187    }
188}
189#[cfg(any(boringssl, awslc))]
190type BitType = libc::c_uint;
191#[cfg(not(any(boringssl, awslc)))]
192type BitType = c_int;
193
194impl Dsa<Params> {
195    /// Creates a DSA params based upon the given parameters.
196    #[corresponds(DSA_set0_pqg)]
197    pub fn from_pqg(p: BigNum, q: BigNum, g: BigNum) -> Result<Dsa<Params>, ErrorStack> {
198        unsafe {
199            let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
200            cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
201            mem::forget((p, q, g));
202            Ok(dsa)
203        }
204    }
205
206    /// Generates DSA params based on the given number of bits.
207    #[corresponds(DSA_generate_parameters_ex)]
208    pub fn generate_params(bits: u32) -> Result<Dsa<Params>, ErrorStack> {
209        ffi::init();
210        unsafe {
211            let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
212            cvt(ffi::DSA_generate_parameters_ex(
213                dsa.0,
214                bits as BitType,
215                ptr::null(),
216                0,
217                ptr::null_mut(),
218                ptr::null_mut(),
219                ptr::null_mut(),
220            ))?;
221            Ok(dsa)
222        }
223    }
224
225    /// Generates a private key based on the DSA params.
226    #[corresponds(DSA_generate_key)]
227    pub fn generate_key(self) -> Result<Dsa<Private>, ErrorStack> {
228        unsafe {
229            let dsa_ptr = self.0;
230            cvt(ffi::DSA_generate_key(dsa_ptr))?;
231            mem::forget(self);
232            Ok(Dsa::from_ptr(dsa_ptr))
233        }
234    }
235}
236
237impl Dsa<Private> {
238    /// Generate a DSA key pair.
239    ///
240    /// The `bits` parameter corresponds to the length of the prime `p`.
241    pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
242        let params = Dsa::generate_params(bits)?;
243        params.generate_key()
244    }
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    pub fn from_private_components(
252        p: BigNum,
253        q: BigNum,
254        g: BigNum,
255        priv_key: BigNum,
256        pub_key: BigNum,
257    ) -> Result<Dsa<Private>, ErrorStack> {
258        ffi::init();
259        unsafe {
260            let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
261            cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
262            mem::forget((p, q, g));
263            cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), priv_key.as_ptr()))?;
264            mem::forget((pub_key, priv_key));
265            Ok(dsa)
266        }
267    }
268}
269
270impl 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    pub fn from_public_components(
294        p: BigNum,
295        q: BigNum,
296        g: BigNum,
297        pub_key: BigNum,
298    ) -> Result<Dsa<Public>, ErrorStack> {
299        ffi::init();
300        unsafe {
301            let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
302            cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
303            mem::forget((p, q, g));
304            cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), ptr::null_mut()))?;
305            mem::forget(pub_key);
306            Ok(dsa)
307        }
308    }
309}
310
311impl<T> fmt::Debug for Dsa<T> {
312    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
313        write!(f, "DSA")
314    }
315}
316
317cfg_if! {
318    if #[cfg(any(ossl110, libressl273, boringssl, awslc))] {
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
379foreign_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
437impl DsaSig {
438    /// Returns a new `DsaSig` by setting the `r` and `s` values associated with an DSA signature.
439    #[corresponds(DSA_SIG_set0)]
440    pub fn from_private_components(r: BigNum, s: BigNum) -> Result<Self, ErrorStack> {
441        unsafe {
442            let sig = cvt_p(ffi::DSA_SIG_new())?;
443            DSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
444            mem::forget((r, s));
445            Ok(DsaSig::from_ptr(sig))
446        }
447    }
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
458impl fmt::Debug for DsaSig {
459    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
460        f.debug_struct("DsaSig")
461            .field("r", self.r())
462            .field("s", self.s())
463            .finish()
464    }
465}
466
467impl 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    pub fn r(&self) -> &BigNumRef {
478        unsafe {
479            let mut r = ptr::null();
480            DSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
481            BigNumRef::from_const_ptr(r)
482        }
483    }
484
485    /// Returns internal component `s` of an `DsaSig`.
486    #[corresponds(DSA_SIG_get0)]
487    pub fn s(&self) -> &BigNumRef {
488        unsafe {
489            let mut s = ptr::null();
490            DSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
491            BigNumRef::from_const_ptr(s)
492        }
493    }
494}
495
496cfg_if! {
497    if #[cfg(any(ossl110, libressl273, boringssl, awslc))] {
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)]
533mod 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}