rustls_pemfile/
lib.rs

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::new();
61
62    loop {
63        match read_one(rd)? {
64            None => return Ok(certs),
65            Some(Item::X509Certificate(cert)) => 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::new();
78
79    loop {
80        match read_one(rd)? {
81            None => return Ok(crls),
82            Some(Item::Crl(crl)) => 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::new();
95
96    loop {
97        match read_one(rd)? {
98            None => return Ok(keys),
99            Some(Item::RSAKey(key)) => 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::new();
112
113    loop {
114        match read_one(rd)? {
115            None => return Ok(keys),
116            Some(Item::PKCS8Key(key)) => 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::new();
129
130    loop {
131        match read_one(rd)? {
132            None => return Ok(keys),
133            Some(Item::ECKey(key)) => keys.push(key),
134            _ => {}
135        };
136    }
137}