1 | //! # rustls-pemfile |
2 | //! A basic parser for .pem files containing cryptographic keys and certificates. |
3 | //! |
4 | //! The input to this crate is a .pem file containing potentially many sections, |
5 | //! and the output is those sections as alleged DER-encodings. This crate does |
6 | //! not decode the actual DER-encoded keys/certificates. |
7 | //! |
8 | //! ## Quick start |
9 | //! Starting with an `io::BufRead` containing the file to be read: |
10 | //! - Use `read_all()` to ingest the whole file, then work through the contents in-memory, or, |
11 | //! - Use `read_one()` to stream through the file, processing the items as found, or, |
12 | //! - Use `certs()` to extract just the certificates (silently discarding other sections), and |
13 | //! similarly for `rsa_private_keys()` and `pkcs8_private_keys()`. |
14 | //! |
15 | //! ## Example code |
16 | //! ``` |
17 | //! use std::iter; |
18 | //! use rustls_pemfile::{Item, read_one}; |
19 | //! # let mut reader = std::io::BufReader::new(&b"junk \n-----BEGIN RSA PRIVATE KEY----- \nqw \n-----END RSA PRIVATE KEY----- \n" [..]); |
20 | //! // Assume `reader` is any std::io::BufRead implementor |
21 | //! for item in iter::from_fn(|| read_one(&mut reader).transpose()) { |
22 | //! match item.unwrap() { |
23 | //! Item::X509Certificate(cert) => println!("certificate {:?}" , cert), |
24 | //! Item::Crl(crl) => println!("certificate revocation list: {:?}" , crl), |
25 | //! Item::RSAKey(key) => println!("rsa pkcs1 key {:?}" , key), |
26 | //! Item::PKCS8Key(key) => println!("pkcs8 key {:?}" , key), |
27 | //! Item::ECKey(key) => println!("sec1 ec key {:?}" , key), |
28 | //! _ => println!("unhandled item" ), |
29 | //! } |
30 | //! } |
31 | //! ``` |
32 | |
33 | // Require docs for public APIs, deny unsafe code, etc. |
34 | #![forbid (unsafe_code, unused_must_use, unstable_features)] |
35 | #![deny ( |
36 | trivial_casts, |
37 | trivial_numeric_casts, |
38 | missing_docs, |
39 | unused_import_braces, |
40 | unused_extern_crates, |
41 | unused_qualifications |
42 | )] |
43 | |
44 | #[cfg (test)] |
45 | mod tests; |
46 | |
47 | /// --- Main crate APIs: |
48 | mod pemfile; |
49 | pub use pemfile::{read_all, read_one, Item}; |
50 | |
51 | /// --- Legacy APIs: |
52 | use std::io; |
53 | |
54 | /// Extract all the certificates from `rd`, and return a vec of byte vecs |
55 | /// containing the der-format contents. |
56 | /// |
57 | /// This function does not fail if there are no certificates in the file -- |
58 | /// it returns an empty vector. |
59 | pub fn certs(rd: &mut dyn io::BufRead) -> Result<Vec<Vec<u8>>, io::Error> { |
60 | let mut certs: Vec> = Vec::new(); |
61 | |
62 | loop { |
63 | match read_one(rd)? { |
64 | None => return Ok(certs), |
65 | Some(Item::X509Certificate(cert: Vec)) => certs.push(cert), |
66 | _ => {} |
67 | }; |
68 | } |
69 | } |
70 | |
71 | /// Extract all the certificate revocation lists (CRLs) from `rd`, and return a vec of byte vecs |
72 | /// containing the der-format contents. |
73 | /// |
74 | /// This function does not fail if there are no CRLs in the file -- |
75 | /// it returns an empty vector. |
76 | pub fn crls(rd: &mut dyn io::BufRead) -> Result<Vec<Vec<u8>>, io::Error> { |
77 | let mut crls: Vec> = Vec::new(); |
78 | |
79 | loop { |
80 | match read_one(rd)? { |
81 | None => return Ok(crls), |
82 | Some(Item::Crl(crl: Vec)) => crls.push(crl), |
83 | _ => {} |
84 | }; |
85 | } |
86 | } |
87 | |
88 | /// Extract all RSA private keys from `rd`, and return a vec of byte vecs |
89 | /// containing the der-format contents. |
90 | /// |
91 | /// This function does not fail if there are no keys in the file -- it returns an |
92 | /// empty vector. |
93 | pub fn rsa_private_keys(rd: &mut dyn io::BufRead) -> Result<Vec<Vec<u8>>, io::Error> { |
94 | let mut keys: Vec> = Vec::new(); |
95 | |
96 | loop { |
97 | match read_one(rd)? { |
98 | None => return Ok(keys), |
99 | Some(Item::RSAKey(key: Vec)) => keys.push(key), |
100 | _ => {} |
101 | }; |
102 | } |
103 | } |
104 | |
105 | /// Extract all PKCS8-encoded private keys from `rd`, and return a vec of |
106 | /// byte vecs containing the der-format contents. |
107 | /// |
108 | /// This function does not fail if there are no keys in the file -- it returns an |
109 | /// empty vector. |
110 | pub fn pkcs8_private_keys(rd: &mut dyn io::BufRead) -> Result<Vec<Vec<u8>>, io::Error> { |
111 | let mut keys: Vec> = Vec::new(); |
112 | |
113 | loop { |
114 | match read_one(rd)? { |
115 | None => return Ok(keys), |
116 | Some(Item::PKCS8Key(key: Vec)) => keys.push(key), |
117 | _ => {} |
118 | }; |
119 | } |
120 | } |
121 | |
122 | /// Extract all SEC1-encoded EC private keys from `rd`, and return a vec of |
123 | /// byte vecs containing the der-format contents. |
124 | /// |
125 | /// This function does not fail if there are no keys in the file -- it returns an |
126 | /// empty vector. |
127 | pub fn ec_private_keys(rd: &mut dyn io::BufRead) -> Result<Vec<Vec<u8>>, io::Error> { |
128 | let mut keys: Vec> = Vec::new(); |
129 | |
130 | loop { |
131 | match read_one(rd)? { |
132 | None => return Ok(keys), |
133 | Some(Item::ECKey(key: Vec)) => keys.push(key), |
134 | _ => {} |
135 | }; |
136 | } |
137 | } |
138 | |