Coverage Report

Created: 2026-09-28 07:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/x509-parser-0.16.0/src/extensions/mod.rs
Line
Count
Source
1
//! X.509 Extensions objects and types
2
3
use crate::error::{X509Error, X509Result};
4
use crate::time::ASN1Time;
5
use crate::utils::format_serial;
6
use crate::x509::{ReasonCode, RelativeDistinguishedName};
7
8
use asn1_rs::FromDer;
9
use der_parser::ber::parse_ber_bool;
10
use der_parser::der::*;
11
use der_parser::error::{BerError, BerResult};
12
use der_parser::num_bigint::BigUint;
13
use der_parser::oid::Oid;
14
use nom::combinator::{all_consuming, complete, cut, map, map_res, opt};
15
use nom::multi::{many0, many1};
16
use nom::{Err, IResult, Parser};
17
use oid_registry::*;
18
use std::collections::HashMap;
19
use std::fmt::{self, LowerHex};
20
21
mod generalname;
22
mod keyusage;
23
mod nameconstraints;
24
mod policymappings;
25
mod sct;
26
27
pub use generalname::*;
28
pub use keyusage::*;
29
pub use nameconstraints::*;
30
pub use policymappings::*;
31
pub use sct::*;
32
33
/// X.509 version 3 extension
34
///
35
/// X.509 extensions allow adding attributes to objects like certificates or revocation lists.
36
///
37
/// Each extension in a certificate is designated as either critical or non-critical.  A
38
/// certificate using system MUST reject the certificate if it encounters a critical extension it
39
/// does not recognize; however, a non-critical extension MAY be ignored if it is not recognized.
40
///
41
/// Each extension includes an OID and an ASN.1 structure.  When an extension appears in a
42
/// certificate, the OID appears as the field extnID and the corresponding ASN.1 encoded structure
43
/// is the value of the octet string extnValue.  A certificate MUST NOT include more than one
44
/// instance of a particular extension.
45
///
46
/// When parsing an extension, the global extension structure (described above) is parsed,
47
/// and the object is returned if it succeeds.
48
/// During this step, it also attempts to parse the content of the extension, if known.
49
/// The returned object has a
50
/// [`X509Extension::parsed_extension()`] method. The returned
51
/// enum is either a known extension, or the special value `ParsedExtension::UnsupportedExtension`.
52
///
53
/// # Example
54
///
55
/// ```rust
56
/// use x509_parser::prelude::FromDer;
57
/// use x509_parser::extensions::{X509Extension, ParsedExtension};
58
///
59
/// static DER: &[u8] = &[
60
///    0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xA3, 0x05, 0x2F, 0x18,
61
///    0x60, 0x50, 0xC2, 0x89, 0x0A, 0xDD, 0x2B, 0x21, 0x4F, 0xFF, 0x8E, 0x4E, 0xA8, 0x30, 0x31,
62
///    0x36 ];
63
///
64
/// # fn main() {
65
/// let res = X509Extension::from_der(DER);
66
/// match res {
67
///     Ok((_rem, ext)) => {
68
///         println!("Extension OID: {}", ext.oid);
69
///         println!("  Critical: {}", ext.critical);
70
///         let parsed_ext = ext.parsed_extension();
71
///         assert!(!parsed_ext.unsupported());
72
///         assert!(parsed_ext.error().is_none());
73
///         if let ParsedExtension::SubjectKeyIdentifier(key_id) = parsed_ext {
74
///             assert!(key_id.0.len() > 0);
75
///         } else {
76
///             panic!("Extension has wrong type");
77
///         }
78
///     },
79
///     _ => panic!("x509 extension parsing failed: {:?}", res),
80
/// }
81
/// # }
82
/// ```
83
#[derive(Clone, Debug, PartialEq)]
84
pub struct X509Extension<'a> {
85
    /// OID describing the extension content
86
    pub oid: Oid<'a>,
87
    /// Boolean value describing the 'critical' attribute of the extension
88
    ///
89
    /// An extension includes the boolean critical, with a default value of FALSE.
90
    pub critical: bool,
91
    /// Raw content of the extension
92
    pub value: &'a [u8],
93
    pub(crate) parsed_extension: ParsedExtension<'a>,
94
}
95
96
impl<'a> X509Extension<'a> {
97
    /// Creates a new extension with the provided values.
98
    #[inline]
99
0
    pub const fn new(
100
0
        oid: Oid<'a>,
101
0
        critical: bool,
102
0
        value: &'a [u8],
103
0
        parsed_extension: ParsedExtension<'a>,
104
0
    ) -> X509Extension<'a> {
105
0
        X509Extension {
106
0
            oid,
107
0
            critical,
108
0
            value,
109
0
            parsed_extension,
110
0
        }
111
0
    }
Unexecuted instantiation: <x509_parser::extensions::X509Extension>::new
Unexecuted instantiation: <x509_parser::extensions::X509Extension>::new
112
113
    /// Return the extension type or `UnsupportedExtension` if the extension is not implemented.
114
    #[inline]
115
0
    pub fn parsed_extension(&self) -> &ParsedExtension<'a> {
116
0
        &self.parsed_extension
117
0
    }
Unexecuted instantiation: <x509_parser::extensions::X509Extension>::parsed_extension
Unexecuted instantiation: <x509_parser::extensions::X509Extension>::parsed_extension
118
}
119
120
/// <pre>
121
/// Extension  ::=  SEQUENCE  {
122
///     extnID      OBJECT IDENTIFIER,
123
///     critical    BOOLEAN DEFAULT FALSE,
124
///     extnValue   OCTET STRING  }
125
/// </pre>
126
impl<'a> FromDer<'a, X509Error> for X509Extension<'a> {
127
23.7k
    fn from_der(i: &'a [u8]) -> X509Result<Self> {
128
23.7k
        X509ExtensionParser::new().parse(i)
129
23.7k
    }
Unexecuted instantiation: <x509_parser::extensions::X509Extension as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
<x509_parser::extensions::X509Extension as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
Line
Count
Source
127
23.7k
    fn from_der(i: &'a [u8]) -> X509Result<Self> {
128
23.7k
        X509ExtensionParser::new().parse(i)
129
23.7k
    }
130
}
131
132
/// `X509Extension` parser builder
133
#[derive(Clone, Copy, Debug)]
134
pub struct X509ExtensionParser {
135
    deep_parse_extensions: bool,
136
}
137
138
impl X509ExtensionParser {
139
    #[inline]
140
23.7k
    pub const fn new() -> Self {
141
23.7k
        X509ExtensionParser {
142
23.7k
            deep_parse_extensions: true,
143
23.7k
        }
144
23.7k
    }
Unexecuted instantiation: <x509_parser::extensions::X509ExtensionParser>::new
<x509_parser::extensions::X509ExtensionParser>::new
Line
Count
Source
140
23.7k
    pub const fn new() -> Self {
141
23.7k
        X509ExtensionParser {
142
23.7k
            deep_parse_extensions: true,
143
23.7k
        }
144
23.7k
    }
145
146
    #[inline]
147
0
    pub const fn with_deep_parse_extensions(self, deep_parse_extensions: bool) -> Self {
148
0
        X509ExtensionParser {
149
0
            deep_parse_extensions,
150
0
        }
151
0
    }
Unexecuted instantiation: <x509_parser::extensions::X509ExtensionParser>::with_deep_parse_extensions
Unexecuted instantiation: <x509_parser::extensions::X509ExtensionParser>::with_deep_parse_extensions
152
}
153
154
impl<'a> Parser<&'a [u8], X509Extension<'a>, X509Error> for X509ExtensionParser {
155
23.7k
    fn parse(&mut self, input: &'a [u8]) -> IResult<&'a [u8], X509Extension<'a>, X509Error> {
156
23.7k
        parse_der_sequence_defined_g(|i, _| {
157
20.9k
            let (i, oid) = Oid::from_der(i)?;
158
20.9k
            let (i, critical) = der_read_critical(i)?;
159
20.9k
            let (i, value) = <&[u8]>::from_der(i)?;
160
20.8k
            let (i, parsed_extension) = if self.deep_parse_extensions {
161
20.8k
                parser::parse_extension(i, value, &oid)?
162
            } else {
163
0
                (&[] as &[_], ParsedExtension::Unparsed)
164
            };
165
20.8k
            let ext = X509Extension {
166
20.8k
                oid,
167
20.8k
                critical,
168
20.8k
                value,
169
20.8k
                parsed_extension,
170
20.8k
            };
171
20.8k
            Ok((i, ext))
172
23.7k
        })(input)
Unexecuted instantiation: <x509_parser::extensions::X509ExtensionParser as nom::internal::Parser<&[u8], x509_parser::extensions::X509Extension, x509_parser::error::X509Error>>::parse::{closure#0}
<x509_parser::extensions::X509ExtensionParser as nom::internal::Parser<&[u8], x509_parser::extensions::X509Extension, x509_parser::error::X509Error>>::parse::{closure#0}
Line
Count
Source
156
20.9k
        parse_der_sequence_defined_g(|i, _| {
157
20.9k
            let (i, oid) = Oid::from_der(i)?;
158
20.9k
            let (i, critical) = der_read_critical(i)?;
159
20.9k
            let (i, value) = <&[u8]>::from_der(i)?;
160
20.8k
            let (i, parsed_extension) = if self.deep_parse_extensions {
161
20.8k
                parser::parse_extension(i, value, &oid)?
162
            } else {
163
0
                (&[] as &[_], ParsedExtension::Unparsed)
164
            };
165
20.8k
            let ext = X509Extension {
166
20.8k
                oid,
167
20.8k
                critical,
168
20.8k
                value,
169
20.8k
                parsed_extension,
170
20.8k
            };
171
20.8k
            Ok((i, ext))
172
20.9k
        })(input)
173
23.7k
        .map_err(|_| X509Error::InvalidExtensions.into())
Unexecuted instantiation: <x509_parser::extensions::X509ExtensionParser as nom::internal::Parser<&[u8], x509_parser::extensions::X509Extension, x509_parser::error::X509Error>>::parse::{closure#1}
<x509_parser::extensions::X509ExtensionParser as nom::internal::Parser<&[u8], x509_parser::extensions::X509Extension, x509_parser::error::X509Error>>::parse::{closure#1}
Line
Count
Source
173
2.86k
        .map_err(|_| X509Error::InvalidExtensions.into())
174
23.7k
    }
Unexecuted instantiation: <x509_parser::extensions::X509ExtensionParser as nom::internal::Parser<&[u8], x509_parser::extensions::X509Extension, x509_parser::error::X509Error>>::parse
<x509_parser::extensions::X509ExtensionParser as nom::internal::Parser<&[u8], x509_parser::extensions::X509Extension, x509_parser::error::X509Error>>::parse
Line
Count
Source
155
23.7k
    fn parse(&mut self, input: &'a [u8]) -> IResult<&'a [u8], X509Extension<'a>, X509Error> {
156
23.7k
        parse_der_sequence_defined_g(|i, _| {
157
            let (i, oid) = Oid::from_der(i)?;
158
            let (i, critical) = der_read_critical(i)?;
159
            let (i, value) = <&[u8]>::from_der(i)?;
160
            let (i, parsed_extension) = if self.deep_parse_extensions {
161
                parser::parse_extension(i, value, &oid)?
162
            } else {
163
                (&[] as &[_], ParsedExtension::Unparsed)
164
            };
165
            let ext = X509Extension {
166
                oid,
167
                critical,
168
                value,
169
                parsed_extension,
170
            };
171
            Ok((i, ext))
172
23.7k
        })(input)
173
23.7k
        .map_err(|_| X509Error::InvalidExtensions.into())
174
23.7k
    }
175
}
176
177
#[derive(Clone, Debug, PartialEq)]
178
pub enum ParsedExtension<'a> {
179
    /// Crate parser does not support this extension (yet)
180
    UnsupportedExtension {
181
        oid: Oid<'a>,
182
    },
183
    ParseError {
184
        error: Err<BerError>,
185
    },
186
    /// Section 4.2.1.1 of rfc 5280
187
    AuthorityKeyIdentifier(AuthorityKeyIdentifier<'a>),
188
    /// Section 4.2.1.2 of rfc 5280
189
    SubjectKeyIdentifier(KeyIdentifier<'a>),
190
    /// Section 4.2.1.3 of rfc 5280
191
    KeyUsage(KeyUsage),
192
    /// Section 4.2.1.4 of rfc 5280
193
    CertificatePolicies(CertificatePolicies<'a>),
194
    /// Section 4.2.1.5 of rfc 5280
195
    PolicyMappings(PolicyMappings<'a>),
196
    /// Section 4.2.1.6 of rfc 5280
197
    SubjectAlternativeName(SubjectAlternativeName<'a>),
198
    /// Section 4.2.1.7 of rfc 5280
199
    IssuerAlternativeName(IssuerAlternativeName<'a>),
200
    /// Section 4.2.1.9 of rfc 5280
201
    BasicConstraints(BasicConstraints),
202
    /// Section 4.2.1.10 of rfc 5280
203
    NameConstraints(NameConstraints<'a>),
204
    /// Section 4.2.1.11 of rfc 5280
205
    PolicyConstraints(PolicyConstraints),
206
    /// Section 4.2.1.12 of rfc 5280
207
    ExtendedKeyUsage(ExtendedKeyUsage<'a>),
208
    /// Section 4.2.1.13 of rfc 5280
209
    CRLDistributionPoints(CRLDistributionPoints<'a>),
210
    /// Section 4.2.1.14 of rfc 5280
211
    InhibitAnyPolicy(InhibitAnyPolicy),
212
    /// Section 4.2.2.1 of rfc 5280
213
    AuthorityInfoAccess(AuthorityInfoAccess<'a>),
214
    /// Netscape certificate type (subject is SSL client, an SSL server, or a CA)
215
    NSCertType(NSCertType),
216
    /// Netscape certificate comment
217
    NsCertComment(&'a str),
218
    /// Section 5.2.5 of rfc 5280
219
    IssuingDistributionPoint(IssuingDistributionPoint<'a>),
220
    /// Section 5.3.1 of rfc 5280
221
    CRLNumber(BigUint),
222
    /// Section 5.3.1 of rfc 5280
223
    ReasonCode(ReasonCode),
224
    /// Section 5.3.3 of rfc 5280
225
    InvalidityDate(ASN1Time),
226
    /// rfc 6962
227
    SCT(Vec<SignedCertificateTimestamp<'a>>),
228
    /// Unparsed extension (was not requested in parsing options)
229
    Unparsed,
230
}
231
232
impl<'a> ParsedExtension<'a> {
233
    /// Return `true` if the extension is unsupported
234
0
    pub fn unsupported(&self) -> bool {
235
0
        matches!(self, &ParsedExtension::UnsupportedExtension { .. })
236
0
    }
Unexecuted instantiation: <x509_parser::extensions::ParsedExtension>::unsupported
Unexecuted instantiation: <x509_parser::extensions::ParsedExtension>::unsupported
237
238
    /// Return a reference on the parsing error if the extension parsing failed
239
0
    pub fn error(&self) -> Option<&Err<BerError>> {
240
0
        match self {
241
0
            ParsedExtension::ParseError { error } => Some(error),
242
0
            _ => None,
243
        }
244
0
    }
Unexecuted instantiation: <x509_parser::extensions::ParsedExtension>::error
Unexecuted instantiation: <x509_parser::extensions::ParsedExtension>::error
245
}
246
247
#[derive(Clone, Debug, PartialEq)]
248
pub struct AuthorityKeyIdentifier<'a> {
249
    pub key_identifier: Option<KeyIdentifier<'a>>,
250
    pub authority_cert_issuer: Option<Vec<GeneralName<'a>>>,
251
    pub authority_cert_serial: Option<&'a [u8]>,
252
}
253
254
impl<'a> FromDer<'a, X509Error> for AuthorityKeyIdentifier<'a> {
255
0
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
256
0
        parser::parse_authoritykeyidentifier(i).map_err(Err::convert)
257
0
    }
Unexecuted instantiation: <x509_parser::extensions::AuthorityKeyIdentifier as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
Unexecuted instantiation: <x509_parser::extensions::AuthorityKeyIdentifier as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
258
}
259
260
pub type CertificatePolicies<'a> = Vec<PolicyInformation<'a>>;
261
262
// impl<'a> FromDer<'a> for CertificatePolicies<'a> {
263
//     fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
264
//         parser::parse_certificatepolicies(i).map_err(Err::convert)
265
//     }
266
// }
267
268
#[derive(Clone, Debug, PartialEq, Eq)]
269
pub struct PolicyInformation<'a> {
270
    pub policy_id: Oid<'a>,
271
    pub policy_qualifiers: Option<Vec<PolicyQualifierInfo<'a>>>,
272
}
273
274
#[derive(Clone, Debug, PartialEq, Eq)]
275
pub struct PolicyQualifierInfo<'a> {
276
    pub policy_qualifier_id: Oid<'a>,
277
    pub qualifier: &'a [u8],
278
}
279
280
/// Identifies whether the subject of the certificate is a CA, and the max validation depth.
281
#[derive(Clone, Debug, PartialEq, Eq)]
282
pub struct BasicConstraints {
283
    pub ca: bool,
284
    pub path_len_constraint: Option<u32>,
285
}
286
287
impl<'a> FromDer<'a, X509Error> for BasicConstraints {
288
0
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
289
0
        parser::parse_basicconstraints(i).map_err(Err::convert)
290
0
    }
Unexecuted instantiation: <x509_parser::extensions::BasicConstraints as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
Unexecuted instantiation: <x509_parser::extensions::BasicConstraints as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
291
}
292
293
#[derive(Clone, Debug, PartialEq, Eq)]
294
pub struct KeyIdentifier<'a>(pub &'a [u8]);
295
296
impl<'a> FromDer<'a, X509Error> for KeyIdentifier<'a> {
297
0
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
298
0
        parser::parse_keyidentifier(i).map_err(Err::convert)
299
0
    }
Unexecuted instantiation: <x509_parser::extensions::KeyIdentifier as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
Unexecuted instantiation: <x509_parser::extensions::KeyIdentifier as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
300
}
301
302
impl<'a> LowerHex for KeyIdentifier<'a> {
303
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
304
0
        let s = format_serial(self.0);
305
0
        f.write_str(&s)
306
0
    }
Unexecuted instantiation: <x509_parser::extensions::KeyIdentifier as core::fmt::LowerHex>::fmt
Unexecuted instantiation: <x509_parser::extensions::KeyIdentifier as core::fmt::LowerHex>::fmt
307
}
308
309
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
310
pub struct NSCertType(u8);
311
312
// The value is a bit-string, where the individual bit positions are defined as:
313
//
314
//     bit-0 SSL client - this cert is certified for SSL client authentication use
315
//     bit-1 SSL server - this cert is certified for SSL server authentication use
316
//     bit-2 S/MIME - this cert is certified for use by clients (New in PR3)
317
//     bit-3 Object Signing - this cert is certified for signing objects such as Java applets and plugins(New in PR3)
318
//     bit-4 Reserved - this bit is reserved for future use
319
//     bit-5 SSL CA - this cert is certified for issuing certs for SSL use
320
//     bit-6 S/MIME CA - this cert is certified for issuing certs for S/MIME use (New in PR3)
321
//     bit-7 Object Signing CA - this cert is certified for issuing certs for Object Signing (New in PR3)
322
impl NSCertType {
323
0
    pub fn ssl_client(&self) -> bool {
324
0
        self.0 & 0x1 == 1
325
0
    }
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::ssl_client
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::ssl_client
326
0
    pub fn ssl_server(&self) -> bool {
327
0
        (self.0 >> 1) & 1 == 1
328
0
    }
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::ssl_server
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::ssl_server
329
0
    pub fn smime(&self) -> bool {
330
0
        (self.0 >> 2) & 1 == 1
331
0
    }
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::smime
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::smime
332
0
    pub fn object_signing(&self) -> bool {
333
0
        (self.0 >> 3) & 1 == 1
334
0
    }
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::object_signing
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::object_signing
335
0
    pub fn ssl_ca(&self) -> bool {
336
0
        (self.0 >> 5) & 1 == 1
337
0
    }
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::ssl_ca
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::ssl_ca
338
0
    pub fn smime_ca(&self) -> bool {
339
0
        (self.0 >> 6) & 1 == 1
340
0
    }
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::smime_ca
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::smime_ca
341
0
    pub fn object_signing_ca(&self) -> bool {
342
0
        (self.0 >> 7) & 1 == 1
343
0
    }
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::object_signing_ca
Unexecuted instantiation: <x509_parser::extensions::NSCertType>::object_signing_ca
344
}
345
346
const NS_CERT_TYPE_FLAGS: &[&str] = &[
347
    "SSL CLient",
348
    "SSL Server",
349
    "S/MIME",
350
    "Object Signing",
351
    "Reserved",
352
    "SSL CA",
353
    "S/MIME CA",
354
    "Object Signing CA",
355
];
356
357
impl fmt::Display for NSCertType {
358
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
359
0
        let mut s = String::new();
360
0
        let mut acc = self.0;
361
0
        for flag_text in NS_CERT_TYPE_FLAGS {
362
0
            if acc & 1 != 0 {
363
0
                s = s + flag_text + ", ";
364
0
            }
365
0
            acc >>= 1;
366
        }
367
0
        s.pop();
368
0
        s.pop();
369
0
        f.write_str(&s)
370
0
    }
Unexecuted instantiation: <x509_parser::extensions::NSCertType as core::fmt::Display>::fmt
Unexecuted instantiation: <x509_parser::extensions::NSCertType as core::fmt::Display>::fmt
371
}
372
373
impl<'a> FromDer<'a, X509Error> for NSCertType {
374
0
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
375
0
        parser::parse_nscerttype(i).map_err(Err::convert)
376
0
    }
Unexecuted instantiation: <x509_parser::extensions::NSCertType as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
Unexecuted instantiation: <x509_parser::extensions::NSCertType as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
377
}
378
379
#[derive(Clone, Debug, PartialEq)]
380
pub struct AuthorityInfoAccess<'a> {
381
    pub accessdescs: Vec<AccessDescription<'a>>,
382
}
383
384
impl<'a> AuthorityInfoAccess<'a> {
385
    /// Returns an iterator over the Access Descriptors
386
0
    pub fn iter(&self) -> impl Iterator<Item = &AccessDescription<'a>> {
387
0
        self.accessdescs.iter()
388
0
    }
Unexecuted instantiation: <x509_parser::extensions::AuthorityInfoAccess>::iter
Unexecuted instantiation: <x509_parser::extensions::AuthorityInfoAccess>::iter
389
390
    /// Returns a `HashMap` mapping `Oid` to the list of references to `GeneralNames`
391
    ///
392
    /// If several names match the same `Oid`, they are merged in the same entry.
393
0
    pub fn as_hashmap(&self) -> HashMap<Oid<'a>, Vec<&GeneralName<'a>>> {
394
        // create the hashmap and merge entries with same OID
395
0
        let mut m: HashMap<Oid, Vec<&GeneralName>> = HashMap::new();
396
0
        for desc in &self.accessdescs {
397
            let AccessDescription {
398
0
                access_method: oid,
399
0
                access_location: gn,
400
0
            } = desc;
401
0
            if let Some(general_names) = m.get_mut(oid) {
402
0
                general_names.push(gn);
403
0
            } else {
404
0
                m.insert(oid.clone(), vec![gn]);
405
0
            }
406
        }
407
0
        m
408
0
    }
Unexecuted instantiation: <x509_parser::extensions::AuthorityInfoAccess>::as_hashmap
Unexecuted instantiation: <x509_parser::extensions::AuthorityInfoAccess>::as_hashmap
409
410
    /// Returns a `HashMap` mapping `Oid` to the list of `GeneralNames` (consuming the input)
411
    ///
412
    /// If several names match the same `Oid`, they are merged in the same entry.
413
0
    pub fn into_hashmap(self) -> HashMap<Oid<'a>, Vec<GeneralName<'a>>> {
414
0
        let mut aia_list = self.accessdescs;
415
        // create the hashmap and merge entries with same OID
416
0
        let mut m: HashMap<Oid, Vec<GeneralName>> = HashMap::new();
417
0
        for desc in aia_list.drain(..) {
418
            let AccessDescription {
419
0
                access_method: oid,
420
0
                access_location: gn,
421
0
            } = desc;
422
0
            if let Some(general_names) = m.get_mut(&oid) {
423
0
                general_names.push(gn);
424
0
            } else {
425
0
                m.insert(oid, vec![gn]);
426
0
            }
427
        }
428
0
        m
429
0
    }
Unexecuted instantiation: <x509_parser::extensions::AuthorityInfoAccess>::into_hashmap
Unexecuted instantiation: <x509_parser::extensions::AuthorityInfoAccess>::into_hashmap
430
}
431
432
impl<'a> FromDer<'a, X509Error> for AuthorityInfoAccess<'a> {
433
0
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
434
0
        parser::parse_authorityinfoaccess(i).map_err(Err::convert)
435
0
    }
Unexecuted instantiation: <x509_parser::extensions::AuthorityInfoAccess as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
Unexecuted instantiation: <x509_parser::extensions::AuthorityInfoAccess as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
436
}
437
438
#[derive(Clone, Debug, PartialEq)]
439
pub struct AccessDescription<'a> {
440
    pub access_method: Oid<'a>,
441
    pub access_location: GeneralName<'a>,
442
}
443
444
impl<'a> AccessDescription<'a> {
445
4.18k
    pub const fn new(access_method: Oid<'a>, access_location: GeneralName<'a>) -> Self {
446
4.18k
        AccessDescription {
447
4.18k
            access_method,
448
4.18k
            access_location,
449
4.18k
        }
450
4.18k
    }
Unexecuted instantiation: <x509_parser::extensions::AccessDescription>::new
<x509_parser::extensions::AccessDescription>::new
Line
Count
Source
445
4.18k
    pub const fn new(access_method: Oid<'a>, access_location: GeneralName<'a>) -> Self {
446
4.18k
        AccessDescription {
447
4.18k
            access_method,
448
4.18k
            access_location,
449
4.18k
        }
450
4.18k
    }
451
}
452
453
#[derive(Clone, Debug, PartialEq, Eq)]
454
pub struct InhibitAnyPolicy {
455
    pub skip_certs: u32,
456
}
457
458
impl<'a> FromDer<'a, X509Error> for InhibitAnyPolicy {
459
0
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
460
0
        map(parse_der_u32, |skip_certs| InhibitAnyPolicy { skip_certs })(i).map_err(Err::convert)
Unexecuted instantiation: <x509_parser::extensions::InhibitAnyPolicy as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der::{closure#0}
Unexecuted instantiation: <x509_parser::extensions::InhibitAnyPolicy as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der::{closure#0}
461
0
    }
Unexecuted instantiation: <x509_parser::extensions::InhibitAnyPolicy as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
Unexecuted instantiation: <x509_parser::extensions::InhibitAnyPolicy as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
462
}
463
464
#[derive(Clone, Debug, PartialEq, Eq)]
465
pub struct PolicyConstraints {
466
    pub require_explicit_policy: Option<u32>,
467
    pub inhibit_policy_mapping: Option<u32>,
468
}
469
470
impl<'a> FromDer<'a, X509Error> for PolicyConstraints {
471
0
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
472
0
        parser::parse_policyconstraints(i).map_err(Err::convert)
473
0
    }
Unexecuted instantiation: <x509_parser::extensions::PolicyConstraints as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
Unexecuted instantiation: <x509_parser::extensions::PolicyConstraints as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
474
}
475
476
#[derive(Clone, Debug, PartialEq)]
477
pub struct SubjectAlternativeName<'a> {
478
    pub general_names: Vec<GeneralName<'a>>,
479
}
480
481
impl<'a> FromDer<'a, X509Error> for SubjectAlternativeName<'a> {
482
0
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
483
0
        parse_der_sequence_defined_g(|input, _| {
484
0
            let (i, general_names) =
485
0
                all_consuming(many0(complete(cut(GeneralName::from_der))))(input)?;
486
0
            Ok((i, SubjectAlternativeName { general_names }))
487
0
        })(i)
Unexecuted instantiation: <x509_parser::extensions::SubjectAlternativeName as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der::{closure#0}
Unexecuted instantiation: <x509_parser::extensions::SubjectAlternativeName as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der::{closure#0}
488
0
    }
Unexecuted instantiation: <x509_parser::extensions::SubjectAlternativeName as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
Unexecuted instantiation: <x509_parser::extensions::SubjectAlternativeName as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
489
}
490
491
#[derive(Clone, Debug, PartialEq)]
492
pub struct IssuerAlternativeName<'a> {
493
    pub general_names: Vec<GeneralName<'a>>,
494
}
495
496
impl<'a> FromDer<'a, X509Error> for IssuerAlternativeName<'a> {
497
0
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
498
0
        parse_der_sequence_defined_g(|input, _| {
499
0
            let (i, general_names) =
500
0
                all_consuming(many0(complete(cut(GeneralName::from_der))))(input)?;
501
0
            Ok((i, IssuerAlternativeName { general_names }))
502
0
        })(i)
Unexecuted instantiation: <x509_parser::extensions::IssuerAlternativeName as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der::{closure#0}
Unexecuted instantiation: <x509_parser::extensions::IssuerAlternativeName as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der::{closure#0}
503
0
    }
Unexecuted instantiation: <x509_parser::extensions::IssuerAlternativeName as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
Unexecuted instantiation: <x509_parser::extensions::IssuerAlternativeName as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
504
}
505
506
#[derive(Clone, Debug, PartialEq)]
507
pub struct CRLDistributionPoints<'a> {
508
    pub points: Vec<CRLDistributionPoint<'a>>,
509
}
510
511
impl<'a> std::ops::Deref for CRLDistributionPoints<'a> {
512
    type Target = Vec<CRLDistributionPoint<'a>>;
513
514
0
    fn deref(&self) -> &Self::Target {
515
0
        &self.points
516
0
    }
Unexecuted instantiation: <x509_parser::extensions::CRLDistributionPoints as core::ops::deref::Deref>::deref
Unexecuted instantiation: <x509_parser::extensions::CRLDistributionPoints as core::ops::deref::Deref>::deref
517
}
518
519
impl<'a> FromDer<'a, X509Error> for CRLDistributionPoints<'a> {
520
0
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
521
0
        parser::parse_crldistributionpoints(i).map_err(Err::convert)
522
0
    }
Unexecuted instantiation: <x509_parser::extensions::CRLDistributionPoints as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
Unexecuted instantiation: <x509_parser::extensions::CRLDistributionPoints as asn1_rs::traits::FromDer<x509_parser::error::X509Error>>::from_der
523
}
524
525
#[derive(Clone, Debug, PartialEq)]
526
pub struct CRLDistributionPoint<'a> {
527
    pub distribution_point: Option<DistributionPointName<'a>>,
528
    pub reasons: Option<ReasonFlags>,
529
    pub crl_issuer: Option<Vec<GeneralName<'a>>>,
530
}
531
532
#[derive(Clone, Debug, PartialEq)]
533
pub enum DistributionPointName<'a> {
534
    FullName(Vec<GeneralName<'a>>),
535
    NameRelativeToCRLIssuer(RelativeDistinguishedName<'a>),
536
}
537
538
#[derive(Clone, Debug, PartialEq, Eq)]
539
pub struct ReasonFlags {
540
    pub flags: u16,
541
}
542
543
impl ReasonFlags {
544
0
    pub fn key_compromise(&self) -> bool {
545
0
        (self.flags >> 1) & 1 == 1
546
0
    }
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::key_compromise
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::key_compromise
547
0
    pub fn ca_compromise(&self) -> bool {
548
0
        (self.flags >> 2) & 1 == 1
549
0
    }
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::ca_compromise
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::ca_compromise
550
0
    pub fn affilation_changed(&self) -> bool {
551
0
        (self.flags >> 3) & 1 == 1
552
0
    }
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::affilation_changed
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::affilation_changed
553
0
    pub fn superseded(&self) -> bool {
554
0
        (self.flags >> 4) & 1 == 1
555
0
    }
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::superseded
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::superseded
556
0
    pub fn cessation_of_operation(&self) -> bool {
557
0
        (self.flags >> 5) & 1 == 1
558
0
    }
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::cessation_of_operation
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::cessation_of_operation
559
0
    pub fn certificate_hold(&self) -> bool {
560
0
        (self.flags >> 6) & 1 == 1
561
0
    }
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::certificate_hold
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::certificate_hold
562
0
    pub fn privelege_withdrawn(&self) -> bool {
563
0
        (self.flags >> 7) & 1 == 1
564
0
    }
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::privelege_withdrawn
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::privelege_withdrawn
565
0
    pub fn aa_compromise(&self) -> bool {
566
0
        (self.flags >> 8) & 1 == 1
567
0
    }
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::aa_compromise
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags>::aa_compromise
568
}
569
570
const REASON_FLAGS: &[&str] = &[
571
    "Unused",
572
    "Key Compromise",
573
    "CA Compromise",
574
    "Affiliation Changed",
575
    "Superseded",
576
    "Cessation Of Operation",
577
    "Certificate Hold",
578
    "Privilege Withdrawn",
579
    "AA Compromise",
580
];
581
582
impl fmt::Display for ReasonFlags {
583
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
584
0
        let mut s = String::new();
585
0
        let mut acc = self.flags;
586
0
        for flag_text in REASON_FLAGS {
587
0
            if acc & 1 != 0 {
588
0
                s = s + flag_text + ", ";
589
0
            }
590
0
            acc >>= 1;
591
        }
592
0
        s.pop();
593
0
        s.pop();
594
0
        f.write_str(&s)
595
0
    }
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags as core::fmt::Display>::fmt
Unexecuted instantiation: <x509_parser::extensions::ReasonFlags as core::fmt::Display>::fmt
596
}
597
598
#[derive(Clone, Debug, PartialEq)]
599
pub struct IssuingDistributionPoint<'a> {
600
    pub distribution_point: Option<DistributionPointName<'a>>,
601
    pub only_contains_user_certs: bool,
602
    pub only_contains_ca_certs: bool,
603
    pub only_some_reasons: Option<ReasonFlags>,
604
    pub indirect_crl: bool,
605
    pub only_contains_attribute_certs: bool,
606
}
607
608
pub(crate) mod parser {
609
    use crate::extensions::*;
610
    use crate::time::ASN1Time;
611
    use asn1_rs::{GeneralizedTime, ParseResult};
612
    use der_parser::ber::BerObject;
613
    use der_parser::error::BerError;
614
    use der_parser::{oid::Oid, *};
615
    use lazy_static::lazy_static;
616
    use nom::combinator::{cut, map};
617
    use nom::{Err, IResult};
618
619
    type ExtParser = fn(&[u8]) -> IResult<&[u8], ParsedExtension, BerError>;
620
621
    lazy_static! {
622
        static ref EXTENSION_PARSERS: HashMap<Oid<'static>, ExtParser> = {
623
            macro_rules! add {
624
                ($m:ident, $oid:ident, $p:ident) => {
625
                    $m.insert($oid, $p as ExtParser);
626
                };
627
            }
628
629
            let mut m = HashMap::new();
630
            add!(
631
                m,
632
                OID_X509_EXT_SUBJECT_KEY_IDENTIFIER,
633
                parse_keyidentifier_ext
634
            );
635
            add!(m, OID_X509_EXT_KEY_USAGE, parse_keyusage_ext);
636
            add!(
637
                m,
638
                OID_X509_EXT_SUBJECT_ALT_NAME,
639
                parse_subjectalternativename_ext
640
            );
641
            add!(
642
                m,
643
                OID_X509_EXT_ISSUER_ALT_NAME,
644
                parse_issueralternativename_ext
645
            );
646
            add!(
647
                m,
648
                OID_X509_EXT_BASIC_CONSTRAINTS,
649
                parse_basicconstraints_ext
650
            );
651
            add!(m, OID_X509_EXT_NAME_CONSTRAINTS, parse_nameconstraints_ext);
652
            add!(
653
                m,
654
                OID_X509_EXT_CERTIFICATE_POLICIES,
655
                parse_certificatepolicies_ext
656
            );
657
            add!(m, OID_X509_EXT_POLICY_MAPPINGS, parse_policymappings_ext);
658
            add!(
659
                m,
660
                OID_X509_EXT_POLICY_CONSTRAINTS,
661
                parse_policyconstraints_ext
662
            );
663
            add!(
664
                m,
665
                OID_X509_EXT_EXTENDED_KEY_USAGE,
666
                parse_extendedkeyusage_ext
667
            );
668
            add!(
669
                m,
670
                OID_X509_EXT_CRL_DISTRIBUTION_POINTS,
671
                parse_crldistributionpoints_ext
672
            );
673
            add!(
674
                m,
675
                OID_X509_EXT_INHIBITANT_ANY_POLICY,
676
                parse_inhibitanypolicy_ext
677
            );
678
            add!(
679
                m,
680
                OID_PKIX_AUTHORITY_INFO_ACCESS,
681
                parse_authorityinfoaccess_ext
682
            );
683
            add!(
684
                m,
685
                OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER,
686
                parse_authoritykeyidentifier_ext
687
            );
688
            add!(m, OID_CT_LIST_SCT, parse_sct_ext);
689
            add!(m, OID_X509_EXT_CERT_TYPE, parse_nscerttype_ext);
690
            add!(m, OID_X509_EXT_CERT_COMMENT, parse_nscomment_ext);
691
            add!(m, OID_X509_EXT_CRL_NUMBER, parse_crl_number);
692
            add!(m, OID_X509_EXT_REASON_CODE, parse_reason_code);
693
            add!(m, OID_X509_EXT_INVALIDITY_DATE, parse_invalidity_date);
694
            add!(
695
                m,
696
                OID_X509_EXT_ISSUER_DISTRIBUTION_POINT,
697
                parse_issuingdistributionpoint_ext
698
            );
699
            m
700
        };
701
    }
702
703
    // look into the parser map if the extension is known, and parse it
704
    // otherwise, leave it as UnsupportedExtension
705
20.8k
    fn parse_extension0<'a>(
706
20.8k
        orig_i: &'a [u8],
707
20.8k
        i: &'a [u8],
708
20.8k
        oid: &Oid,
709
20.8k
    ) -> IResult<&'a [u8], ParsedExtension<'a>, BerError> {
710
20.8k
        if let Some(parser) = EXTENSION_PARSERS.get(oid) {
711
20.1k
            match parser(i) {
712
19.9k
                Ok((_, ext)) => Ok((orig_i, ext)),
713
172
                Err(error) => Ok((orig_i, ParsedExtension::ParseError { error })),
714
            }
715
        } else {
716
709
            Ok((
717
709
                orig_i,
718
709
                ParsedExtension::UnsupportedExtension {
719
709
                    oid: oid.to_owned(),
720
709
                },
721
709
            ))
722
        }
723
20.8k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_extension0
x509_parser::extensions::parser::parse_extension0
Line
Count
Source
705
20.8k
    fn parse_extension0<'a>(
706
20.8k
        orig_i: &'a [u8],
707
20.8k
        i: &'a [u8],
708
20.8k
        oid: &Oid,
709
20.8k
    ) -> IResult<&'a [u8], ParsedExtension<'a>, BerError> {
710
20.8k
        if let Some(parser) = EXTENSION_PARSERS.get(oid) {
711
20.1k
            match parser(i) {
712
19.9k
                Ok((_, ext)) => Ok((orig_i, ext)),
713
172
                Err(error) => Ok((orig_i, ParsedExtension::ParseError { error })),
714
            }
715
        } else {
716
709
            Ok((
717
709
                orig_i,
718
709
                ParsedExtension::UnsupportedExtension {
719
709
                    oid: oid.to_owned(),
720
709
                },
721
709
            ))
722
        }
723
20.8k
    }
724
725
20.8k
    pub(crate) fn parse_extension<'a>(
726
20.8k
        orig_i: &'a [u8],
727
20.8k
        i: &'a [u8],
728
20.8k
        oid: &Oid,
729
20.8k
    ) -> IResult<&'a [u8], ParsedExtension<'a>, BerError> {
730
20.8k
        parse_extension0(orig_i, i, oid)
731
20.8k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_extension
x509_parser::extensions::parser::parse_extension
Line
Count
Source
725
20.8k
    pub(crate) fn parse_extension<'a>(
726
20.8k
        orig_i: &'a [u8],
727
20.8k
        i: &'a [u8],
728
20.8k
        oid: &Oid,
729
20.8k
    ) -> IResult<&'a [u8], ParsedExtension<'a>, BerError> {
730
20.8k
        parse_extension0(orig_i, i, oid)
731
20.8k
    }
732
733
    /// Parse a "Basic Constraints" extension
734
    ///
735
    /// <pre>
736
    ///   id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }
737
    ///   BasicConstraints ::= SEQUENCE {
738
    ///        cA                      BOOLEAN DEFAULT FALSE,
739
    ///        pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
740
    /// </pre>
741
    ///
742
    /// Note the maximum length of the `pathLenConstraint` field is limited to the size of a 32-bits
743
    /// unsigned integer, and parsing will fail if value if larger.
744
2.11k
    pub(super) fn parse_basicconstraints(i: &[u8]) -> IResult<&[u8], BasicConstraints, BerError> {
745
2.11k
        let (rem, obj) = parse_der_sequence(i)?;
746
2.10k
        if let Ok(seq) = obj.as_sequence() {
747
2.10k
            let (ca, path_len_constraint) = match seq.len() {
748
1.75k
                0 => (false, None),
749
                1 => {
750
159
                    if let Ok(b) = seq[0].as_bool() {
751
159
                        (b, None)
752
0
                    } else if let Ok(u) = seq[0].as_u32() {
753
0
                        (false, Some(u))
754
                    } else {
755
0
                        return Err(nom::Err::Error(BerError::InvalidTag));
756
                    }
757
                }
758
                2 => {
759
191
                    let ca = seq[0]
760
191
                        .as_bool()
761
191
                        .or(Err(nom::Err::Error(BerError::InvalidLength)))?;
762
191
                    let pl = seq[1]
763
191
                        .as_u32()
764
191
                        .or(Err(nom::Err::Error(BerError::InvalidLength)))?;
765
191
                    (ca, Some(pl))
766
                }
767
0
                _ => return Err(nom::Err::Error(BerError::InvalidLength)),
768
            };
769
2.10k
            Ok((
770
2.10k
                rem,
771
2.10k
                BasicConstraints {
772
2.10k
                    ca,
773
2.10k
                    path_len_constraint,
774
2.10k
                },
775
2.10k
            ))
776
        } else {
777
0
            Err(nom::Err::Error(BerError::InvalidLength))
778
        }
779
2.11k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_basicconstraints
x509_parser::extensions::parser::parse_basicconstraints
Line
Count
Source
744
2.11k
    pub(super) fn parse_basicconstraints(i: &[u8]) -> IResult<&[u8], BasicConstraints, BerError> {
745
2.11k
        let (rem, obj) = parse_der_sequence(i)?;
746
2.10k
        if let Ok(seq) = obj.as_sequence() {
747
2.10k
            let (ca, path_len_constraint) = match seq.len() {
748
1.75k
                0 => (false, None),
749
                1 => {
750
159
                    if let Ok(b) = seq[0].as_bool() {
751
159
                        (b, None)
752
0
                    } else if let Ok(u) = seq[0].as_u32() {
753
0
                        (false, Some(u))
754
                    } else {
755
0
                        return Err(nom::Err::Error(BerError::InvalidTag));
756
                    }
757
                }
758
                2 => {
759
191
                    let ca = seq[0]
760
191
                        .as_bool()
761
191
                        .or(Err(nom::Err::Error(BerError::InvalidLength)))?;
762
191
                    let pl = seq[1]
763
191
                        .as_u32()
764
191
                        .or(Err(nom::Err::Error(BerError::InvalidLength)))?;
765
191
                    (ca, Some(pl))
766
                }
767
0
                _ => return Err(nom::Err::Error(BerError::InvalidLength)),
768
            };
769
2.10k
            Ok((
770
2.10k
                rem,
771
2.10k
                BasicConstraints {
772
2.10k
                    ca,
773
2.10k
                    path_len_constraint,
774
2.10k
                },
775
2.10k
            ))
776
        } else {
777
0
            Err(nom::Err::Error(BerError::InvalidLength))
778
        }
779
2.11k
    }
780
781
2.11k
    fn parse_basicconstraints_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
782
2.11k
        map(parse_basicconstraints, ParsedExtension::BasicConstraints)(i)
783
2.11k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_basicconstraints_ext
x509_parser::extensions::parser::parse_basicconstraints_ext
Line
Count
Source
781
2.11k
    fn parse_basicconstraints_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
782
2.11k
        map(parse_basicconstraints, ParsedExtension::BasicConstraints)(i)
783
2.11k
    }
784
785
1
    fn parse_nameconstraints_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
786
1
        map(parse_nameconstraints, ParsedExtension::NameConstraints)(i)
787
1
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_nameconstraints_ext
x509_parser::extensions::parser::parse_nameconstraints_ext
Line
Count
Source
785
1
    fn parse_nameconstraints_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
786
1
        map(parse_nameconstraints, ParsedExtension::NameConstraints)(i)
787
1
    }
788
789
2.28k
    pub(super) fn parse_subjectalternativename_ext(
790
2.28k
        i: &[u8],
791
2.28k
    ) -> IResult<&[u8], ParsedExtension, BerError> {
792
2.28k
        parse_der_sequence_defined_g(|input, _| {
793
2.28k
            let (i, general_names) = all_consuming(many0(complete(cut(parse_generalname))))(input)?;
794
2.21k
            Ok((
795
2.21k
                i,
796
2.21k
                ParsedExtension::SubjectAlternativeName(SubjectAlternativeName { general_names }),
797
2.21k
            ))
798
2.28k
        })(i)
Unexecuted instantiation: x509_parser::extensions::parser::parse_subjectalternativename_ext::{closure#0}
x509_parser::extensions::parser::parse_subjectalternativename_ext::{closure#0}
Line
Count
Source
792
2.28k
        parse_der_sequence_defined_g(|input, _| {
793
2.28k
            let (i, general_names) = all_consuming(many0(complete(cut(parse_generalname))))(input)?;
794
2.21k
            Ok((
795
2.21k
                i,
796
2.21k
                ParsedExtension::SubjectAlternativeName(SubjectAlternativeName { general_names }),
797
2.21k
            ))
798
2.28k
        })(i)
799
2.28k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_subjectalternativename_ext
x509_parser::extensions::parser::parse_subjectalternativename_ext
Line
Count
Source
789
2.28k
    pub(super) fn parse_subjectalternativename_ext(
790
2.28k
        i: &[u8],
791
2.28k
    ) -> IResult<&[u8], ParsedExtension, BerError> {
792
2.28k
        parse_der_sequence_defined_g(|input, _| {
793
            let (i, general_names) = all_consuming(many0(complete(cut(parse_generalname))))(input)?;
794
            Ok((
795
                i,
796
                ParsedExtension::SubjectAlternativeName(SubjectAlternativeName { general_names }),
797
            ))
798
2.28k
        })(i)
799
2.28k
    }
800
801
0
    pub(super) fn parse_issueralternativename_ext(
802
0
        i: &[u8],
803
0
    ) -> IResult<&[u8], ParsedExtension, BerError> {
804
0
        parse_der_sequence_defined_g(|input, _| {
805
0
            let (i, general_names) = all_consuming(many0(complete(cut(parse_generalname))))(input)?;
806
0
            Ok((
807
0
                i,
808
0
                ParsedExtension::IssuerAlternativeName(IssuerAlternativeName { general_names }),
809
0
            ))
810
0
        })(i)
Unexecuted instantiation: x509_parser::extensions::parser::parse_issueralternativename_ext::{closure#0}
Unexecuted instantiation: x509_parser::extensions::parser::parse_issueralternativename_ext::{closure#0}
811
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_issueralternativename_ext
Unexecuted instantiation: x509_parser::extensions::parser::parse_issueralternativename_ext
812
813
0
    pub(super) fn parse_policyconstraints(i: &[u8]) -> IResult<&[u8], PolicyConstraints, BerError> {
814
0
        parse_der_sequence_defined_g(|input, _| {
815
0
            let (i, require_explicit_policy) = opt(complete(map_res(
816
0
                parse_der_tagged_implicit(0, parse_der_content(Tag::Integer)),
817
0
                |x| x.as_u32(),
Unexecuted instantiation: x509_parser::extensions::parser::parse_policyconstraints::{closure#0}::{closure#0}
Unexecuted instantiation: x509_parser::extensions::parser::parse_policyconstraints::{closure#0}::{closure#0}
818
0
            )))(input)?;
819
0
            let (i, inhibit_policy_mapping) = all_consuming(opt(complete(map_res(
820
0
                parse_der_tagged_implicit(1, parse_der_content(Tag::Integer)),
821
0
                |x| x.as_u32(),
Unexecuted instantiation: x509_parser::extensions::parser::parse_policyconstraints::{closure#0}::{closure#1}
Unexecuted instantiation: x509_parser::extensions::parser::parse_policyconstraints::{closure#0}::{closure#1}
822
0
            ))))(i)?;
823
0
            let policy_constraint = PolicyConstraints {
824
0
                require_explicit_policy,
825
0
                inhibit_policy_mapping,
826
0
            };
827
0
            Ok((i, policy_constraint))
828
0
        })(i)
Unexecuted instantiation: x509_parser::extensions::parser::parse_policyconstraints::{closure#0}
Unexecuted instantiation: x509_parser::extensions::parser::parse_policyconstraints::{closure#0}
829
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_policyconstraints
Unexecuted instantiation: x509_parser::extensions::parser::parse_policyconstraints
830
831
0
    fn parse_policyconstraints_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
832
0
        map(parse_policyconstraints, ParsedExtension::PolicyConstraints)(i)
833
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_policyconstraints_ext
Unexecuted instantiation: x509_parser::extensions::parser::parse_policyconstraints_ext
834
835
0
    fn parse_policymappings_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
836
0
        map(parse_policymappings, ParsedExtension::PolicyMappings)(i)
837
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_policymappings_ext
Unexecuted instantiation: x509_parser::extensions::parser::parse_policymappings_ext
838
839
0
    fn parse_inhibitanypolicy_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
840
0
        let (ret, skip_certs) = parse_der_u32(i)?;
841
0
        Ok((
842
0
            ret,
843
0
            ParsedExtension::InhibitAnyPolicy(InhibitAnyPolicy { skip_certs }),
844
0
        ))
845
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_inhibitanypolicy_ext
Unexecuted instantiation: x509_parser::extensions::parser::parse_inhibitanypolicy_ext
846
847
1.84k
    fn parse_extendedkeyusage_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
848
1.84k
        map(parse_extendedkeyusage, ParsedExtension::ExtendedKeyUsage)(i)
849
1.84k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_extendedkeyusage_ext
x509_parser::extensions::parser::parse_extendedkeyusage_ext
Line
Count
Source
847
1.84k
    fn parse_extendedkeyusage_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
848
1.84k
        map(parse_extendedkeyusage, ParsedExtension::ExtendedKeyUsage)(i)
849
1.84k
    }
850
851
    // DistributionPointName ::= CHOICE {
852
    //     fullName                [0]     GeneralNames,
853
    //     nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
854
3.14k
    fn parse_distributionpointname(i: &[u8]) -> IResult<&[u8], DistributionPointName, BerError> {
855
3.14k
        let (rem, header) = der_read_element_header(i)?;
856
3.14k
        match header.tag().0 {
857
            0 => {
858
3.14k
                let (rem, names) = many1(complete(parse_generalname))(rem)?;
859
3.12k
                Ok((rem, DistributionPointName::FullName(names)))
860
            }
861
            1 => {
862
1
                let (rem, rdn) = RelativeDistinguishedName::from_der(rem)
863
1
                    .map_err(|_| BerError::BerValueError)?;
864
0
                Ok((rem, DistributionPointName::NameRelativeToCRLIssuer(rdn)))
865
            }
866
1
            _ => Err(Err::Error(BerError::InvalidTag)),
867
        }
868
3.14k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_distributionpointname
x509_parser::extensions::parser::parse_distributionpointname
Line
Count
Source
854
3.14k
    fn parse_distributionpointname(i: &[u8]) -> IResult<&[u8], DistributionPointName, BerError> {
855
3.14k
        let (rem, header) = der_read_element_header(i)?;
856
3.14k
        match header.tag().0 {
857
            0 => {
858
3.14k
                let (rem, names) = many1(complete(parse_generalname))(rem)?;
859
3.12k
                Ok((rem, DistributionPointName::FullName(names)))
860
            }
861
            1 => {
862
1
                let (rem, rdn) = RelativeDistinguishedName::from_der(rem)
863
1
                    .map_err(|_| BerError::BerValueError)?;
864
0
                Ok((rem, DistributionPointName::NameRelativeToCRLIssuer(rdn)))
865
            }
866
1
            _ => Err(Err::Error(BerError::InvalidTag)),
867
        }
868
3.14k
    }
869
870
3.15k
    fn parse_implicit_tagged_reasons(tag: u32) -> impl Fn(&[u8]) -> BerResult<ReasonFlags> {
871
3.15k
        move |i: &[u8]| {
872
3.15k
            let (rem, obj) = parse_der_tagged_implicit(tag, parse_der_content(Tag::BitString))(i)?;
873
0
            parse_reasons(rem, obj)
874
3.15k
        }
Unexecuted instantiation: x509_parser::extensions::parser::parse_implicit_tagged_reasons::{closure#0}
x509_parser::extensions::parser::parse_implicit_tagged_reasons::{closure#0}
Line
Count
Source
871
3.15k
        move |i: &[u8]| {
872
3.15k
            let (rem, obj) = parse_der_tagged_implicit(tag, parse_der_content(Tag::BitString))(i)?;
873
0
            parse_reasons(rem, obj)
874
3.15k
        }
875
3.15k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_implicit_tagged_reasons
x509_parser::extensions::parser::parse_implicit_tagged_reasons
Line
Count
Source
870
3.15k
    fn parse_implicit_tagged_reasons(tag: u32) -> impl Fn(&[u8]) -> BerResult<ReasonFlags> {
871
        move |i: &[u8]| {
872
            let (rem, obj) = parse_der_tagged_implicit(tag, parse_der_content(Tag::BitString))(i)?;
873
            parse_reasons(rem, obj)
874
        }
875
3.15k
    }
876
877
    // ReasonFlags ::= BIT STRING {
878
    // unused                  (0),
879
    // keyCompromise           (1),
880
    // cACompromise            (2),
881
    // affiliationChanged      (3),
882
    // superseded              (4),
883
    // cessationOfOperation    (5),
884
    // certificateHold         (6),
885
    // privilegeWithdrawn      (7),
886
    // aACompromise            (8) }
887
0
    fn parse_reasons<'a>(rem: &'a [u8], obj: BerObject<'a>) -> BerResult<'a, ReasonFlags> {
888
0
        if let DerObjectContent::BitString(_, b) = obj.content {
889
0
            let flags = b
890
0
                .data
891
0
                .iter()
892
0
                .rev()
893
0
                .fold(0, |acc, x| acc << 8 | (x.reverse_bits() as u16));
Unexecuted instantiation: x509_parser::extensions::parser::parse_reasons::{closure#0}
Unexecuted instantiation: x509_parser::extensions::parser::parse_reasons::{closure#0}
894
0
            Ok((rem, ReasonFlags { flags }))
895
        } else {
896
0
            Err(nom::Err::Failure(BerError::InvalidTag))
897
        }
898
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_reasons
Unexecuted instantiation: x509_parser::extensions::parser::parse_reasons
899
900
0
    fn parse_crlissuer_content(i: &[u8]) -> BerResult<Vec<GeneralName>> {
901
0
        many1(complete(parse_generalname))(i)
902
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_crlissuer_content
Unexecuted instantiation: x509_parser::extensions::parser::parse_crlissuer_content
903
904
    // DistributionPoint ::= SEQUENCE {
905
    //     distributionPoint       [0]     DistributionPointName OPTIONAL,
906
    //     reasons                 [1]     ReasonFlags OPTIONAL,
907
    //     cRLIssuer               [2]     GeneralNames OPTIONAL }
908
5.64k
    pub(super) fn parse_crldistributionpoint(
909
5.64k
        i: &[u8],
910
5.64k
    ) -> IResult<&[u8], CRLDistributionPoint, BerError> {
911
5.64k
        parse_der_sequence_defined_g(|content, _| {
912
3.15k
            let (rem, distribution_point) =
913
3.15k
                opt(complete(parse_der_tagged_explicit_g(0, |b, _| {
914
3.14k
                    parse_distributionpointname(b)
915
3.15k
                })))(content)?;
Unexecuted instantiation: x509_parser::extensions::parser::parse_crldistributionpoint::{closure#0}::{closure#0}
x509_parser::extensions::parser::parse_crldistributionpoint::{closure#0}::{closure#0}
Line
Count
Source
913
3.14k
                opt(complete(parse_der_tagged_explicit_g(0, |b, _| {
914
3.14k
                    parse_distributionpointname(b)
915
3.14k
                })))(content)?;
916
3.15k
            let (rem, reasons) = opt(complete(parse_implicit_tagged_reasons(1)))(rem)?;
917
3.15k
            let (rem, crl_issuer) = opt(complete(parse_der_tagged_implicit_g(2, |i, _, _| {
918
0
                parse_crlissuer_content(i)
919
3.15k
            })))(rem)?;
Unexecuted instantiation: x509_parser::extensions::parser::parse_crldistributionpoint::{closure#0}::{closure#1}
Unexecuted instantiation: x509_parser::extensions::parser::parse_crldistributionpoint::{closure#0}::{closure#1}
920
3.15k
            let crl_dp = CRLDistributionPoint {
921
3.15k
                distribution_point,
922
3.15k
                reasons,
923
3.15k
                crl_issuer,
924
3.15k
            };
925
3.15k
            Ok((rem, crl_dp))
926
5.64k
        })(i)
Unexecuted instantiation: x509_parser::extensions::parser::parse_crldistributionpoint::{closure#0}
x509_parser::extensions::parser::parse_crldistributionpoint::{closure#0}
Line
Count
Source
911
3.15k
        parse_der_sequence_defined_g(|content, _| {
912
3.15k
            let (rem, distribution_point) =
913
3.15k
                opt(complete(parse_der_tagged_explicit_g(0, |b, _| {
914
                    parse_distributionpointname(b)
915
3.15k
                })))(content)?;
916
3.15k
            let (rem, reasons) = opt(complete(parse_implicit_tagged_reasons(1)))(rem)?;
917
3.15k
            let (rem, crl_issuer) = opt(complete(parse_der_tagged_implicit_g(2, |i, _, _| {
918
                parse_crlissuer_content(i)
919
3.15k
            })))(rem)?;
920
3.15k
            let crl_dp = CRLDistributionPoint {
921
3.15k
                distribution_point,
922
3.15k
                reasons,
923
3.15k
                crl_issuer,
924
3.15k
            };
925
3.15k
            Ok((rem, crl_dp))
926
3.15k
        })(i)
927
5.64k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_crldistributionpoint
x509_parser::extensions::parser::parse_crldistributionpoint
Line
Count
Source
908
5.64k
    pub(super) fn parse_crldistributionpoint(
909
5.64k
        i: &[u8],
910
5.64k
    ) -> IResult<&[u8], CRLDistributionPoint, BerError> {
911
5.64k
        parse_der_sequence_defined_g(|content, _| {
912
            let (rem, distribution_point) =
913
                opt(complete(parse_der_tagged_explicit_g(0, |b, _| {
914
                    parse_distributionpointname(b)
915
                })))(content)?;
916
            let (rem, reasons) = opt(complete(parse_implicit_tagged_reasons(1)))(rem)?;
917
            let (rem, crl_issuer) = opt(complete(parse_der_tagged_implicit_g(2, |i, _, _| {
918
                parse_crlissuer_content(i)
919
            })))(rem)?;
920
            let crl_dp = CRLDistributionPoint {
921
                distribution_point,
922
                reasons,
923
                crl_issuer,
924
            };
925
            Ok((rem, crl_dp))
926
5.64k
        })(i)
927
5.64k
    }
928
929
2.50k
    pub(super) fn parse_crldistributionpoints(
930
2.50k
        i: &[u8],
931
2.50k
    ) -> IResult<&[u8], CRLDistributionPoints, BerError> {
932
2.50k
        let (ret, crldps) = parse_der_sequence_of_v(parse_crldistributionpoint)(i)?;
933
2.48k
        Ok((ret, CRLDistributionPoints { points: crldps }))
934
2.50k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_crldistributionpoints
x509_parser::extensions::parser::parse_crldistributionpoints
Line
Count
Source
929
2.50k
    pub(super) fn parse_crldistributionpoints(
930
2.50k
        i: &[u8],
931
2.50k
    ) -> IResult<&[u8], CRLDistributionPoints, BerError> {
932
2.50k
        let (ret, crldps) = parse_der_sequence_of_v(parse_crldistributionpoint)(i)?;
933
2.48k
        Ok((ret, CRLDistributionPoints { points: crldps }))
934
2.50k
    }
935
936
2.50k
    fn parse_crldistributionpoints_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
937
2.50k
        map(
938
2.50k
            parse_crldistributionpoints,
939
2.50k
            ParsedExtension::CRLDistributionPoints,
940
2.50k
        )(i)
941
2.50k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_crldistributionpoints_ext
x509_parser::extensions::parser::parse_crldistributionpoints_ext
Line
Count
Source
936
2.50k
    fn parse_crldistributionpoints_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
937
2.50k
        map(
938
2.50k
            parse_crldistributionpoints,
939
2.50k
            ParsedExtension::CRLDistributionPoints,
940
2.50k
        )(i)
941
2.50k
    }
942
943
    //  IssuingDistributionPoint ::= SEQUENCE {
944
    //         distributionPoint          [0] DistributionPointName OPTIONAL,
945
    //         onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE,
946
    //         onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE,
947
    //         onlySomeReasons            [3] ReasonFlags OPTIONAL,
948
    //         indirectCRL                [4] BOOLEAN DEFAULT FALSE,
949
    //         onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
950
0
    pub(super) fn parse_issuingdistributionpoint(
951
0
        i: &[u8],
952
0
    ) -> IResult<&[u8], IssuingDistributionPoint, BerError> {
953
0
        parse_der_sequence_defined_g(|content, _| {
954
0
            let parse_tagged_bool = |tag: u32, rem| -> IResult<&[u8], bool, BerError> {
955
0
                let (rem, value) = opt(complete(|_| {
956
0
                    parse_der_implicit(rem, tag, parse_der_content(Tag::Boolean))
957
0
                        .map(|(res, ob)| (res, ob.as_bool().unwrap_or(false)))
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint::{closure#0}::{closure#0}::{closure#0}::{closure#0}
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint::{closure#0}::{closure#0}::{closure#0}::{closure#0}
958
0
                }))(rem)?;
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint::{closure#0}::{closure#0}::{closure#0}
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint::{closure#0}::{closure#0}::{closure#0}
959
0
                Ok((rem, value.unwrap_or_default()))
960
0
            };
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint::{closure#0}::{closure#0}
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint::{closure#0}::{closure#0}
961
962
0
            let (rem, distribution_point) =
963
0
                opt(complete(parse_der_tagged_explicit_g(0, |b, _| {
964
0
                    parse_distributionpointname(b)
965
0
                })))(content)?;
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint::{closure#0}::{closure#1}
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint::{closure#0}::{closure#1}
966
967
0
            let (rem, only_contains_user_certs) = parse_tagged_bool(1, rem)?;
968
0
            let (rem, only_contains_ca_certs) = parse_tagged_bool(2, rem)?;
969
0
            let (rem, only_some_reasons) = opt(complete(parse_implicit_tagged_reasons(3)))(rem)?;
970
0
            let (rem, indirect_crl) = parse_tagged_bool(4, rem)?;
971
0
            let (rem, only_contains_attribute_certs) = parse_tagged_bool(5, rem)?;
972
973
0
            let crl_idp = IssuingDistributionPoint {
974
0
                distribution_point,
975
0
                only_contains_user_certs,
976
0
                only_contains_ca_certs,
977
0
                only_some_reasons,
978
0
                indirect_crl,
979
0
                only_contains_attribute_certs,
980
0
            };
981
0
            Ok((rem, crl_idp))
982
0
        })(i)
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint::{closure#0}
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint::{closure#0}
983
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint
984
985
0
    fn parse_issuingdistributionpoint_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
986
0
        map(
987
0
            parse_issuingdistributionpoint,
988
0
            ParsedExtension::IssuingDistributionPoint,
989
0
        )(i)
990
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint_ext
Unexecuted instantiation: x509_parser::extensions::parser::parse_issuingdistributionpoint_ext
991
992
    // AuthorityInfoAccessSyntax  ::=
993
    //         SEQUENCE SIZE (1..MAX) OF AccessDescription
994
    //
995
    // AccessDescription  ::=  SEQUENCE {
996
    //         accessMethod          OBJECT IDENTIFIER,
997
    //         accessLocation        GeneralName  }
998
2.46k
    pub(super) fn parse_authorityinfoaccess(
999
2.46k
        i: &[u8],
1000
2.46k
    ) -> IResult<&[u8], AuthorityInfoAccess, BerError> {
1001
6.63k
        fn parse_aia(i: &[u8]) -> IResult<&[u8], AccessDescription, BerError> {
1002
6.63k
            parse_der_sequence_defined_g(|content, _| {
1003
                // Read first element, an oid.
1004
4.20k
                let (gn, oid) = Oid::from_der(content)?;
1005
                // Parse second element
1006
4.20k
                let (rest, gn) = parse_generalname(gn)?;
1007
4.18k
                Ok((rest, AccessDescription::new(oid, gn)))
1008
6.63k
            })(i)
Unexecuted instantiation: x509_parser::extensions::parser::parse_authorityinfoaccess::parse_aia::{closure#0}
x509_parser::extensions::parser::parse_authorityinfoaccess::parse_aia::{closure#0}
Line
Count
Source
1002
4.20k
            parse_der_sequence_defined_g(|content, _| {
1003
                // Read first element, an oid.
1004
4.20k
                let (gn, oid) = Oid::from_der(content)?;
1005
                // Parse second element
1006
4.20k
                let (rest, gn) = parse_generalname(gn)?;
1007
4.18k
                Ok((rest, AccessDescription::new(oid, gn)))
1008
4.20k
            })(i)
1009
6.63k
        }
Unexecuted instantiation: x509_parser::extensions::parser::parse_authorityinfoaccess::parse_aia
x509_parser::extensions::parser::parse_authorityinfoaccess::parse_aia
Line
Count
Source
1001
6.63k
        fn parse_aia(i: &[u8]) -> IResult<&[u8], AccessDescription, BerError> {
1002
6.63k
            parse_der_sequence_defined_g(|content, _| {
1003
                // Read first element, an oid.
1004
                let (gn, oid) = Oid::from_der(content)?;
1005
                // Parse second element
1006
                let (rest, gn) = parse_generalname(gn)?;
1007
                Ok((rest, AccessDescription::new(oid, gn)))
1008
6.63k
            })(i)
1009
6.63k
        }
1010
2.46k
        let (ret, accessdescs) = parse_der_sequence_of_v(parse_aia)(i)?;
1011
2.42k
        Ok((ret, AuthorityInfoAccess { accessdescs }))
1012
2.46k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_authorityinfoaccess
x509_parser::extensions::parser::parse_authorityinfoaccess
Line
Count
Source
998
2.46k
    pub(super) fn parse_authorityinfoaccess(
999
2.46k
        i: &[u8],
1000
2.46k
    ) -> IResult<&[u8], AuthorityInfoAccess, BerError> {
1001
        fn parse_aia(i: &[u8]) -> IResult<&[u8], AccessDescription, BerError> {
1002
            parse_der_sequence_defined_g(|content, _| {
1003
                // Read first element, an oid.
1004
                let (gn, oid) = Oid::from_der(content)?;
1005
                // Parse second element
1006
                let (rest, gn) = parse_generalname(gn)?;
1007
                Ok((rest, AccessDescription::new(oid, gn)))
1008
            })(i)
1009
        }
1010
2.46k
        let (ret, accessdescs) = parse_der_sequence_of_v(parse_aia)(i)?;
1011
2.42k
        Ok((ret, AuthorityInfoAccess { accessdescs }))
1012
2.46k
    }
1013
1014
2.46k
    fn parse_authorityinfoaccess_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1015
2.46k
        map(
1016
2.46k
            parse_authorityinfoaccess,
1017
2.46k
            ParsedExtension::AuthorityInfoAccess,
1018
2.46k
        )(i)
1019
2.46k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_authorityinfoaccess_ext
x509_parser::extensions::parser::parse_authorityinfoaccess_ext
Line
Count
Source
1014
2.46k
    fn parse_authorityinfoaccess_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1015
2.46k
        map(
1016
2.46k
            parse_authorityinfoaccess,
1017
2.46k
            ParsedExtension::AuthorityInfoAccess,
1018
2.46k
        )(i)
1019
2.46k
    }
1020
1021
2.52k
    fn parse_aki_content<'a>(
1022
2.52k
        i: &'a [u8],
1023
2.52k
        _hdr: Header<'_>,
1024
2.52k
    ) -> IResult<&'a [u8], AuthorityKeyIdentifier<'a>, BerError> {
1025
2.52k
        let (i, key_identifier) = opt(complete(parse_der_tagged_implicit_g(0, |d, _, _| {
1026
2.51k
            Ok((&[], KeyIdentifier(d)))
1027
2.52k
        })))(i)?;
Unexecuted instantiation: x509_parser::extensions::parser::parse_aki_content::{closure#0}
x509_parser::extensions::parser::parse_aki_content::{closure#0}
Line
Count
Source
1025
2.51k
        let (i, key_identifier) = opt(complete(parse_der_tagged_implicit_g(0, |d, _, _| {
1026
2.51k
            Ok((&[], KeyIdentifier(d)))
1027
2.51k
        })))(i)?;
1028
2.52k
        let (i, authority_cert_issuer) =
1029
2.52k
            opt(complete(parse_der_tagged_implicit_g(1, |d, _, _| {
1030
6
                many0(complete(parse_generalname))(d)
1031
2.52k
            })))(i)?;
Unexecuted instantiation: x509_parser::extensions::parser::parse_aki_content::{closure#1}
x509_parser::extensions::parser::parse_aki_content::{closure#1}
Line
Count
Source
1029
6
            opt(complete(parse_der_tagged_implicit_g(1, |d, _, _| {
1030
6
                many0(complete(parse_generalname))(d)
1031
6
            })))(i)?;
1032
2.52k
        let (i, authority_cert_serial) = opt(complete(parse_der_tagged_implicit(
1033
2.52k
            2,
1034
2.52k
            parse_der_content(Tag::Integer),
1035
2.52k
        )))(i)?;
1036
2.52k
        let authority_cert_serial = authority_cert_serial.and_then(|o| o.as_slice().ok());
Unexecuted instantiation: x509_parser::extensions::parser::parse_aki_content::{closure#2}
x509_parser::extensions::parser::parse_aki_content::{closure#2}
Line
Count
Source
1036
4
        let authority_cert_serial = authority_cert_serial.and_then(|o| o.as_slice().ok());
1037
2.52k
        let aki = AuthorityKeyIdentifier {
1038
2.52k
            key_identifier,
1039
2.52k
            authority_cert_issuer,
1040
2.52k
            authority_cert_serial,
1041
2.52k
        };
1042
2.52k
        Ok((i, aki))
1043
2.52k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_aki_content
x509_parser::extensions::parser::parse_aki_content
Line
Count
Source
1021
2.52k
    fn parse_aki_content<'a>(
1022
2.52k
        i: &'a [u8],
1023
2.52k
        _hdr: Header<'_>,
1024
2.52k
    ) -> IResult<&'a [u8], AuthorityKeyIdentifier<'a>, BerError> {
1025
2.52k
        let (i, key_identifier) = opt(complete(parse_der_tagged_implicit_g(0, |d, _, _| {
1026
            Ok((&[], KeyIdentifier(d)))
1027
2.52k
        })))(i)?;
1028
2.52k
        let (i, authority_cert_issuer) =
1029
2.52k
            opt(complete(parse_der_tagged_implicit_g(1, |d, _, _| {
1030
                many0(complete(parse_generalname))(d)
1031
2.52k
            })))(i)?;
1032
2.52k
        let (i, authority_cert_serial) = opt(complete(parse_der_tagged_implicit(
1033
2.52k
            2,
1034
2.52k
            parse_der_content(Tag::Integer),
1035
2.52k
        )))(i)?;
1036
2.52k
        let authority_cert_serial = authority_cert_serial.and_then(|o| o.as_slice().ok());
1037
2.52k
        let aki = AuthorityKeyIdentifier {
1038
2.52k
            key_identifier,
1039
2.52k
            authority_cert_issuer,
1040
2.52k
            authority_cert_serial,
1041
2.52k
        };
1042
2.52k
        Ok((i, aki))
1043
2.52k
    }
1044
1045
    // RFC 5280 section 4.2.1.1: Authority Key Identifier
1046
2.52k
    pub(super) fn parse_authoritykeyidentifier(
1047
2.52k
        i: &[u8],
1048
2.52k
    ) -> IResult<&[u8], AuthorityKeyIdentifier, BerError> {
1049
2.52k
        let (rem, aki) = parse_der_sequence_defined_g(parse_aki_content)(i)?;
1050
2.52k
        Ok((rem, aki))
1051
2.52k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_authoritykeyidentifier
x509_parser::extensions::parser::parse_authoritykeyidentifier
Line
Count
Source
1046
2.52k
    pub(super) fn parse_authoritykeyidentifier(
1047
2.52k
        i: &[u8],
1048
2.52k
    ) -> IResult<&[u8], AuthorityKeyIdentifier, BerError> {
1049
2.52k
        let (rem, aki) = parse_der_sequence_defined_g(parse_aki_content)(i)?;
1050
2.52k
        Ok((rem, aki))
1051
2.52k
    }
1052
1053
2.52k
    fn parse_authoritykeyidentifier_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1054
2.52k
        map(
1055
2.52k
            parse_authoritykeyidentifier,
1056
2.52k
            ParsedExtension::AuthorityKeyIdentifier,
1057
2.52k
        )(i)
1058
2.52k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_authoritykeyidentifier_ext
x509_parser::extensions::parser::parse_authoritykeyidentifier_ext
Line
Count
Source
1053
2.52k
    fn parse_authoritykeyidentifier_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1054
2.52k
        map(
1055
2.52k
            parse_authoritykeyidentifier,
1056
2.52k
            ParsedExtension::AuthorityKeyIdentifier,
1057
2.52k
        )(i)
1058
2.52k
    }
1059
1060
1.82k
    pub(super) fn parse_keyidentifier(i: &[u8]) -> IResult<&[u8], KeyIdentifier, BerError> {
1061
1.82k
        let (rest, id) = <&[u8]>::from_der(i)?;
1062
1.82k
        let ki = KeyIdentifier(id);
1063
1.82k
        Ok((rest, ki))
1064
1.82k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_keyidentifier
x509_parser::extensions::parser::parse_keyidentifier
Line
Count
Source
1060
1.82k
    pub(super) fn parse_keyidentifier(i: &[u8]) -> IResult<&[u8], KeyIdentifier, BerError> {
1061
1.82k
        let (rest, id) = <&[u8]>::from_der(i)?;
1062
1.82k
        let ki = KeyIdentifier(id);
1063
1.82k
        Ok((rest, ki))
1064
1.82k
    }
1065
1066
1.82k
    fn parse_keyidentifier_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1067
1.82k
        map(parse_keyidentifier, ParsedExtension::SubjectKeyIdentifier)(i)
1068
1.82k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_keyidentifier_ext
x509_parser::extensions::parser::parse_keyidentifier_ext
Line
Count
Source
1066
1.82k
    fn parse_keyidentifier_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1067
1.82k
        map(parse_keyidentifier, ParsedExtension::SubjectKeyIdentifier)(i)
1068
1.82k
    }
1069
1070
1.86k
    fn parse_keyusage_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1071
1.86k
        map(parse_keyusage, ParsedExtension::KeyUsage)(i)
1072
1.86k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_keyusage_ext
x509_parser::extensions::parser::parse_keyusage_ext
Line
Count
Source
1070
1.86k
    fn parse_keyusage_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1071
1.86k
        map(parse_keyusage, ParsedExtension::KeyUsage)(i)
1072
1.86k
    }
1073
1074
6
    pub(super) fn parse_nscerttype(i: &[u8]) -> IResult<&[u8], NSCertType, BerError> {
1075
6
        let (rest, obj) = parse_der_bitstring(i)?;
1076
6
        let bitstring = obj
1077
6
            .content
1078
6
            .as_bitstring()
1079
6
            .or(Err(Err::Error(BerError::BerTypeError)))?;
1080
        // bitstring should be 1 byte long
1081
6
        if bitstring.data.len() != 1 {
1082
0
            return Err(Err::Error(BerError::BerValueError));
1083
6
        }
1084
6
        let flags = bitstring.data[0].reverse_bits();
1085
6
        Ok((rest, NSCertType(flags)))
1086
6
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_nscerttype
x509_parser::extensions::parser::parse_nscerttype
Line
Count
Source
1074
6
    pub(super) fn parse_nscerttype(i: &[u8]) -> IResult<&[u8], NSCertType, BerError> {
1075
6
        let (rest, obj) = parse_der_bitstring(i)?;
1076
6
        let bitstring = obj
1077
6
            .content
1078
6
            .as_bitstring()
1079
6
            .or(Err(Err::Error(BerError::BerTypeError)))?;
1080
        // bitstring should be 1 byte long
1081
6
        if bitstring.data.len() != 1 {
1082
0
            return Err(Err::Error(BerError::BerValueError));
1083
6
        }
1084
6
        let flags = bitstring.data[0].reverse_bits();
1085
6
        Ok((rest, NSCertType(flags)))
1086
6
    }
1087
1088
6
    fn parse_nscerttype_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1089
6
        map(parse_nscerttype, ParsedExtension::NSCertType)(i)
1090
6
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_nscerttype_ext
x509_parser::extensions::parser::parse_nscerttype_ext
Line
Count
Source
1088
6
    fn parse_nscerttype_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1089
6
        map(parse_nscerttype, ParsedExtension::NSCertType)(i)
1090
6
    }
1091
1092
0
    fn parse_nscomment_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1093
0
        match parse_der_ia5string(i) {
1094
0
            Ok((i, obj)) => {
1095
0
                let s = obj.as_str()?;
1096
0
                Ok((i, ParsedExtension::NsCertComment(s)))
1097
            }
1098
0
            Err(e) => {
1099
                // Some implementations encode the comment directly, without
1100
                // wrapping it in an IA5String
1101
0
                if let Ok(s) = std::str::from_utf8(i) {
1102
0
                    Ok((&[], ParsedExtension::NsCertComment(s)))
1103
                } else {
1104
0
                    Err(e)
1105
                }
1106
            }
1107
        }
1108
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_nscomment_ext
Unexecuted instantiation: x509_parser::extensions::parser::parse_nscomment_ext
1109
1110
    // CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
1111
    //
1112
    // PolicyInformation ::= SEQUENCE {
1113
    //      policyIdentifier   CertPolicyId,
1114
    //      policyQualifiers   SEQUENCE SIZE (1..MAX) OF
1115
    //              PolicyQualifierInfo OPTIONAL }
1116
    //
1117
    // CertPolicyId ::= OBJECT IDENTIFIER
1118
    //
1119
    // PolicyQualifierInfo ::= SEQUENCE {
1120
    //      policyQualifierId  PolicyQualifierId,
1121
    //      qualifier          ANY DEFINED BY policyQualifierId }
1122
    //
1123
    // -- Implementations that recognize additional policy qualifiers MUST
1124
    // -- augment the following definition for PolicyQualifierId
1125
    //
1126
    // PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
1127
1.74k
    pub(super) fn parse_certificatepolicies(
1128
1.74k
        i: &[u8],
1129
1.74k
    ) -> IResult<&[u8], Vec<PolicyInformation>, BerError> {
1130
3.99k
        fn parse_policy_qualifier_info(i: &[u8]) -> IResult<&[u8], PolicyQualifierInfo, BerError> {
1131
3.99k
            parse_der_sequence_defined_g(|content, _| {
1132
2.38k
                let (rem, policy_qualifier_id) = Oid::from_der(content)?;
1133
2.38k
                let info = PolicyQualifierInfo {
1134
2.38k
                    policy_qualifier_id,
1135
2.38k
                    qualifier: rem,
1136
2.38k
                };
1137
2.38k
                Ok((&[], info))
1138
3.99k
            })(i)
Unexecuted instantiation: x509_parser::extensions::parser::parse_certificatepolicies::parse_policy_qualifier_info::{closure#0}
x509_parser::extensions::parser::parse_certificatepolicies::parse_policy_qualifier_info::{closure#0}
Line
Count
Source
1131
2.38k
            parse_der_sequence_defined_g(|content, _| {
1132
2.38k
                let (rem, policy_qualifier_id) = Oid::from_der(content)?;
1133
2.38k
                let info = PolicyQualifierInfo {
1134
2.38k
                    policy_qualifier_id,
1135
2.38k
                    qualifier: rem,
1136
2.38k
                };
1137
2.38k
                Ok((&[], info))
1138
2.38k
            })(i)
1139
3.99k
        }
Unexecuted instantiation: x509_parser::extensions::parser::parse_certificatepolicies::parse_policy_qualifier_info
x509_parser::extensions::parser::parse_certificatepolicies::parse_policy_qualifier_info
Line
Count
Source
1130
3.99k
        fn parse_policy_qualifier_info(i: &[u8]) -> IResult<&[u8], PolicyQualifierInfo, BerError> {
1131
3.99k
            parse_der_sequence_defined_g(|content, _| {
1132
                let (rem, policy_qualifier_id) = Oid::from_der(content)?;
1133
                let info = PolicyQualifierInfo {
1134
                    policy_qualifier_id,
1135
                    qualifier: rem,
1136
                };
1137
                Ok((&[], info))
1138
3.99k
            })(i)
1139
3.99k
        }
1140
4.22k
        fn parse_policy_information(i: &[u8]) -> IResult<&[u8], PolicyInformation, BerError> {
1141
4.22k
            parse_der_sequence_defined_g(|content, _| {
1142
2.48k
                let (rem, policy_id) = Oid::from_der(content)?;
1143
2.48k
                let (rem, policy_qualifiers) =
1144
2.48k
                    opt(complete(parse_der_sequence_defined_g(|content, _| {
1145
1.60k
                        many1(complete(parse_policy_qualifier_info))(content)
1146
2.48k
                    })))(rem)?;
Unexecuted instantiation: x509_parser::extensions::parser::parse_certificatepolicies::parse_policy_information::{closure#0}::{closure#0}
x509_parser::extensions::parser::parse_certificatepolicies::parse_policy_information::{closure#0}::{closure#0}
Line
Count
Source
1144
1.60k
                    opt(complete(parse_der_sequence_defined_g(|content, _| {
1145
1.60k
                        many1(complete(parse_policy_qualifier_info))(content)
1146
1.60k
                    })))(rem)?;
1147
2.48k
                let info = PolicyInformation {
1148
2.48k
                    policy_id,
1149
2.48k
                    policy_qualifiers,
1150
2.48k
                };
1151
2.48k
                Ok((rem, info))
1152
4.22k
            })(i)
Unexecuted instantiation: x509_parser::extensions::parser::parse_certificatepolicies::parse_policy_information::{closure#0}
x509_parser::extensions::parser::parse_certificatepolicies::parse_policy_information::{closure#0}
Line
Count
Source
1141
2.48k
            parse_der_sequence_defined_g(|content, _| {
1142
2.48k
                let (rem, policy_id) = Oid::from_der(content)?;
1143
2.48k
                let (rem, policy_qualifiers) =
1144
2.48k
                    opt(complete(parse_der_sequence_defined_g(|content, _| {
1145
                        many1(complete(parse_policy_qualifier_info))(content)
1146
2.48k
                    })))(rem)?;
1147
2.48k
                let info = PolicyInformation {
1148
2.48k
                    policy_id,
1149
2.48k
                    policy_qualifiers,
1150
2.48k
                };
1151
2.48k
                Ok((rem, info))
1152
2.48k
            })(i)
1153
4.22k
        }
Unexecuted instantiation: x509_parser::extensions::parser::parse_certificatepolicies::parse_policy_information
x509_parser::extensions::parser::parse_certificatepolicies::parse_policy_information
Line
Count
Source
1140
4.22k
        fn parse_policy_information(i: &[u8]) -> IResult<&[u8], PolicyInformation, BerError> {
1141
4.22k
            parse_der_sequence_defined_g(|content, _| {
1142
                let (rem, policy_id) = Oid::from_der(content)?;
1143
                let (rem, policy_qualifiers) =
1144
                    opt(complete(parse_der_sequence_defined_g(|content, _| {
1145
                        many1(complete(parse_policy_qualifier_info))(content)
1146
                    })))(rem)?;
1147
                let info = PolicyInformation {
1148
                    policy_id,
1149
                    policy_qualifiers,
1150
                };
1151
                Ok((rem, info))
1152
4.22k
            })(i)
1153
4.22k
        }
1154
1.74k
        parse_der_sequence_of_v(parse_policy_information)(i)
1155
1.74k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_certificatepolicies
x509_parser::extensions::parser::parse_certificatepolicies
Line
Count
Source
1127
1.74k
    pub(super) fn parse_certificatepolicies(
1128
1.74k
        i: &[u8],
1129
1.74k
    ) -> IResult<&[u8], Vec<PolicyInformation>, BerError> {
1130
        fn parse_policy_qualifier_info(i: &[u8]) -> IResult<&[u8], PolicyQualifierInfo, BerError> {
1131
            parse_der_sequence_defined_g(|content, _| {
1132
                let (rem, policy_qualifier_id) = Oid::from_der(content)?;
1133
                let info = PolicyQualifierInfo {
1134
                    policy_qualifier_id,
1135
                    qualifier: rem,
1136
                };
1137
                Ok((&[], info))
1138
            })(i)
1139
        }
1140
        fn parse_policy_information(i: &[u8]) -> IResult<&[u8], PolicyInformation, BerError> {
1141
            parse_der_sequence_defined_g(|content, _| {
1142
                let (rem, policy_id) = Oid::from_der(content)?;
1143
                let (rem, policy_qualifiers) =
1144
                    opt(complete(parse_der_sequence_defined_g(|content, _| {
1145
                        many1(complete(parse_policy_qualifier_info))(content)
1146
                    })))(rem)?;
1147
                let info = PolicyInformation {
1148
                    policy_id,
1149
                    policy_qualifiers,
1150
                };
1151
                Ok((rem, info))
1152
            })(i)
1153
        }
1154
1.74k
        parse_der_sequence_of_v(parse_policy_information)(i)
1155
1.74k
    }
1156
1157
1.74k
    fn parse_certificatepolicies_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1158
1.74k
        map(
1159
1.74k
            parse_certificatepolicies,
1160
1.74k
            ParsedExtension::CertificatePolicies,
1161
1.74k
        )(i)
1162
1.74k
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_certificatepolicies_ext
x509_parser::extensions::parser::parse_certificatepolicies_ext
Line
Count
Source
1157
1.74k
    fn parse_certificatepolicies_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1158
1.74k
        map(
1159
1.74k
            parse_certificatepolicies,
1160
1.74k
            ParsedExtension::CertificatePolicies,
1161
1.74k
        )(i)
1162
1.74k
    }
1163
1164
    // CRLReason ::= ENUMERATED { ...
1165
0
    fn parse_reason_code(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1166
0
        let (rest, obj) = parse_der_enum(i)?;
1167
0
        let code = obj
1168
0
            .content
1169
0
            .as_u32()
1170
0
            .or(Err(Err::Error(BerError::BerValueError)))?;
1171
0
        if code > 10 {
1172
0
            return Err(Err::Error(BerError::BerValueError));
1173
0
        }
1174
0
        let ret = ParsedExtension::ReasonCode(ReasonCode(code as u8));
1175
0
        Ok((rest, ret))
1176
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_reason_code
Unexecuted instantiation: x509_parser::extensions::parser::parse_reason_code
1177
1178
    // invalidityDate ::=  GeneralizedTime
1179
0
    fn parse_invalidity_date(i: &[u8]) -> ParseResult<ParsedExtension> {
1180
0
        let (rest, t) = GeneralizedTime::from_der(i)?;
1181
0
        let dt = t.utc_datetime()?;
1182
0
        Ok((rest, ParsedExtension::InvalidityDate(ASN1Time::new(dt))))
1183
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_invalidity_date
Unexecuted instantiation: x509_parser::extensions::parser::parse_invalidity_date
1184
1185
    // CRLNumber ::= INTEGER (0..MAX)
1186
    // Note from RFC 3280: "CRL verifiers MUST be able to handle CRLNumber values up to 20 octets."
1187
0
    fn parse_crl_number(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1188
0
        let (rest, num) = map_res(parse_der_integer, |obj| obj.as_biguint())(i)?;
Unexecuted instantiation: x509_parser::extensions::parser::parse_crl_number::{closure#0}
Unexecuted instantiation: x509_parser::extensions::parser::parse_crl_number::{closure#0}
1189
0
        Ok((rest, ParsedExtension::CRLNumber(num)))
1190
0
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_crl_number
Unexecuted instantiation: x509_parser::extensions::parser::parse_crl_number
1191
1192
957
    fn parse_sct_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1193
957
        map(
1194
957
            parse_ct_signed_certificate_timestamp_list,
1195
957
            ParsedExtension::SCT,
1196
957
        )(i)
1197
957
    }
Unexecuted instantiation: x509_parser::extensions::parser::parse_sct_ext
x509_parser::extensions::parser::parse_sct_ext
Line
Count
Source
1192
957
    fn parse_sct_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
1193
957
        map(
1194
957
            parse_ct_signed_certificate_timestamp_list,
1195
957
            ParsedExtension::SCT,
1196
957
        )(i)
1197
957
    }
1198
}
1199
1200
/// Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
1201
2.87k
pub(crate) fn parse_extension_sequence(i: &[u8]) -> X509Result<Vec<X509Extension>> {
1202
2.87k
    parse_der_sequence_defined_g(|a, _| all_consuming(many0(complete(X509Extension::from_der)))(a))(
Unexecuted instantiation: x509_parser::extensions::parse_extension_sequence::{closure#0}
x509_parser::extensions::parse_extension_sequence::{closure#0}
Line
Count
Source
1202
2.86k
    parse_der_sequence_defined_g(|a, _| all_consuming(many0(complete(X509Extension::from_der)))(a))(
1203
2.87k
        i,
1204
    )
1205
2.87k
}
Unexecuted instantiation: x509_parser::extensions::parse_extension_sequence
x509_parser::extensions::parse_extension_sequence
Line
Count
Source
1201
2.87k
pub(crate) fn parse_extension_sequence(i: &[u8]) -> X509Result<Vec<X509Extension>> {
1202
2.87k
    parse_der_sequence_defined_g(|a, _| all_consuming(many0(complete(X509Extension::from_der)))(a))(
1203
2.87k
        i,
1204
    )
1205
2.87k
}
1206
1207
3.15k
pub(crate) fn parse_extensions(i: &[u8], explicit_tag: Tag) -> X509Result<Vec<X509Extension>> {
1208
3.15k
    if i.is_empty() {
1209
240
        return Ok((i, Vec::new()));
1210
2.91k
    }
1211
1212
2.91k
    match der_read_element_header(i) {
1213
2.91k
        Ok((rem, hdr)) => {
1214
2.91k
            if hdr.tag() != explicit_tag {
1215
33
                return Err(Err::Error(X509Error::InvalidExtensions));
1216
2.87k
            }
1217
2.87k
            all_consuming(parse_extension_sequence)(rem)
1218
        }
1219
0
        Err(_) => Err(X509Error::InvalidExtensions.into()),
1220
    }
1221
3.15k
}
Unexecuted instantiation: x509_parser::extensions::parse_extensions
x509_parser::extensions::parse_extensions
Line
Count
Source
1207
3.15k
pub(crate) fn parse_extensions(i: &[u8], explicit_tag: Tag) -> X509Result<Vec<X509Extension>> {
1208
3.15k
    if i.is_empty() {
1209
240
        return Ok((i, Vec::new()));
1210
2.91k
    }
1211
1212
2.91k
    match der_read_element_header(i) {
1213
2.91k
        Ok((rem, hdr)) => {
1214
2.91k
            if hdr.tag() != explicit_tag {
1215
33
                return Err(Err::Error(X509Error::InvalidExtensions));
1216
2.87k
            }
1217
2.87k
            all_consuming(parse_extension_sequence)(rem)
1218
        }
1219
0
        Err(_) => Err(X509Error::InvalidExtensions.into()),
1220
    }
1221
3.15k
}
1222
1223
/// Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
1224
0
pub(crate) fn parse_extension_envelope_sequence(i: &[u8]) -> X509Result<Vec<X509Extension>> {
1225
0
    let parser = X509ExtensionParser::new().with_deep_parse_extensions(false);
1226
1227
0
    parse_der_sequence_defined_g(move |a, _| all_consuming(many0(complete(parser)))(a))(i)
Unexecuted instantiation: x509_parser::extensions::parse_extension_envelope_sequence::{closure#0}
Unexecuted instantiation: x509_parser::extensions::parse_extension_envelope_sequence::{closure#0}
1228
0
}
Unexecuted instantiation: x509_parser::extensions::parse_extension_envelope_sequence
Unexecuted instantiation: x509_parser::extensions::parse_extension_envelope_sequence
1229
1230
0
pub(crate) fn parse_extensions_envelope(
1231
0
    i: &[u8],
1232
0
    explicit_tag: Tag,
1233
0
) -> X509Result<Vec<X509Extension>> {
1234
0
    if i.is_empty() {
1235
0
        return Ok((i, Vec::new()));
1236
0
    }
1237
1238
0
    match der_read_element_header(i) {
1239
0
        Ok((rem, hdr)) => {
1240
0
            if hdr.tag() != explicit_tag {
1241
0
                return Err(Err::Error(X509Error::InvalidExtensions));
1242
0
            }
1243
0
            all_consuming(parse_extension_envelope_sequence)(rem)
1244
        }
1245
0
        Err(_) => Err(X509Error::InvalidExtensions.into()),
1246
    }
1247
0
}
Unexecuted instantiation: x509_parser::extensions::parse_extensions_envelope
Unexecuted instantiation: x509_parser::extensions::parse_extensions_envelope
1248
1249
20.9k
fn der_read_critical(i: &[u8]) -> BerResult<bool> {
1250
    // Some certificates do not respect the DER BOOLEAN constraint (true must be encoded as 0xff)
1251
    // so we attempt to parse as BER
1252
20.9k
    let (rem, obj) = opt(parse_ber_bool)(i)?;
1253
20.9k
    let value = obj
1254
20.9k
        .map(|o| o.as_bool().unwrap_or_default()) // unwrap cannot fail, we just read a bool
Unexecuted instantiation: x509_parser::extensions::der_read_critical::{closure#0}
x509_parser::extensions::der_read_critical::{closure#0}
Line
Count
Source
1254
3.01k
        .map(|o| o.as_bool().unwrap_or_default()) // unwrap cannot fail, we just read a bool
1255
20.9k
        .unwrap_or(false) // default critical value
1256
        ;
1257
20.9k
    Ok((rem, value))
1258
20.9k
}
Unexecuted instantiation: x509_parser::extensions::der_read_critical
x509_parser::extensions::der_read_critical
Line
Count
Source
1249
20.9k
fn der_read_critical(i: &[u8]) -> BerResult<bool> {
1250
    // Some certificates do not respect the DER BOOLEAN constraint (true must be encoded as 0xff)
1251
    // so we attempt to parse as BER
1252
20.9k
    let (rem, obj) = opt(parse_ber_bool)(i)?;
1253
20.9k
    let value = obj
1254
20.9k
        .map(|o| o.as_bool().unwrap_or_default()) // unwrap cannot fail, we just read a bool
1255
20.9k
        .unwrap_or(false) // default critical value
1256
        ;
1257
20.9k
    Ok((rem, value))
1258
20.9k
}
1259
1260
#[cfg(test)]
1261
mod tests {
1262
    use super::*;
1263
1264
    #[test]
1265
    fn test_keyusage_flags() {
1266
        let ku = KeyUsage { flags: 98 };
1267
        assert!(!ku.digital_signature());
1268
        assert!(ku.non_repudiation());
1269
        assert!(!ku.key_encipherment());
1270
        assert!(!ku.data_encipherment());
1271
        assert!(!ku.key_agreement());
1272
        assert!(ku.key_cert_sign());
1273
        assert!(ku.crl_sign());
1274
        assert!(!ku.encipher_only());
1275
        assert!(!ku.decipher_only());
1276
    }
1277
1278
    #[test]
1279
    fn test_extensions1() {
1280
        use der_parser::oid;
1281
        let crt = crate::parse_x509_certificate(include_bytes!("../../assets/extension1.der"))
1282
            .unwrap()
1283
            .1;
1284
        let tbs = &crt.tbs_certificate;
1285
        let bc = crt
1286
            .basic_constraints()
1287
            .expect("could not get basic constraints")
1288
            .expect("no basic constraints found");
1289
        assert_eq!(
1290
            bc.value,
1291
            &BasicConstraints {
1292
                ca: true,
1293
                path_len_constraint: Some(1)
1294
            }
1295
        );
1296
        {
1297
            let ku = tbs
1298
                .key_usage()
1299
                .expect("could not get key usage")
1300
                .expect("no key usage found")
1301
                .value;
1302
            assert!(ku.digital_signature());
1303
            assert!(!ku.non_repudiation());
1304
            assert!(ku.key_encipherment());
1305
            assert!(ku.data_encipherment());
1306
            assert!(ku.key_agreement());
1307
            assert!(!ku.key_cert_sign());
1308
            assert!(!ku.crl_sign());
1309
            assert!(ku.encipher_only());
1310
            assert!(ku.decipher_only());
1311
        }
1312
        {
1313
            let eku = tbs
1314
                .extended_key_usage()
1315
                .expect("could not get extended key usage")
1316
                .expect("no extended key usage found")
1317
                .value;
1318
            assert!(!eku.any);
1319
            assert!(eku.server_auth);
1320
            assert!(!eku.client_auth);
1321
            assert!(eku.code_signing);
1322
            assert!(!eku.email_protection);
1323
            assert!(eku.time_stamping);
1324
            assert!(!eku.ocsp_signing);
1325
            assert_eq!(eku.other, vec![oid!(1.2.3 .4 .0 .42)]);
1326
        }
1327
        assert_eq!(
1328
            tbs.policy_constraints()
1329
                .expect("could not get policy constraints")
1330
                .expect("no policy constraints found")
1331
                .value,
1332
            &PolicyConstraints {
1333
                require_explicit_policy: None,
1334
                inhibit_policy_mapping: Some(10)
1335
            }
1336
        );
1337
        let val = tbs
1338
            .inhibit_anypolicy()
1339
            .expect("could not get inhibit_anypolicy")
1340
            .expect("no inhibit_anypolicy found")
1341
            .value;
1342
        assert_eq!(val, &InhibitAnyPolicy { skip_certs: 2 });
1343
        {
1344
            let alt_names = &tbs
1345
                .subject_alternative_name()
1346
                .expect("could not get subject alt names")
1347
                .expect("no subject alt names found")
1348
                .value
1349
                .general_names;
1350
            assert_eq!(alt_names[0], GeneralName::RFC822Name("foo@example.com"));
1351
            assert_eq!(alt_names[1], GeneralName::URI("http://my.url.here/"));
1352
            assert_eq!(
1353
                alt_names[2],
1354
                GeneralName::IPAddress([192, 168, 7, 1].as_ref())
1355
            );
1356
            assert_eq!(
1357
                format!(
1358
                    "{}",
1359
                    match alt_names[3] {
1360
                        GeneralName::DirectoryName(ref dn) => dn,
1361
                        _ => unreachable!(),
1362
                    }
1363
                ),
1364
                "C=UK, O=My Organization, OU=My Unit, CN=My Name"
1365
            );
1366
            assert_eq!(alt_names[4], GeneralName::DNSName("localhost"));
1367
            assert_eq!(alt_names[5], GeneralName::RegisteredID(oid!(1.2.90 .0)));
1368
            assert_eq!(
1369
                alt_names[6],
1370
                GeneralName::OtherName(oid!(1.2.3 .4), b"\xA0\x17\x0C\x15some other identifier")
1371
            );
1372
        }
1373
1374
        {
1375
            let name_constraints = &tbs
1376
                .name_constraints()
1377
                .expect("could not get name constraints")
1378
                .expect("no name constraints found")
1379
                .value;
1380
            assert_eq!(name_constraints.permitted_subtrees, None);
1381
            assert_eq!(
1382
                name_constraints.excluded_subtrees,
1383
                Some(vec![
1384
                    GeneralSubtree {
1385
                        base: GeneralName::IPAddress([192, 168, 0, 0, 255, 255, 0, 0].as_ref())
1386
                    },
1387
                    GeneralSubtree {
1388
                        base: GeneralName::RFC822Name("foo.com")
1389
                    },
1390
                ])
1391
            );
1392
        }
1393
    }
1394
1395
    #[test]
1396
    fn test_extensions2() {
1397
        use der_parser::oid;
1398
        let crt = crate::parse_x509_certificate(include_bytes!("../../assets/extension2.der"))
1399
            .unwrap()
1400
            .1;
1401
        let tbs = crt.tbs_certificate;
1402
        assert_eq!(
1403
            tbs.policy_constraints()
1404
                .expect("could not get policy constraints")
1405
                .expect("no policy constraints found")
1406
                .value,
1407
            &PolicyConstraints {
1408
                require_explicit_policy: Some(5000),
1409
                inhibit_policy_mapping: None
1410
            }
1411
        );
1412
        {
1413
            let pm = tbs
1414
                .policy_mappings()
1415
                .expect("could not get policy_mappings")
1416
                .expect("no policy_mappings found")
1417
                .value
1418
                .clone()
1419
                .into_hashmap();
1420
            let mut pm_ref = HashMap::new();
1421
            pm_ref.insert(oid!(2.34.23), vec![oid!(2.2)]);
1422
            pm_ref.insert(oid!(1.1), vec![oid!(0.0.4)]);
1423
            pm_ref.insert(oid!(2.2), vec![oid!(2.2.1), oid!(2.2.3)]);
1424
            assert_eq!(pm, pm_ref);
1425
        }
1426
    }
1427
1428
    #[test]
1429
    fn test_extensions_crl_distribution_points() {
1430
        // Extension not present
1431
        {
1432
            let crt = crate::parse_x509_certificate(include_bytes!(
1433
                "../../assets/crl-ext/crl-no-crl.der"
1434
            ))
1435
            .unwrap()
1436
            .1;
1437
            assert!(crt
1438
                .tbs_certificate
1439
                .extensions_map()
1440
                .unwrap()
1441
                .get(&OID_X509_EXT_CRL_DISTRIBUTION_POINTS)
1442
                .is_none());
1443
        }
1444
        // CRLDistributionPoints has 1 entry with 1 URI
1445
        {
1446
            let crt = crate::parse_x509_certificate(include_bytes!(
1447
                "../../assets/crl-ext/crl-simple.der"
1448
            ))
1449
            .unwrap()
1450
            .1;
1451
            let crl = crt
1452
                .tbs_certificate
1453
                .extensions_map()
1454
                .unwrap()
1455
                .get(&OID_X509_EXT_CRL_DISTRIBUTION_POINTS)
1456
                .unwrap()
1457
                .parsed_extension();
1458
            assert!(matches!(crl, ParsedExtension::CRLDistributionPoints(_)));
1459
            if let ParsedExtension::CRLDistributionPoints(crl) = crl {
1460
                assert_eq!(crl.len(), 1);
1461
                assert!(crl[0].reasons.is_none());
1462
                assert!(crl[0].crl_issuer.is_none());
1463
                let distribution_point = crl[0].distribution_point.as_ref().unwrap();
1464
                assert!(matches!(
1465
                    distribution_point,
1466
                    DistributionPointName::FullName(_)
1467
                ));
1468
                if let DistributionPointName::FullName(names) = distribution_point {
1469
                    assert_eq!(names.len(), 1);
1470
                    assert!(matches!(names[0], GeneralName::URI(_)));
1471
                    if let GeneralName::URI(uri) = names[0] {
1472
                        assert_eq!(uri, "http://example.com/myca.crl")
1473
                    }
1474
                }
1475
            }
1476
        }
1477
        // CRLDistributionPoints has 2 entries
1478
        {
1479
            let crt = crate::parse_x509_certificate(include_bytes!(
1480
                "../../assets/crl-ext/crl-complex.der"
1481
            ))
1482
            .unwrap()
1483
            .1;
1484
            let crl = crt
1485
                .tbs_certificate
1486
                .extensions_map()
1487
                .unwrap()
1488
                .get(&OID_X509_EXT_CRL_DISTRIBUTION_POINTS)
1489
                .unwrap()
1490
                .parsed_extension();
1491
            assert!(matches!(crl, ParsedExtension::CRLDistributionPoints(_)));
1492
            if let ParsedExtension::CRLDistributionPoints(crl) = crl {
1493
                assert_eq!(crl.len(), 2);
1494
                // First CRL Distribution point
1495
                let reasons = crl[0].reasons.as_ref().unwrap();
1496
                assert!(reasons.key_compromise());
1497
                assert!(reasons.ca_compromise());
1498
                assert!(!reasons.affilation_changed());
1499
                assert!(!reasons.superseded());
1500
                assert!(!reasons.cessation_of_operation());
1501
                assert!(!reasons.certificate_hold());
1502
                assert!(!reasons.privelege_withdrawn());
1503
                assert!(reasons.aa_compromise());
1504
                assert_eq!(
1505
                    format!("{}", reasons),
1506
                    "Key Compromise, CA Compromise, AA Compromise"
1507
                );
1508
                let issuers = crl[0].crl_issuer.as_ref().unwrap();
1509
                assert_eq!(issuers.len(), 1);
1510
                assert!(matches!(issuers[0], GeneralName::DirectoryName(_)));
1511
                if let GeneralName::DirectoryName(name) = &issuers[0] {
1512
                    assert_eq!(name.to_string(), "C=US, O=Organisation, CN=Some Name");
1513
                }
1514
                let distribution_point = crl[0].distribution_point.as_ref().unwrap();
1515
                assert!(matches!(
1516
                    distribution_point,
1517
                    DistributionPointName::FullName(_)
1518
                ));
1519
                if let DistributionPointName::FullName(names) = distribution_point {
1520
                    assert_eq!(names.len(), 1);
1521
                    assert!(matches!(names[0], GeneralName::URI(_)));
1522
                    if let GeneralName::URI(uri) = names[0] {
1523
                        assert_eq!(uri, "http://example.com/myca.crl")
1524
                    }
1525
                }
1526
                // Second CRL Distribution point
1527
                let reasons = crl[1].reasons.as_ref().unwrap();
1528
                assert!(reasons.key_compromise());
1529
                assert!(reasons.ca_compromise());
1530
                assert!(!reasons.affilation_changed());
1531
                assert!(!reasons.superseded());
1532
                assert!(!reasons.cessation_of_operation());
1533
                assert!(!reasons.certificate_hold());
1534
                assert!(!reasons.privelege_withdrawn());
1535
                assert!(!reasons.aa_compromise());
1536
                assert_eq!(format!("{}", reasons), "Key Compromise, CA Compromise");
1537
                assert!(crl[1].crl_issuer.is_none());
1538
                let distribution_point = crl[1].distribution_point.as_ref().unwrap();
1539
                assert!(matches!(
1540
                    distribution_point,
1541
                    DistributionPointName::FullName(_)
1542
                ));
1543
                if let DistributionPointName::FullName(names) = distribution_point {
1544
                    assert_eq!(names.len(), 1);
1545
                    assert!(matches!(names[0], GeneralName::URI(_)));
1546
                    if let GeneralName::URI(uri) = names[0] {
1547
                        assert_eq!(uri, "http://example.com/myca2.crl")
1548
                    }
1549
                }
1550
            }
1551
        }
1552
    }
1553
1554
    // Test cases for:
1555
    // - parsing SubjectAlternativeName
1556
    // - parsing NameConstraints
1557
}