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