use crate::{asn1, AlgorithmIdentifier, Error, Result};
use core::{convert::TryFrom, fmt};
#[cfg(feature = "alloc")]
use {crate::document::PrivateKeyDocument, zeroize::Zeroizing};
#[cfg(feature = "pem")]
use crate::pem;
#[derive(Copy, Clone)]
pub struct PrivateKeyInfo<'a> {
pub algorithm: AlgorithmIdentifier,
pub private_key: &'a [u8],
}
impl<'a> PrivateKeyInfo<'a> {
pub fn from_der(bytes: &'a [u8]) -> Result<Self> {
asn1::decoder::decode_private_key_info(bytes)
}
pub fn write_der<'b>(&self, buffer: &'b mut [u8]) -> Result<&'b [u8]> {
let offset = asn1::encoder::encode_private_key_info(buffer, self)?;
Ok(&buffer[..offset])
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
pub fn to_der(&self) -> PrivateKeyDocument {
let len = asn1::encoder::private_key_info_len(self).unwrap();
let mut buffer = Zeroizing::new(vec![0u8; len]);
self.write_der(&mut buffer).unwrap();
PrivateKeyDocument::from_der(&buffer).expect("malformed DER")
}
#[cfg(feature = "pem")]
#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
pub fn to_pem(&self) -> Zeroizing<alloc::string::String> {
let doc = self.to_der();
let pem = pem::encode(doc.as_ref(), pem::PRIVATE_KEY_BOUNDARY);
Zeroizing::new(pem)
}
}
impl<'a> TryFrom<&'a [u8]> for PrivateKeyInfo<'a> {
type Error = Error;
fn try_from(bytes: &'a [u8]) -> Result<Self> {
Self::from_der(bytes)
}
}
impl<'a> fmt::Debug for PrivateKeyInfo<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PrivateKeyInfo")
.field("algorithm", &self.algorithm)
.finish() }
}