//! X.509 Extensions objects and types

use crate::error::{X509Error, X509Result};
use crate::time::{der_to_utctime, ASN1Time};
use crate::traits::FromDer;
use crate::x509::{ReasonCode, RelativeDistinguishedName, X509Name};

use der_parser::ber::parse_ber_bool;
use der_parser::der::*;
use der_parser::error::{BerError, BerResult};
use der_parser::num_bigint::BigUint;
use der_parser::oid::Oid;
use nom::combinator::{all_consuming, complete, map, map_res, opt};
use nom::multi::{many0, many1};
use nom::{Err, IResult, Parser};
use oid_registry::*;
use std::collections::HashMap;
use std::fmt;

/// X.509 version 3 extension
///
/// X.509 extensions allow adding attributes to objects like certificates or revocation lists.
///
/// Each extension in a certificate is designated as either critical or non-critical.  A
/// certificate using system MUST reject the certificate if it encounters a critical extension it
/// does not recognize; however, a non-critical extension MAY be ignored if it is not recognized.
///
/// Each extension includes an OID and an ASN.1 structure.  When an extension appears in a
/// certificate, the OID appears as the field extnID and the corresponding ASN.1 encoded structure
/// is the value of the octet string extnValue.  A certificate MUST NOT include more than one
/// instance of a particular extension.
///
/// When parsing an extension, the global extension structure (described above) is parsed,
/// and the object is returned if it succeeds.
/// During this step, it also attempts to parse the content of the extension, if known.
/// The returned object has a
/// [`X509Extension::parsed_extension()`] method. The returned
/// enum is either a known extension, or the special value `ParsedExtension::UnsupportedExtension`.
///
/// # Example
///
/// ```rust
/// use x509_parser::extensions::{X509Extension, ParsedExtension};
/// use x509_parser::traits::FromDer;
///
/// static DER: &[u8] = &[
///    0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xA3, 0x05, 0x2F, 0x18,
///    0x60, 0x50, 0xC2, 0x89, 0x0A, 0xDD, 0x2B, 0x21, 0x4F, 0xFF, 0x8E, 0x4E, 0xA8, 0x30, 0x31,
///    0x36 ];
///
/// # fn main() {
/// let res = X509Extension::from_der(DER);
/// match res {
///     Ok((_rem, ext)) => {
///         println!("Extension OID: {}", ext.oid);
///         println!("  Critical: {}", ext.critical);
///         let parsed_ext = ext.parsed_extension();
///         assert!(!parsed_ext.unsupported());
///         assert!(parsed_ext.error().is_none());
///         if let ParsedExtension::SubjectKeyIdentifier(key_id) = parsed_ext {
///             assert!(key_id.0.len() > 0);
///         } else {
///             panic!("Extension has wrong type");
///         }
///     },
///     _ => panic!("x509 extension parsing failed: {:?}", res),
/// }
/// # }
/// ```
#[derive(Clone, Debug, PartialEq)]
pub struct X509Extension<'a> {
    /// OID describing the extension content
    pub oid: Oid<'a>,
    /// Boolean value describing the 'critical' attribute of the extension
    ///
    /// An extension includes the boolean critical, with a default value of FALSE.
    pub critical: bool,
    /// Raw content of the extension
    pub value: &'a [u8],
    pub(crate) parsed_extension: ParsedExtension<'a>,
}

impl<'a> X509Extension<'a> {
    /// Creates a new extension with the provided values.
    #[inline]
    pub const fn new(
        oid: Oid<'a>,
        critical: bool,
        value: &'a [u8],
        parsed_extension: ParsedExtension<'a>,
    ) -> X509Extension<'a> {
        X509Extension {
            oid,
            critical,
            value,
            parsed_extension,
        }
    }

    /// Return the extension type or `UnsupportedExtension` if the extension is not implemented.
    #[inline]
    pub fn parsed_extension(&self) -> &ParsedExtension<'a> {
        &self.parsed_extension
    }
}

/// <pre>
/// Extension  ::=  SEQUENCE  {
///     extnID      OBJECT IDENTIFIER,
///     critical    BOOLEAN DEFAULT FALSE,
///     extnValue   OCTET STRING  }
/// </pre>
impl<'a> FromDer<'a> for X509Extension<'a> {
    fn from_der(i: &'a [u8]) -> X509Result<Self> {
        X509ExtensionParser::new().parse(i)
    }
}

/// `X509Extension` parser builder
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct X509ExtensionParser {
    deep_parse_extensions: bool,
}

impl X509ExtensionParser {
    #[inline]
    pub const fn new() -> Self {
        X509ExtensionParser {
            deep_parse_extensions: true,
        }
    }

    #[inline]
    pub const fn with_deep_parse_extensions(self, deep_parse_extensions: bool) -> Self {
        X509ExtensionParser {
            deep_parse_extensions,
        }
    }
}

impl<'a> Parser<&'a [u8], X509Extension<'a>, X509Error> for X509ExtensionParser {
    fn parse(&mut self, input: &'a [u8]) -> IResult<&'a [u8], X509Extension<'a>, X509Error> {
        parse_der_sequence_defined_g(|i, _| {
            let (i, oid) = map_res(parse_der_oid, |x| x.as_oid_val())(i)?;
            let (i, critical) = der_read_critical(i)?;
            let (i, value) = map_res(parse_der_octetstring, |x| x.as_slice())(i)?;
            let (i, parsed_extension) = if self.deep_parse_extensions {
                parser::parse_extension(i, value, &oid)?
            } else {
                (&[] as &[_], ParsedExtension::Unparsed)
            };
            let ext = X509Extension {
                oid,
                critical,
                value,
                parsed_extension,
            };
            Ok((i, ext))
        })(input)
        .map_err(|_| X509Error::InvalidExtensions.into())
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum ParsedExtension<'a> {
    /// Crate parser does not support this extension (yet)
    UnsupportedExtension {
        oid: Oid<'a>,
    },
    ParseError {
        error: Err<BerError>,
    },
    /// Section 4.2.1.1 of rfc 5280
    AuthorityKeyIdentifier(AuthorityKeyIdentifier<'a>),
    /// Section 4.2.1.2 of rfc 5280
    SubjectKeyIdentifier(KeyIdentifier<'a>),
    /// Section 4.2.1.3 of rfc 5280
    KeyUsage(KeyUsage),
    /// Section 4.2.1.4 of rfc 5280
    CertificatePolicies(CertificatePolicies<'a>),
    /// Section 4.2.1.5 of rfc 5280
    PolicyMappings(PolicyMappings<'a>),
    /// Section 4.2.1.6 of rfc 5280
    SubjectAlternativeName(SubjectAlternativeName<'a>),
    /// Section 4.2.1.9 of rfc 5280
    BasicConstraints(BasicConstraints),
    /// Section 4.2.1.10 of rfc 5280
    NameConstraints(NameConstraints<'a>),
    /// Section 4.2.1.11 of rfc 5280
    PolicyConstraints(PolicyConstraints),
    /// Section 4.2.1.12 of rfc 5280
    ExtendedKeyUsage(ExtendedKeyUsage<'a>),
    /// Section 4.2.1.13 of rfc 5280
    CRLDistributionPoints(CRLDistributionPoints<'a>),
    /// Section 4.2.1.14 of rfc 5280
    InhibitAnyPolicy(InhibitAnyPolicy),
    /// Section 4.2.2.1 of rfc 5280
    AuthorityInfoAccess(AuthorityInfoAccess<'a>),
    /// Netscape certificate type (subject is SSL client, an SSL server, or a CA)
    NSCertType(NSCertType),
    /// Section 5.3.1 of rfc 5280
    CRLNumber(BigUint),
    /// Section 5.3.1 of rfc 5280
    ReasonCode(ReasonCode),
    /// Section 5.3.3 of rfc 5280
    InvalidityDate(ASN1Time),
    /// Unparsed extension (was not requested in parsing options)
    Unparsed,
}

impl<'a> ParsedExtension<'a> {
    /// Return `true` if the extension is unsupported
    pub fn unsupported(&self) -> bool {
        matches!(self, &ParsedExtension::UnsupportedExtension { .. })
    }

    /// Return a reference on the parsing error if the extension parsing failed
    pub fn error(&self) -> Option<&Err<BerError>> {
        match self {
            ParsedExtension::ParseError { error } => Some(error),
            _ => None,
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct AuthorityKeyIdentifier<'a> {
    pub key_identifier: Option<KeyIdentifier<'a>>,
    pub authority_cert_issuer: Option<Vec<GeneralName<'a>>>,
    pub authority_cert_serial: Option<&'a [u8]>,
}

impl<'a> FromDer<'a> for AuthorityKeyIdentifier<'a> {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_authoritykeyidentifier(i).map_err(Err::convert)
    }
}

pub type CertificatePolicies<'a> = Vec<PolicyInformation<'a>>;

impl<'a> FromDer<'a> for CertificatePolicies<'a> {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_certificatepolicies(i).map_err(Err::convert)
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct PolicyInformation<'a> {
    pub policy_id: Oid<'a>,
    pub policy_qualifiers: Option<Vec<PolicyQualifierInfo<'a>>>,
}

#[derive(Clone, Debug, PartialEq)]
pub struct PolicyQualifierInfo<'a> {
    pub policy_qualifier_id: Oid<'a>,
    pub qualifier: &'a [u8],
}

/// Identifies whether the subject of the certificate is a CA, and the max validation depth.
#[derive(Clone, Debug, PartialEq)]
pub struct BasicConstraints {
    pub ca: bool,
    pub path_len_constraint: Option<u32>,
}

impl<'a> FromDer<'a> for BasicConstraints {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_basicconstraints(i).map_err(Err::convert)
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct KeyIdentifier<'a>(pub &'a [u8]);

impl<'a> FromDer<'a> for KeyIdentifier<'a> {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_keyidentifier(i).map_err(Err::convert)
    }
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct KeyUsage {
    pub flags: u16,
}

impl KeyUsage {
    pub fn digital_signature(&self) -> bool {
        self.flags & 1 == 1
    }
    pub fn non_repudiation(&self) -> bool {
        (self.flags >> 1) & 1u16 == 1
    }
    pub fn key_encipherment(&self) -> bool {
        (self.flags >> 2) & 1u16 == 1
    }
    pub fn data_encipherment(&self) -> bool {
        (self.flags >> 3) & 1u16 == 1
    }
    pub fn key_agreement(&self) -> bool {
        (self.flags >> 4) & 1u16 == 1
    }
    pub fn key_cert_sign(&self) -> bool {
        (self.flags >> 5) & 1u16 == 1
    }
    pub fn crl_sign(&self) -> bool {
        (self.flags >> 6) & 1u16 == 1
    }
    pub fn encipher_only(&self) -> bool {
        (self.flags >> 7) & 1u16 == 1
    }
    pub fn decipher_only(&self) -> bool {
        (self.flags >> 8) & 1u16 == 1
    }
}

// This list must have the same order as KeyUsage flags declaration (4.2.1.3)
const KEY_USAGE_FLAGS: &[&str] = &[
    "Digital Signature",
    "Non Repudiation",
    "Key Encipherment",
    "Data Encipherment",
    "Key Agreement",
    "Key Cert Sign",
    "CRL Sign",
    "Encipher Only",
    "Decipher Only",
];

impl fmt::Display for KeyUsage {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut s = KEY_USAGE_FLAGS
            .iter()
            .enumerate()
            .fold(String::new(), |acc, (idx, s)| {
                if self.flags >> idx & 1 != 0 {
                    acc + s + ", "
                } else {
                    acc
                }
            });
        s.pop();
        s.pop();
        f.write_str(&s)
    }
}

impl<'a> FromDer<'a> for KeyUsage {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_keyusage(i).map_err(Err::convert)
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct ExtendedKeyUsage<'a> {
    pub any: bool,
    pub server_auth: bool,
    pub client_auth: bool,
    pub code_signing: bool,
    pub email_protection: bool,
    pub time_stamping: bool,
    pub ocsp_signing: bool,
    pub other: Vec<Oid<'a>>,
}

impl<'a> FromDer<'a> for ExtendedKeyUsage<'a> {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_extendedkeyusage(i).map_err(Err::convert)
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct NSCertType(u8);

// The value is a bit-string, where the individual bit positions are defined as:
//
//     bit-0 SSL client - this cert is certified for SSL client authentication use
//     bit-1 SSL server - this cert is certified for SSL server authentication use
//     bit-2 S/MIME - this cert is certified for use by clients (New in PR3)
//     bit-3 Object Signing - this cert is certified for signing objects such as Java applets and plugins(New in PR3)
//     bit-4 Reserved - this bit is reserved for future use
//     bit-5 SSL CA - this cert is certified for issuing certs for SSL use
//     bit-6 S/MIME CA - this cert is certified for issuing certs for S/MIME use (New in PR3)
//     bit-7 Object Signing CA - this cert is certified for issuing certs for Object Signing (New in PR3)
impl NSCertType {
    pub fn ssl_client(&self) -> bool {
        self.0 & 0x1 == 1
    }
    pub fn ssl_server(&self) -> bool {
        (self.0 >> 1) & 1 == 1
    }
    pub fn smime(&self) -> bool {
        (self.0 >> 2) & 1 == 1
    }
    pub fn object_signing(&self) -> bool {
        (self.0 >> 3) & 1 == 1
    }
    pub fn ssl_ca(&self) -> bool {
        (self.0 >> 5) & 1 == 1
    }
    pub fn smime_ca(&self) -> bool {
        (self.0 >> 6) & 1 == 1
    }
    pub fn object_signing_ca(&self) -> bool {
        (self.0 >> 7) & 1 == 1
    }
}

const NS_CERT_TYPE_FLAGS: &[&str] = &[
    "SSL CLient",
    "SSL Server",
    "S/MIME",
    "Object Signing",
    "Reserved",
    "SSL CA",
    "S/MIME CA",
    "Object Signing CA",
];

impl fmt::Display for NSCertType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut s = String::new();
        let mut acc = self.0;
        for flag_text in NS_CERT_TYPE_FLAGS {
            if acc & 1 != 0 {
                s = s + flag_text + ", ";
            }
            acc >>= 1;
        }
        s.pop();
        s.pop();
        f.write_str(&s)
    }
}

impl<'a> FromDer<'a> for NSCertType {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_nscerttype(i).map_err(Err::convert)
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct AuthorityInfoAccess<'a> {
    pub accessdescs: Vec<AccessDescription<'a>>,
}

impl<'a> AuthorityInfoAccess<'a> {
    /// Returns a `HashMap` mapping `Oid` to the list of references to `GeneralNames`
    ///
    /// If several names match the same `Oid`, they are merged in the same entry.
    pub fn as_hashmap(&self) -> HashMap<Oid<'a>, Vec<&GeneralName<'a>>> {
        // create the hashmap and merge entries with same OID
        let mut m: HashMap<Oid, Vec<&GeneralName>> = HashMap::new();
        for desc in &self.accessdescs {
            let AccessDescription {
                access_method: oid,
                access_location: gn,
            } = desc;
            if let Some(general_names) = m.get_mut(oid) {
                general_names.push(gn);
            } else {
                m.insert(oid.clone(), vec![gn]);
            }
        }
        m
    }

    /// Returns a `HashMap` mapping `Oid` to the list of `GeneralNames` (consuming the input)
    ///
    /// If several names match the same `Oid`, they are merged in the same entry.
    pub fn into_hashmap(self) -> HashMap<Oid<'a>, Vec<GeneralName<'a>>> {
        let mut aia_list = self.accessdescs;
        // create the hashmap and merge entries with same OID
        let mut m: HashMap<Oid, Vec<GeneralName>> = HashMap::new();
        for desc in aia_list.drain(..) {
            let AccessDescription {
                access_method: oid,
                access_location: gn,
            } = desc;
            if let Some(general_names) = m.get_mut(&oid) {
                general_names.push(gn);
            } else {
                m.insert(oid, vec![gn]);
            }
        }
        m
    }
}

impl<'a> FromDer<'a> for AuthorityInfoAccess<'a> {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_authorityinfoaccess(i).map_err(Err::convert)
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct AccessDescription<'a> {
    pub access_method: Oid<'a>,
    pub access_location: GeneralName<'a>,
}

impl<'a> AccessDescription<'a> {
    pub const fn new(access_method: Oid<'a>, access_location: GeneralName<'a>) -> Self {
        AccessDescription {
            access_method,
            access_location,
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct InhibitAnyPolicy {
    pub skip_certs: u32,
}

impl<'a> FromDer<'a> for InhibitAnyPolicy {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        map(parse_der_u32, |skip_certs| InhibitAnyPolicy { skip_certs })(i).map_err(Err::convert)
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct PolicyMappings<'a> {
    pub mappings: Vec<PolicyMapping<'a>>,
}

impl<'a> FromDer<'a> for PolicyMappings<'a> {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_policymappings(i).map_err(Err::convert)
    }
}

impl<'a> PolicyMappings<'a> {
    /// Returns a `HashMap` mapping `Oid` to the list of references to `Oid`
    ///
    /// If several names match the same `Oid`, they are merged in the same entry.
    pub fn as_hashmap(&self) -> HashMap<Oid<'a>, Vec<&Oid<'a>>> {
        // create the hashmap and merge entries with same OID
        let mut m: HashMap<Oid, Vec<&_>> = HashMap::new();
        for desc in &self.mappings {
            let PolicyMapping {
                issuer_domain_policy: left,
                subject_domain_policy: right,
            } = desc;
            if let Some(l) = m.get_mut(left) {
                l.push(right);
            } else {
                m.insert(left.clone(), vec![right]);
            }
        }
        m
    }

    /// Returns a `HashMap` mapping `Oid` to the list of `Oid` (consuming the input)
    ///
    /// If several names match the same `Oid`, they are merged in the same entry.
    pub fn into_hashmap(self) -> HashMap<Oid<'a>, Vec<Oid<'a>>> {
        let mut l = self.mappings;
        // create the hashmap and merge entries with same OID
        let mut m: HashMap<Oid, Vec<_>> = HashMap::new();
        for mapping in l.drain(..) {
            let PolicyMapping {
                issuer_domain_policy: left,
                subject_domain_policy: right,
            } = mapping;
            if let Some(general_names) = m.get_mut(&left) {
                general_names.push(right);
            } else {
                m.insert(left, vec![right]);
            }
        }
        m
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct PolicyMapping<'a> {
    pub issuer_domain_policy: Oid<'a>,
    pub subject_domain_policy: Oid<'a>,
}

impl<'a> PolicyMapping<'a> {
    pub const fn new(issuer_domain_policy: Oid<'a>, subject_domain_policy: Oid<'a>) -> Self {
        PolicyMapping {
            issuer_domain_policy,
            subject_domain_policy,
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct PolicyConstraints {
    pub require_explicit_policy: Option<u32>,
    pub inhibit_policy_mapping: Option<u32>,
}

impl<'a> FromDer<'a> for PolicyConstraints {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_policyconstraints(i).map_err(Err::convert)
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct SubjectAlternativeName<'a> {
    pub general_names: Vec<GeneralName<'a>>,
}

impl<'a> FromDer<'a> for SubjectAlternativeName<'a> {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parse_der_sequence_defined_g(|input, _| {
            let (i, general_names) = all_consuming(many0(complete(GeneralName::from_der)))(input)?;
            Ok((i, SubjectAlternativeName { general_names }))
        })(i)
    }
}

#[derive(Clone, Debug, PartialEq)]
/// Represents a GeneralName as defined in RFC5280. There
/// is no support X.400 addresses and EDIPartyName.
///
/// String formats are not validated.
pub enum GeneralName<'a> {
    OtherName(Oid<'a>, &'a [u8]),
    /// More or less an e-mail, the format is not checked.
    RFC822Name(&'a str),
    /// A hostname, format is not checked.
    DNSName(&'a str),
    /// X400Address,
    X400Address(UnparsedObject<'a>),
    /// RFC5280 defines several string types, we always try to parse as utf-8
    /// which is more or less a superset of the string types.
    DirectoryName(X509Name<'a>),
    /// EDIPartyName
    EDIPartyName(UnparsedObject<'a>),
    /// An uniform resource identifier. The format is not checked.
    URI(&'a str),
    /// An ip address, provided as encoded.
    IPAddress(&'a [u8]),
    RegisteredID(Oid<'a>),
}

impl<'a> FromDer<'a> for GeneralName<'a> {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_generalname(i).map_err(Err::convert)
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct UnparsedObject<'a> {
    pub header: DerObjectHeader<'a>,
    pub data: &'a [u8],
}

#[derive(Clone, Debug, PartialEq)]
pub struct NameConstraints<'a> {
    pub permitted_subtrees: Option<Vec<GeneralSubtree<'a>>>,
    pub excluded_subtrees: Option<Vec<GeneralSubtree<'a>>>,
}

impl<'a> FromDer<'a> for NameConstraints<'a> {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_nameconstraints(i).map_err(Err::convert)
    }
}

#[derive(Clone, Debug, PartialEq)]
/// Represents the structure used in the name constraints extensions.
/// The fields minimum and maximum are not supported (openssl also has no support).
pub struct GeneralSubtree<'a> {
    pub base: GeneralName<'a>,
    // minimum: u32,
    // maximum: Option<u32>,
}

pub type CRLDistributionPoints<'a> = Vec<CRLDistributionPoint<'a>>;

impl<'a> FromDer<'a> for CRLDistributionPoints<'a> {
    fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
        parser::parse_crldistributionpoints(i).map_err(Err::convert)
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct CRLDistributionPoint<'a> {
    pub distribution_point: Option<DistributionPointName<'a>>,
    pub reasons: Option<ReasonFlags>,
    pub crl_issuer: Option<Vec<GeneralName<'a>>>,
}

#[derive(Clone, Debug, PartialEq)]
pub enum DistributionPointName<'a> {
    FullName(Vec<GeneralName<'a>>),
    NameRelativeToCRLIssuer(RelativeDistinguishedName<'a>),
}

#[derive(Clone, Debug, PartialEq)]
pub struct ReasonFlags {
    pub flags: u16,
}

impl ReasonFlags {
    pub fn key_compromise(&self) -> bool {
        (self.flags >> 1) & 1 == 1
    }
    pub fn ca_compromise(&self) -> bool {
        (self.flags >> 2) & 1 == 1
    }
    pub fn affilation_changed(&self) -> bool {
        (self.flags >> 3) & 1 == 1
    }
    pub fn superseded(&self) -> bool {
        (self.flags >> 4) & 1 == 1
    }
    pub fn cessation_of_operation(&self) -> bool {
        (self.flags >> 5) & 1 == 1
    }
    pub fn certificate_hold(&self) -> bool {
        (self.flags >> 6) & 1 == 1
    }
    pub fn privelege_withdrawn(&self) -> bool {
        (self.flags >> 7) & 1 == 1
    }
    pub fn aa_compromise(&self) -> bool {
        (self.flags >> 8) & 1 == 1
    }
}

const REASON_FLAGS: &[&str] = &[
    "Unused",
    "Key Compromise",
    "CA Compromise",
    "Affiliation Changed",
    "Superseded",
    "Cessation Of Operation",
    "Certificate Hold",
    "Privilege Withdrawn",
    "AA Compromise",
];

impl fmt::Display for ReasonFlags {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut s = String::new();
        let mut acc = self.flags;
        for flag_text in REASON_FLAGS {
            if acc & 1 != 0 {
                s = s + flag_text + ", ";
            }
            acc >>= 1;
        }
        s.pop();
        s.pop();
        f.write_str(&s)
    }
}

pub(crate) mod parser {
    use crate::extensions::*;
    use crate::traits::FromDer;
    use der_parser::error::BerError;
    use der_parser::{oid::Oid, *};
    use lazy_static::lazy_static;
    use nom::bytes::streaming::take;
    use nom::combinator::{map, verify};
    use nom::{Err, IResult};

    type ExtParser = fn(&[u8]) -> IResult<&[u8], ParsedExtension, BerError>;

    lazy_static! {
        static ref EXTENSION_PARSERS: HashMap<Oid<'static>, ExtParser> = {
            macro_rules! add {
                ($m:ident, $oid:ident, $p:ident) => {
                    $m.insert($oid, $p as ExtParser);
                };
            }

            let mut m = HashMap::new();
            add!(
                m,
                OID_X509_EXT_SUBJECT_KEY_IDENTIFIER,
                parse_keyidentifier_ext
            );
            add!(m, OID_X509_EXT_KEY_USAGE, parse_keyusage_ext);
            add!(
                m,
                OID_X509_EXT_SUBJECT_ALT_NAME,
                parse_subjectalternativename_ext
            );
            add!(
                m,
                OID_X509_EXT_BASIC_CONSTRAINTS,
                parse_basicconstraints_ext
            );
            add!(m, OID_X509_EXT_NAME_CONSTRAINTS, parse_nameconstraints_ext);
            add!(
                m,
                OID_X509_EXT_CERTIFICATE_POLICIES,
                parse_certificatepolicies_ext
            );
            add!(m, OID_X509_EXT_POLICY_MAPPINGS, parse_policymappings_ext);
            add!(
                m,
                OID_X509_EXT_POLICY_CONSTRAINTS,
                parse_policyconstraints_ext
            );
            add!(
                m,
                OID_X509_EXT_EXTENDED_KEY_USAGE,
                parse_extendedkeyusage_ext
            );
            add!(
                m,
                OID_X509_EXT_CRL_DISTRIBUTION_POINTS,
                parse_crldistributionpoints_ext
            );
            add!(
                m,
                OID_X509_EXT_INHIBITANT_ANY_POLICY,
                parse_inhibitanypolicy_ext
            );
            add!(
                m,
                OID_PKIX_AUTHORITY_INFO_ACCESS,
                parse_authorityinfoaccess_ext
            );
            add!(
                m,
                OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER,
                parse_authoritykeyidentifier_ext
            );
            add!(m, OID_X509_EXT_CERT_TYPE, parse_nscerttype_ext);
            add!(m, OID_X509_EXT_CRL_NUMBER, parse_crl_number);
            add!(m, OID_X509_EXT_REASON_CODE, parse_reason_code);
            add!(m, OID_X509_EXT_INVALIDITY_DATE, parse_invalidity_date);
            m
        };
    }

    // look into the parser map if the extension is known, and parse it
    // otherwise, leave it as UnsupportedExtension
    fn parse_extension0<'a>(
        orig_i: &'a [u8],
        i: &'a [u8],
        oid: &Oid,
    ) -> IResult<&'a [u8], ParsedExtension<'a>, BerError> {
        if let Some(parser) = EXTENSION_PARSERS.get(oid) {
            match parser(i) {
                Ok((_, ext)) => Ok((orig_i, ext)),
                Err(error) => Ok((orig_i, ParsedExtension::ParseError { error })),
            }
        } else {
            Ok((
                orig_i,
                ParsedExtension::UnsupportedExtension {
                    oid: oid.to_owned(),
                },
            ))
        }
    }

    pub(crate) fn parse_extension<'a>(
        orig_i: &'a [u8],
        i: &'a [u8],
        oid: &Oid,
    ) -> IResult<&'a [u8], ParsedExtension<'a>, BerError> {
        parse_extension0(orig_i, i, oid)
    }

    /// Parse a "Basic Constraints" extension
    ///
    /// <pre>
    ///   id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }
    ///   BasicConstraints ::= SEQUENCE {
    ///        cA                      BOOLEAN DEFAULT FALSE,
    ///        pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
    /// </pre>
    ///
    /// Note the maximum length of the `pathLenConstraint` field is limited to the size of a 32-bits
    /// unsigned integer, and parsing will fail if value if larger.
    pub(super) fn parse_basicconstraints(i: &[u8]) -> IResult<&[u8], BasicConstraints, BerError> {
        let (rem, obj) = parse_der_sequence(i)?;
        if let Ok(seq) = obj.as_sequence() {
            let (ca, path_len_constraint) = match seq.len() {
                0 => (false, None),
                1 => {
                    if let Ok(b) = seq[0].as_bool() {
                        (b, None)
                    } else if let Ok(u) = seq[0].as_u32() {
                        (false, Some(u))
                    } else {
                        return Err(nom::Err::Error(BerError::InvalidTag));
                    }
                }
                2 => {
                    let ca = seq[0]
                        .as_bool()
                        .or(Err(nom::Err::Error(BerError::InvalidLength)))?;
                    let pl = seq[1]
                        .as_u32()
                        .or(Err(nom::Err::Error(BerError::InvalidLength)))?;
                    (ca, Some(pl))
                }
                _ => return Err(nom::Err::Error(BerError::InvalidLength)),
            };
            Ok((
                rem,
                BasicConstraints {
                    ca,
                    path_len_constraint,
                },
            ))
        } else {
            Err(nom::Err::Error(BerError::InvalidLength))
        }
    }

    fn parse_basicconstraints_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        map(parse_basicconstraints, ParsedExtension::BasicConstraints)(i)
    }

    pub(super) fn parse_nameconstraints<'a>(
        i: &'a [u8],
    ) -> IResult<&'a [u8], NameConstraints, BerError> {
        fn parse_subtree<'a>(i: &'a [u8]) -> IResult<&'a [u8], GeneralSubtree, BerError> {
            parse_der_sequence_defined_g(|input, _| {
                map(parse_generalname, |base| GeneralSubtree { base })(input)
            })(i)
        }
        fn parse_subtrees(i: &[u8]) -> IResult<&[u8], Vec<GeneralSubtree>, BerError> {
            all_consuming(many1(complete(parse_subtree)))(i)
        }

        let (ret, named_constraints) = parse_der_sequence_defined_g(|input, _| {
            let (rem, permitted_subtrees) =
                opt(complete(parse_der_tagged_explicit_g(0, |input, _| {
                    parse_subtrees(input)
                })))(input)?;
            let (rem, excluded_subtrees) =
                opt(complete(parse_der_tagged_explicit_g(1, |input, _| {
                    parse_subtrees(input)
                })))(rem)?;
            let named_constraints = NameConstraints {
                permitted_subtrees,
                excluded_subtrees,
            };
            Ok((rem, named_constraints))
        })(i)?;

        Ok((ret, named_constraints))
    }

    fn parse_nameconstraints_ext<'a>(i: &'a [u8]) -> IResult<&'a [u8], ParsedExtension, BerError> {
        map(parse_nameconstraints, ParsedExtension::NameConstraints)(i)
    }

    pub(super) fn parse_generalname<'a>(i: &'a [u8]) -> IResult<&'a [u8], GeneralName, BerError> {
        let (rest, hdr) = verify(der_read_element_header, |hdr| hdr.is_contextspecific())(i)?;
        let len = hdr.len.primitive()?;
        if len > rest.len() {
            return Err(nom::Err::Failure(BerError::ObjectTooShort));
        }
        fn ia5str<'a>(i: &'a [u8], hdr: DerObjectHeader) -> Result<&'a str, Err<BerError>> {
            // Relax constraints from RFC here: we are expecting an IA5String, but many certificates
            // are using unicode characters
            der_read_element_content_as(i, DerTag::Utf8String, hdr.len, hdr.is_constructed(), 0)?
                .1
                .as_slice()
                .and_then(|s| std::str::from_utf8(s).map_err(|_| BerError::BerValueError))
                .map_err(nom::Err::Failure)
        }
        let name = match hdr.tag.0 {
            0 => {
                // otherName SEQUENCE { OID, [0] explicit any defined by oid }
                let (any, oid) = parse_der_oid(rest)?;
                let oid = oid.as_oid_val().map_err(nom::Err::Failure)?;
                GeneralName::OtherName(oid, any)
            }
            1 => GeneralName::RFC822Name(ia5str(rest, hdr)?),
            2 => GeneralName::DNSName(ia5str(rest, hdr)?),
            3 => {
                // XXX Not yet implemented
                let (_, data) = take(len)(rest)?;
                let obj = UnparsedObject { header: hdr, data };
                GeneralName::X400Address(obj)
            }
            4 => {
                // directoryName, name
                let (_, name) = all_consuming(X509Name::from_der)(&rest[..len])
                    .or(Err(BerError::Unsupported)) // XXX remove me
                    ?;
                GeneralName::DirectoryName(name)
            }
            5 => {
                // XXX Not yet implemented
                let (_, data) = take(len)(rest)?;
                let obj = UnparsedObject { header: hdr, data };
                GeneralName::EDIPartyName(obj)
            }
            6 => GeneralName::URI(ia5str(rest, hdr)?),
            7 => {
                // IPAddress, OctetString
                let ip = der_read_element_content_as(
                    rest,
                    DerTag::OctetString,
                    hdr.len,
                    hdr.is_constructed(),
                    0,
                )?
                .1
                .as_slice()
                .map_err(nom::Err::Failure)?;
                GeneralName::IPAddress(ip)
            }
            8 => {
                let oid = der_read_element_content_as(
                    rest,
                    DerTag::Oid,
                    hdr.len,
                    hdr.is_constructed(),
                    0,
                )?
                .1
                .as_oid_val()
                .map_err(nom::Err::Failure)?;
                GeneralName::RegisteredID(oid)
            }
            _ => return Err(Err::Failure(BerError::UnknownTag)),
        };
        Ok((&rest[len..], name))
    }

    pub(super) fn parse_subjectalternativename_ext<'a>(
        i: &'a [u8],
    ) -> IResult<&'a [u8], ParsedExtension, BerError> {
        parse_der_sequence_defined_g(|input, _| {
            let (i, general_names) = all_consuming(many0(complete(parse_generalname)))(input)?;
            Ok((
                i,
                ParsedExtension::SubjectAlternativeName(SubjectAlternativeName { general_names }),
            ))
        })(i)
    }

    pub(super) fn parse_policyconstraints(i: &[u8]) -> IResult<&[u8], PolicyConstraints, BerError> {
        parse_der_sequence_defined_g(|input, _| {
            let (i, require_explicit_policy) = opt(complete(map_res(
                parse_der_tagged_implicit(0, parse_der_content(DerTag::Integer)),
                |x| x.as_u32(),
            )))(input)?;
            let (i, inhibit_policy_mapping) = all_consuming(opt(complete(map_res(
                parse_der_tagged_implicit(1, parse_der_content(DerTag::Integer)),
                |x| x.as_u32(),
            ))))(i)?;
            let policy_constraint = PolicyConstraints {
                require_explicit_policy,
                inhibit_policy_mapping,
            };
            Ok((i, policy_constraint))
        })(i)
    }

    fn parse_policyconstraints_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        map(parse_policyconstraints, ParsedExtension::PolicyConstraints)(i)
    }

    // PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
    //  issuerDomainPolicy      CertPolicyId,
    //  subjectDomainPolicy     CertPolicyId }
    pub(super) fn parse_policymappings(i: &[u8]) -> IResult<&[u8], PolicyMappings, BerError> {
        fn parse_oid_pair(i: &[u8]) -> IResult<&[u8], Vec<DerObject<'_>>, BerError> {
            // read 2 OID as a SEQUENCE OF OID - length will be checked later
            parse_der_sequence_of_v(parse_der_oid)(i)
        }
        let (ret, pairs) = parse_der_sequence_of_v(parse_oid_pair)(i)?;
        let mut mappings = Vec::new();
        // let mut mappings: HashMap<Oid, Vec<Oid>> = HashMap::new();
        for pair in pairs.iter() {
            if pair.len() != 2 {
                return Err(Err::Failure(BerError::BerValueError));
            }
            let left = pair[0].as_oid_val().map_err(nom::Err::Failure)?;
            let right = pair[1].as_oid_val().map_err(nom::Err::Failure)?;
            // XXX this should go to Validate
            // if left.bytes() == oid!(raw 2.5.29.32.0) || right.bytes() == oid!(raw 2.5.29.32.0) {
            //     // mapping to or from anyPolicy is not allowed
            //     return Err(Err::Failure(BerError::InvalidTag));
            // }
            mappings.push(PolicyMapping::new(left, right));
        }
        Ok((ret, PolicyMappings { mappings }))
    }

    fn parse_policymappings_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        map(parse_policymappings, ParsedExtension::PolicyMappings)(i)
    }

    fn parse_inhibitanypolicy_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        let (ret, skip_certs) = parse_der_u32(i)?;
        Ok((
            ret,
            ParsedExtension::InhibitAnyPolicy(InhibitAnyPolicy { skip_certs }),
        ))
    }

    pub(super) fn parse_extendedkeyusage(i: &[u8]) -> IResult<&[u8], ExtendedKeyUsage, BerError> {
        let (ret, seq) = parse_der_sequence_of(parse_der_oid)(i)?;
        let mut seen = std::collections::HashSet::new();
        let mut eku = ExtendedKeyUsage {
            any: false,
            server_auth: false,
            client_auth: false,
            code_signing: false,
            email_protection: false,
            time_stamping: false,
            ocsp_signing: false,
            other: Vec::new(),
        };
        for oid in seq.as_sequence().map_err(nom::Err::Failure)?.iter() {
            let oid = oid.as_oid_val().map_err(nom::Err::Failure)?;
            if !seen.insert(oid.clone()) {
                continue;
            }
            let asn1 = oid.bytes();
            if asn1 == oid!(raw 2.5.29.37.0) {
                eku.any = true;
            } else if asn1 == oid!(raw 1.3.6.1.5.5.7.3.1) {
                eku.server_auth = true;
            } else if asn1 == oid!(raw 1.3.6.1.5.5.7.3.2) {
                eku.client_auth = true;
            } else if asn1 == oid!(raw 1.3.6.1.5.5.7.3.3) {
                eku.code_signing = true;
            } else if asn1 == oid!(raw 1.3.6.1.5.5.7.3.4) {
                eku.email_protection = true;
            } else if asn1 == oid!(raw 1.3.6.1.5.5.7.3.8) {
                eku.time_stamping = true;
            } else if asn1 == oid!(raw 1.3.6.1.5.5.7.3.9) {
                eku.ocsp_signing = true;
            } else {
                eku.other.push(oid);
            }
        }
        Ok((ret, eku))
    }

    fn parse_extendedkeyusage_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        map(parse_extendedkeyusage, ParsedExtension::ExtendedKeyUsage)(i)
    }

    // DistributionPointName ::= CHOICE {
    //     fullName                [0]     GeneralNames,
    //     nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
    fn parse_distributionpointname(i: &[u8]) -> IResult<&[u8], DistributionPointName, BerError> {
        let (rem, header) = der_read_element_header(i)?;
        match header.tag.0 {
            0 => {
                let (rem, names) = many1(complete(parse_generalname))(rem)?;
                Ok((rem, DistributionPointName::FullName(names)))
            }
            1 => {
                let (rem, rdn) = RelativeDistinguishedName::from_der(rem)
                    .map_err(|_| BerError::BerValueError)?;
                Ok((rem, DistributionPointName::NameRelativeToCRLIssuer(rdn)))
            }
            _ => Err(Err::Error(BerError::InvalidTag)),
        }
    }

    // ReasonFlags ::= BIT STRING {
    // unused                  (0),
    // keyCompromise           (1),
    // cACompromise            (2),
    // affiliationChanged      (3),
    // superseded              (4),
    // cessationOfOperation    (5),
    // certificateHold         (6),
    // privilegeWithdrawn      (7),
    // aACompromise            (8) }
    fn parse_tagged1_reasons(i: &[u8]) -> BerResult<ReasonFlags> {
        let (rem, obj) = parse_der_tagged_implicit(1, parse_der_content(DerTag::BitString))(i)?;
        if let DerObjectContent::BitString(_, b) = obj.content {
            let flags = b
                .data
                .iter()
                .rev()
                .fold(0, |acc, x| acc << 8 | (x.reverse_bits() as u16));
            Ok((rem, ReasonFlags { flags }))
        } else {
            Err(nom::Err::Failure(BerError::InvalidTag))
        }
    }

    fn parse_crlissuer_content(i: &[u8]) -> BerResult<Vec<GeneralName>> {
        many1(complete(parse_generalname))(i)
    }

    // DistributionPoint ::= SEQUENCE {
    //     distributionPoint       [0]     DistributionPointName OPTIONAL,
    //     reasons                 [1]     ReasonFlags OPTIONAL,
    //     cRLIssuer               [2]     GeneralNames OPTIONAL }
    pub(super) fn parse_crldistributionpoint(
        i: &[u8],
    ) -> IResult<&[u8], CRLDistributionPoint, BerError> {
        parse_der_sequence_defined_g(|content, _| {
            let (rem, distribution_point) =
                opt(complete(parse_der_tagged_explicit_g(0, |b, _| {
                    parse_distributionpointname(b)
                })))(content)?;
            let (rem, reasons) = opt(complete(parse_tagged1_reasons))(rem)?;
            let (rem, crl_issuer) = opt(complete(parse_der_tagged_implicit_g(2, |i, _, _| {
                parse_crlissuer_content(i)
            })))(rem)?;
            let crl_dp = CRLDistributionPoint {
                distribution_point,
                reasons,
                crl_issuer,
            };
            Ok((rem, crl_dp))
        })(i)
    }

    pub(super) fn parse_crldistributionpoints(
        i: &[u8],
    ) -> IResult<&[u8], CRLDistributionPoints, BerError> {
        parse_der_sequence_of_v(parse_crldistributionpoint)(i)
    }

    fn parse_crldistributionpoints_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        map(
            parse_crldistributionpoints,
            ParsedExtension::CRLDistributionPoints,
        )(i)
    }

    // AuthorityInfoAccessSyntax  ::=
    //         SEQUENCE SIZE (1..MAX) OF AccessDescription
    //
    // AccessDescription  ::=  SEQUENCE {
    //         accessMethod          OBJECT IDENTIFIER,
    //         accessLocation        GeneralName  }
    pub(super) fn parse_authorityinfoaccess(
        i: &[u8],
    ) -> IResult<&[u8], AuthorityInfoAccess, BerError> {
        fn parse_aia(i: &[u8]) -> IResult<&[u8], AccessDescription, BerError> {
            parse_der_sequence_defined_g(|content, _| {
                // Read first element, an oid.
                let (gn, oid) = map_res(parse_der_oid, |x: DerObject| x.as_oid_val())(content)?;
                // Parse second element
                let (rest, gn) = parse_generalname(gn)?;
                Ok((rest, AccessDescription::new(oid, gn)))
            })(i)
        }
        let (ret, accessdescs) = parse_der_sequence_of_v(parse_aia)(i)?;
        Ok((ret, AuthorityInfoAccess { accessdescs }))
    }

    fn parse_authorityinfoaccess_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        map(
            parse_authorityinfoaccess,
            ParsedExtension::AuthorityInfoAccess,
        )(i)
    }

    fn parse_aki_content<'a>(
        i: &'a [u8],
        _hdr: DerObjectHeader<'_>,
    ) -> IResult<&'a [u8], AuthorityKeyIdentifier<'a>, BerError> {
        let (i, key_identifier) = opt(complete(parse_der_tagged_implicit_g(0, |d, _, _| {
            Ok((&[], KeyIdentifier(d)))
        })))(i)?;
        let (i, authority_cert_issuer) =
            opt(complete(parse_der_tagged_implicit_g(1, |d, _, _| {
                many0(complete(parse_generalname))(d)
            })))(i)?;
        let (i, authority_cert_serial) = opt(complete(parse_der_tagged_implicit(
            2,
            parse_der_content(DerTag::Integer),
        )))(i)?;
        let authority_cert_serial = authority_cert_serial.and_then(|o| o.as_slice().ok());
        let aki = AuthorityKeyIdentifier {
            key_identifier,
            authority_cert_issuer,
            authority_cert_serial,
        };
        Ok((i, aki))
    }

    // RFC 5280 section 4.2.1.1: Authority Key Identifier
    pub(super) fn parse_authoritykeyidentifier(
        i: &[u8],
    ) -> IResult<&[u8], AuthorityKeyIdentifier, BerError> {
        let (rem, aki) = parse_der_sequence_defined_g(parse_aki_content)(i)?;
        Ok((rem, aki))
    }

    fn parse_authoritykeyidentifier_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        map(
            parse_authoritykeyidentifier,
            ParsedExtension::AuthorityKeyIdentifier,
        )(i)
    }

    pub(super) fn parse_keyidentifier<'a>(
        i: &'a [u8],
    ) -> IResult<&'a [u8], KeyIdentifier, BerError> {
        let (rest, obj) = parse_der_octetstring(i)?;
        let id = obj
            .content
            .as_slice()
            .or(Err(Err::Error(BerError::BerTypeError)))?;
        let ki = KeyIdentifier(id);
        Ok((rest, ki))
    }

    fn parse_keyidentifier_ext<'a>(i: &'a [u8]) -> IResult<&'a [u8], ParsedExtension, BerError> {
        map(parse_keyidentifier, ParsedExtension::SubjectKeyIdentifier)(i)
    }

    pub(super) fn parse_keyusage(i: &[u8]) -> IResult<&[u8], KeyUsage, BerError> {
        let (rest, obj) = parse_der_bitstring(i)?;
        let bitstring = obj
            .content
            .as_bitstring()
            .or(Err(Err::Error(BerError::BerTypeError)))?;
        let flags = bitstring
            .data
            .iter()
            .rev()
            .fold(0, |acc, x| acc << 8 | (x.reverse_bits() as u16));
        Ok((rest, KeyUsage { flags }))
    }

    fn parse_keyusage_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        map(parse_keyusage, ParsedExtension::KeyUsage)(i)
    }

    pub(super) fn parse_nscerttype(i: &[u8]) -> IResult<&[u8], NSCertType, BerError> {
        let (rest, obj) = parse_der_bitstring(i)?;
        let bitstring = obj
            .content
            .as_bitstring()
            .or(Err(Err::Error(BerError::BerTypeError)))?;
        // bitstring should be 1 byte long
        if bitstring.data.len() != 1 {
            return Err(Err::Error(BerError::BerValueError));
        }
        let flags = bitstring.data[0].reverse_bits();
        Ok((rest, NSCertType(flags)))
    }

    fn parse_nscerttype_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        map(parse_nscerttype, ParsedExtension::NSCertType)(i)
    }

    // CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
    //
    // PolicyInformation ::= SEQUENCE {
    //      policyIdentifier   CertPolicyId,
    //      policyQualifiers   SEQUENCE SIZE (1..MAX) OF
    //              PolicyQualifierInfo OPTIONAL }
    //
    // CertPolicyId ::= OBJECT IDENTIFIER
    //
    // PolicyQualifierInfo ::= SEQUENCE {
    //      policyQualifierId  PolicyQualifierId,
    //      qualifier          ANY DEFINED BY policyQualifierId }
    //
    // -- Implementations that recognize additional policy qualifiers MUST
    // -- augment the following definition for PolicyQualifierId
    //
    // PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
    pub(super) fn parse_certificatepolicies(
        i: &[u8],
    ) -> IResult<&[u8], Vec<PolicyInformation>, BerError> {
        fn parse_policy_qualifier_info(i: &[u8]) -> IResult<&[u8], PolicyQualifierInfo, BerError> {
            parse_der_sequence_defined_g(|content, _| {
                let (rem, policy_qualifier_id) =
                    map_res(parse_der_oid, |x: DerObject| x.as_oid_val())(content)?;
                let info = PolicyQualifierInfo {
                    policy_qualifier_id,
                    qualifier: rem,
                };
                Ok((&[], info))
            })(i)
        }
        fn parse_policy_information(i: &[u8]) -> IResult<&[u8], PolicyInformation, BerError> {
            parse_der_sequence_defined_g(|content, _| {
                let (rem, policy_id) =
                    map_res(parse_der_oid, |x: DerObject| x.as_oid_val())(content)?;
                let (rem, policy_qualifiers) =
                    opt(complete(parse_der_sequence_defined_g(|content, _| {
                        many1(complete(parse_policy_qualifier_info))(content)
                    })))(rem)?;
                let info = PolicyInformation {
                    policy_id,
                    policy_qualifiers,
                };
                Ok((rem, info))
            })(i)
        }
        parse_der_sequence_of_v(parse_policy_information)(i)
    }

    fn parse_certificatepolicies_ext(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        map(
            parse_certificatepolicies,
            ParsedExtension::CertificatePolicies,
        )(i)
    }

    // CRLReason ::= ENUMERATED { ...
    fn parse_reason_code<'a>(i: &'a [u8]) -> IResult<&'a [u8], ParsedExtension, BerError> {
        let (rest, obj) = parse_der_enum(i)?;
        let code = obj
            .content
            .as_u32()
            .or(Err(Err::Error(BerError::BerValueError)))?;
        if code > 10 {
            return Err(Err::Error(BerError::BerValueError));
        }
        let ret = ParsedExtension::ReasonCode(ReasonCode(code as u8));
        Ok((rest, ret))
    }

    // invalidityDate ::=  GeneralizedTime
    fn parse_invalidity_date<'a>(i: &'a [u8]) -> IResult<&'a [u8], ParsedExtension, BerError> {
        let (rest, date) = map_res(parse_der_generalizedtime, der_to_utctime)(i)?;
        Ok((rest, ParsedExtension::InvalidityDate(date)))
    }

    // CRLNumber ::= INTEGER (0..MAX)
    // Note from RFC 3280: "CRL verifiers MUST be able to handle CRLNumber values up to 20 octets."
    fn parse_crl_number(i: &[u8]) -> IResult<&[u8], ParsedExtension, BerError> {
        let (rest, num) = map_res(parse_der_integer, |obj| obj.as_biguint())(i)?;
        Ok((rest, ParsedExtension::CRLNumber(num)))
    }
}

/// Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
pub(crate) fn parse_extension_sequence(i: &[u8]) -> X509Result<Vec<X509Extension>> {
    parse_der_sequence_defined_g(|a, _| all_consuming(many0(complete(X509Extension::from_der)))(a))(
        i,
    )
}

pub(crate) fn parse_extensions(i: &[u8], explicit_tag: DerTag) -> X509Result<Vec<X509Extension>> {
    if i.is_empty() {
        return Ok((i, Vec::new()));
    }

    match der_read_element_header(i) {
        Ok((rem, hdr)) => {
            if hdr.tag != explicit_tag {
                return Err(Err::Error(X509Error::InvalidExtensions));
            }
            all_consuming(parse_extension_sequence)(rem)
        }
        Err(_) => Err(X509Error::InvalidExtensions.into()),
    }
}

/// Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
pub(crate) fn parse_extension_envelope_sequence(i: &[u8]) -> X509Result<Vec<X509Extension>> {
    let parser = X509ExtensionParser::new().with_deep_parse_extensions(false);

    parse_der_sequence_defined_g(move |a, _| all_consuming(many0(complete(parser)))(a))(i)
}

pub(crate) fn parse_extensions_envelope(
    i: &[u8],
    explicit_tag: DerTag,
) -> X509Result<Vec<X509Extension>> {
    if i.is_empty() {
        return Ok((i, Vec::new()));
    }

    match der_read_element_header(i) {
        Ok((rem, hdr)) => {
            if hdr.tag != explicit_tag {
                return Err(Err::Error(X509Error::InvalidExtensions));
            }
            all_consuming(parse_extension_envelope_sequence)(rem)
        }
        Err(_) => Err(X509Error::InvalidExtensions.into()),
    }
}

fn der_read_critical(i: &[u8]) -> BerResult<bool> {
    // Some certificates do not respect the DER BOOLEAN constraint (true must be encoded as 0xff)
    // so we attempt to parse as BER
    let (rem, obj) = opt(parse_ber_bool)(i)?;
    let value = obj
        .map(|o| o.as_bool().unwrap_or_default()) // unwrap cannot fail, we just read a bool
        .unwrap_or(false) // default critical value
        ;
    Ok((rem, value))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_keyusage_flags() {
        let ku = KeyUsage { flags: 98 };
        assert!(!ku.digital_signature());
        assert!(ku.non_repudiation());
        assert!(!ku.key_encipherment());
        assert!(!ku.data_encipherment());
        assert!(!ku.key_agreement());
        assert!(ku.key_cert_sign());
        assert!(ku.crl_sign());
        assert!(!ku.encipher_only());
        assert!(!ku.decipher_only());
    }

    #[test]
    fn test_extensions1() {
        use der_parser::oid;
        let crt = crate::parse_x509_certificate(include_bytes!("../assets/extension1.der"))
            .unwrap()
            .1;
        let tbs = crt.tbs_certificate;
        assert_eq!(
            tbs.basic_constraints().unwrap().1,
            &BasicConstraints {
                ca: true,
                path_len_constraint: Some(1)
            }
        );
        {
            let ku = tbs.key_usage().unwrap().1;
            assert!(ku.digital_signature());
            assert!(!ku.non_repudiation());
            assert!(ku.key_encipherment());
            assert!(ku.data_encipherment());
            assert!(ku.key_agreement());
            assert!(!ku.key_cert_sign());
            assert!(!ku.crl_sign());
            assert!(ku.encipher_only());
            assert!(ku.decipher_only());
        }
        {
            let eku = tbs.extended_key_usage().unwrap().1;
            assert!(!eku.any);
            assert!(eku.server_auth);
            assert!(!eku.client_auth);
            assert!(eku.code_signing);
            assert!(!eku.email_protection);
            assert!(eku.time_stamping);
            assert!(!eku.ocsp_signing);
            assert_eq!(eku.other, vec![oid!(1.2.3 .4 .0 .42)]);
        }
        assert_eq!(
            tbs.policy_constraints().unwrap().1,
            &PolicyConstraints {
                require_explicit_policy: None,
                inhibit_policy_mapping: Some(10)
            }
        );
        assert_eq!(
            tbs.inhibit_anypolicy().unwrap().1,
            &InhibitAnyPolicy { skip_certs: 2 }
        );
        {
            let alt_names = &tbs.subject_alternative_name().unwrap().1.general_names;
            assert_eq!(alt_names[0], GeneralName::RFC822Name("foo@example.com"));
            assert_eq!(alt_names[1], GeneralName::URI("http://my.url.here/"));
            assert_eq!(
                alt_names[2],
                GeneralName::IPAddress([192, 168, 7, 1].as_ref())
            );
            assert_eq!(
                format!(
                    "{}",
                    match alt_names[3] {
                        GeneralName::DirectoryName(ref dn) => dn,
                        _ => unreachable!(),
                    }
                ),
                "C=UK, O=My Organization, OU=My Unit, CN=My Name"
            );
            assert_eq!(alt_names[4], GeneralName::DNSName("localhost"));
            assert_eq!(alt_names[5], GeneralName::RegisteredID(oid!(1.2.90 .0)));
            assert_eq!(
                alt_names[6],
                GeneralName::OtherName(oid!(1.2.3 .4), b"\xA0\x17\x0C\x15some other identifier")
            );
        }

        {
            let name_constraints = &tbs.name_constraints().unwrap().1;
            assert_eq!(name_constraints.permitted_subtrees, None);
            assert_eq!(
                name_constraints.excluded_subtrees,
                Some(vec![
                    GeneralSubtree {
                        base: GeneralName::IPAddress([192, 168, 0, 0, 255, 255, 0, 0].as_ref())
                    },
                    GeneralSubtree {
                        base: GeneralName::RFC822Name("foo.com")
                    },
                ])
            );
        }
    }

    #[test]
    fn test_extensions2() {
        use der_parser::oid;
        let crt = crate::parse_x509_certificate(include_bytes!("../assets/extension2.der"))
            .unwrap()
            .1;
        let tbs = crt.tbs_certificate;
        assert_eq!(
            tbs.policy_constraints().unwrap().1,
            &PolicyConstraints {
                require_explicit_policy: Some(5000),
                inhibit_policy_mapping: None
            }
        );
        {
            let pm = tbs.policy_mappings().unwrap().1.clone().into_hashmap();
            let mut pm_ref = HashMap::new();
            pm_ref.insert(oid!(2.34.23), vec![oid!(2.2)]);
            pm_ref.insert(oid!(1.1), vec![oid!(0.0.4)]);
            pm_ref.insert(oid!(2.2), vec![oid!(2.2.1), oid!(2.2.3)]);
            assert_eq!(pm, pm_ref);
        }
    }

    #[test]
    fn test_extensions_crl_distribution_points() {
        // Extension not present
        {
            let crt =
                crate::parse_x509_certificate(include_bytes!("../assets/crl-ext/crl-no-crl.der"))
                    .unwrap()
                    .1;
            assert!(crt
                .tbs_certificate
                .extensions_map()
                .unwrap()
                .get(&OID_X509_EXT_CRL_DISTRIBUTION_POINTS)
                .is_none());
        }
        // CRLDistributionPoints has 1 entry with 1 URI
        {
            let crt =
                crate::parse_x509_certificate(include_bytes!("../assets/crl-ext/crl-simple.der"))
                    .unwrap()
                    .1;
            let crl = crt
                .tbs_certificate
                .extensions_map()
                .unwrap()
                .get(&OID_X509_EXT_CRL_DISTRIBUTION_POINTS)
                .unwrap()
                .parsed_extension();
            assert!(matches!(crl, ParsedExtension::CRLDistributionPoints(_)));
            if let ParsedExtension::CRLDistributionPoints(crl) = crl {
                assert_eq!(crl.len(), 1);
                assert!(crl[0].reasons.is_none());
                assert!(crl[0].crl_issuer.is_none());
                let distribution_point = crl[0].distribution_point.as_ref().unwrap();
                assert!(matches!(
                    distribution_point,
                    DistributionPointName::FullName(_)
                ));
                if let DistributionPointName::FullName(names) = distribution_point {
                    assert_eq!(names.len(), 1);
                    assert!(matches!(names[0], GeneralName::URI(_)));
                    if let GeneralName::URI(uri) = names[0] {
                        assert_eq!(uri, "http://example.com/myca.crl")
                    }
                }
            }
        }
        // CRLDistributionPoints has 2 entries
        {
            let crt =
                crate::parse_x509_certificate(include_bytes!("../assets/crl-ext/crl-complex.der"))
                    .unwrap()
                    .1;
            let crl = crt
                .tbs_certificate
                .extensions_map()
                .unwrap()
                .get(&OID_X509_EXT_CRL_DISTRIBUTION_POINTS)
                .unwrap()
                .parsed_extension();
            assert!(matches!(crl, ParsedExtension::CRLDistributionPoints(_)));
            if let ParsedExtension::CRLDistributionPoints(crl) = crl {
                assert_eq!(crl.len(), 2);
                // First CRL Distribution point
                let reasons = crl[0].reasons.as_ref().unwrap();
                assert!(reasons.key_compromise());
                assert!(reasons.ca_compromise());
                assert!(!reasons.affilation_changed());
                assert!(!reasons.superseded());
                assert!(!reasons.cessation_of_operation());
                assert!(!reasons.certificate_hold());
                assert!(!reasons.privelege_withdrawn());
                assert!(reasons.aa_compromise());
                assert_eq!(
                    format!("{}", reasons),
                    "Key Compromise, CA Compromise, AA Compromise"
                );
                let issuers = crl[0].crl_issuer.as_ref().unwrap();
                assert_eq!(issuers.len(), 1);
                assert!(matches!(issuers[0], GeneralName::DirectoryName(_)));
                if let GeneralName::DirectoryName(name) = &issuers[0] {
                    assert_eq!(name.to_string(), "C=US, O=Organisation, CN=Some Name");
                }
                let distribution_point = crl[0].distribution_point.as_ref().unwrap();
                assert!(matches!(
                    distribution_point,
                    DistributionPointName::FullName(_)
                ));
                if let DistributionPointName::FullName(names) = distribution_point {
                    assert_eq!(names.len(), 1);
                    assert!(matches!(names[0], GeneralName::URI(_)));
                    if let GeneralName::URI(uri) = names[0] {
                        assert_eq!(uri, "http://example.com/myca.crl")
                    }
                }
                // Second CRL Distribution point
                let reasons = crl[1].reasons.as_ref().unwrap();
                assert!(reasons.key_compromise());
                assert!(reasons.ca_compromise());
                assert!(!reasons.affilation_changed());
                assert!(!reasons.superseded());
                assert!(!reasons.cessation_of_operation());
                assert!(!reasons.certificate_hold());
                assert!(!reasons.privelege_withdrawn());
                assert!(!reasons.aa_compromise());
                assert_eq!(format!("{}", reasons), "Key Compromise, CA Compromise");
                assert!(crl[1].crl_issuer.is_none());
                let distribution_point = crl[1].distribution_point.as_ref().unwrap();
                assert!(matches!(
                    distribution_point,
                    DistributionPointName::FullName(_)
                ));
                if let DistributionPointName::FullName(names) = distribution_point {
                    assert_eq!(names.len(), 1);
                    assert!(matches!(names[0], GeneralName::URI(_)));
                    if let GeneralName::URI(uri) = names[0] {
                        assert_eq!(uri, "http://example.com/myca2.crl")
                    }
                }
            }
        }
    }

    // Test cases for:
    // - parsing SubjectAlternativeName
    // - parsing NameConstraints
}
