1use crate::key;
2use base64;
3use std::io;
4
5fn extract<A>(
9 rd: &mut dyn io::BufRead,
10 start_mark: &str,
11 end_mark: &str,
12 f: &dyn Fn(Vec<u8>) -> A,
13) -> Result<Vec<A>, ()> {
14 let mut ders = Vec::new();
15 let mut b64buf = String::new();
16 let mut take_base64 = false;
17
18 let mut raw_line = Vec::<u8>::new();
19 loop {
20 raw_line.clear();
21 let len = rd
22 .read_until(b'\n', &mut raw_line)
23 .map_err(|_| ())?;
24
25 if len == 0 {
26 return Ok(ders);
27 }
28 let line = String::from_utf8_lossy(&raw_line);
29
30 if line.starts_with(start_mark) {
31 take_base64 = true;
32 continue;
33 }
34
35 if line.starts_with(end_mark) {
36 take_base64 = false;
37 let der = base64::decode(&b64buf).map_err(|_| ())?;
38 ders.push(f(der));
39 b64buf = String::new();
40 continue;
41 }
42
43 if take_base64 {
44 b64buf.push_str(line.trim());
45 }
46 }
47}
48
49pub fn certs(rd: &mut dyn io::BufRead) -> Result<Vec<key::Certificate>, ()> {
52 extract(
53 rd,
54 "-----BEGIN CERTIFICATE-----",
55 "-----END CERTIFICATE-----",
56 &|v| key::Certificate(v),
57 )
58}
59
60pub fn rsa_private_keys(rd: &mut dyn io::BufRead) -> Result<Vec<key::PrivateKey>, ()> {
63 extract(
64 rd,
65 "-----BEGIN RSA PRIVATE KEY-----",
66 "-----END RSA PRIVATE KEY-----",
67 &|v| key::PrivateKey(v),
68 )
69}
70
71pub fn pkcs8_private_keys(rd: &mut dyn io::BufRead) -> Result<Vec<key::PrivateKey>, ()> {
74 extract(
75 rd,
76 "-----BEGIN PRIVATE KEY-----",
77 "-----END PRIVATE KEY-----",
78 &|v| key::PrivateKey(v),
79 )
80}