nss_certdata_parser/
collect.rs1use std::cmp::{Ord, Ordering};
8
9use structured::{Certificate, Trust, Object, Usage};
10use structured::TrustLevel::*;
11
12fn cert_cmp(ca: &Certificate, cb: &Certificate) -> Ordering {
13 ca.subject.cmp(&cb.subject)
14}
15fn trust_cmp_with(t: &Trust, issuer: &[u8], serial: &[u8]) -> Ordering {
16 (&t.issuer[..], &t.serial[..]).cmp(&(issuer, serial))
17}
18fn trust_cmp(ta: &Trust, tb: &Trust) -> Ordering {
19 trust_cmp_with(ta, &tb.issuer, &tb.serial)
20}
21
22pub struct CertData {
23 certs: Box<[Certificate]>,
24 trusts: Box<[Trust]>,
25}
26
27impl CertData {
28 pub fn from_iter<E, I>(iter: I) -> Result<Self, E>
29 where I: IntoIterator<Item = Result<Object, E>>
30 {
31 let mut certbuf = Vec::new();
32 let mut trustbuf = Vec::new();
33 for thing in iter {
34 match try!(thing) {
35 Object::Certificate(cert) => certbuf.push(cert),
36 Object::Trust(trust) => trustbuf.push(trust),
37 }
38 }
39 let mut certs = certbuf.into_boxed_slice();
40 let mut trusts = trustbuf.into_boxed_slice();
41 certs.sort_by(cert_cmp);
42 trusts.sort_by(trust_cmp);
43 Ok(CertData {
44 certs: certs,
45 trusts: trusts,
46 })
47 }
48
49 pub fn certs(&self) -> &[Certificate] {
50 &self.certs
51 }
52 pub fn trusts(&self) -> &[Trust] {
53 &self.trusts
54 }
55
56 pub fn trust_for(&self, issuer: &[u8], serial: &[u8]) -> Option<&Trust> {
57 if let Ok(i) = self.trusts.binary_search_by(|t| trust_cmp_with(t, issuer, serial)) {
58 Some(&self.trusts[i])
59 } else {
60 None
61 }
62 }
63
64 pub fn trust_for_cert(&self, cert: &Certificate) -> Option<&Trust> {
65 self.trust_for(&cert.issuer, &cert.serial)
66 }
67
68 pub fn trusted_certs(&self, usage: Usage) -> Vec<&Certificate> {
69 self.certs.iter()
70 .filter(|cert| {
71 self.trust_for_cert(cert)
72 .map_or(MustVerify, |trust| trust.trust_level(usage))
73 == TrustedDelegator
74 }).collect()
75 }
76 pub fn distrusts(&self, usage: Usage) -> Vec<&Trust> {
77 self.trusts.iter()
78 .filter(|trust| trust.trust_level(usage) == Distrust)
79 .collect()
80 }
81}