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)]
45mod tests;
46
47/// --- Main crate APIs:
48mod pemfile;
49pub use pemfile::{read_all, read_one, Item};
50
51/// --- Legacy APIs:
52use 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.
59pub 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.
76pub 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.
93pub 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.
110pub 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.
127pub 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