Skip to content

Commit 9a1da55

Browse files
committed
Add helper for combined PEM decoding of ech+key
1 parent 4017292 commit 9a1da55

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/lib.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,50 @@ impl EchConfigListBytes<'_> {
761761
}
762762
}
763763

764+
#[cfg(feature = "alloc")]
765+
impl EchConfigListBytes<'static> {
766+
/// Convert an iterator over PEM items into an `EchConfigListBytes` and private key.
767+
///
768+
/// This handles the "ECHConfig file" format specified in
769+
/// <https://www.ietf.org/archive/id/draft-farrell-tls-pemesni-05.html#name-echconfig-file>
770+
///
771+
/// Use it like:
772+
///
773+
/// ```rust
774+
/// # #[cfg(all(feature = "alloc", feature = "std"))] {
775+
/// # use rustls_pki_types::{EchConfigListBytes, pem::PemObject};
776+
/// let (config, key) = EchConfigListBytes::config_and_key_from_iter(
777+
/// PemObject::pem_file_iter("tests/data/ech.pem").unwrap()
778+
/// ).unwrap();
779+
/// # }
780+
/// ```
781+
pub fn config_and_key_from_iter(
782+
iter: impl Iterator<Item = Result<(SectionKind, Vec<u8>), pem::Error>>,
783+
) -> Result<(Self, PrivatePkcs8KeyDer<'static>), pem::Error> {
784+
let mut key = None;
785+
let mut config = None;
786+
787+
for item in iter {
788+
let (kind, data) = item?;
789+
match kind {
790+
SectionKind::PrivateKey => {
791+
key = PrivatePkcs8KeyDer::from_pem(kind, data);
792+
}
793+
SectionKind::EchConfigList => {
794+
config = Self::from_pem(kind, data);
795+
}
796+
_ => continue,
797+
};
798+
799+
if let (Some(_key), Some(_config)) = (&key, &config) {
800+
return Ok((config.take().unwrap(), key.take().unwrap()));
801+
}
802+
}
803+
804+
Err(pem::Error::NoItemsFound)
805+
}
806+
}
807+
764808
#[cfg(feature = "alloc")]
765809
impl PemObjectFilter for EchConfigListBytes<'static> {
766810
const KIND: SectionKind = SectionKind::EchConfigList;

tests/pem.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,20 @@ fn ech_config() {
193193
EchConfigListBytes::from_pem_file("tests/data/certificate.chain.pem").unwrap_err(),
194194
pem::Error::NoItemsFound
195195
));
196+
197+
let (config, key) = EchConfigListBytes::config_and_key_from_iter(
198+
PemObject::pem_file_iter("tests/data/ech.pem").unwrap(),
199+
)
200+
.unwrap();
201+
println!("{config:?} {key:?}");
202+
203+
assert!(matches!(
204+
EchConfigListBytes::config_and_key_from_iter(
205+
PemObject::pem_file_iter("tests/data/certificate.chain.pem").unwrap(),
206+
)
207+
.unwrap_err(),
208+
pem::Error::NoItemsFound,
209+
));
196210
}
197211

198212
#[test]

0 commit comments

Comments
 (0)