1use 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 pub struct Dsa<T>;
59 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 #[corresponds(PEM_write_bio_DSA_PUBKEY)]
91 public_key_to_pem,
92 ffi::PEM_write_bio_DSA_PUBKEY
93 }
94
95 to_der! {
96 #[corresponds(i2d_DSA_PUBKEY)]
98 public_key_to_der,
99 ffi::i2d_DSA_PUBKEY
100 }
101
102 #[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 #[corresponds(PEM_write_bio_DSAPrivateKey)]
122 private_key_to_pem,
123 #[corresponds(PEM_write_bio_DSAPrivateKey)]
127 private_key_to_pem_passphrase,
128 ffi::PEM_write_bio_DSAPrivateKey
129 }
130
131 to_der! {
132 #[corresponds(i2d_DSAPrivateKey)]
134 private_key_to_der,
135 ffi::i2d_DSAPrivateKey
136 }
137
138 #[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 #[corresponds(DSA_size)]
155 pub fn size(&self) -> u32 {
156 unsafe { ffi::DSA_size(self.as_ptr()) as u32 }
157 }
158
159 #[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 #[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 #[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 #[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 #[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 #[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 pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
242 let params = Dsa::generate_params(bits)?;
243 params.generate_key()
244 }
245
246 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 #[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 #[corresponds(d2i_DSA_PUBKEY)]
284 public_key_from_der,
285 Dsa<Public>,
286 ffi::d2i_DSA_PUBKEY
287 }
288
289 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 pub struct DsaSig;
432
433 pub struct DsaSigRef;
435}
436
437impl DsaSig {
438 #[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 #[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 #[corresponds(i2d_DSA_SIG)]
471 to_der,
472 ffi::i2d_DSA_SIG
473 }
474
475 #[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 #[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}