Skip to content

Commit f2cea2b

Browse files
committed
pkey_ctx: add ability to crate a PKey from params
1 parent 3d13bd8 commit f2cea2b

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

openssl/src/pkey_ctx.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ use crate::error::ErrorStack;
7171
use crate::md::MdRef;
7272
use crate::nid::Nid;
7373
#[cfg(ossl300)]
74+
use crate::params::ParamsRef;
75+
#[cfg(ossl300)]
7476
use crate::pkey::Public;
7577
use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Params, Private};
7678
use crate::rsa::Padding;
@@ -457,6 +459,31 @@ impl<T> PkeyCtxRef<T> {
457459
Ok(())
458460
}
459461

462+
/// Prepares the context for creating a key from user data.
463+
#[corresponds(EVP_PKEY_fromdata_init)]
464+
#[inline]
465+
#[cfg(ossl300)]
466+
#[allow(dead_code)]
467+
pub(crate) fn fromdata_init(&mut self) -> Result<(), ErrorStack> {
468+
cvt(unsafe { ffi::EVP_PKEY_fromdata_init(self.as_ptr()) }).map(|_| ())
469+
}
470+
471+
/// Convert a stack of Params into a PKey.
472+
#[corresponds(EVP_PKEY_fromdata)]
473+
#[inline]
474+
#[cfg(ossl300)]
475+
#[allow(dead_code)]
476+
pub(crate) fn fromdata<K: Selection>(
477+
&mut self,
478+
params: &ParamsRef<'_>,
479+
) -> Result<PKey<K>, ErrorStack> {
480+
let mut key_ptr = ptr::null_mut();
481+
cvt(unsafe {
482+
ffi::EVP_PKEY_fromdata(self.as_ptr(), &mut key_ptr, K::SELECTION, params.as_ptr())
483+
})?;
484+
Ok(unsafe { PKey::from_ptr(key_ptr) })
485+
}
486+
460487
/// Sets which algorithm was used to compute the digest used in a
461488
/// signature. With RSA signatures this causes the signature to be wrapped
462489
/// in a `DigestInfo` structure. This is almost always what you want with
@@ -938,6 +965,18 @@ impl<T> PkeyCtxRef<T> {
938965
}
939966
}
940967

968+
/// Creates a new `PKey` from the given ID and parameters.
969+
#[cfg(ossl300)]
970+
#[allow(dead_code)]
971+
pub(crate) fn pkey_from_params<K: Selection>(
972+
id: Id,
973+
params: &ParamsRef<'_>,
974+
) -> Result<PKey<K>, ErrorStack> {
975+
let mut ctx = PkeyCtx::new_id(id)?;
976+
ctx.fromdata_init()?;
977+
ctx.fromdata(params)
978+
}
979+
941980
#[cfg(test)]
942981
mod test {
943982
use super::*;
@@ -948,11 +987,17 @@ mod test {
948987
use crate::hash::{hash, MessageDigest};
949988
use crate::md::Md;
950989
use crate::nid::Nid;
990+
#[cfg(ossl300)]
991+
use crate::params::ParamBuilder;
951992
use crate::pkey::PKey;
952993
use crate::rsa::Rsa;
953994
use crate::sign::Verifier;
995+
#[cfg(ossl300)]
996+
use crate::util::c_str;
954997
#[cfg(not(boringssl))]
955998
use cfg_if::cfg_if;
999+
#[cfg(ossl300)]
1000+
use std::cmp::Ordering;
9561001

9571002
#[test]
9581003
fn rsa() {
@@ -1324,4 +1369,30 @@ mxJ7imIrEg9nIQ==
13241369
assert_eq!(output, expected_output);
13251370
assert!(ErrorStack::get().errors().is_empty());
13261371
}
1372+
1373+
#[test]
1374+
#[cfg(ossl300)]
1375+
fn test_fromdata() {
1376+
let n = BigNum::from_u32(0xbc747fc5).unwrap();
1377+
let e = BigNum::from_u32(0x10001).unwrap();
1378+
let d = BigNum::from_u32(0x7b133399).unwrap();
1379+
1380+
let params = ParamBuilder::new()
1381+
.push_bignum(c_str(b"n\0"), &n)
1382+
.unwrap()
1383+
.push_bignum(c_str(b"e\0"), &e)
1384+
.unwrap()
1385+
.push_bignum(c_str(b"d\0"), &d)
1386+
.unwrap()
1387+
.build()
1388+
.unwrap();
1389+
1390+
let pkey: PKey<Private> = pkey_from_params(Id::RSA, &params).unwrap();
1391+
1392+
let rsa = pkey.rsa().unwrap();
1393+
1394+
assert_eq!(rsa.n().ucmp(&n), Ordering::Equal);
1395+
assert_eq!(rsa.e().ucmp(&e), Ordering::Equal);
1396+
assert_eq!(rsa.d().ucmp(&d), Ordering::Equal);
1397+
}
13271398
}

0 commit comments

Comments
 (0)