1use webpki;
2
3use crate::key;
4#[cfg(feature = "logging")]
5use crate::log::{debug, trace};
6pub use crate::msgs::handshake::{DistinguishedName, DistinguishedNames};
7use crate::pemfile;
8use crate::x509;
9use std::io;
10
11#[derive(Debug, Clone)]
15pub struct OwnedTrustAnchor {
16 subject: Vec<u8>,
17 spki: Vec<u8>,
18 name_constraints: Option<Vec<u8>>,
19}
20
21impl OwnedTrustAnchor {
22 pub fn from_trust_anchor(t: &webpki::TrustAnchor) -> OwnedTrustAnchor {
24 OwnedTrustAnchor {
25 subject: t.subject.to_vec(),
26 spki: t.spki.to_vec(),
27 name_constraints: t.name_constraints.map(|x| x.to_vec()),
28 }
29 }
30
31 pub fn to_trust_anchor(&self) -> webpki::TrustAnchor {
33 webpki::TrustAnchor {
34 subject: &self.subject,
35 spki: &self.spki,
36 name_constraints: self
37 .name_constraints
38 .as_ref()
39 .map(Vec::as_slice),
40 }
41 }
42}
43
44impl From<webpki::TrustAnchor<'_>> for OwnedTrustAnchor {
45 fn from(t: webpki::TrustAnchor) -> OwnedTrustAnchor {
46 Self::from_trust_anchor(&t)
47 }
48}
49
50impl<'a> Into<webpki::TrustAnchor<'a>> for &'a OwnedTrustAnchor {
51 fn into(self) -> webpki::TrustAnchor<'a> {
52 self.to_trust_anchor()
53 }
54}
55
56#[derive(Debug, Clone)]
59pub struct RootCertStore {
60 pub roots: Vec<OwnedTrustAnchor>,
62}
63
64impl RootCertStore {
65 pub fn empty() -> RootCertStore {
67 RootCertStore { roots: Vec::new() }
68 }
69
70 pub fn is_empty(&self) -> bool {
72 self.len() == 0
73 }
74
75 pub fn len(&self) -> usize {
77 self.roots.len()
78 }
79
80 pub fn get_subjects(&self) -> DistinguishedNames {
82 let mut r = DistinguishedNames::new();
83
84 for ota in &self.roots {
85 let mut name = Vec::new();
86 name.extend_from_slice(&ota.subject);
87 x509::wrap_in_sequence(&mut name);
88 r.push(DistinguishedName::new(name));
89 }
90
91 r
92 }
93
94 pub fn add(&mut self, der: &key::Certificate) -> Result<(), webpki::Error> {
96 let ta = webpki::trust_anchor_util::cert_der_as_trust_anchor(&der.0)?;
97
98 let ota = OwnedTrustAnchor::from_trust_anchor(&ta);
99 self.roots.push(ota);
100 Ok(())
101 }
102
103 pub fn add_server_trust_anchors(
106 &mut self,
107 &webpki::TLSServerTrustAnchors(anchors): &webpki::TLSServerTrustAnchors,
108 ) {
109 for ta in anchors {
110 self.roots
111 .push(OwnedTrustAnchor::from_trust_anchor(ta));
112 }
113 }
114
115 pub fn add_pem_file(&mut self, rd: &mut dyn io::BufRead) -> Result<(usize, usize), ()> {
126 let ders = pemfile::certs(rd)?;
127 let mut valid_count = 0;
128 let mut invalid_count = 0;
129
130 for der in ders {
131 #[cfg_attr(not(feature = "logging"), allow(unused_variables))]
132 match self.add(&der) {
133 Ok(_) => valid_count += 1,
134 Err(err) => {
135 trace!("invalid cert der {:?}", der);
136 debug!("certificate parsing failed: {:?}", err);
137 invalid_count += 1
138 }
139 }
140 }
141
142 debug!(
143 "add_pem_file processed {} valid and {} invalid certs",
144 valid_count, invalid_count
145 );
146
147 Ok((valid_count, invalid_count))
148 }
149}