192f3ab15Sopenharmony_ci//! Digital Signatures 292f3ab15Sopenharmony_ci//! 392f3ab15Sopenharmony_ci//! DSA ensures a message originated from a known sender, and was not modified. 492f3ab15Sopenharmony_ci//! DSA uses asymmetrical keys and an algorithm to output a signature of the message 592f3ab15Sopenharmony_ci//! using the private key that can be validated with the public key but not be generated 692f3ab15Sopenharmony_ci//! without the private key. 792f3ab15Sopenharmony_ci 892f3ab15Sopenharmony_ciuse cfg_if::cfg_if; 992f3ab15Sopenharmony_ciuse foreign_types::{ForeignType, ForeignTypeRef}; 1092f3ab15Sopenharmony_ci#[cfg(not(boringssl))] 1192f3ab15Sopenharmony_ciuse libc::c_int; 1292f3ab15Sopenharmony_ciuse std::fmt; 1392f3ab15Sopenharmony_ciuse std::mem; 1492f3ab15Sopenharmony_ciuse std::ptr; 1592f3ab15Sopenharmony_ci 1692f3ab15Sopenharmony_ciuse crate::bn::{BigNum, BigNumRef}; 1792f3ab15Sopenharmony_ciuse crate::error::ErrorStack; 1892f3ab15Sopenharmony_ciuse crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public}; 1992f3ab15Sopenharmony_ciuse crate::util::ForeignTypeRefExt; 2092f3ab15Sopenharmony_ciuse crate::{cvt, cvt_p}; 2192f3ab15Sopenharmony_ciuse openssl_macros::corresponds; 2292f3ab15Sopenharmony_ci 2392f3ab15Sopenharmony_cigeneric_foreign_type_and_impl_send_sync! { 2492f3ab15Sopenharmony_ci type CType = ffi::DSA; 2592f3ab15Sopenharmony_ci fn drop = ffi::DSA_free; 2692f3ab15Sopenharmony_ci 2792f3ab15Sopenharmony_ci /// Object representing DSA keys. 2892f3ab15Sopenharmony_ci /// 2992f3ab15Sopenharmony_ci /// A DSA object contains the parameters p, q, and g. There is a private 3092f3ab15Sopenharmony_ci /// and public key. The values p, g, and q are: 3192f3ab15Sopenharmony_ci /// 3292f3ab15Sopenharmony_ci /// * `p`: DSA prime parameter 3392f3ab15Sopenharmony_ci /// * `q`: DSA sub-prime parameter 3492f3ab15Sopenharmony_ci /// * `g`: DSA base parameter 3592f3ab15Sopenharmony_ci /// 3692f3ab15Sopenharmony_ci /// These values are used to calculate a pair of asymmetrical keys used for 3792f3ab15Sopenharmony_ci /// signing. 3892f3ab15Sopenharmony_ci /// 3992f3ab15Sopenharmony_ci /// OpenSSL documentation at [`DSA_new`] 4092f3ab15Sopenharmony_ci /// 4192f3ab15Sopenharmony_ci /// [`DSA_new`]: https://www.openssl.org/docs/manmaster/crypto/DSA_new.html 4292f3ab15Sopenharmony_ci /// 4392f3ab15Sopenharmony_ci /// # Examples 4492f3ab15Sopenharmony_ci /// 4592f3ab15Sopenharmony_ci /// ``` 4692f3ab15Sopenharmony_ci /// use openssl::dsa::Dsa; 4792f3ab15Sopenharmony_ci /// use openssl::error::ErrorStack; 4892f3ab15Sopenharmony_ci /// use openssl::pkey::Private; 4992f3ab15Sopenharmony_ci /// 5092f3ab15Sopenharmony_ci /// fn create_dsa() -> Result<Dsa<Private>, ErrorStack> { 5192f3ab15Sopenharmony_ci /// let sign = Dsa::generate(2048)?; 5292f3ab15Sopenharmony_ci /// Ok(sign) 5392f3ab15Sopenharmony_ci /// } 5492f3ab15Sopenharmony_ci /// # fn main() { 5592f3ab15Sopenharmony_ci /// # create_dsa(); 5692f3ab15Sopenharmony_ci /// # } 5792f3ab15Sopenharmony_ci /// ``` 5892f3ab15Sopenharmony_ci pub struct Dsa<T>; 5992f3ab15Sopenharmony_ci /// Reference to [`Dsa`]. 6092f3ab15Sopenharmony_ci /// 6192f3ab15Sopenharmony_ci /// [`Dsa`]: struct.Dsa.html 6292f3ab15Sopenharmony_ci pub struct DsaRef<T>; 6392f3ab15Sopenharmony_ci} 6492f3ab15Sopenharmony_ci 6592f3ab15Sopenharmony_ciimpl<T> Clone for Dsa<T> { 6692f3ab15Sopenharmony_ci fn clone(&self) -> Dsa<T> { 6792f3ab15Sopenharmony_ci (**self).to_owned() 6892f3ab15Sopenharmony_ci } 6992f3ab15Sopenharmony_ci} 7092f3ab15Sopenharmony_ci 7192f3ab15Sopenharmony_ciimpl<T> ToOwned for DsaRef<T> { 7292f3ab15Sopenharmony_ci type Owned = Dsa<T>; 7392f3ab15Sopenharmony_ci 7492f3ab15Sopenharmony_ci fn to_owned(&self) -> Dsa<T> { 7592f3ab15Sopenharmony_ci unsafe { 7692f3ab15Sopenharmony_ci ffi::DSA_up_ref(self.as_ptr()); 7792f3ab15Sopenharmony_ci Dsa::from_ptr(self.as_ptr()) 7892f3ab15Sopenharmony_ci } 7992f3ab15Sopenharmony_ci } 8092f3ab15Sopenharmony_ci} 8192f3ab15Sopenharmony_ci 8292f3ab15Sopenharmony_ciimpl<T> DsaRef<T> 8392f3ab15Sopenharmony_ciwhere 8492f3ab15Sopenharmony_ci T: HasPublic, 8592f3ab15Sopenharmony_ci{ 8692f3ab15Sopenharmony_ci to_pem! { 8792f3ab15Sopenharmony_ci /// Serializes the public key into a PEM-encoded SubjectPublicKeyInfo structure. 8892f3ab15Sopenharmony_ci /// 8992f3ab15Sopenharmony_ci /// The output will have a header of `-----BEGIN PUBLIC KEY-----`. 9092f3ab15Sopenharmony_ci #[corresponds(PEM_write_bio_DSA_PUBKEY)] 9192f3ab15Sopenharmony_ci public_key_to_pem, 9292f3ab15Sopenharmony_ci ffi::PEM_write_bio_DSA_PUBKEY 9392f3ab15Sopenharmony_ci } 9492f3ab15Sopenharmony_ci 9592f3ab15Sopenharmony_ci to_der! { 9692f3ab15Sopenharmony_ci /// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure. 9792f3ab15Sopenharmony_ci #[corresponds(i2d_DSA_PUBKEY)] 9892f3ab15Sopenharmony_ci public_key_to_der, 9992f3ab15Sopenharmony_ci ffi::i2d_DSA_PUBKEY 10092f3ab15Sopenharmony_ci } 10192f3ab15Sopenharmony_ci 10292f3ab15Sopenharmony_ci /// Returns a reference to the public key component of `self`. 10392f3ab15Sopenharmony_ci #[corresponds(DSA_get0_key)] 10492f3ab15Sopenharmony_ci pub fn pub_key(&self) -> &BigNumRef { 10592f3ab15Sopenharmony_ci unsafe { 10692f3ab15Sopenharmony_ci let mut pub_key = ptr::null(); 10792f3ab15Sopenharmony_ci DSA_get0_key(self.as_ptr(), &mut pub_key, ptr::null_mut()); 10892f3ab15Sopenharmony_ci BigNumRef::from_const_ptr(pub_key) 10992f3ab15Sopenharmony_ci } 11092f3ab15Sopenharmony_ci } 11192f3ab15Sopenharmony_ci} 11292f3ab15Sopenharmony_ci 11392f3ab15Sopenharmony_ciimpl<T> DsaRef<T> 11492f3ab15Sopenharmony_ciwhere 11592f3ab15Sopenharmony_ci T: HasPrivate, 11692f3ab15Sopenharmony_ci{ 11792f3ab15Sopenharmony_ci private_key_to_pem! { 11892f3ab15Sopenharmony_ci /// Serializes the private key to a PEM-encoded DSAPrivateKey structure. 11992f3ab15Sopenharmony_ci /// 12092f3ab15Sopenharmony_ci /// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`. 12192f3ab15Sopenharmony_ci #[corresponds(PEM_write_bio_DSAPrivateKey)] 12292f3ab15Sopenharmony_ci private_key_to_pem, 12392f3ab15Sopenharmony_ci /// Serializes the private key to a PEM-encoded encrypted DSAPrivateKey structure. 12492f3ab15Sopenharmony_ci /// 12592f3ab15Sopenharmony_ci /// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`. 12692f3ab15Sopenharmony_ci #[corresponds(PEM_write_bio_DSAPrivateKey)] 12792f3ab15Sopenharmony_ci private_key_to_pem_passphrase, 12892f3ab15Sopenharmony_ci ffi::PEM_write_bio_DSAPrivateKey 12992f3ab15Sopenharmony_ci } 13092f3ab15Sopenharmony_ci 13192f3ab15Sopenharmony_ci to_der! { 13292f3ab15Sopenharmony_ci /// Serializes the private_key to a DER-encoded `DSAPrivateKey` structure. 13392f3ab15Sopenharmony_ci #[corresponds(i2d_DSAPrivateKey)] 13492f3ab15Sopenharmony_ci private_key_to_der, 13592f3ab15Sopenharmony_ci ffi::i2d_DSAPrivateKey 13692f3ab15Sopenharmony_ci } 13792f3ab15Sopenharmony_ci 13892f3ab15Sopenharmony_ci /// Returns a reference to the private key component of `self`. 13992f3ab15Sopenharmony_ci #[corresponds(DSA_get0_key)] 14092f3ab15Sopenharmony_ci pub fn priv_key(&self) -> &BigNumRef { 14192f3ab15Sopenharmony_ci unsafe { 14292f3ab15Sopenharmony_ci let mut priv_key = ptr::null(); 14392f3ab15Sopenharmony_ci DSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut priv_key); 14492f3ab15Sopenharmony_ci BigNumRef::from_const_ptr(priv_key) 14592f3ab15Sopenharmony_ci } 14692f3ab15Sopenharmony_ci } 14792f3ab15Sopenharmony_ci} 14892f3ab15Sopenharmony_ci 14992f3ab15Sopenharmony_ciimpl<T> DsaRef<T> 15092f3ab15Sopenharmony_ciwhere 15192f3ab15Sopenharmony_ci T: HasParams, 15292f3ab15Sopenharmony_ci{ 15392f3ab15Sopenharmony_ci /// Returns the maximum size of the signature output by `self` in bytes. 15492f3ab15Sopenharmony_ci #[corresponds(DSA_size)] 15592f3ab15Sopenharmony_ci pub fn size(&self) -> u32 { 15692f3ab15Sopenharmony_ci unsafe { ffi::DSA_size(self.as_ptr()) as u32 } 15792f3ab15Sopenharmony_ci } 15892f3ab15Sopenharmony_ci 15992f3ab15Sopenharmony_ci /// Returns the DSA prime parameter of `self`. 16092f3ab15Sopenharmony_ci #[corresponds(DSA_get0_pqg)] 16192f3ab15Sopenharmony_ci pub fn p(&self) -> &BigNumRef { 16292f3ab15Sopenharmony_ci unsafe { 16392f3ab15Sopenharmony_ci let mut p = ptr::null(); 16492f3ab15Sopenharmony_ci DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut()); 16592f3ab15Sopenharmony_ci BigNumRef::from_const_ptr(p) 16692f3ab15Sopenharmony_ci } 16792f3ab15Sopenharmony_ci } 16892f3ab15Sopenharmony_ci 16992f3ab15Sopenharmony_ci /// Returns the DSA sub-prime parameter of `self`. 17092f3ab15Sopenharmony_ci #[corresponds(DSA_get0_pqg)] 17192f3ab15Sopenharmony_ci pub fn q(&self) -> &BigNumRef { 17292f3ab15Sopenharmony_ci unsafe { 17392f3ab15Sopenharmony_ci let mut q = ptr::null(); 17492f3ab15Sopenharmony_ci DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut()); 17592f3ab15Sopenharmony_ci BigNumRef::from_const_ptr(q) 17692f3ab15Sopenharmony_ci } 17792f3ab15Sopenharmony_ci } 17892f3ab15Sopenharmony_ci 17992f3ab15Sopenharmony_ci /// Returns the DSA base parameter of `self`. 18092f3ab15Sopenharmony_ci #[corresponds(DSA_get0_pqg)] 18192f3ab15Sopenharmony_ci pub fn g(&self) -> &BigNumRef { 18292f3ab15Sopenharmony_ci unsafe { 18392f3ab15Sopenharmony_ci let mut g = ptr::null(); 18492f3ab15Sopenharmony_ci DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g); 18592f3ab15Sopenharmony_ci BigNumRef::from_const_ptr(g) 18692f3ab15Sopenharmony_ci } 18792f3ab15Sopenharmony_ci } 18892f3ab15Sopenharmony_ci} 18992f3ab15Sopenharmony_ci#[cfg(boringssl)] 19092f3ab15Sopenharmony_citype BitType = libc::c_uint; 19192f3ab15Sopenharmony_ci#[cfg(not(boringssl))] 19292f3ab15Sopenharmony_citype BitType = c_int; 19392f3ab15Sopenharmony_ci 19492f3ab15Sopenharmony_ciimpl Dsa<Params> { 19592f3ab15Sopenharmony_ci /// Creates a DSA params based upon the given parameters. 19692f3ab15Sopenharmony_ci #[corresponds(DSA_set0_pqg)] 19792f3ab15Sopenharmony_ci pub fn from_pqg(p: BigNum, q: BigNum, g: BigNum) -> Result<Dsa<Params>, ErrorStack> { 19892f3ab15Sopenharmony_ci unsafe { 19992f3ab15Sopenharmony_ci let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?); 20092f3ab15Sopenharmony_ci cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?; 20192f3ab15Sopenharmony_ci mem::forget((p, q, g)); 20292f3ab15Sopenharmony_ci Ok(dsa) 20392f3ab15Sopenharmony_ci } 20492f3ab15Sopenharmony_ci } 20592f3ab15Sopenharmony_ci 20692f3ab15Sopenharmony_ci /// Generates DSA params based on the given number of bits. 20792f3ab15Sopenharmony_ci #[corresponds(DSA_generate_parameters_ex)] 20892f3ab15Sopenharmony_ci pub fn generate_params(bits: u32) -> Result<Dsa<Params>, ErrorStack> { 20992f3ab15Sopenharmony_ci ffi::init(); 21092f3ab15Sopenharmony_ci unsafe { 21192f3ab15Sopenharmony_ci let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?); 21292f3ab15Sopenharmony_ci cvt(ffi::DSA_generate_parameters_ex( 21392f3ab15Sopenharmony_ci dsa.0, 21492f3ab15Sopenharmony_ci bits as BitType, 21592f3ab15Sopenharmony_ci ptr::null(), 21692f3ab15Sopenharmony_ci 0, 21792f3ab15Sopenharmony_ci ptr::null_mut(), 21892f3ab15Sopenharmony_ci ptr::null_mut(), 21992f3ab15Sopenharmony_ci ptr::null_mut(), 22092f3ab15Sopenharmony_ci ))?; 22192f3ab15Sopenharmony_ci Ok(dsa) 22292f3ab15Sopenharmony_ci } 22392f3ab15Sopenharmony_ci } 22492f3ab15Sopenharmony_ci 22592f3ab15Sopenharmony_ci /// Generates a private key based on the DSA params. 22692f3ab15Sopenharmony_ci #[corresponds(DSA_generate_key)] 22792f3ab15Sopenharmony_ci pub fn generate_key(self) -> Result<Dsa<Private>, ErrorStack> { 22892f3ab15Sopenharmony_ci unsafe { 22992f3ab15Sopenharmony_ci let dsa_ptr = self.0; 23092f3ab15Sopenharmony_ci cvt(ffi::DSA_generate_key(dsa_ptr))?; 23192f3ab15Sopenharmony_ci mem::forget(self); 23292f3ab15Sopenharmony_ci Ok(Dsa::from_ptr(dsa_ptr)) 23392f3ab15Sopenharmony_ci } 23492f3ab15Sopenharmony_ci } 23592f3ab15Sopenharmony_ci} 23692f3ab15Sopenharmony_ci 23792f3ab15Sopenharmony_ciimpl Dsa<Private> { 23892f3ab15Sopenharmony_ci /// Generate a DSA key pair. 23992f3ab15Sopenharmony_ci /// 24092f3ab15Sopenharmony_ci /// The `bits` parameter corresponds to the length of the prime `p`. 24192f3ab15Sopenharmony_ci pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> { 24292f3ab15Sopenharmony_ci let params = Dsa::generate_params(bits)?; 24392f3ab15Sopenharmony_ci params.generate_key() 24492f3ab15Sopenharmony_ci } 24592f3ab15Sopenharmony_ci 24692f3ab15Sopenharmony_ci /// Create a DSA key pair with the given parameters 24792f3ab15Sopenharmony_ci /// 24892f3ab15Sopenharmony_ci /// `p`, `q` and `g` are the common parameters. 24992f3ab15Sopenharmony_ci /// `priv_key` is the private component of the key pair. 25092f3ab15Sopenharmony_ci /// `pub_key` is the public component of the key. Can be computed via `g^(priv_key) mod p` 25192f3ab15Sopenharmony_ci pub fn from_private_components( 25292f3ab15Sopenharmony_ci p: BigNum, 25392f3ab15Sopenharmony_ci q: BigNum, 25492f3ab15Sopenharmony_ci g: BigNum, 25592f3ab15Sopenharmony_ci priv_key: BigNum, 25692f3ab15Sopenharmony_ci pub_key: BigNum, 25792f3ab15Sopenharmony_ci ) -> Result<Dsa<Private>, ErrorStack> { 25892f3ab15Sopenharmony_ci ffi::init(); 25992f3ab15Sopenharmony_ci unsafe { 26092f3ab15Sopenharmony_ci let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?); 26192f3ab15Sopenharmony_ci cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?; 26292f3ab15Sopenharmony_ci mem::forget((p, q, g)); 26392f3ab15Sopenharmony_ci cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), priv_key.as_ptr()))?; 26492f3ab15Sopenharmony_ci mem::forget((pub_key, priv_key)); 26592f3ab15Sopenharmony_ci Ok(dsa) 26692f3ab15Sopenharmony_ci } 26792f3ab15Sopenharmony_ci } 26892f3ab15Sopenharmony_ci} 26992f3ab15Sopenharmony_ci 27092f3ab15Sopenharmony_ciimpl Dsa<Public> { 27192f3ab15Sopenharmony_ci from_pem! { 27292f3ab15Sopenharmony_ci /// Decodes a PEM-encoded SubjectPublicKeyInfo structure containing a DSA key. 27392f3ab15Sopenharmony_ci /// 27492f3ab15Sopenharmony_ci /// The input should have a header of `-----BEGIN PUBLIC KEY-----`. 27592f3ab15Sopenharmony_ci #[corresponds(PEM_read_bio_DSA_PUBKEY)] 27692f3ab15Sopenharmony_ci public_key_from_pem, 27792f3ab15Sopenharmony_ci Dsa<Public>, 27892f3ab15Sopenharmony_ci ffi::PEM_read_bio_DSA_PUBKEY 27992f3ab15Sopenharmony_ci } 28092f3ab15Sopenharmony_ci 28192f3ab15Sopenharmony_ci from_der! { 28292f3ab15Sopenharmony_ci /// Decodes a DER-encoded SubjectPublicKeyInfo structure containing a DSA key. 28392f3ab15Sopenharmony_ci #[corresponds(d2i_DSA_PUBKEY)] 28492f3ab15Sopenharmony_ci public_key_from_der, 28592f3ab15Sopenharmony_ci Dsa<Public>, 28692f3ab15Sopenharmony_ci ffi::d2i_DSA_PUBKEY 28792f3ab15Sopenharmony_ci } 28892f3ab15Sopenharmony_ci 28992f3ab15Sopenharmony_ci /// Create a new DSA key with only public components. 29092f3ab15Sopenharmony_ci /// 29192f3ab15Sopenharmony_ci /// `p`, `q` and `g` are the common parameters. 29292f3ab15Sopenharmony_ci /// `pub_key` is the public component of the key. 29392f3ab15Sopenharmony_ci pub fn from_public_components( 29492f3ab15Sopenharmony_ci p: BigNum, 29592f3ab15Sopenharmony_ci q: BigNum, 29692f3ab15Sopenharmony_ci g: BigNum, 29792f3ab15Sopenharmony_ci pub_key: BigNum, 29892f3ab15Sopenharmony_ci ) -> Result<Dsa<Public>, ErrorStack> { 29992f3ab15Sopenharmony_ci ffi::init(); 30092f3ab15Sopenharmony_ci unsafe { 30192f3ab15Sopenharmony_ci let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?); 30292f3ab15Sopenharmony_ci cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?; 30392f3ab15Sopenharmony_ci mem::forget((p, q, g)); 30492f3ab15Sopenharmony_ci cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), ptr::null_mut()))?; 30592f3ab15Sopenharmony_ci mem::forget(pub_key); 30692f3ab15Sopenharmony_ci Ok(dsa) 30792f3ab15Sopenharmony_ci } 30892f3ab15Sopenharmony_ci } 30992f3ab15Sopenharmony_ci} 31092f3ab15Sopenharmony_ci 31192f3ab15Sopenharmony_ciimpl<T> fmt::Debug for Dsa<T> { 31292f3ab15Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 31392f3ab15Sopenharmony_ci write!(f, "DSA") 31492f3ab15Sopenharmony_ci } 31592f3ab15Sopenharmony_ci} 31692f3ab15Sopenharmony_ci 31792f3ab15Sopenharmony_cicfg_if! { 31892f3ab15Sopenharmony_ci if #[cfg(any(ossl110, libressl273, boringssl))] { 31992f3ab15Sopenharmony_ci use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg}; 32092f3ab15Sopenharmony_ci } else { 32192f3ab15Sopenharmony_ci #[allow(bad_style)] 32292f3ab15Sopenharmony_ci unsafe fn DSA_get0_pqg( 32392f3ab15Sopenharmony_ci d: *mut ffi::DSA, 32492f3ab15Sopenharmony_ci p: *mut *const ffi::BIGNUM, 32592f3ab15Sopenharmony_ci q: *mut *const ffi::BIGNUM, 32692f3ab15Sopenharmony_ci g: *mut *const ffi::BIGNUM) 32792f3ab15Sopenharmony_ci { 32892f3ab15Sopenharmony_ci if !p.is_null() { 32992f3ab15Sopenharmony_ci *p = (*d).p; 33092f3ab15Sopenharmony_ci } 33192f3ab15Sopenharmony_ci if !q.is_null() { 33292f3ab15Sopenharmony_ci *q = (*d).q; 33392f3ab15Sopenharmony_ci } 33492f3ab15Sopenharmony_ci if !g.is_null() { 33592f3ab15Sopenharmony_ci *g = (*d).g; 33692f3ab15Sopenharmony_ci } 33792f3ab15Sopenharmony_ci } 33892f3ab15Sopenharmony_ci 33992f3ab15Sopenharmony_ci #[allow(bad_style)] 34092f3ab15Sopenharmony_ci unsafe fn DSA_get0_key( 34192f3ab15Sopenharmony_ci d: *mut ffi::DSA, 34292f3ab15Sopenharmony_ci pub_key: *mut *const ffi::BIGNUM, 34392f3ab15Sopenharmony_ci priv_key: *mut *const ffi::BIGNUM) 34492f3ab15Sopenharmony_ci { 34592f3ab15Sopenharmony_ci if !pub_key.is_null() { 34692f3ab15Sopenharmony_ci *pub_key = (*d).pub_key; 34792f3ab15Sopenharmony_ci } 34892f3ab15Sopenharmony_ci if !priv_key.is_null() { 34992f3ab15Sopenharmony_ci *priv_key = (*d).priv_key; 35092f3ab15Sopenharmony_ci } 35192f3ab15Sopenharmony_ci } 35292f3ab15Sopenharmony_ci 35392f3ab15Sopenharmony_ci #[allow(bad_style)] 35492f3ab15Sopenharmony_ci unsafe fn DSA_set0_key( 35592f3ab15Sopenharmony_ci d: *mut ffi::DSA, 35692f3ab15Sopenharmony_ci pub_key: *mut ffi::BIGNUM, 35792f3ab15Sopenharmony_ci priv_key: *mut ffi::BIGNUM) -> c_int 35892f3ab15Sopenharmony_ci { 35992f3ab15Sopenharmony_ci (*d).pub_key = pub_key; 36092f3ab15Sopenharmony_ci (*d).priv_key = priv_key; 36192f3ab15Sopenharmony_ci 1 36292f3ab15Sopenharmony_ci } 36392f3ab15Sopenharmony_ci 36492f3ab15Sopenharmony_ci #[allow(bad_style)] 36592f3ab15Sopenharmony_ci unsafe fn DSA_set0_pqg( 36692f3ab15Sopenharmony_ci d: *mut ffi::DSA, 36792f3ab15Sopenharmony_ci p: *mut ffi::BIGNUM, 36892f3ab15Sopenharmony_ci q: *mut ffi::BIGNUM, 36992f3ab15Sopenharmony_ci g: *mut ffi::BIGNUM) -> c_int 37092f3ab15Sopenharmony_ci { 37192f3ab15Sopenharmony_ci (*d).p = p; 37292f3ab15Sopenharmony_ci (*d).q = q; 37392f3ab15Sopenharmony_ci (*d).g = g; 37492f3ab15Sopenharmony_ci 1 37592f3ab15Sopenharmony_ci } 37692f3ab15Sopenharmony_ci } 37792f3ab15Sopenharmony_ci} 37892f3ab15Sopenharmony_ci 37992f3ab15Sopenharmony_ciforeign_type_and_impl_send_sync! { 38092f3ab15Sopenharmony_ci type CType = ffi::DSA_SIG; 38192f3ab15Sopenharmony_ci fn drop = ffi::DSA_SIG_free; 38292f3ab15Sopenharmony_ci 38392f3ab15Sopenharmony_ci /// Object representing DSA signature. 38492f3ab15Sopenharmony_ci /// 38592f3ab15Sopenharmony_ci /// DSA signatures consist of two components: `r` and `s`. 38692f3ab15Sopenharmony_ci /// 38792f3ab15Sopenharmony_ci /// # Examples 38892f3ab15Sopenharmony_ci /// 38992f3ab15Sopenharmony_ci /// ``` 39092f3ab15Sopenharmony_ci /// use std::convert::TryInto; 39192f3ab15Sopenharmony_ci /// 39292f3ab15Sopenharmony_ci /// use openssl::bn::BigNum; 39392f3ab15Sopenharmony_ci /// use openssl::dsa::{Dsa, DsaSig}; 39492f3ab15Sopenharmony_ci /// use openssl::hash::MessageDigest; 39592f3ab15Sopenharmony_ci /// use openssl::pkey::PKey; 39692f3ab15Sopenharmony_ci /// use openssl::sign::{Signer, Verifier}; 39792f3ab15Sopenharmony_ci /// 39892f3ab15Sopenharmony_ci /// const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 39992f3ab15Sopenharmony_ci /// let dsa_ref = Dsa::generate(1024).unwrap(); 40092f3ab15Sopenharmony_ci /// 40192f3ab15Sopenharmony_ci /// let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap(); 40292f3ab15Sopenharmony_ci /// let priv_key: PKey<_> = dsa_ref.try_into().unwrap(); 40392f3ab15Sopenharmony_ci /// 40492f3ab15Sopenharmony_ci /// let mut signer = if let Ok(signer) = Signer::new(MessageDigest::sha256(), &priv_key) { 40592f3ab15Sopenharmony_ci /// signer 40692f3ab15Sopenharmony_ci /// } else { 40792f3ab15Sopenharmony_ci /// // DSA signing is not supported (eg. BoringSSL) 40892f3ab15Sopenharmony_ci /// return; 40992f3ab15Sopenharmony_ci /// }; 41092f3ab15Sopenharmony_ci /// 41192f3ab15Sopenharmony_ci /// signer.update(TEST_DATA).unwrap(); 41292f3ab15Sopenharmony_ci /// 41392f3ab15Sopenharmony_ci /// let signature = signer.sign_to_vec().unwrap(); 41492f3ab15Sopenharmony_ci /// // Parse DER-encoded DSA signature 41592f3ab15Sopenharmony_ci /// let signature = DsaSig::from_der(&signature).unwrap(); 41692f3ab15Sopenharmony_ci /// 41792f3ab15Sopenharmony_ci /// // Extract components `r` and `s` 41892f3ab15Sopenharmony_ci /// let r = BigNum::from_slice(&signature.r().to_vec()).unwrap(); 41992f3ab15Sopenharmony_ci /// let s = BigNum::from_slice(&signature.s().to_vec()).unwrap(); 42092f3ab15Sopenharmony_ci /// 42192f3ab15Sopenharmony_ci /// // Construct new DSA signature from components 42292f3ab15Sopenharmony_ci /// let signature = DsaSig::from_private_components(r, s).unwrap(); 42392f3ab15Sopenharmony_ci /// 42492f3ab15Sopenharmony_ci /// // Serialize DSA signature to DER 42592f3ab15Sopenharmony_ci /// let signature = signature.to_der().unwrap(); 42692f3ab15Sopenharmony_ci /// 42792f3ab15Sopenharmony_ci /// let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap(); 42892f3ab15Sopenharmony_ci /// verifier.update(TEST_DATA).unwrap(); 42992f3ab15Sopenharmony_ci /// assert!(verifier.verify(&signature[..]).unwrap()); 43092f3ab15Sopenharmony_ci /// ``` 43192f3ab15Sopenharmony_ci pub struct DsaSig; 43292f3ab15Sopenharmony_ci 43392f3ab15Sopenharmony_ci /// Reference to a [`DsaSig`]. 43492f3ab15Sopenharmony_ci pub struct DsaSigRef; 43592f3ab15Sopenharmony_ci} 43692f3ab15Sopenharmony_ci 43792f3ab15Sopenharmony_ciimpl DsaSig { 43892f3ab15Sopenharmony_ci /// Returns a new `DsaSig` by setting the `r` and `s` values associated with an DSA signature. 43992f3ab15Sopenharmony_ci #[corresponds(DSA_SIG_set0)] 44092f3ab15Sopenharmony_ci pub fn from_private_components(r: BigNum, s: BigNum) -> Result<Self, ErrorStack> { 44192f3ab15Sopenharmony_ci unsafe { 44292f3ab15Sopenharmony_ci let sig = cvt_p(ffi::DSA_SIG_new())?; 44392f3ab15Sopenharmony_ci DSA_SIG_set0(sig, r.as_ptr(), s.as_ptr()); 44492f3ab15Sopenharmony_ci mem::forget((r, s)); 44592f3ab15Sopenharmony_ci Ok(DsaSig::from_ptr(sig)) 44692f3ab15Sopenharmony_ci } 44792f3ab15Sopenharmony_ci } 44892f3ab15Sopenharmony_ci 44992f3ab15Sopenharmony_ci from_der! { 45092f3ab15Sopenharmony_ci /// Decodes a DER-encoded DSA signature. 45192f3ab15Sopenharmony_ci #[corresponds(d2i_DSA_SIG)] 45292f3ab15Sopenharmony_ci from_der, 45392f3ab15Sopenharmony_ci DsaSig, 45492f3ab15Sopenharmony_ci ffi::d2i_DSA_SIG 45592f3ab15Sopenharmony_ci } 45692f3ab15Sopenharmony_ci} 45792f3ab15Sopenharmony_ci 45892f3ab15Sopenharmony_ciimpl fmt::Debug for DsaSig { 45992f3ab15Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 46092f3ab15Sopenharmony_ci f.debug_struct("DsaSig") 46192f3ab15Sopenharmony_ci .field("r", self.r()) 46292f3ab15Sopenharmony_ci .field("s", self.s()) 46392f3ab15Sopenharmony_ci .finish() 46492f3ab15Sopenharmony_ci } 46592f3ab15Sopenharmony_ci} 46692f3ab15Sopenharmony_ci 46792f3ab15Sopenharmony_ciimpl DsaSigRef { 46892f3ab15Sopenharmony_ci to_der! { 46992f3ab15Sopenharmony_ci /// Serializes the DSA signature into a DER-encoded `DSASignature` structure. 47092f3ab15Sopenharmony_ci #[corresponds(i2d_DSA_SIG)] 47192f3ab15Sopenharmony_ci to_der, 47292f3ab15Sopenharmony_ci ffi::i2d_DSA_SIG 47392f3ab15Sopenharmony_ci } 47492f3ab15Sopenharmony_ci 47592f3ab15Sopenharmony_ci /// Returns internal component `r` of an `DsaSig`. 47692f3ab15Sopenharmony_ci #[corresponds(DSA_SIG_get0)] 47792f3ab15Sopenharmony_ci pub fn r(&self) -> &BigNumRef { 47892f3ab15Sopenharmony_ci unsafe { 47992f3ab15Sopenharmony_ci let mut r = ptr::null(); 48092f3ab15Sopenharmony_ci DSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut()); 48192f3ab15Sopenharmony_ci BigNumRef::from_const_ptr(r) 48292f3ab15Sopenharmony_ci } 48392f3ab15Sopenharmony_ci } 48492f3ab15Sopenharmony_ci 48592f3ab15Sopenharmony_ci /// Returns internal component `s` of an `DsaSig`. 48692f3ab15Sopenharmony_ci #[corresponds(DSA_SIG_get0)] 48792f3ab15Sopenharmony_ci pub fn s(&self) -> &BigNumRef { 48892f3ab15Sopenharmony_ci unsafe { 48992f3ab15Sopenharmony_ci let mut s = ptr::null(); 49092f3ab15Sopenharmony_ci DSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s); 49192f3ab15Sopenharmony_ci BigNumRef::from_const_ptr(s) 49292f3ab15Sopenharmony_ci } 49392f3ab15Sopenharmony_ci } 49492f3ab15Sopenharmony_ci} 49592f3ab15Sopenharmony_ci 49692f3ab15Sopenharmony_cicfg_if! { 49792f3ab15Sopenharmony_ci if #[cfg(any(ossl110, libressl273, boringssl))] { 49892f3ab15Sopenharmony_ci use ffi::{DSA_SIG_set0, DSA_SIG_get0}; 49992f3ab15Sopenharmony_ci } else { 50092f3ab15Sopenharmony_ci #[allow(bad_style)] 50192f3ab15Sopenharmony_ci unsafe fn DSA_SIG_set0( 50292f3ab15Sopenharmony_ci sig: *mut ffi::DSA_SIG, 50392f3ab15Sopenharmony_ci r: *mut ffi::BIGNUM, 50492f3ab15Sopenharmony_ci s: *mut ffi::BIGNUM, 50592f3ab15Sopenharmony_ci ) -> c_int { 50692f3ab15Sopenharmony_ci if r.is_null() || s.is_null() { 50792f3ab15Sopenharmony_ci return 0; 50892f3ab15Sopenharmony_ci } 50992f3ab15Sopenharmony_ci ffi::BN_clear_free((*sig).r); 51092f3ab15Sopenharmony_ci ffi::BN_clear_free((*sig).s); 51192f3ab15Sopenharmony_ci (*sig).r = r; 51292f3ab15Sopenharmony_ci (*sig).s = s; 51392f3ab15Sopenharmony_ci 1 51492f3ab15Sopenharmony_ci } 51592f3ab15Sopenharmony_ci 51692f3ab15Sopenharmony_ci #[allow(bad_style)] 51792f3ab15Sopenharmony_ci unsafe fn DSA_SIG_get0( 51892f3ab15Sopenharmony_ci sig: *const ffi::DSA_SIG, 51992f3ab15Sopenharmony_ci pr: *mut *const ffi::BIGNUM, 52092f3ab15Sopenharmony_ci ps: *mut *const ffi::BIGNUM) 52192f3ab15Sopenharmony_ci { 52292f3ab15Sopenharmony_ci if !pr.is_null() { 52392f3ab15Sopenharmony_ci (*pr) = (*sig).r; 52492f3ab15Sopenharmony_ci } 52592f3ab15Sopenharmony_ci if !ps.is_null() { 52692f3ab15Sopenharmony_ci (*ps) = (*sig).s; 52792f3ab15Sopenharmony_ci } 52892f3ab15Sopenharmony_ci } 52992f3ab15Sopenharmony_ci } 53092f3ab15Sopenharmony_ci} 53192f3ab15Sopenharmony_ci 53292f3ab15Sopenharmony_ci#[cfg(test)] 53392f3ab15Sopenharmony_cimod test { 53492f3ab15Sopenharmony_ci use super::*; 53592f3ab15Sopenharmony_ci use crate::bn::BigNumContext; 53692f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 53792f3ab15Sopenharmony_ci use crate::hash::MessageDigest; 53892f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 53992f3ab15Sopenharmony_ci use crate::pkey::PKey; 54092f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 54192f3ab15Sopenharmony_ci use crate::sign::{Signer, Verifier}; 54292f3ab15Sopenharmony_ci 54392f3ab15Sopenharmony_ci #[test] 54492f3ab15Sopenharmony_ci pub fn test_generate() { 54592f3ab15Sopenharmony_ci Dsa::generate(1024).unwrap(); 54692f3ab15Sopenharmony_ci } 54792f3ab15Sopenharmony_ci 54892f3ab15Sopenharmony_ci #[test] 54992f3ab15Sopenharmony_ci fn test_pubkey_generation() { 55092f3ab15Sopenharmony_ci let dsa = Dsa::generate(1024).unwrap(); 55192f3ab15Sopenharmony_ci let p = dsa.p(); 55292f3ab15Sopenharmony_ci let g = dsa.g(); 55392f3ab15Sopenharmony_ci let priv_key = dsa.priv_key(); 55492f3ab15Sopenharmony_ci let pub_key = dsa.pub_key(); 55592f3ab15Sopenharmony_ci let mut ctx = BigNumContext::new().unwrap(); 55692f3ab15Sopenharmony_ci let mut calc = BigNum::new().unwrap(); 55792f3ab15Sopenharmony_ci calc.mod_exp(g, priv_key, p, &mut ctx).unwrap(); 55892f3ab15Sopenharmony_ci assert_eq!(&calc, pub_key) 55992f3ab15Sopenharmony_ci } 56092f3ab15Sopenharmony_ci 56192f3ab15Sopenharmony_ci #[test] 56292f3ab15Sopenharmony_ci fn test_priv_key_from_parts() { 56392f3ab15Sopenharmony_ci let p = BigNum::from_u32(283).unwrap(); 56492f3ab15Sopenharmony_ci let q = BigNum::from_u32(47).unwrap(); 56592f3ab15Sopenharmony_ci let g = BigNum::from_u32(60).unwrap(); 56692f3ab15Sopenharmony_ci let priv_key = BigNum::from_u32(15).unwrap(); 56792f3ab15Sopenharmony_ci let pub_key = BigNum::from_u32(207).unwrap(); 56892f3ab15Sopenharmony_ci 56992f3ab15Sopenharmony_ci let dsa = Dsa::from_private_components(p, q, g, priv_key, pub_key).unwrap(); 57092f3ab15Sopenharmony_ci assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap()); 57192f3ab15Sopenharmony_ci assert_eq!(dsa.priv_key(), &BigNum::from_u32(15).unwrap()); 57292f3ab15Sopenharmony_ci assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap()); 57392f3ab15Sopenharmony_ci assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap()); 57492f3ab15Sopenharmony_ci assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap()); 57592f3ab15Sopenharmony_ci } 57692f3ab15Sopenharmony_ci 57792f3ab15Sopenharmony_ci #[test] 57892f3ab15Sopenharmony_ci fn test_pub_key_from_parts() { 57992f3ab15Sopenharmony_ci let p = BigNum::from_u32(283).unwrap(); 58092f3ab15Sopenharmony_ci let q = BigNum::from_u32(47).unwrap(); 58192f3ab15Sopenharmony_ci let g = BigNum::from_u32(60).unwrap(); 58292f3ab15Sopenharmony_ci let pub_key = BigNum::from_u32(207).unwrap(); 58392f3ab15Sopenharmony_ci 58492f3ab15Sopenharmony_ci let dsa = Dsa::from_public_components(p, q, g, pub_key).unwrap(); 58592f3ab15Sopenharmony_ci assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap()); 58692f3ab15Sopenharmony_ci assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap()); 58792f3ab15Sopenharmony_ci assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap()); 58892f3ab15Sopenharmony_ci assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap()); 58992f3ab15Sopenharmony_ci } 59092f3ab15Sopenharmony_ci 59192f3ab15Sopenharmony_ci #[test] 59292f3ab15Sopenharmony_ci fn test_params() { 59392f3ab15Sopenharmony_ci let params = Dsa::generate_params(1024).unwrap(); 59492f3ab15Sopenharmony_ci let p = params.p().to_owned().unwrap(); 59592f3ab15Sopenharmony_ci let q = params.q().to_owned().unwrap(); 59692f3ab15Sopenharmony_ci let g = params.g().to_owned().unwrap(); 59792f3ab15Sopenharmony_ci let key = params.generate_key().unwrap(); 59892f3ab15Sopenharmony_ci let params2 = Dsa::from_pqg( 59992f3ab15Sopenharmony_ci key.p().to_owned().unwrap(), 60092f3ab15Sopenharmony_ci key.q().to_owned().unwrap(), 60192f3ab15Sopenharmony_ci key.g().to_owned().unwrap(), 60292f3ab15Sopenharmony_ci ) 60392f3ab15Sopenharmony_ci .unwrap(); 60492f3ab15Sopenharmony_ci assert_eq!(p, *params2.p()); 60592f3ab15Sopenharmony_ci assert_eq!(q, *params2.q()); 60692f3ab15Sopenharmony_ci assert_eq!(g, *params2.g()); 60792f3ab15Sopenharmony_ci } 60892f3ab15Sopenharmony_ci 60992f3ab15Sopenharmony_ci #[test] 61092f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 61192f3ab15Sopenharmony_ci fn test_signature() { 61292f3ab15Sopenharmony_ci const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 61392f3ab15Sopenharmony_ci let dsa_ref = Dsa::generate(1024).unwrap(); 61492f3ab15Sopenharmony_ci 61592f3ab15Sopenharmony_ci let p = dsa_ref.p(); 61692f3ab15Sopenharmony_ci let q = dsa_ref.q(); 61792f3ab15Sopenharmony_ci let g = dsa_ref.g(); 61892f3ab15Sopenharmony_ci 61992f3ab15Sopenharmony_ci let pub_key = dsa_ref.pub_key(); 62092f3ab15Sopenharmony_ci let priv_key = dsa_ref.priv_key(); 62192f3ab15Sopenharmony_ci 62292f3ab15Sopenharmony_ci let priv_key = Dsa::from_private_components( 62392f3ab15Sopenharmony_ci BigNumRef::to_owned(p).unwrap(), 62492f3ab15Sopenharmony_ci BigNumRef::to_owned(q).unwrap(), 62592f3ab15Sopenharmony_ci BigNumRef::to_owned(g).unwrap(), 62692f3ab15Sopenharmony_ci BigNumRef::to_owned(priv_key).unwrap(), 62792f3ab15Sopenharmony_ci BigNumRef::to_owned(pub_key).unwrap(), 62892f3ab15Sopenharmony_ci ) 62992f3ab15Sopenharmony_ci .unwrap(); 63092f3ab15Sopenharmony_ci let priv_key = PKey::from_dsa(priv_key).unwrap(); 63192f3ab15Sopenharmony_ci 63292f3ab15Sopenharmony_ci let pub_key = Dsa::from_public_components( 63392f3ab15Sopenharmony_ci BigNumRef::to_owned(p).unwrap(), 63492f3ab15Sopenharmony_ci BigNumRef::to_owned(q).unwrap(), 63592f3ab15Sopenharmony_ci BigNumRef::to_owned(g).unwrap(), 63692f3ab15Sopenharmony_ci BigNumRef::to_owned(pub_key).unwrap(), 63792f3ab15Sopenharmony_ci ) 63892f3ab15Sopenharmony_ci .unwrap(); 63992f3ab15Sopenharmony_ci let pub_key = PKey::from_dsa(pub_key).unwrap(); 64092f3ab15Sopenharmony_ci 64192f3ab15Sopenharmony_ci let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap(); 64292f3ab15Sopenharmony_ci signer.update(TEST_DATA).unwrap(); 64392f3ab15Sopenharmony_ci 64492f3ab15Sopenharmony_ci let signature = signer.sign_to_vec().unwrap(); 64592f3ab15Sopenharmony_ci let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap(); 64692f3ab15Sopenharmony_ci verifier.update(TEST_DATA).unwrap(); 64792f3ab15Sopenharmony_ci assert!(verifier.verify(&signature[..]).unwrap()); 64892f3ab15Sopenharmony_ci } 64992f3ab15Sopenharmony_ci 65092f3ab15Sopenharmony_ci #[test] 65192f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 65292f3ab15Sopenharmony_ci fn test_signature_der() { 65392f3ab15Sopenharmony_ci use std::convert::TryInto; 65492f3ab15Sopenharmony_ci 65592f3ab15Sopenharmony_ci const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 65692f3ab15Sopenharmony_ci let dsa_ref = Dsa::generate(1024).unwrap(); 65792f3ab15Sopenharmony_ci 65892f3ab15Sopenharmony_ci let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap(); 65992f3ab15Sopenharmony_ci let priv_key: PKey<_> = dsa_ref.try_into().unwrap(); 66092f3ab15Sopenharmony_ci 66192f3ab15Sopenharmony_ci let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap(); 66292f3ab15Sopenharmony_ci signer.update(TEST_DATA).unwrap(); 66392f3ab15Sopenharmony_ci 66492f3ab15Sopenharmony_ci let signature = signer.sign_to_vec().unwrap(); 66592f3ab15Sopenharmony_ci eprintln!("{:?}", signature); 66692f3ab15Sopenharmony_ci let signature = DsaSig::from_der(&signature).unwrap(); 66792f3ab15Sopenharmony_ci 66892f3ab15Sopenharmony_ci let r = BigNum::from_slice(&signature.r().to_vec()).unwrap(); 66992f3ab15Sopenharmony_ci let s = BigNum::from_slice(&signature.s().to_vec()).unwrap(); 67092f3ab15Sopenharmony_ci 67192f3ab15Sopenharmony_ci let signature = DsaSig::from_private_components(r, s).unwrap(); 67292f3ab15Sopenharmony_ci let signature = signature.to_der().unwrap(); 67392f3ab15Sopenharmony_ci 67492f3ab15Sopenharmony_ci let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap(); 67592f3ab15Sopenharmony_ci verifier.update(TEST_DATA).unwrap(); 67692f3ab15Sopenharmony_ci assert!(verifier.verify(&signature[..]).unwrap()); 67792f3ab15Sopenharmony_ci } 67892f3ab15Sopenharmony_ci 67992f3ab15Sopenharmony_ci #[test] 68092f3ab15Sopenharmony_ci #[allow(clippy::redundant_clone)] 68192f3ab15Sopenharmony_ci fn clone() { 68292f3ab15Sopenharmony_ci let key = Dsa::generate(2048).unwrap(); 68392f3ab15Sopenharmony_ci drop(key.clone()); 68492f3ab15Sopenharmony_ci } 68592f3ab15Sopenharmony_ci 68692f3ab15Sopenharmony_ci #[test] 68792f3ab15Sopenharmony_ci fn dsa_sig_debug() { 68892f3ab15Sopenharmony_ci let sig = DsaSig::from_der(&[ 68992f3ab15Sopenharmony_ci 48, 46, 2, 21, 0, 135, 169, 24, 58, 153, 37, 175, 248, 200, 45, 251, 112, 238, 238, 89, 69092f3ab15Sopenharmony_ci 172, 177, 182, 166, 237, 2, 21, 0, 159, 146, 151, 237, 187, 8, 82, 115, 14, 183, 103, 69192f3ab15Sopenharmony_ci 12, 203, 46, 161, 208, 251, 167, 123, 131, 69292f3ab15Sopenharmony_ci ]) 69392f3ab15Sopenharmony_ci .unwrap(); 69492f3ab15Sopenharmony_ci let s = format!("{:?}", sig); 69592f3ab15Sopenharmony_ci assert_eq!(s, "DsaSig { r: 774484690634577222213819810519929266740561094381, s: 910998676210681457251421818099943952372231273347 }"); 69692f3ab15Sopenharmony_ci } 69792f3ab15Sopenharmony_ci} 698