summaryrefslogtreecommitdiffstats
path: root/vendor/openssl/src/dsa.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/openssl/src/dsa.rs')
-rw-r--r--vendor/openssl/src/dsa.rs697
1 files changed, 697 insertions, 0 deletions
diff --git a/vendor/openssl/src/dsa.rs b/vendor/openssl/src/dsa.rs
new file mode 100644
index 0000000..1a63e8a
--- /dev/null
+++ b/vendor/openssl/src/dsa.rs
@@ -0,0 +1,697 @@
+//! Digital Signatures
+//!
+//! DSA ensures a message originated from a known sender, and was not modified.
+//! DSA uses asymmetrical keys and an algorithm to output a signature of the message
+//! using the private key that can be validated with the public key but not be generated
+//! without the private key.
+
+use cfg_if::cfg_if;
+use foreign_types::{ForeignType, ForeignTypeRef};
+#[cfg(not(boringssl))]
+use libc::c_int;
+use std::fmt;
+use std::mem;
+use std::ptr;
+
+use crate::bn::{BigNum, BigNumRef};
+use crate::error::ErrorStack;
+use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
+use crate::util::ForeignTypeRefExt;
+use crate::{cvt, cvt_p};
+use openssl_macros::corresponds;
+
+generic_foreign_type_and_impl_send_sync! {
+ type CType = ffi::DSA;
+ fn drop = ffi::DSA_free;
+
+ /// Object representing DSA keys.
+ ///
+ /// A DSA object contains the parameters p, q, and g. There is a private
+ /// and public key. The values p, g, and q are:
+ ///
+ /// * `p`: DSA prime parameter
+ /// * `q`: DSA sub-prime parameter
+ /// * `g`: DSA base parameter
+ ///
+ /// These values are used to calculate a pair of asymmetrical keys used for
+ /// signing.
+ ///
+ /// OpenSSL documentation at [`DSA_new`]
+ ///
+ /// [`DSA_new`]: https://www.openssl.org/docs/manmaster/crypto/DSA_new.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use openssl::dsa::Dsa;
+ /// use openssl::error::ErrorStack;
+ /// use openssl::pkey::Private;
+ ///
+ /// fn create_dsa() -> Result<Dsa<Private>, ErrorStack> {
+ /// let sign = Dsa::generate(2048)?;
+ /// Ok(sign)
+ /// }
+ /// # fn main() {
+ /// # create_dsa();
+ /// # }
+ /// ```
+ pub struct Dsa<T>;
+ /// Reference to [`Dsa`].
+ ///
+ /// [`Dsa`]: struct.Dsa.html
+ pub struct DsaRef<T>;
+}
+
+impl<T> Clone for Dsa<T> {
+ fn clone(&self) -> Dsa<T> {
+ (**self).to_owned()
+ }
+}
+
+impl<T> ToOwned for DsaRef<T> {
+ type Owned = Dsa<T>;
+
+ fn to_owned(&self) -> Dsa<T> {
+ unsafe {
+ ffi::DSA_up_ref(self.as_ptr());
+ Dsa::from_ptr(self.as_ptr())
+ }
+ }
+}
+
+impl<T> DsaRef<T>
+where
+ T: HasPublic,
+{
+ to_pem! {
+ /// Serializes the public key into a PEM-encoded SubjectPublicKeyInfo structure.
+ ///
+ /// The output will have a header of `-----BEGIN PUBLIC KEY-----`.
+ #[corresponds(PEM_write_bio_DSA_PUBKEY)]
+ public_key_to_pem,
+ ffi::PEM_write_bio_DSA_PUBKEY
+ }
+
+ to_der! {
+ /// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure.
+ #[corresponds(i2d_DSA_PUBKEY)]
+ public_key_to_der,
+ ffi::i2d_DSA_PUBKEY
+ }
+
+ /// Returns a reference to the public key component of `self`.
+ #[corresponds(DSA_get0_key)]
+ pub fn pub_key(&self) -> &BigNumRef {
+ unsafe {
+ let mut pub_key = ptr::null();
+ DSA_get0_key(self.as_ptr(), &mut pub_key, ptr::null_mut());
+ BigNumRef::from_const_ptr(pub_key)
+ }
+ }
+}
+
+impl<T> DsaRef<T>
+where
+ T: HasPrivate,
+{
+ private_key_to_pem! {
+ /// Serializes the private key to a PEM-encoded DSAPrivateKey structure.
+ ///
+ /// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`.
+ #[corresponds(PEM_write_bio_DSAPrivateKey)]
+ private_key_to_pem,
+ /// Serializes the private key to a PEM-encoded encrypted DSAPrivateKey structure.
+ ///
+ /// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`.
+ #[corresponds(PEM_write_bio_DSAPrivateKey)]
+ private_key_to_pem_passphrase,
+ ffi::PEM_write_bio_DSAPrivateKey
+ }
+
+ to_der! {
+ /// Serializes the private_key to a DER-encoded `DSAPrivateKey` structure.
+ #[corresponds(i2d_DSAPrivateKey)]
+ private_key_to_der,
+ ffi::i2d_DSAPrivateKey
+ }
+
+ /// Returns a reference to the private key component of `self`.
+ #[corresponds(DSA_get0_key)]
+ pub fn priv_key(&self) -> &BigNumRef {
+ unsafe {
+ let mut priv_key = ptr::null();
+ DSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut priv_key);
+ BigNumRef::from_const_ptr(priv_key)
+ }
+ }
+}
+
+impl<T> DsaRef<T>
+where
+ T: HasParams,
+{
+ /// Returns the maximum size of the signature output by `self` in bytes.
+ #[corresponds(DSA_size)]
+ pub fn size(&self) -> u32 {
+ unsafe { ffi::DSA_size(self.as_ptr()) as u32 }
+ }
+
+ /// Returns the DSA prime parameter of `self`.
+ #[corresponds(DSA_get0_pqg)]
+ pub fn p(&self) -> &BigNumRef {
+ unsafe {
+ let mut p = ptr::null();
+ DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut());
+ BigNumRef::from_const_ptr(p)
+ }
+ }
+
+ /// Returns the DSA sub-prime parameter of `self`.
+ #[corresponds(DSA_get0_pqg)]
+ pub fn q(&self) -> &BigNumRef {
+ unsafe {
+ let mut q = ptr::null();
+ DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut());
+ BigNumRef::from_const_ptr(q)
+ }
+ }
+
+ /// Returns the DSA base parameter of `self`.
+ #[corresponds(DSA_get0_pqg)]
+ pub fn g(&self) -> &BigNumRef {
+ unsafe {
+ let mut g = ptr::null();
+ DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g);
+ BigNumRef::from_const_ptr(g)
+ }
+ }
+}
+#[cfg(boringssl)]
+type BitType = libc::c_uint;
+#[cfg(not(boringssl))]
+type BitType = c_int;
+
+impl Dsa<Params> {
+ /// Creates a DSA params based upon the given parameters.
+ #[corresponds(DSA_set0_pqg)]
+ pub fn from_pqg(p: BigNum, q: BigNum, g: BigNum) -> Result<Dsa<Params>, ErrorStack> {
+ unsafe {
+ let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
+ cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
+ mem::forget((p, q, g));
+ Ok(dsa)
+ }
+ }
+
+ /// Generates DSA params based on the given number of bits.
+ #[corresponds(DSA_generate_parameters_ex)]
+ pub fn generate_params(bits: u32) -> Result<Dsa<Params>, ErrorStack> {
+ ffi::init();
+ unsafe {
+ let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
+ cvt(ffi::DSA_generate_parameters_ex(
+ dsa.0,
+ bits as BitType,
+ ptr::null(),
+ 0,
+ ptr::null_mut(),
+ ptr::null_mut(),
+ ptr::null_mut(),
+ ))?;
+ Ok(dsa)
+ }
+ }
+
+ /// Generates a private key based on the DSA params.
+ #[corresponds(DSA_generate_key)]
+ pub fn generate_key(self) -> Result<Dsa<Private>, ErrorStack> {
+ unsafe {
+ let dsa_ptr = self.0;
+ cvt(ffi::DSA_generate_key(dsa_ptr))?;
+ mem::forget(self);
+ Ok(Dsa::from_ptr(dsa_ptr))
+ }
+ }
+}
+
+impl Dsa<Private> {
+ /// Generate a DSA key pair.
+ ///
+ /// The `bits` parameter corresponds to the length of the prime `p`.
+ pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
+ let params = Dsa::generate_params(bits)?;
+ params.generate_key()
+ }
+
+ /// Create a DSA key pair with the given parameters
+ ///
+ /// `p`, `q` and `g` are the common parameters.
+ /// `priv_key` is the private component of the key pair.
+ /// `pub_key` is the public component of the key. Can be computed via `g^(priv_key) mod p`
+ pub fn from_private_components(
+ p: BigNum,
+ q: BigNum,
+ g: BigNum,
+ priv_key: BigNum,
+ pub_key: BigNum,
+ ) -> Result<Dsa<Private>, ErrorStack> {
+ ffi::init();
+ unsafe {
+ let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
+ cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
+ mem::forget((p, q, g));
+ cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), priv_key.as_ptr()))?;
+ mem::forget((pub_key, priv_key));
+ Ok(dsa)
+ }
+ }
+}
+
+impl Dsa<Public> {
+ from_pem! {
+ /// Decodes a PEM-encoded SubjectPublicKeyInfo structure containing a DSA key.
+ ///
+ /// The input should have a header of `-----BEGIN PUBLIC KEY-----`.
+ #[corresponds(PEM_read_bio_DSA_PUBKEY)]
+ public_key_from_pem,
+ Dsa<Public>,
+ ffi::PEM_read_bio_DSA_PUBKEY
+ }
+
+ from_der! {
+ /// Decodes a DER-encoded SubjectPublicKeyInfo structure containing a DSA key.
+ #[corresponds(d2i_DSA_PUBKEY)]
+ public_key_from_der,
+ Dsa<Public>,
+ ffi::d2i_DSA_PUBKEY
+ }
+
+ /// Create a new DSA key with only public components.
+ ///
+ /// `p`, `q` and `g` are the common parameters.
+ /// `pub_key` is the public component of the key.
+ pub fn from_public_components(
+ p: BigNum,
+ q: BigNum,
+ g: BigNum,
+ pub_key: BigNum,
+ ) -> Result<Dsa<Public>, ErrorStack> {
+ ffi::init();
+ unsafe {
+ let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
+ cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
+ mem::forget((p, q, g));
+ cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), ptr::null_mut()))?;
+ mem::forget(pub_key);
+ Ok(dsa)
+ }
+ }
+}
+
+impl<T> fmt::Debug for Dsa<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "DSA")
+ }
+}
+
+cfg_if! {
+ if #[cfg(any(ossl110, libressl273, boringssl))] {
+ use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg};
+ } else {
+ #[allow(bad_style)]
+ unsafe fn DSA_get0_pqg(
+ d: *mut ffi::DSA,
+ p: *mut *const ffi::BIGNUM,
+ q: *mut *const ffi::BIGNUM,
+ g: *mut *const ffi::BIGNUM)
+ {
+ if !p.is_null() {
+ *p = (*d).p;
+ }
+ if !q.is_null() {
+ *q = (*d).q;
+ }
+ if !g.is_null() {
+ *g = (*d).g;
+ }
+ }
+
+ #[allow(bad_style)]
+ unsafe fn DSA_get0_key(
+ d: *mut ffi::DSA,
+ pub_key: *mut *const ffi::BIGNUM,
+ priv_key: *mut *const ffi::BIGNUM)
+ {
+ if !pub_key.is_null() {
+ *pub_key = (*d).pub_key;
+ }
+ if !priv_key.is_null() {
+ *priv_key = (*d).priv_key;
+ }
+ }
+
+ #[allow(bad_style)]
+ unsafe fn DSA_set0_key(
+ d: *mut ffi::DSA,
+ pub_key: *mut ffi::BIGNUM,
+ priv_key: *mut ffi::BIGNUM) -> c_int
+ {
+ (*d).pub_key = pub_key;
+ (*d).priv_key = priv_key;
+ 1
+ }
+
+ #[allow(bad_style)]
+ unsafe fn DSA_set0_pqg(
+ d: *mut ffi::DSA,
+ p: *mut ffi::BIGNUM,
+ q: *mut ffi::BIGNUM,
+ g: *mut ffi::BIGNUM) -> c_int
+ {
+ (*d).p = p;
+ (*d).q = q;
+ (*d).g = g;
+ 1
+ }
+ }
+}
+
+foreign_type_and_impl_send_sync! {
+ type CType = ffi::DSA_SIG;
+ fn drop = ffi::DSA_SIG_free;
+
+ /// Object representing DSA signature.
+ ///
+ /// DSA signatures consist of two components: `r` and `s`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::convert::TryInto;
+ ///
+ /// use openssl::bn::BigNum;
+ /// use openssl::dsa::{Dsa, DsaSig};
+ /// use openssl::hash::MessageDigest;
+ /// use openssl::pkey::PKey;
+ /// use openssl::sign::{Signer, Verifier};
+ ///
+ /// const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ /// let dsa_ref = Dsa::generate(1024).unwrap();
+ ///
+ /// let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap();
+ /// let priv_key: PKey<_> = dsa_ref.try_into().unwrap();
+ ///
+ /// let mut signer = if let Ok(signer) = Signer::new(MessageDigest::sha256(), &priv_key) {
+ /// signer
+ /// } else {
+ /// // DSA signing is not supported (eg. BoringSSL)
+ /// return;
+ /// };
+ ///
+ /// signer.update(TEST_DATA).unwrap();
+ ///
+ /// let signature = signer.sign_to_vec().unwrap();
+ /// // Parse DER-encoded DSA signature
+ /// let signature = DsaSig::from_der(&signature).unwrap();
+ ///
+ /// // Extract components `r` and `s`
+ /// let r = BigNum::from_slice(&signature.r().to_vec()).unwrap();
+ /// let s = BigNum::from_slice(&signature.s().to_vec()).unwrap();
+ ///
+ /// // Construct new DSA signature from components
+ /// let signature = DsaSig::from_private_components(r, s).unwrap();
+ ///
+ /// // Serialize DSA signature to DER
+ /// let signature = signature.to_der().unwrap();
+ ///
+ /// let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
+ /// verifier.update(TEST_DATA).unwrap();
+ /// assert!(verifier.verify(&signature[..]).unwrap());
+ /// ```
+ pub struct DsaSig;
+
+ /// Reference to a [`DsaSig`].
+ pub struct DsaSigRef;
+}
+
+impl DsaSig {
+ /// Returns a new `DsaSig` by setting the `r` and `s` values associated with an DSA signature.
+ #[corresponds(DSA_SIG_set0)]
+ pub fn from_private_components(r: BigNum, s: BigNum) -> Result<Self, ErrorStack> {
+ unsafe {
+ let sig = cvt_p(ffi::DSA_SIG_new())?;
+ DSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
+ mem::forget((r, s));
+ Ok(DsaSig::from_ptr(sig))
+ }
+ }
+
+ from_der! {
+ /// Decodes a DER-encoded DSA signature.
+ #[corresponds(d2i_DSA_SIG)]
+ from_der,
+ DsaSig,
+ ffi::d2i_DSA_SIG
+ }
+}
+
+impl fmt::Debug for DsaSig {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("DsaSig")
+ .field("r", self.r())
+ .field("s", self.s())
+ .finish()
+ }
+}
+
+impl DsaSigRef {
+ to_der! {
+ /// Serializes the DSA signature into a DER-encoded `DSASignature` structure.
+ #[corresponds(i2d_DSA_SIG)]
+ to_der,
+ ffi::i2d_DSA_SIG
+ }
+
+ /// Returns internal component `r` of an `DsaSig`.
+ #[corresponds(DSA_SIG_get0)]
+ pub fn r(&self) -> &BigNumRef {
+ unsafe {
+ let mut r = ptr::null();
+ DSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
+ BigNumRef::from_const_ptr(r)
+ }
+ }
+
+ /// Returns internal component `s` of an `DsaSig`.
+ #[corresponds(DSA_SIG_get0)]
+ pub fn s(&self) -> &BigNumRef {
+ unsafe {
+ let mut s = ptr::null();
+ DSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
+ BigNumRef::from_const_ptr(s)
+ }
+ }
+}
+
+cfg_if! {
+ if #[cfg(any(ossl110, libressl273, boringssl))] {
+ use ffi::{DSA_SIG_set0, DSA_SIG_get0};
+ } else {
+ #[allow(bad_style)]
+ unsafe fn DSA_SIG_set0(
+ sig: *mut ffi::DSA_SIG,
+ r: *mut ffi::BIGNUM,
+ s: *mut ffi::BIGNUM,
+ ) -> c_int {
+ if r.is_null() || s.is_null() {
+ return 0;
+ }
+ ffi::BN_clear_free((*sig).r);
+ ffi::BN_clear_free((*sig).s);
+ (*sig).r = r;
+ (*sig).s = s;
+ 1
+ }
+
+ #[allow(bad_style)]
+ unsafe fn DSA_SIG_get0(
+ sig: *const ffi::DSA_SIG,
+ pr: *mut *const ffi::BIGNUM,
+ ps: *mut *const ffi::BIGNUM)
+ {
+ if !pr.is_null() {
+ (*pr) = (*sig).r;
+ }
+ if !ps.is_null() {
+ (*ps) = (*sig).s;
+ }
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use crate::bn::BigNumContext;
+ #[cfg(not(boringssl))]
+ use crate::hash::MessageDigest;
+ #[cfg(not(boringssl))]
+ use crate::pkey::PKey;
+ #[cfg(not(boringssl))]
+ use crate::sign::{Signer, Verifier};
+
+ #[test]
+ pub fn test_generate() {
+ Dsa::generate(1024).unwrap();
+ }
+
+ #[test]
+ fn test_pubkey_generation() {
+ let dsa = Dsa::generate(1024).unwrap();
+ let p = dsa.p();
+ let g = dsa.g();
+ let priv_key = dsa.priv_key();
+ let pub_key = dsa.pub_key();
+ let mut ctx = BigNumContext::new().unwrap();
+ let mut calc = BigNum::new().unwrap();
+ calc.mod_exp(g, priv_key, p, &mut ctx).unwrap();
+ assert_eq!(&calc, pub_key)
+ }
+
+ #[test]
+ fn test_priv_key_from_parts() {
+ let p = BigNum::from_u32(283).unwrap();
+ let q = BigNum::from_u32(47).unwrap();
+ let g = BigNum::from_u32(60).unwrap();
+ let priv_key = BigNum::from_u32(15).unwrap();
+ let pub_key = BigNum::from_u32(207).unwrap();
+
+ let dsa = Dsa::from_private_components(p, q, g, priv_key, pub_key).unwrap();
+ assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
+ assert_eq!(dsa.priv_key(), &BigNum::from_u32(15).unwrap());
+ assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
+ assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
+ assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
+ }
+
+ #[test]
+ fn test_pub_key_from_parts() {
+ let p = BigNum::from_u32(283).unwrap();
+ let q = BigNum::from_u32(47).unwrap();
+ let g = BigNum::from_u32(60).unwrap();
+ let pub_key = BigNum::from_u32(207).unwrap();
+
+ let dsa = Dsa::from_public_components(p, q, g, pub_key).unwrap();
+ assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
+ assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
+ assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
+ assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
+ }
+
+ #[test]
+ fn test_params() {
+ let params = Dsa::generate_params(1024).unwrap();
+ let p = params.p().to_owned().unwrap();
+ let q = params.q().to_owned().unwrap();
+ let g = params.g().to_owned().unwrap();
+ let key = params.generate_key().unwrap();
+ let params2 = Dsa::from_pqg(
+ key.p().to_owned().unwrap(),
+ key.q().to_owned().unwrap(),
+ key.g().to_owned().unwrap(),
+ )
+ .unwrap();
+ assert_eq!(p, *params2.p());
+ assert_eq!(q, *params2.q());
+ assert_eq!(g, *params2.g());
+ }
+
+ #[test]
+ #[cfg(not(boringssl))]
+ fn test_signature() {
+ const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ let dsa_ref = Dsa::generate(1024).unwrap();
+
+ let p = dsa_ref.p();
+ let q = dsa_ref.q();
+ let g = dsa_ref.g();
+
+ let pub_key = dsa_ref.pub_key();
+ let priv_key = dsa_ref.priv_key();
+
+ let priv_key = Dsa::from_private_components(
+ BigNumRef::to_owned(p).unwrap(),
+ BigNumRef::to_owned(q).unwrap(),
+ BigNumRef::to_owned(g).unwrap(),
+ BigNumRef::to_owned(priv_key).unwrap(),
+ BigNumRef::to_owned(pub_key).unwrap(),
+ )
+ .unwrap();
+ let priv_key = PKey::from_dsa(priv_key).unwrap();
+
+ let pub_key = Dsa::from_public_components(
+ BigNumRef::to_owned(p).unwrap(),
+ BigNumRef::to_owned(q).unwrap(),
+ BigNumRef::to_owned(g).unwrap(),
+ BigNumRef::to_owned(pub_key).unwrap(),
+ )
+ .unwrap();
+ let pub_key = PKey::from_dsa(pub_key).unwrap();
+
+ let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
+ signer.update(TEST_DATA).unwrap();
+
+ let signature = signer.sign_to_vec().unwrap();
+ let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
+ verifier.update(TEST_DATA).unwrap();
+ assert!(verifier.verify(&signature[..]).unwrap());
+ }
+
+ #[test]
+ #[cfg(not(boringssl))]
+ fn test_signature_der() {
+ use std::convert::TryInto;
+
+ const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ let dsa_ref = Dsa::generate(1024).unwrap();
+
+ let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap();
+ let priv_key: PKey<_> = dsa_ref.try_into().unwrap();
+
+ let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
+ signer.update(TEST_DATA).unwrap();
+
+ let signature = signer.sign_to_vec().unwrap();
+ eprintln!("{:?}", signature);
+ let signature = DsaSig::from_der(&signature).unwrap();
+
+ let r = BigNum::from_slice(&signature.r().to_vec()).unwrap();
+ let s = BigNum::from_slice(&signature.s().to_vec()).unwrap();
+
+ let signature = DsaSig::from_private_components(r, s).unwrap();
+ let signature = signature.to_der().unwrap();
+
+ let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
+ verifier.update(TEST_DATA).unwrap();
+ assert!(verifier.verify(&signature[..]).unwrap());
+ }
+
+ #[test]
+ #[allow(clippy::redundant_clone)]
+ fn clone() {
+ let key = Dsa::generate(2048).unwrap();
+ drop(key.clone());
+ }
+
+ #[test]
+ fn dsa_sig_debug() {
+ let sig = DsaSig::from_der(&[
+ 48, 46, 2, 21, 0, 135, 169, 24, 58, 153, 37, 175, 248, 200, 45, 251, 112, 238, 238, 89,
+ 172, 177, 182, 166, 237, 2, 21, 0, 159, 146, 151, 237, 187, 8, 82, 115, 14, 183, 103,
+ 12, 203, 46, 161, 208, 251, 167, 123, 131,
+ ])
+ .unwrap();
+ let s = format!("{:?}", sig);
+ assert_eq!(s, "DsaSig { r: 774484690634577222213819810519929266740561094381, s: 910998676210681457251421818099943952372231273347 }");
+ }
+}