1use foreign_types::{ForeignType, ForeignTypeRef};
9#[cfg(not(any(boringssl, awslc)))]
10use libc::c_int;
11use std::fmt;
12use std::mem;
13use std::ptr;
14
15use crate::bn::{BigNum, BigNumRef};
16use crate::error::ErrorStack;
17use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
18use crate::util::ForeignTypeRefExt;
19use crate::{cvt, cvt_p};
20use openssl_macros::corresponds;
21
22generic_foreign_type_and_impl_send_sync! {
23 type CType = ffi::DSA;
24 fn drop = ffi::DSA_free;
25
26 pub struct Dsa<T>;
58 pub struct DsaRef<T>;
62}
63
64impl<T> Clone for Dsa<T> {
65 fn clone(&self) -> Dsa<T> {
66 (**self).to_owned()
67 }
68}
69
70impl<T> ToOwned for DsaRef<T> {
71 type Owned = Dsa<T>;
72
73 fn to_owned(&self) -> Dsa<T> {
74 unsafe {
75 let r = ffi::DSA_up_ref(self.as_ptr());
76 assert!(r == 1);
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)]
164 pub fn p(&self) -> &BigNumRef {
165 self.p_opt().expect("DSA has no p parameter")
166 }
167
168 #[corresponds(DSA_get0_pqg)]
170 pub fn p_opt(&self) -> Option<&BigNumRef> {
171 unsafe {
172 let mut p = ptr::null();
173 DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut());
174 BigNumRef::from_const_ptr_opt(p)
175 }
176 }
177
178 #[corresponds(DSA_get0_pqg)]
183 pub fn q(&self) -> &BigNumRef {
184 self.q_opt().expect("DSA has no q parameter")
185 }
186
187 #[corresponds(DSA_get0_pqg)]
190 pub fn q_opt(&self) -> Option<&BigNumRef> {
191 unsafe {
192 let mut q = ptr::null();
193 DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut());
194 BigNumRef::from_const_ptr_opt(q)
195 }
196 }
197
198 #[corresponds(DSA_get0_pqg)]
203 pub fn g(&self) -> &BigNumRef {
204 self.g_opt().expect("DSA has no g parameter")
205 }
206
207 #[corresponds(DSA_get0_pqg)]
209 pub fn g_opt(&self) -> Option<&BigNumRef> {
210 unsafe {
211 let mut g = ptr::null();
212 DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g);
213 BigNumRef::from_const_ptr_opt(g)
214 }
215 }
216}
217fn check_pqg<T>(dsa: &DsaRef<T>) -> Result<(), ErrorStack>
222where
223 T: HasParams,
224{
225 if dsa.p_opt().is_none() || dsa.q_opt().is_none() || dsa.g_opt().is_none() {
226 return Err(ErrorStack::get());
227 }
228 Ok(())
229}
230
231#[cfg(any(boringssl, awslc))]
232type BitType = libc::c_uint;
233#[cfg(not(any(boringssl, awslc)))]
234type BitType = c_int;
235
236impl Dsa<Params> {
237 #[corresponds(DSA_set0_pqg)]
239 pub fn from_pqg(p: BigNum, q: BigNum, g: BigNum) -> Result<Dsa<Params>, ErrorStack> {
240 unsafe {
241 let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
242 cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
243 mem::forget((p, q, g));
244 Ok(dsa)
245 }
246 }
247
248 #[corresponds(DSA_generate_parameters_ex)]
250 pub fn generate_params(bits: u32) -> Result<Dsa<Params>, ErrorStack> {
251 ffi::init();
252 unsafe {
253 let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
254 cvt(ffi::DSA_generate_parameters_ex(
255 dsa.0,
256 bits as BitType,
257 ptr::null(),
258 0,
259 ptr::null_mut(),
260 ptr::null_mut(),
261 ptr::null_mut(),
262 ))?;
263 Ok(dsa)
264 }
265 }
266
267 #[corresponds(DSA_generate_key)]
269 pub fn generate_key(self) -> Result<Dsa<Private>, ErrorStack> {
270 unsafe {
271 let dsa_ptr = self.0;
272 cvt(ffi::DSA_generate_key(dsa_ptr))?;
273 mem::forget(self);
274 Ok(Dsa::from_ptr(dsa_ptr))
275 }
276 }
277}
278
279impl Dsa<Private> {
280 pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
284 let params = Dsa::generate_params(bits)?;
285 params.generate_key()
286 }
287
288 pub fn from_private_components(
294 p: BigNum,
295 q: BigNum,
296 g: BigNum,
297 priv_key: BigNum,
298 pub_key: BigNum,
299 ) -> Result<Dsa<Private>, ErrorStack> {
300 ffi::init();
301 unsafe {
302 let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
303 cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
304 mem::forget((p, q, g));
305 cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), priv_key.as_ptr()))?;
306 mem::forget((pub_key, priv_key));
307 Ok(dsa)
308 }
309 }
310}
311
312impl Dsa<Public> {
313 #[corresponds(PEM_read_bio_DSA_PUBKEY)]
319 pub fn public_key_from_pem(pem: &[u8]) -> Result<Dsa<Public>, ErrorStack> {
320 unsafe {
321 crate::init();
322 let bio = crate::bio::MemBioSlice::new(pem)?;
323 let dsa = cvt_p(ffi::PEM_read_bio_DSA_PUBKEY(
324 bio.as_ptr(),
325 ptr::null_mut(),
326 None,
327 ptr::null_mut(),
328 ))
329 .map(|p| Dsa::from_ptr(p))?;
330 check_pqg(&dsa)?;
331 Ok(dsa)
332 }
333 }
334
335 #[corresponds(d2i_DSA_PUBKEY)]
339 pub fn public_key_from_der(der: &[u8]) -> Result<Dsa<Public>, ErrorStack> {
340 unsafe {
341 ffi::init();
342 let len = ::std::cmp::min(der.len(), libc::c_long::MAX as usize) as libc::c_long;
343 let dsa = cvt_p(ffi::d2i_DSA_PUBKEY(ptr::null_mut(), &mut der.as_ptr(), len))
344 .map(|p| Dsa::from_ptr(p))?;
345 check_pqg(&dsa)?;
346 Ok(dsa)
347 }
348 }
349
350 pub fn from_public_components(
355 p: BigNum,
356 q: BigNum,
357 g: BigNum,
358 pub_key: BigNum,
359 ) -> Result<Dsa<Public>, ErrorStack> {
360 ffi::init();
361 unsafe {
362 let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
363 cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
364 mem::forget((p, q, g));
365 cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), ptr::null_mut()))?;
366 mem::forget(pub_key);
367 Ok(dsa)
368 }
369 }
370}
371
372impl<T> fmt::Debug for Dsa<T> {
373 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
374 write!(f, "DSA")
375 }
376}
377
378use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg};
379
380foreign_type_and_impl_send_sync! {
381 type CType = ffi::DSA_SIG;
382 fn drop = ffi::DSA_SIG_free;
383
384 pub struct DsaSig;
433
434 pub struct DsaSigRef;
436}
437
438impl DsaSig {
439 #[corresponds(DSA_SIG_set0)]
441 pub fn from_private_components(r: BigNum, s: BigNum) -> Result<Self, ErrorStack> {
442 unsafe {
443 let sig = cvt_p(ffi::DSA_SIG_new())?;
444 DSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
445 mem::forget((r, s));
446 Ok(DsaSig::from_ptr(sig))
447 }
448 }
449
450 from_der! {
451 #[corresponds(d2i_DSA_SIG)]
453 from_der,
454 DsaSig,
455 ffi::d2i_DSA_SIG
456 }
457}
458
459impl fmt::Debug for DsaSig {
460 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
461 f.debug_struct("DsaSig")
462 .field("r", self.r())
463 .field("s", self.s())
464 .finish()
465 }
466}
467
468impl DsaSigRef {
469 to_der! {
470 #[corresponds(i2d_DSA_SIG)]
472 to_der,
473 ffi::i2d_DSA_SIG
474 }
475
476 #[corresponds(DSA_SIG_get0)]
478 pub fn r(&self) -> &BigNumRef {
479 unsafe {
480 let mut r = ptr::null();
481 DSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
482 BigNumRef::from_const_ptr(r)
483 }
484 }
485
486 #[corresponds(DSA_SIG_get0)]
488 pub fn s(&self) -> &BigNumRef {
489 unsafe {
490 let mut s = ptr::null();
491 DSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
492 BigNumRef::from_const_ptr(s)
493 }
494 }
495}
496
497use ffi::{DSA_SIG_get0, DSA_SIG_set0};
498
499#[cfg(test)]
500mod test {
501 use super::*;
502 use crate::bn::BigNumContext;
503 #[cfg(not(any(boringssl, awslc_fips)))]
504 use crate::hash::MessageDigest;
505 #[cfg(not(any(boringssl, awslc_fips)))]
506 use crate::pkey::PKey;
507 #[cfg(not(any(boringssl, awslc_fips)))]
508 use crate::sign::{Signer, Verifier};
509
510 #[test]
511 pub fn test_generate() {
512 Dsa::generate(1024).unwrap();
513 }
514
515 #[test]
516 fn test_pubkey_generation() {
517 let dsa = Dsa::generate(1024).unwrap();
518 let p = dsa.p();
519 let g = dsa.g();
520 let priv_key = dsa.priv_key();
521 let pub_key = dsa.pub_key();
522 let mut ctx = BigNumContext::new().unwrap();
523 let mut calc = BigNum::new().unwrap();
524 calc.mod_exp(g, priv_key, p, &mut ctx).unwrap();
525 assert_eq!(&calc, pub_key)
526 }
527
528 #[test]
529 fn test_priv_key_from_parts() {
530 let p = BigNum::from_u32(283).unwrap();
531 let q = BigNum::from_u32(47).unwrap();
532 let g = BigNum::from_u32(60).unwrap();
533 let priv_key = BigNum::from_u32(15).unwrap();
534 let pub_key = BigNum::from_u32(207).unwrap();
535
536 let dsa = Dsa::from_private_components(p, q, g, priv_key, pub_key).unwrap();
537 assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
538 assert_eq!(dsa.priv_key(), &BigNum::from_u32(15).unwrap());
539 assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
540 assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
541 assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
542 }
543
544 #[test]
545 fn test_pub_key_from_parts() {
546 let p = BigNum::from_u32(283).unwrap();
547 let q = BigNum::from_u32(47).unwrap();
548 let g = BigNum::from_u32(60).unwrap();
549 let pub_key = BigNum::from_u32(207).unwrap();
550
551 let dsa = Dsa::from_public_components(p, q, g, pub_key).unwrap();
552 assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
553 assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
554 assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
555 assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
556 }
557
558 #[test]
559 fn test_params() {
560 let params = Dsa::generate_params(1024).unwrap();
561 let p = params.p().to_owned().unwrap();
562 let q = params.q().to_owned().unwrap();
563 let g = params.g().to_owned().unwrap();
564 let key = params.generate_key().unwrap();
565 let params2 = Dsa::from_pqg(
566 key.p().to_owned().unwrap(),
567 key.q().to_owned().unwrap(),
568 key.g().to_owned().unwrap(),
569 )
570 .unwrap();
571 assert_eq!(p, *params2.p());
572 assert_eq!(q, *params2.q());
573 assert_eq!(g, *params2.g());
574 }
575
576 #[test]
577 #[cfg(not(any(boringssl, awslc_fips)))]
578 fn test_signature() {
579 const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
580 let dsa_ref = Dsa::generate(1024).unwrap();
581
582 let p = dsa_ref.p();
583 let q = dsa_ref.q();
584 let g = dsa_ref.g();
585
586 let pub_key = dsa_ref.pub_key();
587 let priv_key = dsa_ref.priv_key();
588
589 let priv_key = Dsa::from_private_components(
590 BigNumRef::to_owned(p).unwrap(),
591 BigNumRef::to_owned(q).unwrap(),
592 BigNumRef::to_owned(g).unwrap(),
593 BigNumRef::to_owned(priv_key).unwrap(),
594 BigNumRef::to_owned(pub_key).unwrap(),
595 )
596 .unwrap();
597 let priv_key = PKey::from_dsa(priv_key).unwrap();
598
599 let pub_key = Dsa::from_public_components(
600 BigNumRef::to_owned(p).unwrap(),
601 BigNumRef::to_owned(q).unwrap(),
602 BigNumRef::to_owned(g).unwrap(),
603 BigNumRef::to_owned(pub_key).unwrap(),
604 )
605 .unwrap();
606 let pub_key = PKey::from_dsa(pub_key).unwrap();
607
608 let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
609 signer.update(TEST_DATA).unwrap();
610
611 let signature = signer.sign_to_vec().unwrap();
612 let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
613 verifier.update(TEST_DATA).unwrap();
614 assert!(verifier.verify(&signature[..]).unwrap());
615 }
616
617 #[test]
618 #[cfg(not(any(boringssl, awslc_fips)))]
619 fn test_signature_der() {
620 use std::convert::TryInto;
621
622 const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
623 let dsa_ref = Dsa::generate(1024).unwrap();
624
625 let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap();
626 let priv_key: PKey<_> = dsa_ref.try_into().unwrap();
627
628 let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
629 signer.update(TEST_DATA).unwrap();
630
631 let signature = signer.sign_to_vec().unwrap();
632 eprintln!("{:?}", signature);
633 let signature = DsaSig::from_der(&signature).unwrap();
634
635 let r = BigNum::from_slice(&signature.r().to_vec()).unwrap();
636 let s = BigNum::from_slice(&signature.s().to_vec()).unwrap();
637
638 let signature = DsaSig::from_private_components(r, s).unwrap();
639 let signature = signature.to_der().unwrap();
640
641 let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
642 verifier.update(TEST_DATA).unwrap();
643 assert!(verifier.verify(&signature[..]).unwrap());
644 }
645
646 #[test]
647 #[allow(clippy::redundant_clone)]
648 fn clone() {
649 let key = Dsa::generate(2048).unwrap();
650 drop(key.clone());
651 }
652
653 #[test]
654 fn dsa_sig_debug() {
655 let sig = DsaSig::from_der(&[
656 48, 46, 2, 21, 0, 135, 169, 24, 58, 153, 37, 175, 248, 200, 45, 251, 112, 238, 238, 89,
657 172, 177, 182, 166, 237, 2, 21, 0, 159, 146, 151, 237, 187, 8, 82, 115, 14, 183, 103,
658 12, 203, 46, 161, 208, 251, 167, 123, 131,
659 ])
660 .unwrap();
661 let s = format!("{:?}", sig);
662 assert_eq!(s, "DsaSig { r: 774484690634577222213819810519929266740561094381, s: 910998676210681457251421818099943952372231273347 }");
663 }
664
665 const DSA_SPKI_NO_PARAMS: &[u8] = &[
667 0x30, 0x11, 0x30, 0x09, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01, 0x03, 0x04,
668 0x00, 0x02, 0x01, 0x05,
669 ];
670
671 fn dsa_without_params() -> Dsa<Params> {
672 unsafe {
673 ffi::init();
674 Dsa::from_ptr(cvt_p(ffi::DSA_new()).unwrap())
675 }
676 }
677
678 #[test]
679 fn public_key_from_der_rejects_missing_params() {
680 assert!(Dsa::public_key_from_der(DSA_SPKI_NO_PARAMS).is_err());
681 }
682
683 #[test]
684 fn p_opt_is_none_without_params() {
685 let dsa = dsa_without_params();
686 assert!(dsa.p_opt().is_none());
687 assert!(dsa.q_opt().is_none());
688 assert!(dsa.g_opt().is_none());
689 }
690
691 #[test]
692 #[should_panic(expected = "DSA has no p parameter")]
693 fn p_panics_without_params() {
694 dsa_without_params().p();
695 }
696}