Skip to content

Commit 28eade4

Browse files
committed
use underlying libraries for pem parsing
1 parent beb8ebc commit 28eade4

File tree

4 files changed

+3
-116
lines changed

4 files changed

+3
-116
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ libc = "0.2"
2121
tempfile = "3.0"
2222

2323
[target.'cfg(target_os = "windows")'.dependencies]
24-
schannel = "0.1.16"
24+
schannel = "0.1.17"
2525

2626
[target.'cfg(not(any(target_os = "windows", target_os = "macos", target_os = "ios")))'.dependencies]
2727
log = "0.4.5"

src/imp/openssl.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use std::error;
1515
use std::fmt;
1616
use std::io;
1717
use std::sync::{Once, ONCE_INIT};
18-
use pem;
1918

2019
use {Protocol, TlsAcceptorBuilder, TlsConnectorBuilder};
2120

@@ -171,11 +170,7 @@ impl Identity {
171170

172171
pub fn from_pkcs8(buf: &[u8], key: &[u8]) -> Result<Identity, Error> {
173172
let pkey = PKey::private_key_from_pem(key)?;
174-
let mut cert_chain = vec!();
175-
for buf in pem::PemBlock::new(buf) {
176-
cert_chain.push(X509::from_pem(buf)?);
177-
}
178-
let mut cert_chain = cert_chain.into_iter();
173+
let mut cert_chain = X509::stack_from_pem(buf)?.into_iter();
179174
let cert = cert_chain.next();
180175
let chain = cert_chain.collect();
181176
Ok(Identity {

src/imp/schannel.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,8 @@ impl Identity {
112112
Ok(container) => container,
113113
Err(_) => options.new_keyset(true).acquire(type_)?,
114114
};
115-
let key = crate::pem::pem_to_der(key, Some(crate::pem::PEM_PRIVATE_KEY)).expect("invalid PKCS8 key provided");
116115
container.import()
117-
.import_pkcs8(&key)?;
116+
.import_pkcs8_pem(&key)?;
118117

119118
cert.set_key_prov_info()
120119
.container("schannel")

src/pem.rs

Lines changed: 0 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -35,67 +35,6 @@ lazy_static!{
3535
};
3636
}
3737

38-
/// Convert PEM to DER. If `guard` is specified (e.g. as PEM_CERTIFICATE), then the guardlines are
39-
/// verified to match the expected string. Otherwise, the guardlines are verified to generally have
40-
/// the correct form.
41-
///
42-
/// On failure (due to guardlines syntax or an illegal PEM character), returns None.
43-
pub fn pem_to_der<T: ?Sized + AsRef<[u8]>>(pem: &T, guard: Option<&PemGuard>) -> Option<Vec<u8>> {
44-
let pem = match std::str::from_utf8(pem.as_ref()) {
45-
Err(_) => return None,
46-
Ok(p) => p,
47-
};
48-
let pem = match pem.find("-----") {
49-
Some(i) => pem.split_at(i).1,
50-
None => return None,
51-
};
52-
let mut lines = pem.lines();
53-
54-
let begin = match lines.next() {
55-
Some(l) => l,
56-
None => return None,
57-
};
58-
let end = match lines.last() {
59-
Some(l) => l,
60-
None => return None,
61-
};
62-
63-
if let Some(g) = guard {
64-
if begin != g.begin || end != g.end {
65-
return None;
66-
}
67-
} else {
68-
if !begin.starts_with("-----BEGIN ") || !begin.ends_with("-----") ||
69-
!end.starts_with("-----END") || !end.ends_with("-----") {
70-
return None;
71-
}
72-
}
73-
74-
let body_start = pem.char_indices()
75-
.skip(begin.len())
76-
.skip_while(|t| t.1.is_whitespace())
77-
.next().unwrap().0;
78-
let body_end = pem.rmatch_indices(&end).next().unwrap().0;
79-
pem[body_start..body_end].from_base64().ok()
80-
}
81-
82-
/// Convert DER to PEM. The guardlines use the identifying string chosen by `guard`
83-
/// (e.g. PEM_CERTIFICATE).
84-
pub fn der_to_pem<T: ?Sized + AsRef<[u8]>>(der: &T, guard: &PemGuard) -> String {
85-
let mut pem = String::new();
86-
87-
pem.push_str(guard.begin);
88-
pem.push('\n');
89-
if der.as_ref().len() > 0 {
90-
pem.push_str(&der.as_ref().to_base64(*BASE64_PEM));
91-
pem.push('\n');
92-
}
93-
pem.push_str(guard.end);
94-
pem.push('\n');
95-
96-
pem
97-
}
98-
9938
/// Split data by PEM guard lines
10039
pub struct PemBlock<'a> {
10140
pem_block: &'a str,
@@ -129,52 +68,6 @@ impl<'a> Iterator for PemBlock<'a> {
12968
}
13069
}
13170

132-
#[test]
133-
fn test_pem() {
134-
assert!(pem_to_der("", None).is_none());
135-
assert!(pem_to_der("-----BEGIN CERTIFICATE-----\n-----END JUNK-----\n", Some(PEM_CERTIFICATE)).is_none());
136-
assert!(pem_to_der("-----BEGIN JUNK-----\n-----END CERTIFICATE-----\n", Some(PEM_CERTIFICATE)).is_none());
137-
assert_eq!(pem_to_der("-----BEGIN JUNK-----\n-----END GARBAGE-----\n", None).unwrap(), vec![]);
138-
assert_eq!(pem_to_der("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n", None).unwrap(), vec![]);
139-
assert!(pem_to_der("-----EGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n", None).is_none());
140-
assert!(pem_to_der("-----BEGIN CERTIFICATE-----\n-----ND CERTIFICATE-----\n", None).is_none());
141-
assert!(pem_to_der("-----BEGIN CERTIFICATE----\n-----END CERTIFICATE-----\n", None).is_none());
142-
assert!(pem_to_der("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE----\n", None).is_none());
143-
assert_eq!(pem_to_der("-----BEGIN JUNK-----\n\
144-
AAECAwQFBgcICQoLDA0ODw==\n\
145-
-----END GARBAGE-----\n", None).unwrap(),
146-
vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
147-
assert_eq!(pem_to_der("-----BEGIN CERTIFICATE-----\n\
148-
AAECAwQFBgcICQoLDA0ODw==\n\
149-
-----END CERTIFICATE-----\n", None).unwrap(),
150-
vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
151-
}
152-
153-
#[test]
154-
fn test_roundtrip_whole_line() {
155-
// Test the case where the PEM is a multiple of whole lines.
156-
let test_cert =
157-
"-----BEGIN CERTIFICATE-----
158-
MIIHBTCCBe2gAwIBAgIRAIFsdIAf8kR29DFR7K4znoIwDQYJKoZIhvcNAQELBQAw
159-
-----END CERTIFICATE-----
160-
";
161-
162-
assert_eq!(der_to_pem(&pem_to_der(test_cert, Some(PEM_CERTIFICATE)).unwrap(), PEM_CERTIFICATE), test_cert);
163-
}
164-
165-
#[test]
166-
fn test_wrapping() {
167-
let mut v: Vec<u8> = vec![];
168-
let bytes_per_line = BASE64_PEM_WRAP * 3 / 4;
169-
for i in 0..2*bytes_per_line {
170-
let pem = der_to_pem(&v, PEM_CERTIFICATE);
171-
// Check that we can do a round trip, and that we got the expected number of lines.
172-
assert_eq!(pem_to_der(&pem, Some(PEM_CERTIFICATE)).unwrap(), v);
173-
assert_eq!(pem.matches("\n").count(), 2 + (i + bytes_per_line - 1) / bytes_per_line);
174-
v.push(0);
175-
}
176-
}
177-
17871
#[test]
17972
fn test_split() {
18073
// Split three certs, CRLF line terminators.

0 commit comments

Comments
 (0)