#![cfg_attr(feature = "std", doc = "```")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
#![forbid(unsafe_code, unused_must_use, unstable_features)]
#![deny(
trivial_casts,
trivial_numeric_casts,
missing_docs,
unused_import_braces,
unused_extern_crates,
unused_qualifications
)]
#![no_std]
extern crate alloc;
#[cfg(any(feature = "std", test))]
extern crate std;
#[cfg(test)]
#[cfg(feature = "std")]
mod tests;
mod pemfile;
#[cfg(feature = "std")]
use core::iter;
#[cfg(feature = "std")]
use std::io;
#[cfg(feature = "std")]
pub use pemfile::{read_all, read_one};
pub use pemfile::{read_one_from_slice, Error, Item};
#[cfg(feature = "std")]
use pki_types::PrivateKeyDer;
#[cfg(feature = "std")]
use pki_types::{
CertificateDer, CertificateRevocationListDer, CertificateSigningRequestDer, PrivatePkcs1KeyDer,
PrivatePkcs8KeyDer, PrivateSec1KeyDer, SubjectPublicKeyInfoDer,
};
#[cfg(feature = "std")]
pub fn certs(
rd: &mut dyn io::BufRead,
) -> impl Iterator<Item = Result<CertificateDer<'static>, io::Error>> + '_ {
iter::from_fn(move || read_one(rd).transpose()).filter_map(|item| match item {
Ok(Item::X509Certificate(cert)) => Some(Ok(cert)),
Err(err) => Some(Err(err)),
_ => None,
})
}
#[cfg(feature = "std")]
pub fn private_key(rd: &mut dyn io::BufRead) -> Result<Option<PrivateKeyDer<'static>>, io::Error> {
for result in iter::from_fn(move || read_one(rd).transpose()) {
match result? {
Item::Pkcs1Key(key) => return Ok(Some(key.into())),
Item::Pkcs8Key(key) => return Ok(Some(key.into())),
Item::Sec1Key(key) => return Ok(Some(key.into())),
Item::X509Certificate(_)
| Item::SubjectPublicKeyInfo(_)
| Item::Crl(_)
| Item::Csr(_) => continue,
}
}
Ok(None)
}
#[cfg(feature = "std")]
pub fn csr(
rd: &mut dyn io::BufRead,
) -> Result<Option<CertificateSigningRequestDer<'static>>, io::Error> {
for result in iter::from_fn(move || read_one(rd).transpose()) {
match result? {
Item::Csr(csr) => return Ok(Some(csr)),
Item::Pkcs1Key(_)
| Item::Pkcs8Key(_)
| Item::Sec1Key(_)
| Item::X509Certificate(_)
| Item::SubjectPublicKeyInfo(_)
| Item::Crl(_) => continue,
}
}
Ok(None)
}
#[cfg(feature = "std")]
pub fn crls(
rd: &mut dyn io::BufRead,
) -> impl Iterator<Item = Result<CertificateRevocationListDer<'static>, io::Error>> + '_ {
iter::from_fn(move || read_one(rd).transpose()).filter_map(|item| match item {
Ok(Item::Crl(crl)) => Some(Ok(crl)),
Err(err) => Some(Err(err)),
_ => None,
})
}
#[cfg(feature = "std")]
pub fn rsa_private_keys(
rd: &mut dyn io::BufRead,
) -> impl Iterator<Item = Result<PrivatePkcs1KeyDer<'static>, io::Error>> + '_ {
iter::from_fn(move || read_one(rd).transpose()).filter_map(|item| match item {
Ok(Item::Pkcs1Key(key)) => Some(Ok(key)),
Err(err) => Some(Err(err)),
_ => None,
})
}
#[cfg(feature = "std")]
pub fn pkcs8_private_keys(
rd: &mut dyn io::BufRead,
) -> impl Iterator<Item = Result<PrivatePkcs8KeyDer<'static>, io::Error>> + '_ {
iter::from_fn(move || read_one(rd).transpose()).filter_map(|item| match item {
Ok(Item::Pkcs8Key(key)) => Some(Ok(key)),
Err(err) => Some(Err(err)),
_ => None,
})
}
#[cfg(feature = "std")]
pub fn ec_private_keys(
rd: &mut dyn io::BufRead,
) -> impl Iterator<Item = Result<PrivateSec1KeyDer<'static>, io::Error>> + '_ {
iter::from_fn(move || read_one(rd).transpose()).filter_map(|item| match item {
Ok(Item::Sec1Key(key)) => Some(Ok(key)),
Err(err) => Some(Err(err)),
_ => None,
})
}
#[cfg(feature = "std")]
pub fn public_keys(
rd: &mut dyn io::BufRead,
) -> impl Iterator<Item = Result<SubjectPublicKeyInfoDer<'static>, io::Error>> + '_ {
iter::from_fn(move || read_one(rd).transpose()).filter_map(|item| match item {
Ok(Item::SubjectPublicKeyInfo(key)) => Some(Ok(key)),
Err(err) => Some(Err(err)),
_ => None,
})
}