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(boringssl))]
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(boringssl)]
190type BitType = libc::c_uint;
191#[cfg(not(boringssl))]
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))] {
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: *mut DSA_SIG = cvt_p(ffi::DSA_SIG_new())?;
443 DSA_SIG_set0(sig, pr:r.as_ptr(), ps: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&mut DebugStruct<'_, '_>.debug_struct("DsaSig")
461 .field("r", self.r())
462 .field(name:"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))] {
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}
698