1#[cfg(feature = "logging")]
2use crate::log::{debug, trace};
3use crate::x509;
4use crate::{key, DistinguishedName};
5use crate::{CertificateError, Error};
6
7#[derive(Debug, Clone)]
9pub struct OwnedTrustAnchor {
10 subject_dn_header_len: usize,
11 subject_dn: DistinguishedName,
12 spki: Vec<u8>,
13 name_constraints: Option<Vec<u8>>,
14}
15
16impl OwnedTrustAnchor {
17 pub(crate) fn to_trust_anchor(&self) -> webpki::TrustAnchor {
19 webpki::TrustAnchor {
20 subject: &self.subject_dn.as_ref()[self.subject_dn_header_len..],
21 spki: &self.spki,
22 name_constraints: self.name_constraints.as_deref(),
23 }
24 }
25
26 pub fn from_subject_spki_name_constraints(
42 subject: impl Into<Vec<u8>>,
43 spki: impl Into<Vec<u8>>,
44 name_constraints: Option<impl Into<Vec<u8>>>,
45 ) -> Self {
46 let (subject_dn, subject_dn_header_len) = {
47 let mut subject = subject.into();
48 let before_len = subject.len();
49 x509::wrap_in_sequence(&mut subject);
50 let header_len = subject.len().saturating_sub(before_len);
51 (DistinguishedName::from(subject), header_len)
52 };
53 Self {
54 subject_dn_header_len,
55 subject_dn,
56 spki: spki.into(),
57 name_constraints: name_constraints.map(|x| x.into()),
58 }
59 }
60
61 pub fn subject(&self) -> &DistinguishedName {
70 &self.subject_dn
71 }
72}
73
74#[derive(Debug, Clone)]
77pub struct RootCertStore {
78 pub roots: Vec<OwnedTrustAnchor>,
80}
81
82impl RootCertStore {
83 pub fn empty() -> Self {
85 Self { roots: Vec::new() }
86 }
87
88 pub fn is_empty(&self) -> bool {
90 self.len() == 0
91 }
92
93 pub fn len(&self) -> usize {
95 self.roots.len()
96 }
97
98 pub fn add(&mut self, der: &key::Certificate) -> Result<(), Error> {
108 self.add_internal(&der.0)
109 }
110
111 pub fn add_trust_anchors(&mut self, trust_anchors: impl Iterator<Item = OwnedTrustAnchor>) {
114 self.roots.extend(trust_anchors);
115 }
116
117 #[deprecated(since = "0.21.6", note = "Please use `add_trust_anchors` instead")]
120 pub fn add_server_trust_anchors(
121 &mut self,
122 trust_anchors: impl Iterator<Item = OwnedTrustAnchor>,
123 ) {
124 self.add_trust_anchors(trust_anchors);
125 }
126
127 pub fn add_parsable_certificates(&mut self, der_certs: &[impl AsRef<[u8]>]) -> (usize, usize) {
135 let mut valid_count = 0;
136 let mut invalid_count = 0;
137
138 for der_cert in der_certs {
139 #[cfg_attr(not(feature = "logging"), allow(unused_variables))]
140 match self.add_internal(der_cert.as_ref()) {
141 Ok(_) => valid_count += 1,
142 Err(err) => {
143 trace!("invalid cert der {:?}", der_cert.as_ref());
144 debug!("certificate parsing failed: {:?}", err);
145 invalid_count += 1;
146 }
147 }
148 }
149
150 debug!(
151 "add_parsable_certificates processed {} valid and {} invalid certs",
152 valid_count, invalid_count
153 );
154
155 (valid_count, invalid_count)
156 }
157
158 fn add_internal(&mut self, der: &[u8]) -> Result<(), Error> {
159 let ta = webpki::TrustAnchor::try_from_cert_der(der)
160 .map_err(|_| Error::InvalidCertificate(CertificateError::BadEncoding))?;
161 self.roots
162 .push(OwnedTrustAnchor::from_subject_spki_name_constraints(
163 ta.subject,
164 ta.spki,
165 ta.name_constraints,
166 ));
167 Ok(())
168 }
169}
170
171mod tests {
172 #[test]
173 fn ownedtrustanchor_subject_is_correctly_encoding_dn() {
174 let subject = b"subject".to_owned();
175 let ota = super::OwnedTrustAnchor::from_subject_spki_name_constraints(
176 subject,
177 b"".to_owned(),
178 None::<Vec<u8>>,
179 );
180 let expected_prefix = vec![ring::io::der::Tag::Sequence as u8, subject.len() as u8];
181 assert_eq!(
182 ota.subject().as_ref(),
183 [expected_prefix, subject.to_vec()].concat()
184 );
185 }
186}