aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoritz Wanzenböck <[email protected]>2018-06-18 18:10:02 +0200
committerMoritz Wanzenböck <[email protected]>2018-06-18 18:10:02 +0200
commit4994e75d2cecddcaf192623527afe342fb7fd9f2 (patch)
treeb0c1fc0b35a932f93b6e87a99daced1904504b14
parentAdd methods to access private and public part of DSA keys (diff)
downloadrust-openssl-4994e75d2cecddcaf192623527afe342fb7fd9f2.tar.xz
rust-openssl-4994e75d2cecddcaf192623527afe342fb7fd9f2.zip
Add Dsa::from_(private|public)_components
Add 2 methods to create a DSA key pair from its raw components.
-rw-r--r--CHANGELOG.md4
-rw-r--r--openssl-sys/src/libressl/v273.rs16
-rw-r--r--openssl-sys/src/openssl/v110.rs11
-rw-r--r--openssl/src/dsa.rs86
4 files changed, 107 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3df00b89..fd61bd94 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/openssl-sys/src/libressl/v273.rs b/openssl-sys/src/libressl/v273.rs
index 74c331f6..456f8872 100644
--- a/openssl-sys/src/libressl/v273.rs
+++ b/openssl-sys/src/libressl/v273.rs
@@ -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,
diff --git a/openssl-sys/src/openssl/v110.rs b/openssl-sys/src/openssl/v110.rs
index 47d2bee4..493385da 100644
--- a/openssl-sys/src/openssl/v110.rs
+++ b/openssl-sys/src/openssl/v110.rs
@@ -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,
diff --git a/openssl/src/dsa.rs b/openssl/src/dsa.rs
index 684666cf..cd5a2e66 100644
--- a/openssl/src/dsa.rs
+++ b/openssl/src/dsa.rs
@@ -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
+ }
}
}