Skip to content
Merged
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
94 changes: 93 additions & 1 deletion boring/src/pkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use crate::ec::EcKey;
use crate::error::ErrorStack;
use crate::rsa::Rsa;
use crate::util::{invoke_passwd_cb, CallbackState};
use crate::{cvt, cvt_p};
use crate::{cvt, cvt_0i, cvt_p};

/// A tag type indicating that a key only has parameters.
pub enum Params {}
Expand Down Expand Up @@ -222,6 +222,36 @@ where
{
unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 }
}

/// Returns the length of the "raw" form of the public key. Only supported for certain key types.
#[corresponds(EVP_PKEY_get_raw_public_key)]
pub fn raw_public_key_len(&self) -> Result<usize, ErrorStack> {
unsafe {
let mut size = 0;
_ = cvt_0i(ffi::EVP_PKEY_get_raw_public_key(
self.as_ptr(),
std::ptr::null_mut(),
&mut size,
))?;
Ok(size)
}
}

/// Outputs a copy of the "raw" form of the public key. Only supported for certain key types.
///
/// Returns the used portion of `out`.
#[corresponds(EVP_PKEY_get_raw_public_key)]
pub fn raw_public_key<'a>(&self, out: &'a mut [u8]) -> Result<&'a [u8], ErrorStack> {
unsafe {
let mut size = out.len();
_ = cvt_0i(ffi::EVP_PKEY_get_raw_public_key(
self.as_ptr(),
out.as_mut_ptr(),
&mut size,
))?;
Ok(&out[..size])
}
}
}

impl<T> PKeyRef<T>
Expand Down Expand Up @@ -260,6 +290,36 @@ where
private_key_to_der_pkcs8_passphrase,
ffi::i2d_PKCS8PrivateKey_bio
}

/// Returns the length of the "raw" form of the private key. Only supported for certain key types.
#[corresponds(EVP_PKEY_get_raw_private_key)]
pub fn raw_private_key_len(&self) -> Result<usize, ErrorStack> {
unsafe {
let mut size = 0;
_ = cvt_0i(ffi::EVP_PKEY_get_raw_private_key(
self.as_ptr(),
std::ptr::null_mut(),
&mut size,
))?;
Ok(size)
}
}

/// Outputs a copy of the "raw" form of the private key. Only supported for certain key types.
///
/// Returns the used portion of `out`.
#[corresponds(EVP_PKEY_get_raw_private_key)]
pub fn raw_private_key<'a>(&self, out: &'a mut [u8]) -> Result<&'a [u8], ErrorStack> {
unsafe {
let mut size = out.len();
_ = cvt_0i(ffi::EVP_PKEY_get_raw_private_key(
self.as_ptr(),
out.as_mut_ptr(),
&mut size,
))?;
Ok(&out[..size])
}
}
}

impl<T> fmt::Debug for PKey<T> {
Expand Down Expand Up @@ -445,6 +505,8 @@ use crate::ffi::EVP_PKEY_up_ref;

#[cfg(test)]
mod tests {
use hex::FromHex as _;

use crate::ec::EcKey;
use crate::nid::Nid;
use crate::rsa::Rsa;
Expand Down Expand Up @@ -555,4 +617,34 @@ mod tests {
assert_eq!(pkey.id(), Id::EC);
assert!(pkey.rsa().is_err());
}

#[test]
fn test_raw_accessors() {
const ED25519_PRIVATE_KEY_DER: &str = concat!(
"302e020100300506032b6570042204207c8c6497f9960d5595d7815f550569e5",
"f77764ac97e63e339aaa68cc1512b683"
);
let pkey =
PKey::private_key_from_der(&Vec::from_hex(ED25519_PRIVATE_KEY_DER).unwrap()).unwrap();
assert_eq!(pkey.id(), Id::ED25519);

let priv_len = pkey.raw_private_key_len().unwrap();
assert_eq!(priv_len, 32);
let mut raw_private_key_buf = [0; 40];
let raw_private_key = pkey.raw_private_key(&mut raw_private_key_buf).unwrap();
assert_eq!(raw_private_key.len(), 32);
assert_ne!(raw_private_key, [0; 32]);
pkey.raw_private_key(&mut [0; 5])
.expect_err("buffer too small");

let pub_len = pkey.raw_public_key_len().unwrap();
assert_eq!(pub_len, 32);
let mut raw_public_key_buf = [0; 40];
let raw_public_key = pkey.raw_public_key(&mut raw_public_key_buf).unwrap();
assert_eq!(raw_public_key.len(), 32);
assert_ne!(raw_public_key, [0; 32]);
assert_ne!(raw_public_key, raw_private_key);
pkey.raw_public_key(&mut [0; 5])
.expect_err("buffer too small");
}
}
Loading