Skip to content

Commit

Permalink
Add helper for combined PEM decoding of ech+key
Browse files Browse the repository at this point in the history
  • Loading branch information
ctz committed Sep 27, 2024
1 parent 4017292 commit 9a1da55
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,50 @@ impl EchConfigListBytes<'_> {
}
}

#[cfg(feature = "alloc")]
impl EchConfigListBytes<'static> {
/// Convert an iterator over PEM items into an `EchConfigListBytes` and private key.
///
/// This handles the "ECHConfig file" format specified in
/// <https://www.ietf.org/archive/id/draft-farrell-tls-pemesni-05.html#name-echconfig-file>
///
/// Use it like:
///
/// ```rust
/// # #[cfg(all(feature = "alloc", feature = "std"))] {
/// # use rustls_pki_types::{EchConfigListBytes, pem::PemObject};
/// let (config, key) = EchConfigListBytes::config_and_key_from_iter(
/// PemObject::pem_file_iter("tests/data/ech.pem").unwrap()
/// ).unwrap();
/// # }
/// ```
pub fn config_and_key_from_iter(
iter: impl Iterator<Item = Result<(SectionKind, Vec<u8>), pem::Error>>,
) -> Result<(Self, PrivatePkcs8KeyDer<'static>), pem::Error> {
let mut key = None;
let mut config = None;

for item in iter {
let (kind, data) = item?;
match kind {
SectionKind::PrivateKey => {
key = PrivatePkcs8KeyDer::from_pem(kind, data);
}
SectionKind::EchConfigList => {
config = Self::from_pem(kind, data);
}
_ => continue,
};

if let (Some(_key), Some(_config)) = (&key, &config) {
return Ok((config.take().unwrap(), key.take().unwrap()));
}
}

Err(pem::Error::NoItemsFound)
}
}

#[cfg(feature = "alloc")]
impl PemObjectFilter for EchConfigListBytes<'static> {
const KIND: SectionKind = SectionKind::EchConfigList;
Expand Down
14 changes: 14 additions & 0 deletions tests/pem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,20 @@ fn ech_config() {
EchConfigListBytes::from_pem_file("tests/data/certificate.chain.pem").unwrap_err(),
pem::Error::NoItemsFound
));

let (config, key) = EchConfigListBytes::config_and_key_from_iter(
PemObject::pem_file_iter("tests/data/ech.pem").unwrap(),
)
.unwrap();
println!("{config:?} {key:?}");

assert!(matches!(
EchConfigListBytes::config_and_key_from_iter(
PemObject::pem_file_iter("tests/data/certificate.chain.pem").unwrap(),
)
.unwrap_err(),
pem::Error::NoItemsFound,
));
}

#[test]
Expand Down

0 comments on commit 9a1da55

Please sign in to comment.