From 94942a48abc55a9932e1be5e012502cc8a68f560 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Tue, 30 Jan 2024 12:56:05 +0100 Subject: [PATCH] rust/pv: Add function to read a private key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a function to read a private key in PEM or DER format. While at it, fix some documentation issues in read_{certs, crls}. Reviewed-by: Marc Hartmayer Signed-off-by: Steffen Eiden Signed-off-by: Jan Höppner --- rust/pv/src/lib.rs | 2 +- rust/pv/src/utils.rs | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/rust/pv/src/lib.rs b/rust/pv/src/lib.rs index 75684fc3..c3c63421 100644 --- a/rust/pv/src/lib.rs +++ b/rust/pv/src/lib.rs @@ -48,7 +48,7 @@ pub mod misc { get_reader_from_cli_file_arg, get_writer_from_cli_file_arg, CertificateOptions, STDIN, STDOUT, }; - pub use crate::utils::{read_certs, read_crls}; + pub use crate::utils::{read_certs, read_crls, read_private_key}; pub use pv_core::misc::*; pub use pv_core::PvLogger; } diff --git a/rust/pv/src/utils.rs b/rust/pv/src/utils.rs index db948330..1a2ab9e4 100644 --- a/rust/pv/src/utils.rs +++ b/rust/pv/src/utils.rs @@ -2,14 +2,16 @@ // // Copyright IBM Corp. 2023 use crate::{Error, Result}; -use openssl::x509::X509Crl; -use openssl::x509::X509; +use openssl::{ + pkey::{PKey, Private}, + x509::{X509Crl, X509}, +}; /// Read all CRLs from the buffer and parse them into a vector. /// /// # Errors /// -/// This function will return an error if the underlying openssl implementation cannot parse `buf` +/// This function will return an error if the underlying OpenSSL implementation cannot parse `buf` /// as `DER` or `PEM`. pub fn read_crls(buf: &[u8]) -> Result> { use openssl_extensions::crl::StackableX509Crl; @@ -23,8 +25,8 @@ pub fn read_crls(buf: &[u8]) -> Result> { /// /// # Errors /// -/// This function will return an error if the underlying openssl implementation cannot parse `buf` -/// as `DER` or `PEM`. +/// This function will return an error if the underlying OpenSSL implementation cannot parse `buf` + pub fn read_certs(buf: &[u8]) -> Result> { X509::from_der(buf) .map(|crt| vec![crt]) @@ -32,9 +34,21 @@ pub fn read_certs(buf: &[u8]) -> Result> { .map_err(Error::Crypto) } +/// Read+parse the first key from the buffer. +/// +/// # Errors +/// +/// This function will return an error if the underlying OpenSSL implementation cannot parse `buf` +/// as `DER` or `PEM`. +pub fn read_private_key(buf: &[u8]) -> Result> { + PKey::private_key_from_der(buf) + .or_else(|_| PKey::private_key_from_pem(buf)) + .map_err(Error::Crypto) +} + #[cfg(test)] mod tests { - use crate::test_utils::*; + use crate::{get_test_asset, test_utils::*}; #[test] fn read_crls() { @@ -55,4 +69,18 @@ mod tests { assert_eq!(super::read_certs(&crt_der).unwrap().len(), 1); assert_eq!(super::read_certs(&fail).unwrap().len(), 0); } + + #[test] + fn read_private_key() { + let key = get_test_asset!("keys/rsa3072key.pem"); + let key = super::read_private_key(key).unwrap(); + assert_eq!(key.rsa().unwrap().size(), 384); + } + + #[test] + fn read_private_key_fail() { + let key = get_test_asset!("exp/secure_guest.hdr"); + let key = super::read_private_key(key); + assert!(key.is_err()); + } }