Skip to content

Commit cde5612

Browse files
committed
pkey_ctx: add ability to crate a PKey from params
1 parent d8d1bca commit cde5612

File tree

1 file changed

+73
-1
lines changed

1 file changed

+73
-1
lines changed

openssl/src/pkey_ctx.rs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,22 @@ 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
use crate::{cvt, cvt_p};
80+
use cfg_if::cfg_if;
7881
use foreign_types::{ForeignType, ForeignTypeRef};
7982
#[cfg(not(any(boringssl, awslc)))]
8083
use libc::c_int;
8184
#[cfg(ossl320)]
8285
use libc::c_uint;
8386
use openssl_macros::corresponds;
8487
use std::convert::TryFrom;
85-
#[cfg(ossl320)]
88+
#[cfg(ossl300)]
8689
use std::ffi::CStr;
8790
use std::ptr;
8891

@@ -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,38 @@ 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;
909953
#[cfg(not(boringssl))]
910954
use cfg_if::cfg_if;
955+
#[cfg(ossl300)]
956+
use std::cmp::Ordering;
911957

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

0 commit comments

Comments
 (0)