1 use crate::key;
2 use base64;
3 use std::io;
4
5 /// Extract and decode all PEM sections from `rd`, which begin with `start_mark`
6 /// and end with `end_mark`. Apply the functor `f` to each decoded buffer,
7 /// and return a Vec of `f`'s return values.
extract<A>( rd: &mut dyn io::BufRead, start_mark: &str, end_mark: &str, f: &dyn Fn(Vec<u8>) -> A, ) -> Result<Vec<A>, ()>8 fn 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
49 /// Extract all the certificates from rd, and return a vec of `key::Certificate`s
50 /// containing the der-format contents.
certs(rd: &mut dyn io::BufRead) -> Result<Vec<key::Certificate>, ()>51 pub 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
60 /// Extract all RSA private keys from rd, and return a vec of `key::PrivateKey`s
61 /// containing the der-format contents.
rsa_private_keys(rd: &mut dyn io::BufRead) -> Result<Vec<key::PrivateKey>, ()>62 pub 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
71 /// Extract all PKCS8-encoded private keys from rd, and return a vec of
72 /// `key::PrivateKey`s containing the der-format contents.
pkcs8_private_keys(rd: &mut dyn io::BufRead) -> Result<Vec<key::PrivateKey>, ()>73 pub 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 }
81