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> {
clone(&self) -> Dsa<T>66     fn clone(&self) -> Dsa<T> {
67         (**self).to_owned()
68     }
69 }
70 
71 impl<T> ToOwned for DsaRef<T> {
72     type Owned = Dsa<T>;
73 
to_owned(&self) -> Dsa<T>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 
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)]
pub_key(&self) -> &BigNumRef104     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 
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)]
priv_key(&self) -> &BigNumRef140     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 
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)]
size(&self) -> u32155     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)]
p(&self) -> &BigNumRef161     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)]
q(&self) -> &BigNumRef171     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)]
g(&self) -> &BigNumRef181     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(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)]
from_pqg(p: BigNum, q: BigNum, g: BigNum) -> Result<Dsa<Params>, ErrorStack>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)]
generate_params(bits: u32) -> Result<Dsa<Params>, ErrorStack>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)]
generate_key(self) -> Result<Dsa<Private>, ErrorStack>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 
237 impl Dsa<Private> {
238     /// Generate a DSA key pair.
239     ///
240     /// The `bits` parameter corresponds to the length of the prime `p`.
generate(bits: u32) -> Result<Dsa<Private>, ErrorStack>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`
from_private_components( p: BigNum, q: BigNum, g: BigNum, priv_key: BigNum, pub_key: BigNum, ) -> Result<Dsa<Private>, ErrorStack>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 
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.
from_public_components( p: BigNum, q: BigNum, g: BigNum, pub_key: BigNum, ) -> Result<Dsa<Public>, ErrorStack>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 
311 impl<T> fmt::Debug for Dsa<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result312     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
313         write!(f, "DSA")
314     }
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)]
from_private_components(r: BigNum, s: BigNum) -> Result<Self, ErrorStack>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 
458 impl fmt::Debug for DsaSig {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result459     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 
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)]
r(&self) -> &BigNumRef477     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)]
s(&self) -> &BigNumRef487     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 
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]
test_generate()544     pub fn test_generate() {
545         Dsa::generate(1024).unwrap();
546     }
547 
548     #[test]
test_pubkey_generation()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]
test_priv_key_from_parts()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]
test_pub_key_from_parts()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]
test_params()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))]
test_signature()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))]
test_signature_der()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)]
clone()681     fn clone() {
682         let key = Dsa::generate(2048).unwrap();
683         drop(key.clone());
684     }
685 
686     #[test]
dsa_sig_debug()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 }
698