Skip to content

Commit 4a7529e

Browse files
committed
pkey_ctx: add ability to crate a PKey from params
1 parent 9647777 commit 4a7529e

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

openssl/src/pkey_ctx.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,16 @@ use crate::error::ErrorStack;
7070
use crate::md::MdRef;
7171
use crate::nid::Nid;
7272
#[cfg(ossl300)]
73+
use crate::params::ParamsRef;
74+
#[cfg(ossl300)]
7375
use crate::pkey::Public;
7476
use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Params, Private};
7577
use crate::rsa::Padding;
7678
use crate::sign::RsaPssSaltlen;
7779
#[cfg(ossl320)]
7880
use crate::util::c_str;
7981
use crate::{cvt, cvt_p};
82+
use cfg_if::cfg_if;
8083
use foreign_types::{ForeignType, ForeignTypeRef};
8184
#[cfg(not(any(boringssl, awslc)))]
8285
use libc::c_int;
@@ -455,6 +458,31 @@ impl<T> PkeyCtxRef<T> {
455458
Ok(())
456459
}
457460

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

925+
/// Creates a new `PKey` from the given ID and parameters.
926+
#[cfg(ossl300)]
927+
#[allow(dead_code)]
928+
pub(crate) fn pkey_from_params<K: Selection>(
929+
id: Id,
930+
params: &ParamsRef<'_>,
931+
) -> Result<PKey<K>, ErrorStack> {
932+
let mut ctx = PkeyCtx::new_id(id)?;
933+
ctx.fromdata_init()?;
934+
ctx.fromdata(params)
935+
}
936+
897937
#[cfg(test)]
898938
mod test {
899939
use super::*;
940+
#[cfg(ossl300)]
941+
use crate::bn::BigNum;
900942
#[cfg(not(any(boringssl, awslc)))]
901943
use crate::cipher::Cipher;
902944
use crate::ec::{EcGroup, EcKey};
903945
use crate::hash::{hash, MessageDigest};
904946
use crate::md::Md;
905947
use crate::nid::Nid;
948+
#[cfg(ossl300)]
949+
use crate::params::ParamBuilder;
906950
use crate::pkey::PKey;
907951
use crate::rsa::Rsa;
908952
use crate::sign::Verifier;
953+
#[cfg(ossl300)]
954+
use crate::util::c_str;
909955
#[cfg(not(boringssl))]
910956
use cfg_if::cfg_if;
957+
#[cfg(ossl300)]
958+
use std::cmp::Ordering;
911959

912960
#[test]
913961
fn rsa() {
@@ -1267,4 +1315,30 @@ mxJ7imIrEg9nIQ==
12671315
assert_eq!(output, expected_output);
12681316
assert!(ErrorStack::get().errors().is_empty());
12691317
}
1318+
1319+
#[test]
1320+
#[cfg(ossl300)]
1321+
fn test_fromdata() {
1322+
let n = BigNum::from_u32(0xbc747fc5).unwrap();
1323+
let e = BigNum::from_u32(0x10001).unwrap();
1324+
let d = BigNum::from_u32(0x7b133399).unwrap();
1325+
1326+
let params = ParamBuilder::new()
1327+
.push_bignum(c_str(b"n\0"), &n)
1328+
.unwrap()
1329+
.push_bignum(c_str(b"e\0"), &e)
1330+
.unwrap()
1331+
.push_bignum(c_str(b"d\0"), &d)
1332+
.unwrap()
1333+
.build()
1334+
.unwrap();
1335+
1336+
let pkey: PKey<Private> = pkey_from_params(Id::RSA, &params).unwrap();
1337+
1338+
let rsa = pkey.rsa().unwrap();
1339+
1340+
assert_eq!(rsa.n().ucmp(&n), Ordering::Equal);
1341+
assert_eq!(rsa.e().ucmp(&e), Ordering::Equal);
1342+
assert_eq!(rsa.d().ucmp(&d), Ordering::Equal);
1343+
}
12701344
}

0 commit comments

Comments
 (0)