Coverage Report

Created: 2026-01-16 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/x509-parser-0.15.1/src/extensions/policymappings.rs
Line
Count
Source
1
use crate::error::{X509Error, X509Result};
2
use asn1_rs::{DerSequence, Error, FromDer, Oid};
3
use nom::{Err, IResult};
4
use std::collections::HashMap;
5
6
#[derive(Clone, Debug, PartialEq, Eq)]
7
pub struct PolicyMappings<'a> {
8
    pub mappings: Vec<PolicyMapping<'a>>,
9
}
10
11
impl<'a> FromDer<'a, X509Error> for PolicyMappings<'a> {
12
0
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
13
0
        parse_policymappings(i).map_err(Err::convert)
14
0
    }
15
}
16
17
impl<'a> PolicyMappings<'a> {
18
    /// Returns a `HashMap` mapping `Oid` to the list of references to `Oid`
19
    ///
20
    /// If several names match the same `Oid`, they are merged in the same entry.
21
0
    pub fn as_hashmap(&self) -> HashMap<Oid<'a>, Vec<&Oid<'a>>> {
22
        // create the hashmap and merge entries with same OID
23
0
        let mut m: HashMap<Oid, Vec<&_>> = HashMap::new();
24
0
        for desc in &self.mappings {
25
            let PolicyMapping {
26
0
                issuer_domain_policy: left,
27
0
                subject_domain_policy: right,
28
0
            } = desc;
29
0
            if let Some(l) = m.get_mut(left) {
30
0
                l.push(right);
31
0
            } else {
32
0
                m.insert(left.clone(), vec![right]);
33
0
            }
34
        }
35
0
        m
36
0
    }
37
38
    /// Returns a `HashMap` mapping `Oid` to the list of `Oid` (consuming the input)
39
    ///
40
    /// If several names match the same `Oid`, they are merged in the same entry.
41
0
    pub fn into_hashmap(self) -> HashMap<Oid<'a>, Vec<Oid<'a>>> {
42
0
        let mut l = self.mappings;
43
        // create the hashmap and merge entries with same OID
44
0
        let mut m: HashMap<Oid, Vec<_>> = HashMap::new();
45
0
        for mapping in l.drain(..) {
46
            let PolicyMapping {
47
0
                issuer_domain_policy: left,
48
0
                subject_domain_policy: right,
49
0
            } = mapping;
50
0
            if let Some(general_names) = m.get_mut(&left) {
51
0
                general_names.push(right);
52
0
            } else {
53
0
                m.insert(left, vec![right]);
54
0
            }
55
        }
56
0
        m
57
0
    }
58
}
59
60
0
#[derive(Clone, Debug, PartialEq, Eq, DerSequence)]
61
pub struct PolicyMapping<'a> {
62
    pub issuer_domain_policy: Oid<'a>,
63
    pub subject_domain_policy: Oid<'a>,
64
}
65
66
impl<'a> PolicyMapping<'a> {
67
0
    pub const fn new(issuer_domain_policy: Oid<'a>, subject_domain_policy: Oid<'a>) -> Self {
68
0
        PolicyMapping {
69
0
            issuer_domain_policy,
70
0
            subject_domain_policy,
71
0
        }
72
0
    }
73
}
74
75
// PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
76
//  issuerDomainPolicy      CertPolicyId,
77
//  subjectDomainPolicy     CertPolicyId }
78
0
pub(crate) fn parse_policymappings(i: &[u8]) -> IResult<&[u8], PolicyMappings, Error> {
79
0
    let (ret, pairs) = <Vec<PolicyMapping>>::from_der(i)?;
80
    // let mut mappings: HashMap<Oid, Vec<Oid>> = HashMap::new();
81
0
    let mappings = pairs;
82
    // let mut mappings = Vec::new();
83
    // for pair in pairs.iter() {
84
    //     // XXX this should go to Validate
85
    //     // if left.bytes() == oid!(raw 2.5.29.32.0) || right.bytes() == oid!(raw 2.5.29.32.0) {
86
    //     //     // mapping to or from anyPolicy is not allowed
87
    //     //     return Err(Err::Failure(BerError::InvalidTag));
88
    //     // }
89
    //     mappings.push(PolicyMapping::new(left, right));
90
    // }
91
0
    Ok((ret, PolicyMappings { mappings }))
92
0
}