Skip to content

Commit 93f9e02

Browse files
authored
Merge pull request #2432 from huwcbjones/huw/pkey-ctx-dsa-paramgen
pkey_ctx: add ability to generate DSA params & keys
2 parents 9584d98 + 17fe4c8 commit 93f9e02

File tree

6 files changed

+95
-1
lines changed

6 files changed

+95
-1
lines changed

openssl-sys/src/dsa.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use libc::*;
2+
use std::ptr;
3+
4+
use super::super::*;
5+
6+
cfg_if! {
7+
if #[cfg(not(ossl300))] {
8+
pub unsafe fn EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx: *mut EVP_PKEY_CTX, nbits: c_int) -> c_int {
9+
EVP_PKEY_CTX_ctrl(
10+
ctx,
11+
EVP_PKEY_DSA,
12+
EVP_PKEY_OP_PARAMGEN,
13+
EVP_PKEY_CTRL_DSA_PARAMGEN_BITS,
14+
nbits,
15+
ptr::null_mut(),
16+
)
17+
}
18+
}
19+
}
20+
21+
pub const EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: c_int = EVP_PKEY_ALG_CTRL + 1;

openssl-sys/src/evp.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ cfg_if! {
162162
}
163163
}
164164

165+
pub const EVP_PKEY_OP_PARAMGEN: c_int = 1 << 1;
165166
pub const EVP_PKEY_OP_KEYGEN: c_int = 1 << 2;
166167
cfg_if! {
167168
if #[cfg(ossl300)] {

openssl-sys/src/handwritten/dsa.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ use libc::*;
22

33
use super::super::*;
44

5+
#[cfg(ossl300)]
6+
extern "C" {
7+
pub fn EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx: *mut EVP_PKEY_CTX, nbits: c_int) -> c_int;
8+
}
9+
510
cfg_if! {
611
if #[cfg(any(ossl110, libressl280))] {
712
pub enum DSA_SIG {}

openssl-sys/src/handwritten/evp.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,9 @@ extern "C" {
584584
...
585585
) -> *mut EVP_PKEY;
586586
pub fn EVP_PKEY_keygen_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
587+
pub fn EVP_PKEY_paramgen_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
587588
pub fn EVP_PKEY_keygen(ctx: *mut EVP_PKEY_CTX, key: *mut *mut EVP_PKEY) -> c_int;
589+
pub fn EVP_PKEY_paramgen(ctx: *mut EVP_PKEY_CTX, key: *mut *mut EVP_PKEY) -> c_int;
588590

589591
pub fn EVP_PKEY_sign_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
590592
pub fn EVP_PKEY_sign(

openssl-sys/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ mod openssl {
7373
pub use self::bn::*;
7474
pub use self::cms::*;
7575
pub use self::crypto::*;
76+
pub use self::dsa::*;
7677
pub use self::dtls1::*;
7778
pub use self::ec::*;
7879
pub use self::err::*;
@@ -103,6 +104,7 @@ mod openssl {
103104
mod bn;
104105
mod cms;
105106
mod crypto;
107+
mod dsa;
106108
mod dtls1;
107109
mod ec;
108110
mod err;

openssl/src/pkey_ctx.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ let cmac_key = ctx.keygen().unwrap();
6868
use crate::cipher::CipherRef;
6969
use crate::error::ErrorStack;
7070
use crate::md::MdRef;
71-
use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private};
71+
use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Params, Private};
7272
use crate::rsa::Padding;
7373
use crate::sign::RsaPssSaltlen;
7474
use crate::{cvt, cvt_p};
@@ -420,6 +420,17 @@ impl<T> PkeyCtxRef<T> {
420420
Ok(())
421421
}
422422

423+
/// Prepares the context for key parameter generation.
424+
#[corresponds(EVP_PKEY_paramgen_init)]
425+
#[inline]
426+
pub fn paramgen_init(&mut self) -> Result<(), ErrorStack> {
427+
unsafe {
428+
cvt(ffi::EVP_PKEY_paramgen_init(self.as_ptr()))?;
429+
}
430+
431+
Ok(())
432+
}
433+
423434
/// Sets which algorithm was used to compute the digest used in a
424435
/// signature. With RSA signatures this causes the signature to be wrapped
425436
/// in a `DigestInfo` structure. This is almost always what you want with
@@ -436,6 +447,22 @@ impl<T> PkeyCtxRef<T> {
436447
Ok(())
437448
}
438449

450+
/// Sets the DSA paramgen bits.
451+
///
452+
/// This is only useful for DSA keys.
453+
#[corresponds(EVP_PKEY_CTX_set_dsa_paramgen_bits)]
454+
#[inline]
455+
pub fn set_dsa_paramgen_bits(&mut self, bits: u32) -> Result<(), ErrorStack> {
456+
unsafe {
457+
cvt(ffi::EVP_PKEY_CTX_set_dsa_paramgen_bits(
458+
self.as_ptr(),
459+
bits as i32,
460+
))?;
461+
}
462+
463+
Ok(())
464+
}
465+
439466
/// Returns the RSA padding mode in use.
440467
///
441468
/// This is only useful for RSA keys.
@@ -734,6 +761,17 @@ impl<T> PkeyCtxRef<T> {
734761
}
735762
}
736763

764+
/// Generates a new set of key parameters.
765+
#[corresponds(EVP_PKEY_paramgen)]
766+
#[inline]
767+
pub fn paramgen(&mut self) -> Result<PKey<Params>, ErrorStack> {
768+
unsafe {
769+
let mut key = ptr::null_mut();
770+
cvt(ffi::EVP_PKEY_paramgen(self.as_ptr(), &mut key))?;
771+
Ok(PKey::from_ptr(key))
772+
}
773+
}
774+
737775
/// Sets the nonce type for a private key context.
738776
///
739777
/// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979).
@@ -794,6 +832,8 @@ mod test {
794832
use crate::pkey::PKey;
795833
use crate::rsa::Rsa;
796834
use crate::sign::Verifier;
835+
#[cfg(not(boringssl))]
836+
use cfg_if::cfg_if;
797837

798838
#[test]
799839
fn rsa() {
@@ -920,6 +960,29 @@ mod test {
920960
ctx.keygen().unwrap();
921961
}
922962

963+
#[test]
964+
#[cfg(not(boringssl))]
965+
fn dsa_paramgen() {
966+
let mut ctx = PkeyCtx::new_id(Id::DSA).unwrap();
967+
ctx.paramgen_init().unwrap();
968+
ctx.set_dsa_paramgen_bits(2048).unwrap();
969+
let params = ctx.paramgen().unwrap();
970+
971+
let size = {
972+
cfg_if! {
973+
if #[cfg(awslc)] {
974+
72
975+
} else if #[cfg(any(libressl, all(ossl101, not(ossl102))))] {
976+
// LibreSSL and OpenSSL 1.0.1 and earlier
977+
48
978+
} else {
979+
64
980+
}
981+
}
982+
};
983+
assert_eq!(params.size(), size);
984+
}
985+
923986
#[test]
924987
#[cfg(any(ossl110, boringssl, libressl360, awslc))]
925988
fn hkdf() {

0 commit comments

Comments
 (0)