rustls_cert_file_reader/
pem.rs1use std::io::ErrorKind;
4
5use rustls_pemfile::{read_one, Item};
6
7pub fn parse_certs(
9 rd: &mut dyn std::io::BufRead,
10) -> Result<Vec<rustls_pki_types::CertificateDer<'static>>, std::io::Error> {
11 let mut certs = Vec::new();
12
13 loop {
14 let Some(item) = read_one(rd)? else {
15 return Ok(certs);
16 };
17 if let Item::X509Certificate(cert) = item {
18 certs.push(cert);
19 }
20 }
21}
22
23pub fn parse_key(
25 rd: &mut dyn std::io::BufRead,
26) -> Result<rustls_pki_types::PrivateKeyDer<'static>, std::io::Error> {
27 let key = loop {
28 let Some(item) = read_one(rd)? else {
29 return Err(std::io::Error::new(
30 ErrorKind::NotFound,
31 "no key found in the given data".to_string(),
32 ));
33 };
34 if let Some(key) = private_key_from_pemfile_item(item) {
35 break key;
36 }
37 };
38
39 loop {
41 let Some(item) = read_one(rd)? else {
42 break;
43 };
44
45 if private_key_from_pemfile_item(item).is_some() {
46 return Err(std::io::Error::new(
47 ErrorKind::InvalidInput,
48 "more than one key".to_string(),
49 ));
50 }
51 }
52
53 Ok(key)
54}
55
56fn private_key_from_pemfile_item(
59 item: rustls_pemfile::Item,
60) -> Option<rustls_pki_types::PrivateKeyDer<'static>> {
61 Some(match item {
62 Item::Pkcs1Key(key) => key.into(),
63 Item::Pkcs8Key(key) => key.into(),
64 Item::Sec1Key(key) => key.into(),
65 _ => return None,
66 })
67}