Commit 4994e75d authored by Moritz Wanzenböck's avatar Moritz Wanzenböck
Browse files

Add Dsa::from_(private|public)_components

Add 2 methods to create a DSA key pair from its raw components.
parent 52c942f4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -2,6 +2,10 @@

## [Unreleased]

### Added
* Added `DsaRef::pub_key` and `DsaRef::priv_key`.
* Added `Dsa::from_private_components` and `Dsa::from_public_components`.

## [v0.10.10] - 2018-06-06

### Added
+16 −0
Original line number Diff line number Diff line
@@ -47,6 +47,22 @@ extern "C" {
        q: *mut *const ::BIGNUM,
        q: *mut *const ::BIGNUM,
    );
    pub fn DSA_set0_pqg(
        d: *mut ::DSA,
        p: *mut ::BIGNUM,
        q: *mut ::BIGNUM,
        q: *mut ::BIGNUM,
    ) -> c_int;
    pub fn DSA_get0_key(
        d: *const ::DSA,
        pub_key: *mut *const ::BIGNUM,
        priv_key: *mut *const ::BIGNUM,
    );
    pub fn DSA_set0_key(
        d: *mut ::DSA,
        pub_key: *mut ::BIGNUM,
        priv_key: *mut ::BIGNUM,
    ) -> c_int;

    pub fn ECDSA_SIG_get0(
        sig: *const ::ECDSA_SIG,
+11 −0
Original line number Diff line number Diff line
@@ -235,11 +235,22 @@ extern "C" {
        q: *mut *const ::BIGNUM,
        q: *mut *const ::BIGNUM,
    );
    pub fn DSA_set0_pqg(
        d: *mut ::DSA,
        p: *mut ::BIGNUM,
        q: *mut ::BIGNUM,
        q: *mut ::BIGNUM,
    ) -> c_int;
    pub fn DSA_get0_key(
        d: *const ::DSA,
        pub_key: *mut *const ::BIGNUM,
        priv_key: *mut *const ::BIGNUM,
    );
    pub fn DSA_set0_key(
        d: *mut ::DSA,
        pub_key: *mut ::BIGNUM,
        priv_key: *mut ::BIGNUM,
    ) -> c_int;
    pub fn RSA_get0_key(
        r: *const ::RSA,
        n: *mut *const ::BIGNUM,
+76 −10
Original line number Diff line number Diff line
@@ -10,8 +10,9 @@ use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use std::fmt;
use std::ptr;
use std::mem;

use bn::BigNumRef;
use bn::{BigNum, BigNumRef, BigNumContext};
use error::ErrorStack;
use pkey::{HasParams, HasPrivate, HasPublic, Private, Public};
use {cvt, cvt_p};
@@ -84,7 +85,7 @@ where
        ffi::i2d_DSA_PUBKEY
    }

    /// Returns a reference to the public exponent.
    /// Returns a reference to the public key component of `self`.
    pub fn pub_key(&self) -> &BigNumRef {
        unsafe {
            let mut pub_key = ptr::null();
@@ -98,6 +99,7 @@ impl<T> DsaRef<T>
where
    T: HasPrivate,
{
    /// Returns a reference to the private key component of `self`.
    pub fn priv_key(&self) -> &BigNumRef {
        unsafe {
            let mut priv_key = ptr::null();
@@ -154,7 +156,7 @@ impl Dsa<Private> {
    /// Calls [`DSA_generate_parameters_ex`] to populate the `p`, `g`, and `q` values.
    /// These values are used to generate the key pair with [`DSA_generate_key`].
    ///
    /// The `bits` parameter coresponds to the length of the prime `p`.
    /// The `bits` parameter corresponds to the length of the prime `p`.
    ///
    /// [`DSA_generate_parameters_ex`]: https://www.openssl.org/docs/man1.1.0/crypto/DSA_generate_parameters_ex.html
    /// [`DSA_generate_key`]: https://www.openssl.org/docs/man1.1.0/crypto/DSA_generate_key.html
@@ -175,6 +177,31 @@ impl Dsa<Private> {
            Ok(dsa)
        }
    }

    /// 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.
    /// The corresponding public component is calculated from the private component.
    pub fn from_private_components(
        p: BigNum,
        q: BigNum,
        g: BigNum,
        priv_key: BigNum,
    ) -> Result<Dsa<Private>, ErrorStack> {
        ffi::init();
        unsafe {
            let mut bn_ctx = BigNumContext::new()?;
            let mut pub_key = BigNum::new()?;
            pub_key.mod_exp(&g, &priv_key, &p, &mut bn_ctx)?;
            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> {
@@ -201,6 +228,27 @@ impl Dsa<Public> {
        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> {
@@ -211,7 +259,7 @@ impl<T> fmt::Debug for Dsa<T> {

cfg_if! {
    if #[cfg(any(ossl110, libressl273))] {
        use ffi::DSA_get0_pqg;
        use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg};
    } else {
        #[allow(bad_style)]
        unsafe fn DSA_get0_pqg(
@@ -230,13 +278,7 @@ cfg_if! {
                *g = (*d).g;
            }
        }
    }
}

cfg_if! {
    if #[cfg(any(ossl110, libressl273))] {
        use ffi::DSA_get0_key;
    } else {
        #[allow(bad_style)]
        unsafe fn DSA_get0_pqg(
            d: *mut ffi::DSA,
@@ -250,6 +292,30 @@ cfg_if! {
                *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
        }
    }
}