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)]
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
317use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg};
318
319foreign_type_and_impl_send_sync! {
320 type CType = ffi::DSA_SIG;
321 fn drop = ffi::DSA_SIG_free;
322
323 pub struct DsaSig;
372
373 pub struct DsaSigRef;
375}
376
377impl DsaSig {
378 #[corresponds(DSA_SIG_set0)]
380 pub fn from_private_components(r: BigNum, s: BigNum) -> Result<Self, ErrorStack> {
381 unsafe {
382 let sig = cvt_p(ffi::DSA_SIG_new())?;
383 DSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
384 mem::forget((r, s));
385 Ok(DsaSig::from_ptr(sig))
386 }
387 }
388
389 from_der! {
390 #[corresponds(d2i_DSA_SIG)]
392 from_der,
393 DsaSig,
394 ffi::d2i_DSA_SIG
395 }
396}
397
398impl fmt::Debug for DsaSig {
399 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
400 f.debug_struct("DsaSig")
401 .field("r", self.r())
402 .field("s", self.s())
403 .finish()
404 }
405}
406
407impl DsaSigRef {
408 to_der! {
409 #[corresponds(i2d_DSA_SIG)]
411 to_der,
412 ffi::i2d_DSA_SIG
413 }
414
415 #[corresponds(DSA_SIG_get0)]
417 pub fn r(&self) -> &BigNumRef {
418 unsafe {
419 let mut r = ptr::null();
420 DSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
421 BigNumRef::from_const_ptr(r)
422 }
423 }
424
425 #[corresponds(DSA_SIG_get0)]
427 pub fn s(&self) -> &BigNumRef {
428 unsafe {
429 let mut s = ptr::null();
430 DSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
431 BigNumRef::from_const_ptr(s)
432 }
433 }
434}
435
436use ffi::{DSA_SIG_get0, DSA_SIG_set0};
437
438#[cfg(test)]
439mod test {
440 use super::*;
441 use crate::bn::BigNumContext;
442 #[cfg(not(any(boringssl, awslc_fips)))]
443 use crate::hash::MessageDigest;
444 #[cfg(not(any(boringssl, awslc_fips)))]
445 use crate::pkey::PKey;
446 #[cfg(not(any(boringssl, awslc_fips)))]
447 use crate::sign::{Signer, Verifier};
448
449 #[test]
450 pub fn test_generate() {
451 Dsa::generate(1024).unwrap();
452 }
453
454 #[test]
455 fn test_pubkey_generation() {
456 let dsa = Dsa::generate(1024).unwrap();
457 let p = dsa.p();
458 let g = dsa.g();
459 let priv_key = dsa.priv_key();
460 let pub_key = dsa.pub_key();
461 let mut ctx = BigNumContext::new().unwrap();
462 let mut calc = BigNum::new().unwrap();
463 calc.mod_exp(g, priv_key, p, &mut ctx).unwrap();
464 assert_eq!(&calc, pub_key)
465 }
466
467 #[test]
468 fn test_priv_key_from_parts() {
469 let p = BigNum::from_u32(283).unwrap();
470 let q = BigNum::from_u32(47).unwrap();
471 let g = BigNum::from_u32(60).unwrap();
472 let priv_key = BigNum::from_u32(15).unwrap();
473 let pub_key = BigNum::from_u32(207).unwrap();
474
475 let dsa = Dsa::from_private_components(p, q, g, priv_key, pub_key).unwrap();
476 assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
477 assert_eq!(dsa.priv_key(), &BigNum::from_u32(15).unwrap());
478 assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
479 assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
480 assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
481 }
482
483 #[test]
484 fn test_pub_key_from_parts() {
485 let p = BigNum::from_u32(283).unwrap();
486 let q = BigNum::from_u32(47).unwrap();
487 let g = BigNum::from_u32(60).unwrap();
488 let pub_key = BigNum::from_u32(207).unwrap();
489
490 let dsa = Dsa::from_public_components(p, q, g, pub_key).unwrap();
491 assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
492 assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
493 assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
494 assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
495 }
496
497 #[test]
498 fn test_params() {
499 let params = Dsa::generate_params(1024).unwrap();
500 let p = params.p().to_owned().unwrap();
501 let q = params.q().to_owned().unwrap();
502 let g = params.g().to_owned().unwrap();
503 let key = params.generate_key().unwrap();
504 let params2 = Dsa::from_pqg(
505 key.p().to_owned().unwrap(),
506 key.q().to_owned().unwrap(),
507 key.g().to_owned().unwrap(),
508 )
509 .unwrap();
510 assert_eq!(p, *params2.p());
511 assert_eq!(q, *params2.q());
512 assert_eq!(g, *params2.g());
513 }
514
515 #[test]
516 #[cfg(not(any(boringssl, awslc_fips)))]
517 fn test_signature() {
518 const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
519 let dsa_ref = Dsa::generate(1024).unwrap();
520
521 let p = dsa_ref.p();
522 let q = dsa_ref.q();
523 let g = dsa_ref.g();
524
525 let pub_key = dsa_ref.pub_key();
526 let priv_key = dsa_ref.priv_key();
527
528 let priv_key = Dsa::from_private_components(
529 BigNumRef::to_owned(p).unwrap(),
530 BigNumRef::to_owned(q).unwrap(),
531 BigNumRef::to_owned(g).unwrap(),
532 BigNumRef::to_owned(priv_key).unwrap(),
533 BigNumRef::to_owned(pub_key).unwrap(),
534 )
535 .unwrap();
536 let priv_key = PKey::from_dsa(priv_key).unwrap();
537
538 let pub_key = Dsa::from_public_components(
539 BigNumRef::to_owned(p).unwrap(),
540 BigNumRef::to_owned(q).unwrap(),
541 BigNumRef::to_owned(g).unwrap(),
542 BigNumRef::to_owned(pub_key).unwrap(),
543 )
544 .unwrap();
545 let pub_key = PKey::from_dsa(pub_key).unwrap();
546
547 let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
548 signer.update(TEST_DATA).unwrap();
549
550 let signature = signer.sign_to_vec().unwrap();
551 let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
552 verifier.update(TEST_DATA).unwrap();
553 assert!(verifier.verify(&signature[..]).unwrap());
554 }
555
556 #[test]
557 #[cfg(not(any(boringssl, awslc_fips)))]
558 fn test_signature_der() {
559 use std::convert::TryInto;
560
561 const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
562 let dsa_ref = Dsa::generate(1024).unwrap();
563
564 let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap();
565 let priv_key: PKey<_> = dsa_ref.try_into().unwrap();
566
567 let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
568 signer.update(TEST_DATA).unwrap();
569
570 let signature = signer.sign_to_vec().unwrap();
571 eprintln!("{:?}", signature);
572 let signature = DsaSig::from_der(&signature).unwrap();
573
574 let r = BigNum::from_slice(&signature.r().to_vec()).unwrap();
575 let s = BigNum::from_slice(&signature.s().to_vec()).unwrap();
576
577 let signature = DsaSig::from_private_components(r, s).unwrap();
578 let signature = signature.to_der().unwrap();
579
580 let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
581 verifier.update(TEST_DATA).unwrap();
582 assert!(verifier.verify(&signature[..]).unwrap());
583 }
584
585 #[test]
586 #[allow(clippy::redundant_clone)]
587 fn clone() {
588 let key = Dsa::generate(2048).unwrap();
589 drop(key.clone());
590 }
591
592 #[test]
593 fn dsa_sig_debug() {
594 let sig = DsaSig::from_der(&[
595 48, 46, 2, 21, 0, 135, 169, 24, 58, 153, 37, 175, 248, 200, 45, 251, 112, 238, 238, 89,
596 172, 177, 182, 166, 237, 2, 21, 0, 159, 146, 151, 237, 187, 8, 82, 115, 14, 183, 103,
597 12, 203, 46, 161, 208, 251, 167, 123, 131,
598 ])
599 .unwrap();
600 let s = format!("{:?}", sig);
601 assert_eq!(s, "DsaSig { r: 774484690634577222213819810519929266740561094381, s: 910998676210681457251421818099943952372231273347 }");
602 }
603}