Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions openssl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,16 @@ pub mod pkcs5;
pub mod pkcs7;
pub mod pkey;
pub mod pkey_ctx;
#[cfg(ossl350)]
pub mod pkey_ml_dsa;
#[cfg(ossl300)]
pub mod provider;
pub mod rand;
pub mod rsa;
pub mod sha;
pub mod sign;
#[cfg(ossl300)]
pub mod signature;
pub mod srtp;
pub mod ssl;
pub mod stack;
Expand Down
84 changes: 84 additions & 0 deletions openssl/src/pkey_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ use crate::bn::BigNumRef;
#[cfg(not(any(boringssl, awslc)))]
use crate::cipher::CipherRef;
use crate::error::ErrorStack;
#[cfg(ossl300)]
use crate::lib_ctx::LibCtxRef;
use crate::md::MdRef;
use crate::nid::Nid;
use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Params, Private};
Expand All @@ -84,6 +86,8 @@ use openssl_macros::corresponds;
use std::convert::TryFrom;
#[cfg(ossl320)]
use std::ffi::CStr;
#[cfg(ossl300)]
use std::ffi::CString;
use std::ptr;

/// HKDF modes of operation.
Expand Down Expand Up @@ -159,6 +163,26 @@ impl PkeyCtx<()> {
Ok(PkeyCtx::from_ptr(ptr))
}
}

/// Creates a new pkey context from the algorithm name.
#[corresponds(EVP_PKEY_CTX_new_from_name)]
#[cfg(ossl300)]
pub fn new_from_name(
libctx: Option<&LibCtxRef>,
name: &str,
propquery: Option<&str>,
) -> Result<Self, ErrorStack> {
unsafe {
let propquery = propquery.map(|s| CString::new(s).unwrap());
let name = CString::new(name).unwrap();
let ptr = cvt_p(ffi::EVP_PKEY_CTX_new_from_name(
libctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr),
name.as_ptr(),
propquery.map_or(ptr::null_mut(), |s| s.as_ptr()),
))?;
Ok(PkeyCtx::from_ptr(ptr))
}
}
}

impl<T> PkeyCtxRef<T>
Expand Down Expand Up @@ -187,6 +211,26 @@ where
Ok(())
}

/// Prepares the context for signature verification over a message
/// using the public key.
#[cfg(ossl340)]
#[corresponds(EVP_PKEY_verify_message_init)]
#[inline]
pub fn verify_message_init(
&mut self,
algo: &mut crate::signature::Signature,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_verify_message_init(
self.as_ptr(),
algo.as_ptr(),
ptr::null(),
))?;
}

Ok(())
}

/// Prepares the context for signature recovery using the public key.
#[corresponds(EVP_PKEY_verify_recover_init)]
#[inline]
Expand Down Expand Up @@ -319,6 +363,25 @@ where
Ok(())
}

/// Prepares the context for signing a message using the private key.
#[cfg(ossl340)]
#[corresponds(EVP_PKEY_sign_message_init)]
#[inline]
pub fn sign_message_init(
&mut self,
algo: &mut crate::signature::Signature,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_sign_message_init(
self.as_ptr(),
algo.as_ptr(),
ptr::null(),
))?;
}

Ok(())
}

/// Sets the peer key used for secret derivation.
#[corresponds(EVP_PKEY_derive_set_peer)]
pub fn derive_set_peer<U>(&mut self, key: &PKeyRef<U>) -> Result<(), ErrorStack>
Expand Down Expand Up @@ -889,6 +952,19 @@ impl<T> PkeyCtxRef<T> {
Ok(())
}

/// Performs the generation operation and returns the resulting
/// key parameters or key.
#[corresponds(EVP_PKEY_generate)]
#[cfg(ossl300)]
#[inline]
pub fn generate(&mut self) -> Result<PKey<Private>, ErrorStack> {
unsafe {
let mut key = ptr::null_mut();
cvt(ffi::EVP_PKEY_generate(self.as_ptr(), &mut key))?;
Ok(PKey::from_ptr(key))
}
}

/// Gets the nonce type for a private key context.
///
/// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979).
Expand All @@ -913,6 +989,14 @@ impl<T> PkeyCtxRef<T> {
}
Ok(NonceType(nonce_type))
}

/// Initializes a conversion from `OsslParam` to `PKey` on given `PkeyCtx`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a really wacky API, and I don't even understand the theory of it. Why is fromdata an operation you'd do with an EVPK_PKEY_CTX?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the docs:

EVP_PKEY_fromdata_init() initializes a public key algorithm context for creating a key or key parameters from user data

So if we're going to pass a param builder in, then we have to call this first it looks like.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel almost stupid for asking this, but why is an EVP_PKEY_CTX even involved in creating an EVP_PKEY? This is the complete opposite of how EVP_PKEY normally are (where you have a key and then you uuse the CTX to do operations with it)?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use EVP_PKEY_Q_keygen for quick key generation, but normally EVP_PKEY_CTX is a structure keeping the operational context so it is involved.

#[corresponds(EVP_PKEY_fromdata_init)]
#[cfg(ossl300)]
pub fn fromdata_init(&mut self) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::EVP_PKEY_fromdata_init(self.as_ptr()))? };
Ok(())
}
}

#[cfg(test)]
Expand Down
Loading
Loading