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 ffi::DSA_up_ref(self.as_ptr());
76 Dsa::from_ptr(self.as_ptr())
77 }
78 }
79}
80
81impl<T> DsaRef<T>
82where
83 T: HasPublic,
84{
85 to_pem! {
86 #[corresponds(PEM_write_bio_DSA_PUBKEY)]
90 public_key_to_pem,
91 ffi::PEM_write_bio_DSA_PUBKEY
92 }
93
94 to_der! {
95 #[corresponds(i2d_DSA_PUBKEY)]
97 public_key_to_der,
98 ffi::i2d_DSA_PUBKEY
99 }
100
101 #[corresponds(DSA_get0_key)]
103 pub fn pub_key(&self) -> &BigNumRef {
104 unsafe {
105 let mut pub_key = ptr::null();
106 DSA_get0_key(self.as_ptr(), &mut pub_key, ptr::null_mut());
107 BigNumRef::from_const_ptr(pub_key)
108 }
109 }
110}
111
112impl<T> DsaRef<T>
113where
114 T: HasPrivate,
115{
116 private_key_to_pem! {
117 #[corresponds(PEM_write_bio_DSAPrivateKey)]
121 private_key_to_pem,
122 #[corresponds(PEM_write_bio_DSAPrivateKey)]
126 private_key_to_pem_passphrase,
127 ffi::PEM_write_bio_DSAPrivateKey
128 }
129
130 to_der! {
131 #[corresponds(i2d_DSAPrivateKey)]
133 private_key_to_der,
134 ffi::i2d_DSAPrivateKey
135 }
136
137 #[corresponds(DSA_get0_key)]
139 pub fn priv_key(&self) -> &BigNumRef {
140 unsafe {
141 let mut priv_key = ptr::null();
142 DSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut priv_key);
143 BigNumRef::from_const_ptr(priv_key)
144 }
145 }
146}
147
148impl<T> DsaRef<T>
149where
150 T: HasParams,
151{
152 #[corresponds(DSA_size)]
154 pub fn size(&self) -> u32 {
155 unsafe { ffi::DSA_size(self.as_ptr()) as u32 }
156 }
157
158 #[corresponds(DSA_get0_pqg)]
160 pub fn p(&self) -> &BigNumRef {
161 unsafe {
162 let mut p = ptr::null();
163 DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut());
164 BigNumRef::from_const_ptr(p)
165 }
166 }
167
168 #[corresponds(DSA_get0_pqg)]
170 pub fn q(&self) -> &BigNumRef {
171 unsafe {
172 let mut q = ptr::null();
173 DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut());
174 BigNumRef::from_const_ptr(q)
175 }
176 }
177
178 #[corresponds(DSA_get0_pqg)]
180 pub fn g(&self) -> &BigNumRef {
181 unsafe {
182 let mut g = ptr::null();
183 DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g);
184 BigNumRef::from_const_ptr(g)
185 }
186 }
187}
188#[cfg(any(boringssl, awslc))]
189type BitType = libc::c_uint;
190#[cfg(not(any(boringssl, awslc)))]
191type BitType = c_int;
192
193impl Dsa<Params> {
194 #[corresponds(DSA_set0_pqg)]
196 pub fn from_pqg(p: BigNum, q: BigNum, g: BigNum) -> Result<Dsa<Params>, ErrorStack> {
197 unsafe {
198 let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
199 cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
200 mem::forget((p, q, g));
201 Ok(dsa)
202 }
203 }
204
205 #[corresponds(DSA_generate_parameters_ex)]
207 pub fn generate_params(bits: u32) -> Result<Dsa<Params>, ErrorStack> {
208 ffi::init();
209 unsafe {
210 let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
211 cvt(ffi::DSA_generate_parameters_ex(
212 dsa.0,
213 bits as BitType,
214 ptr::null(),
215 0,
216 ptr::null_mut(),
217 ptr::null_mut(),
218 ptr::null_mut(),
219 ))?;
220 Ok(dsa)
221 }
222 }
223
224 #[corresponds(DSA_generate_key)]
226 pub fn generate_key(self) -> Result<Dsa<Private>, ErrorStack> {
227 unsafe {
228 let dsa_ptr = self.0;
229 cvt(ffi::DSA_generate_key(dsa_ptr))?;
230 mem::forget(self);
231 Ok(Dsa::from_ptr(dsa_ptr))
232 }
233 }
234}
235
236impl Dsa<Private> {
237 pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
241 let params = Dsa::generate_params(bits)?;
242 params.generate_key()
243 }
244
245 pub fn from_private_components(
251 p: BigNum,
252 q: BigNum,
253 g: BigNum,
254 priv_key: BigNum,
255 pub_key: BigNum,
256 ) -> Result<Dsa<Private>, ErrorStack> {
257 ffi::init();
258 unsafe {
259 let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
260 cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
261 mem::forget((p, q, g));
262 cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), priv_key.as_ptr()))?;
263 mem::forget((pub_key, priv_key));
264 Ok(dsa)
265 }
266 }
267}
268
269impl Dsa<Public> {
270 from_pem! {
271 #[corresponds(PEM_read_bio_DSA_PUBKEY)]
275 public_key_from_pem,
276 Dsa<Public>,
277 ffi::PEM_read_bio_DSA_PUBKEY
278 }
279
280 from_der! {
281 #[corresponds(d2i_DSA_PUBKEY)]
283 public_key_from_der,
284 Dsa<Public>,
285 ffi::d2i_DSA_PUBKEY
286 }
287
288 pub fn from_public_components(
293 p: BigNum,
294 q: BigNum,
295 g: BigNum,
296 pub_key: BigNum,
297 ) -> Result<Dsa<Public>, ErrorStack> {
298 ffi::init();
299 unsafe {
300 let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
301 cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
302 mem::forget((p, q, g));
303 cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), ptr::null_mut()))?;
304 mem::forget(pub_key);
305 Ok(dsa)
306 }
307 }
308}
309
310impl<T> fmt::Debug for Dsa<T> {
311 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
312 write!(f, "DSA")
313 }
314}
315
316use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg};
317
318foreign_type_and_impl_send_sync! {
319 type CType = ffi::DSA_SIG;
320 fn drop = ffi::DSA_SIG_free;
321
322 pub struct DsaSig;
371
372 pub struct DsaSigRef;
374}
375
376impl DsaSig {
377 #[corresponds(DSA_SIG_set0)]
379 pub fn from_private_components(r: BigNum, s: BigNum) -> Result<Self, ErrorStack> {
380 unsafe {
381 let sig = cvt_p(ffi::DSA_SIG_new())?;
382 DSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
383 mem::forget((r, s));
384 Ok(DsaSig::from_ptr(sig))
385 }
386 }
387
388 from_der! {
389 #[corresponds(d2i_DSA_SIG)]
391 from_der,
392 DsaSig,
393 ffi::d2i_DSA_SIG
394 }
395}
396
397impl fmt::Debug for DsaSig {
398 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
399 f.debug_struct("DsaSig")
400 .field("r", self.r())
401 .field("s", self.s())
402 .finish()
403 }
404}
405
406impl DsaSigRef {
407 to_der! {
408 #[corresponds(i2d_DSA_SIG)]
410 to_der,
411 ffi::i2d_DSA_SIG
412 }
413
414 #[corresponds(DSA_SIG_get0)]
416 pub fn r(&self) -> &BigNumRef {
417 unsafe {
418 let mut r = ptr::null();
419 DSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
420 BigNumRef::from_const_ptr(r)
421 }
422 }
423
424 #[corresponds(DSA_SIG_get0)]
426 pub fn s(&self) -> &BigNumRef {
427 unsafe {
428 let mut s = ptr::null();
429 DSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
430 BigNumRef::from_const_ptr(s)
431 }
432 }
433}
434
435use ffi::{DSA_SIG_get0, DSA_SIG_set0};
436
437#[cfg(test)]
438mod test {
439 use super::*;
440 use crate::bn::BigNumContext;
441 #[cfg(not(any(boringssl, awslc_fips)))]
442 use crate::hash::MessageDigest;
443 #[cfg(not(any(boringssl, awslc_fips)))]
444 use crate::pkey::PKey;
445 #[cfg(not(any(boringssl, awslc_fips)))]
446 use crate::sign::{Signer, Verifier};
447
448 #[test]
449 pub fn test_generate() {
450 Dsa::generate(1024).unwrap();
451 }
452
453 #[test]
454 fn test_pubkey_generation() {
455 let dsa = Dsa::generate(1024).unwrap();
456 let p = dsa.p();
457 let g = dsa.g();
458 let priv_key = dsa.priv_key();
459 let pub_key = dsa.pub_key();
460 let mut ctx = BigNumContext::new().unwrap();
461 let mut calc = BigNum::new().unwrap();
462 calc.mod_exp(g, priv_key, p, &mut ctx).unwrap();
463 assert_eq!(&calc, pub_key)
464 }
465
466 #[test]
467 fn test_priv_key_from_parts() {
468 let p = BigNum::from_u32(283).unwrap();
469 let q = BigNum::from_u32(47).unwrap();
470 let g = BigNum::from_u32(60).unwrap();
471 let priv_key = BigNum::from_u32(15).unwrap();
472 let pub_key = BigNum::from_u32(207).unwrap();
473
474 let dsa = Dsa::from_private_components(p, q, g, priv_key, pub_key).unwrap();
475 assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
476 assert_eq!(dsa.priv_key(), &BigNum::from_u32(15).unwrap());
477 assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
478 assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
479 assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
480 }
481
482 #[test]
483 fn test_pub_key_from_parts() {
484 let p = BigNum::from_u32(283).unwrap();
485 let q = BigNum::from_u32(47).unwrap();
486 let g = BigNum::from_u32(60).unwrap();
487 let pub_key = BigNum::from_u32(207).unwrap();
488
489 let dsa = Dsa::from_public_components(p, q, g, pub_key).unwrap();
490 assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
491 assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
492 assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
493 assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
494 }
495
496 #[test]
497 fn test_params() {
498 let params = Dsa::generate_params(1024).unwrap();
499 let p = params.p().to_owned().unwrap();
500 let q = params.q().to_owned().unwrap();
501 let g = params.g().to_owned().unwrap();
502 let key = params.generate_key().unwrap();
503 let params2 = Dsa::from_pqg(
504 key.p().to_owned().unwrap(),
505 key.q().to_owned().unwrap(),
506 key.g().to_owned().unwrap(),
507 )
508 .unwrap();
509 assert_eq!(p, *params2.p());
510 assert_eq!(q, *params2.q());
511 assert_eq!(g, *params2.g());
512 }
513
514 #[test]
515 #[cfg(not(any(boringssl, awslc_fips)))]
516 fn test_signature() {
517 const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
518 let dsa_ref = Dsa::generate(1024).unwrap();
519
520 let p = dsa_ref.p();
521 let q = dsa_ref.q();
522 let g = dsa_ref.g();
523
524 let pub_key = dsa_ref.pub_key();
525 let priv_key = dsa_ref.priv_key();
526
527 let priv_key = Dsa::from_private_components(
528 BigNumRef::to_owned(p).unwrap(),
529 BigNumRef::to_owned(q).unwrap(),
530 BigNumRef::to_owned(g).unwrap(),
531 BigNumRef::to_owned(priv_key).unwrap(),
532 BigNumRef::to_owned(pub_key).unwrap(),
533 )
534 .unwrap();
535 let priv_key = PKey::from_dsa(priv_key).unwrap();
536
537 let pub_key = Dsa::from_public_components(
538 BigNumRef::to_owned(p).unwrap(),
539 BigNumRef::to_owned(q).unwrap(),
540 BigNumRef::to_owned(g).unwrap(),
541 BigNumRef::to_owned(pub_key).unwrap(),
542 )
543 .unwrap();
544 let pub_key = PKey::from_dsa(pub_key).unwrap();
545
546 let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
547 signer.update(TEST_DATA).unwrap();
548
549 let signature = signer.sign_to_vec().unwrap();
550 let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
551 verifier.update(TEST_DATA).unwrap();
552 assert!(verifier.verify(&signature[..]).unwrap());
553 }
554
555 #[test]
556 #[cfg(not(any(boringssl, awslc_fips)))]
557 fn test_signature_der() {
558 use std::convert::TryInto;
559
560 const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
561 let dsa_ref = Dsa::generate(1024).unwrap();
562
563 let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap();
564 let priv_key: PKey<_> = dsa_ref.try_into().unwrap();
565
566 let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
567 signer.update(TEST_DATA).unwrap();
568
569 let signature = signer.sign_to_vec().unwrap();
570 eprintln!("{:?}", signature);
571 let signature = DsaSig::from_der(&signature).unwrap();
572
573 let r = BigNum::from_slice(&signature.r().to_vec()).unwrap();
574 let s = BigNum::from_slice(&signature.s().to_vec()).unwrap();
575
576 let signature = DsaSig::from_private_components(r, s).unwrap();
577 let signature = signature.to_der().unwrap();
578
579 let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
580 verifier.update(TEST_DATA).unwrap();
581 assert!(verifier.verify(&signature[..]).unwrap());
582 }
583
584 #[test]
585 #[allow(clippy::redundant_clone)]
586 fn clone() {
587 let key = Dsa::generate(2048).unwrap();
588 drop(key.clone());
589 }
590
591 #[test]
592 fn dsa_sig_debug() {
593 let sig = DsaSig::from_der(&[
594 48, 46, 2, 21, 0, 135, 169, 24, 58, 153, 37, 175, 248, 200, 45, 251, 112, 238, 238, 89,
595 172, 177, 182, 166, 237, 2, 21, 0, 159, 146, 151, 237, 187, 8, 82, 115, 14, 183, 103,
596 12, 203, 46, 161, 208, 251, 167, 123, 131,
597 ])
598 .unwrap();
599 let s = format!("{:?}", sig);
600 assert_eq!(s, "DsaSig { r: 774484690634577222213819810519929266740561094381, s: 910998676210681457251421818099943952372231273347 }");
601 }
602}