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            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        /// Serializes the public key into a PEM-encoded SubjectPublicKeyInfo structure.
87        ///
88        /// The output will have a header of `-----BEGIN PUBLIC KEY-----`.
89        #[corresponds(PEM_write_bio_DSA_PUBKEY)]
90        public_key_to_pem,
91        ffi::PEM_write_bio_DSA_PUBKEY
92    }
93
94    to_der! {
95        /// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure.
96        #[corresponds(i2d_DSA_PUBKEY)]
97        public_key_to_der,
98        ffi::i2d_DSA_PUBKEY
99    }
100
101    /// Returns a reference to the public key component of `self`.
102    #[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        /// Serializes the private key to a PEM-encoded DSAPrivateKey structure.
118        ///
119        /// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`.
120        #[corresponds(PEM_write_bio_DSAPrivateKey)]
121        private_key_to_pem,
122        /// Serializes the private key to a PEM-encoded encrypted DSAPrivateKey structure.
123        ///
124        /// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`.
125        #[corresponds(PEM_write_bio_DSAPrivateKey)]
126        private_key_to_pem_passphrase,
127        ffi::PEM_write_bio_DSAPrivateKey
128    }
129
130    to_der! {
131        /// Serializes the private_key to a DER-encoded `DSAPrivateKey` structure.
132        #[corresponds(i2d_DSAPrivateKey)]
133        private_key_to_der,
134        ffi::i2d_DSAPrivateKey
135    }
136
137    /// Returns a reference to the private key component of `self`.
138    #[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    /// Returns the maximum size of the signature output by `self` in bytes.
153    #[corresponds(DSA_size)]
154    pub fn size(&self) -> u32 {
155        unsafe { ffi::DSA_size(self.as_ptr()) as u32 }
156    }
157
158    /// Returns the DSA prime parameter of `self`.
159    #[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    /// Returns the DSA sub-prime parameter of `self`.
169    #[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    /// Returns the DSA base parameter of `self`.
179    #[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    /// Creates a DSA params based upon the given parameters.
195    #[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    /// Generates DSA params based on the given number of bits.
206    #[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    /// Generates a private key based on the DSA params.
225    #[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    /// Generate a DSA key pair.
238    ///
239    /// The `bits` parameter corresponds to the length of the prime `p`.
240    pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
241        let params = Dsa::generate_params(bits)?;
242        params.generate_key()
243    }
244
245    /// Create a DSA key pair with the given parameters
246    ///
247    /// `p`, `q` and `g` are the common parameters.
248    /// `priv_key` is the private component of the key pair.
249    /// `pub_key` is the public component of the key. Can be computed via `g^(priv_key) mod p`
250    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        /// Decodes a PEM-encoded SubjectPublicKeyInfo structure containing a DSA key.
272        ///
273        /// The input should have a header of `-----BEGIN PUBLIC KEY-----`.
274        #[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        /// Decodes a DER-encoded SubjectPublicKeyInfo structure containing a DSA key.
282        #[corresponds(d2i_DSA_PUBKEY)]
283        public_key_from_der,
284        Dsa<Public>,
285        ffi::d2i_DSA_PUBKEY
286    }
287
288    /// Create a new DSA key with only public components.
289    ///
290    /// `p`, `q` and `g` are the common parameters.
291    /// `pub_key` is the public component of the key.
292    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    /// Object representing DSA signature.
323    ///
324    /// DSA signatures consist of two components: `r` and `s`.
325    ///
326    /// # Examples
327    ///
328    /// ```
329    /// use std::convert::TryInto;
330    ///
331    /// use openssl::bn::BigNum;
332    /// use openssl::dsa::{Dsa, DsaSig};
333    /// use openssl::hash::MessageDigest;
334    /// use openssl::pkey::PKey;
335    /// use openssl::sign::{Signer, Verifier};
336    ///
337    /// const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
338    /// let dsa_ref = Dsa::generate(1024).unwrap();
339    ///
340    /// let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap();
341    /// let priv_key: PKey<_> = dsa_ref.try_into().unwrap();
342    ///
343    /// let mut signer = if let Ok(signer) = Signer::new(MessageDigest::sha256(), &priv_key) {
344    ///     signer
345    /// } else {
346    ///     // DSA signing is not supported (eg. BoringSSL)
347    ///     return;
348    /// };
349    ///
350    /// signer.update(TEST_DATA).unwrap();
351    ///
352    /// let signature = signer.sign_to_vec().unwrap();
353    /// // Parse DER-encoded DSA signature
354    /// let signature = DsaSig::from_der(&signature).unwrap();
355    ///
356    /// // Extract components `r` and `s`
357    /// let r = BigNum::from_slice(&signature.r().to_vec()).unwrap();
358    /// let s = BigNum::from_slice(&signature.s().to_vec()).unwrap();
359    ///
360    /// // Construct new DSA signature from components
361    /// let signature = DsaSig::from_private_components(r, s).unwrap();
362    ///
363    /// // Serialize DSA signature to DER
364    /// let signature = signature.to_der().unwrap();
365    ///
366    /// let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
367    /// verifier.update(TEST_DATA).unwrap();
368    /// assert!(verifier.verify(&signature[..]).unwrap());
369    /// ```
370    pub struct DsaSig;
371
372    /// Reference to a [`DsaSig`].
373    pub struct DsaSigRef;
374}
375
376impl DsaSig {
377    /// Returns a new `DsaSig` by setting the `r` and `s` values associated with an DSA signature.
378    #[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        /// Decodes a DER-encoded DSA signature.
390        #[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        /// Serializes the DSA signature into a DER-encoded `DSASignature` structure.
409        #[corresponds(i2d_DSA_SIG)]
410        to_der,
411        ffi::i2d_DSA_SIG
412    }
413
414    /// Returns internal component `r` of an `DsaSig`.
415    #[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    /// Returns internal component `s` of an `DsaSig`.
425    #[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}