nss_certdata_parser/
collect.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5// FIXME: this module is no longer about embedding in code; should be renamed.
6
7use 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}