Skip to main content

variant_ssl/
dsa.rs

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 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    /// Object representing DSA keys.
27    ///
28    /// A DSA object contains the parameters p, q, and g.  There is a private
29    /// and public key.  The values p, g, and q are:
30    ///
31    /// * `p`: DSA prime parameter
32    /// * `q`: DSA sub-prime parameter
33    /// * `g`: DSA base parameter
34    ///
35    /// These values are used to calculate a pair of asymmetrical keys used for
36    /// signing.
37    ///
38    /// OpenSSL documentation at [`DSA_new`]
39    ///
40    /// [`DSA_new`]: https://docs.openssl.org/master/man3/DSA_new/
41    ///
42    /// # Examples
43    ///
44    /// ```
45    /// use openssl::dsa::Dsa;
46    /// use openssl::error::ErrorStack;
47    /// use openssl::pkey::Private;
48    ///
49    /// fn create_dsa() -> Result<Dsa<Private>, ErrorStack> {
50    ///     let sign = Dsa::generate(2048)?;
51    ///     Ok(sign)
52    /// }
53    /// # fn main() {
54    /// #    create_dsa();
55    /// # }
56    /// ```
57    pub struct Dsa<T>;
58    /// Reference to [`Dsa`].
59    ///
60    /// [`Dsa`]: struct.Dsa.html
61    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        /// 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(any(boringssl, awslc))]
190type BitType = libc::c_uint;
191#[cfg(not(any(boringssl, awslc)))]
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
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    /// Object representing DSA signature.
324    ///
325    /// DSA signatures consist of two components: `r` and `s`.
326    ///
327    /// # Examples
328    ///
329    /// ```
330    /// use std::convert::TryInto;
331    ///
332    /// use openssl::bn::BigNum;
333    /// use openssl::dsa::{Dsa, DsaSig};
334    /// use openssl::hash::MessageDigest;
335    /// use openssl::pkey::PKey;
336    /// use openssl::sign::{Signer, Verifier};
337    ///
338    /// const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
339    /// let dsa_ref = Dsa::generate(1024).unwrap();
340    ///
341    /// let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap();
342    /// let priv_key: PKey<_> = dsa_ref.try_into().unwrap();
343    ///
344    /// let mut signer = if let Ok(signer) = Signer::new(MessageDigest::sha256(), &priv_key) {
345    ///     signer
346    /// } else {
347    ///     // DSA signing is not supported (eg. BoringSSL)
348    ///     return;
349    /// };
350    ///
351    /// signer.update(TEST_DATA).unwrap();
352    ///
353    /// let signature = signer.sign_to_vec().unwrap();
354    /// // Parse DER-encoded DSA signature
355    /// let signature = DsaSig::from_der(&signature).unwrap();
356    ///
357    /// // Extract components `r` and `s`
358    /// let r = BigNum::from_slice(&signature.r().to_vec()).unwrap();
359    /// let s = BigNum::from_slice(&signature.s().to_vec()).unwrap();
360    ///
361    /// // Construct new DSA signature from components
362    /// let signature = DsaSig::from_private_components(r, s).unwrap();
363    ///
364    /// // Serialize DSA signature to DER
365    /// let signature = signature.to_der().unwrap();
366    ///
367    /// let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
368    /// verifier.update(TEST_DATA).unwrap();
369    /// assert!(verifier.verify(&signature[..]).unwrap());
370    /// ```
371    pub struct DsaSig;
372
373    /// Reference to a [`DsaSig`].
374    pub struct DsaSigRef;
375}
376
377impl DsaSig {
378    /// Returns a new `DsaSig` by setting the `r` and `s` values associated with an DSA signature.
379    #[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        /// Decodes a DER-encoded DSA signature.
391        #[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        /// Serializes the DSA signature into a DER-encoded `DSASignature` structure.
410        #[corresponds(i2d_DSA_SIG)]
411        to_der,
412        ffi::i2d_DSA_SIG
413    }
414
415    /// Returns internal component `r` of an `DsaSig`.
416    #[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    /// Returns internal component `s` of an `DsaSig`.
426    #[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}