1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::fmt;
use rustls::internal::pemfile;
#[derive(Debug, Clone)]
pub struct Certificate {
pub(crate) inner: rustls::Certificate,
}
impl Certificate {
pub fn from_der(der: &[u8]) -> Result<Self, ParseError> {
Ok(Self {
inner: rustls::Certificate(der.to_vec()),
})
}
}
#[derive(Debug, Clone)]
pub struct CertificateChain {
pub(crate) certs: Vec<rustls::Certificate>,
}
impl CertificateChain {
pub fn from_pem(pem: &[u8]) -> Result<Self, ParseError> {
Ok(Self {
certs: pemfile::certs(&mut &pem[..])
.map_err(|()| ParseError("malformed certificate chain"))?,
})
}
pub fn from_certs(certs: impl IntoIterator<Item = Certificate>) -> Self {
certs.into_iter().collect()
}
}
impl std::iter::FromIterator<Certificate> for CertificateChain {
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = Certificate>,
{
CertificateChain {
certs: iter.into_iter().map(|x| x.inner).collect(),
}
}
}
#[derive(Debug, Clone)]
pub struct PrivateKey {
pub(crate) inner: rustls::PrivateKey,
}
impl PrivateKey {
pub fn from_pem(pem: &[u8]) -> Result<Self, ParseError> {
let pkcs8 = pemfile::pkcs8_private_keys(&mut &pem[..])
.map_err(|()| ParseError("malformed PKCS #8 private key"))?;
if let Some(x) = pkcs8.into_iter().next() {
return Ok(Self { inner: x });
}
let rsa = pemfile::rsa_private_keys(&mut &pem[..])
.map_err(|()| ParseError("malformed PKCS #1 private key"))?;
if let Some(x) = rsa.into_iter().next() {
return Ok(Self { inner: x });
}
Err(ParseError("no private key found"))
}
pub fn from_der(der: &[u8]) -> Result<Self, ParseError> {
Ok(Self {
inner: rustls::PrivateKey(der.to_vec()),
})
}
}
#[derive(Debug, Clone)]
pub struct ParseError(&'static str);
impl std::error::Error for ParseError {}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad(self.0)
}
}