| // Copyright 2015 The Chromium Authors | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef BSSL_PKI_PARSE_CERTIFICATE_H_ | 
 | #define BSSL_PKI_PARSE_CERTIFICATE_H_ | 
 |  | 
 | #include <stdint.h> | 
 |  | 
 | #include <map> | 
 | #include <memory> | 
 | #include <optional> | 
 | #include <vector> | 
 |  | 
 | #include <openssl/base.h> | 
 |  | 
 | #include "general_names.h" | 
 | #include "input.h" | 
 | #include "parse_values.h" | 
 |  | 
 | BSSL_NAMESPACE_BEGIN | 
 |  | 
 | namespace der { | 
 | class Parser; | 
 | } | 
 |  | 
 | class CertErrors; | 
 | struct ParsedTbsCertificate; | 
 |  | 
 | // Returns true if the given serial number (CertificateSerialNumber in RFC 5280) | 
 | // is valid: | 
 | // | 
 | //    CertificateSerialNumber  ::=  INTEGER | 
 | // | 
 | // The input to this function is the (unverified) value octets of the INTEGER. | 
 | // This function will verify that: | 
 | // | 
 | //   * The octets are a valid DER-encoding of an INTEGER (for instance, minimal | 
 | //     encoding length). | 
 | // | 
 | //   * No more than 20 octets are used. | 
 | // | 
 | // Note that it DOES NOT reject non-positive values (zero or negative). | 
 | // | 
 | // For reference, here is what RFC 5280 section 4.1.2.2 says: | 
 | // | 
 | //     Given the uniqueness requirements above, serial numbers can be | 
 | //     expected to contain long integers.  Certificate users MUST be able to | 
 | //     handle serialNumber values up to 20 octets.  Conforming CAs MUST NOT | 
 | //     use serialNumber values longer than 20 octets. | 
 | // | 
 | //     Note: Non-conforming CAs may issue certificates with serial numbers | 
 | //     that are negative or zero.  Certificate users SHOULD be prepared to | 
 | //     gracefully handle such certificates. | 
 | // | 
 | // |errors| must be a non-null destination for any errors/warnings. If | 
 | // |warnings_only| is set to true, then what would ordinarily be errors are | 
 | // instead added as warnings. | 
 | [[nodiscard]] OPENSSL_EXPORT bool VerifySerialNumber(der::Input value, | 
 |                                                      bool warnings_only, | 
 |                                                      CertErrors *errors); | 
 |  | 
 | // Consumes a "Time" value (as defined by RFC 5280) from |parser|. On success | 
 | // writes the result to |*out| and returns true. On failure no guarantees are | 
 | // made about the state of |parser|. | 
 | // | 
 | // From RFC 5280: | 
 | // | 
 | //     Time ::= CHOICE { | 
 | //          utcTime        UTCTime, | 
 | //          generalTime    GeneralizedTime } | 
 | [[nodiscard]] OPENSSL_EXPORT bool ReadUTCOrGeneralizedTime( | 
 |     der::Parser *parser, der::GeneralizedTime *out); | 
 |  | 
 | // Parses a DER-encoded "Validity" as specified by RFC 5280. Returns true on | 
 | // success and sets the results in |not_before| and |not_after|: | 
 | // | 
 | //       Validity ::= SEQUENCE { | 
 | //            notBefore      Time, | 
 | //            notAfter       Time } | 
 | // | 
 | // Note that upon success it is NOT guaranteed that |*not_before <= *not_after|. | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseValidity( | 
 |     der::Input validity_tlv, der::GeneralizedTime *not_before, | 
 |     der::GeneralizedTime *not_after); | 
 |  | 
 | struct OPENSSL_EXPORT ParseCertificateOptions { | 
 |   // If set to true, then parsing will skip checks on the certificate's serial | 
 |   // number. The only requirement will be that the serial number is an INTEGER, | 
 |   // however it is not required to be a valid DER-encoding (i.e. minimal | 
 |   // encoding), nor is it required to be constrained to any particular length. | 
 |   bool allow_invalid_serial_numbers = false; | 
 | }; | 
 |  | 
 | // Parses a DER-encoded "Certificate" as specified by RFC 5280. Returns true on | 
 | // success and sets the results in the |out_*| parameters. On both the failure | 
 | // and success case, if |out_errors| was non-null it may contain extra error | 
 | // information. | 
 | // | 
 | // Note that on success the out parameters alias data from the input | 
 | // |certificate_tlv|.  Hence the output values are only valid as long as | 
 | // |certificate_tlv| remains valid. | 
 | // | 
 | // On failure the out parameters have an undefined state, except for | 
 | // out_errors. Some of them may have been updated during parsing, whereas | 
 | // others may not have been changed. | 
 | // | 
 | // The out parameters represent each field of the Certificate SEQUENCE: | 
 | //       Certificate  ::=  SEQUENCE  { | 
 | // | 
 | // The |out_tbs_certificate_tlv| parameter corresponds with "tbsCertificate" | 
 | // from RFC 5280: | 
 | //         tbsCertificate       TBSCertificate, | 
 | // | 
 | // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No | 
 | // guarantees are made regarding the value of this SEQUENCE. | 
 | // This can be further parsed using ParseTbsCertificate(). | 
 | // | 
 | // The |out_signature_algorithm_tlv| parameter corresponds with | 
 | // "signatureAlgorithm" from RFC 5280: | 
 | //         signatureAlgorithm   AlgorithmIdentifier, | 
 | // | 
 | // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No | 
 | // guarantees are made regarding the value of this SEQUENCE. | 
 | // This can be further parsed using SignatureValue::Create(). | 
 | // | 
 | // The |out_signature_value| parameter corresponds with "signatureValue" from | 
 | // RFC 5280: | 
 | //         signatureValue       BIT STRING  } | 
 | // | 
 | // Parsing guarantees that this is a valid BIT STRING. | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseCertificate( | 
 |     der::Input certificate_tlv, der::Input *out_tbs_certificate_tlv, | 
 |     der::Input *out_signature_algorithm_tlv, | 
 |     der::BitString *out_signature_value, CertErrors *out_errors); | 
 |  | 
 | // Parses a DER-encoded "TBSCertificate" as specified by RFC 5280. Returns true | 
 | // on success and sets the results in |out|. Certain invalid inputs may | 
 | // be accepted based on the provided |options|. | 
 | // | 
 | // If |errors| was non-null then any warnings/errors that occur during parsing | 
 | // are added to it. | 
 | // | 
 | // Note that on success |out| aliases data from the input |tbs_tlv|. | 
 | // Hence the fields of the ParsedTbsCertificate are only valid as long as | 
 | // |tbs_tlv| remains valid. | 
 | // | 
 | // On failure |out| has an undefined state. Some of its fields may have been | 
 | // updated during parsing, whereas others may not have been changed. | 
 | // | 
 | // Refer to the per-field documentation of ParsedTbsCertificate for details on | 
 | // what validity checks parsing performs. | 
 | // | 
 | //       TBSCertificate  ::=  SEQUENCE  { | 
 | //            version         [0]  EXPLICIT Version DEFAULT v1, | 
 | //            serialNumber         CertificateSerialNumber, | 
 | //            signature            AlgorithmIdentifier, | 
 | //            issuer               Name, | 
 | //            validity             Validity, | 
 | //            subject              Name, | 
 | //            subjectPublicKeyInfo SubjectPublicKeyInfo, | 
 | //            issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL, | 
 | //                                 -- If present, version MUST be v2 or v3 | 
 | //            subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL, | 
 | //                                 -- If present, version MUST be v2 or v3 | 
 | //            extensions      [3]  EXPLICIT Extensions OPTIONAL | 
 | //                                 -- If present, version MUST be v3 | 
 | //            } | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseTbsCertificate( | 
 |     der::Input tbs_tlv, const ParseCertificateOptions &options, | 
 |     ParsedTbsCertificate *out, CertErrors *errors); | 
 |  | 
 | // Represents a "Version" from RFC 5280: | 
 | //         Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  } | 
 | enum class CertificateVersion { | 
 |   V1, | 
 |   V2, | 
 |   V3, | 
 | }; | 
 |  | 
 | // ParsedTbsCertificate contains pointers to the main fields of a DER-encoded | 
 | // RFC 5280 "TBSCertificate". | 
 | // | 
 | // ParsedTbsCertificate is expected to be filled by ParseTbsCertificate(), so | 
 | // subsequent field descriptions are in terms of what ParseTbsCertificate() | 
 | // sets. | 
 | struct OPENSSL_EXPORT ParsedTbsCertificate { | 
 |   ParsedTbsCertificate(); | 
 |   ParsedTbsCertificate(ParsedTbsCertificate &&other); | 
 |   ParsedTbsCertificate &operator=(ParsedTbsCertificate &&other) = default; | 
 |   ~ParsedTbsCertificate(); | 
 |  | 
 |   // Corresponds with "version" from RFC 5280: | 
 |   //         version         [0]  EXPLICIT Version DEFAULT v1, | 
 |   // | 
 |   // Parsing guarantees that the version is one of v1, v2, or v3. | 
 |   CertificateVersion version = CertificateVersion::V1; | 
 |  | 
 |   // Corresponds with "serialNumber" from RFC 5280: | 
 |   //         serialNumber         CertificateSerialNumber, | 
 |   // | 
 |   // This field specifically contains the content bytes of the INTEGER. So for | 
 |   // instance if the serial number was 1000 then this would contain bytes | 
 |   // {0x03, 0xE8}. | 
 |   // | 
 |   // The serial number may or may not be a valid DER-encoded INTEGER: | 
 |   // | 
 |   // If the option |allow_invalid_serial_numbers=true| was used during | 
 |   // parsing, then nothing further can be assumed about these bytes. | 
 |   // | 
 |   // Otherwise if |allow_invalid_serial_numbers=false| then in addition | 
 |   // to being a valid DER-encoded INTEGER, parsing guarantees that | 
 |   // the serial number is at most 20 bytes long. Parsing does NOT guarantee | 
 |   // that the integer is positive (might be zero or negative). | 
 |   der::Input serial_number; | 
 |  | 
 |   // Corresponds with "signatureAlgorithm" from RFC 5280: | 
 |   //         signatureAlgorithm   AlgorithmIdentifier, | 
 |   // | 
 |   // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No | 
 |   // guarantees are made regarding the value of this SEQUENCE. | 
 |   // | 
 |   // This can be further parsed using SignatureValue::Create(). | 
 |   der::Input signature_algorithm_tlv; | 
 |  | 
 |   // Corresponds with "issuer" from RFC 5280: | 
 |   //         issuer               Name, | 
 |   // | 
 |   // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No | 
 |   // guarantees are made regarding the value of this SEQUENCE. | 
 |   der::Input issuer_tlv; | 
 |  | 
 |   // Corresponds with "validity" from RFC 5280: | 
 |   //         validity             Validity, | 
 |   // | 
 |   // Where Validity is defined as: | 
 |   // | 
 |   //   Validity ::= SEQUENCE { | 
 |   //        notBefore      Time, | 
 |   //        notAfter       Time } | 
 |   // | 
 |   // Parsing guarantees that notBefore (validity_not_before) and notAfter | 
 |   // (validity_not_after) are valid DER-encoded dates, however it DOES NOT | 
 |   // gurantee anything about their values. For instance notAfter could be | 
 |   // before notBefore, or the dates could indicate an expired certificate. | 
 |   // Consumers are responsible for testing expiration. | 
 |   der::GeneralizedTime validity_not_before; | 
 |   der::GeneralizedTime validity_not_after; | 
 |  | 
 |   // Corresponds with "subject" from RFC 5280: | 
 |   //         subject              Name, | 
 |   // | 
 |   // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No | 
 |   // guarantees are made regarding the value of this SEQUENCE. | 
 |   der::Input subject_tlv; | 
 |  | 
 |   // Corresponds with "subjectPublicKeyInfo" from RFC 5280: | 
 |   //         subjectPublicKeyInfo SubjectPublicKeyInfo, | 
 |   // | 
 |   // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No | 
 |   // guarantees are made regarding the value of this SEQUENCE. | 
 |   der::Input spki_tlv; | 
 |  | 
 |   // Corresponds with "issuerUniqueID" from RFC 5280: | 
 |   //         issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL, | 
 |   //                              -- If present, version MUST be v2 or v3 | 
 |   // | 
 |   // Parsing guarantees that if issuer_unique_id is present it is a valid BIT | 
 |   // STRING, and that the version is either v2 or v3 | 
 |   std::optional<der::BitString> issuer_unique_id; | 
 |  | 
 |   // Corresponds with "subjectUniqueID" from RFC 5280: | 
 |   //         subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL, | 
 |   //                              -- If present, version MUST be v2 or v3 | 
 |   // | 
 |   // Parsing guarantees that if subject_unique_id is present it is a valid BIT | 
 |   // STRING, and that the version is either v2 or v3 | 
 |   std::optional<der::BitString> subject_unique_id; | 
 |  | 
 |   // Corresponds with "extensions" from RFC 5280: | 
 |   //         extensions      [3]  EXPLICIT Extensions OPTIONAL | 
 |   //                              -- If present, version MUST be v3 | 
 |   // | 
 |   // | 
 |   // This contains the full (unverified) Tag-Length-Value for a SEQUENCE. No | 
 |   // guarantees are made regarding the value of this SEQUENCE. (Note that the | 
 |   // EXPLICIT outer tag is stripped.) | 
 |   // | 
 |   // Parsing guarantees that if extensions is present the version is v3. | 
 |   std::optional<der::Input> extensions_tlv; | 
 | }; | 
 |  | 
 | // ParsedExtension represents a parsed "Extension" from RFC 5280. It contains | 
 | // der:Inputs which are not owned so the associated data must be kept alive. | 
 | // | 
 | //    Extension  ::=  SEQUENCE  { | 
 | //            extnID      OBJECT IDENTIFIER, | 
 | //            critical    BOOLEAN DEFAULT FALSE, | 
 | //            extnValue   OCTET STRING | 
 | //                        -- contains the DER encoding of an ASN.1 value | 
 | //                        -- corresponding to the extension type identified | 
 | //                        -- by extnID | 
 | //            } | 
 | struct OPENSSL_EXPORT ParsedExtension { | 
 |   der::Input oid; | 
 |   // |value| will contain the contents of the OCTET STRING. For instance for | 
 |   // basicConstraints it will be the TLV for a SEQUENCE. | 
 |   der::Input value; | 
 |   bool critical = false; | 
 | }; | 
 |  | 
 | // Parses a DER-encoded "Extension" as specified by RFC 5280. Returns true on | 
 | // success and sets the results in |out|. | 
 | // | 
 | // Note that on success |out| aliases data from the input |extension_tlv|. | 
 | // Hence the fields of the ParsedExtension are only valid as long as | 
 | // |extension_tlv| remains valid. | 
 | // | 
 | // On failure |out| has an undefined state. Some of its fields may have been | 
 | // updated during parsing, whereas others may not have been changed. | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseExtension(der::Input extension_tlv, | 
 |                                                  ParsedExtension *out); | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 } | 
 | // | 
 | // In dotted notation: 2.5.29.14 | 
 | inline constexpr uint8_t kSubjectKeyIdentifierOid[] = {0x55, 0x1d, 0x0e}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 } | 
 | // | 
 | // In dotted notation: 2.5.29.15 | 
 | inline constexpr uint8_t kKeyUsageOid[] = {0x55, 0x1d, 0x0f}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 } | 
 | // | 
 | // In dotted notation: 2.5.29.17 | 
 | inline constexpr uint8_t kSubjectAltNameOid[] = {0x55, 0x1d, 0x11}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 } | 
 | // | 
 | // In dotted notation: 2.5.29.19 | 
 | inline constexpr uint8_t kBasicConstraintsOid[] = {0x55, 0x1d, 0x13}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ce-nameConstraints OBJECT IDENTIFIER ::=  { id-ce 30 } | 
 | // | 
 | // In dotted notation: 2.5.29.30 | 
 | inline constexpr uint8_t kNameConstraintsOid[] = {0x55, 0x1d, 0x1e}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 } | 
 | // | 
 | // In dotted notation: 2.5.29.32 | 
 | inline constexpr uint8_t kCertificatePoliciesOid[] = {0x55, 0x1d, 0x20}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 } | 
 | // | 
 | // In dotted notation: 2.5.29.35 | 
 | inline constexpr uint8_t kAuthorityKeyIdentifierOid[] = {0x55, 0x1d, 0x23}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ce-policyConstraints OBJECT IDENTIFIER ::=  { id-ce 36 } | 
 | // | 
 | // In dotted notation: 2.5.29.36 | 
 | inline constexpr uint8_t kPolicyConstraintsOid[] = {0x55, 0x1d, 0x24}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } | 
 | // | 
 | // In dotted notation: 2.5.29.37 | 
 | inline constexpr uint8_t kExtKeyUsageOid[] = {0x55, 0x1d, 0x25}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 } | 
 | // | 
 | // In dotted notation: 1.3.6.1.5.5.7.1.1 | 
 | inline constexpr uint8_t kAuthorityInfoAccessOid[] = {0x2B, 0x06, 0x01, 0x05, | 
 |                                                       0x05, 0x07, 0x01, 0x01}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 } | 
 | // | 
 | // In dotted notation: 1.3.6.1.5.5.7.48.2 | 
 | inline constexpr uint8_t kAdCaIssuersOid[] = {0x2B, 0x06, 0x01, 0x05, | 
 |                                               0x05, 0x07, 0x30, 0x02}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 } | 
 | // | 
 | // In dotted notation: 1.3.6.1.5.5.7.48.1 | 
 | inline constexpr uint8_t kAdOcspOid[] = {0x2B, 0x06, 0x01, 0x05, | 
 |                                          0x05, 0x07, 0x30, 0x01}; | 
 |  | 
 | // From RFC 5280: | 
 | // | 
 | //     id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::=  { id-ce 31 } | 
 | // | 
 | // In dotted notation: 2.5.29.31 | 
 | inline constexpr uint8_t kCrlDistributionPointsOid[] = {0x55, 0x1d, 0x1f}; | 
 |  | 
 | // From RFC 6962: | 
 | // | 
 | // critical poison extension. | 
 | // | 
 | // In dotted notation 1.3.6.1.4.1.11129.2.4.3 | 
 | inline constexpr uint8_t kCtPoisonOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01, | 
 |                                            0xD6, 0x79, 0x02, 0x04, 0x03}; | 
 |  | 
 | // From | 
 | // https://learn.microsoft.com/en-us/windows/win32/seccertenroll/supported-extensions#msapplicationpolicies | 
 | // | 
 | // OID: XCN_OID_APPLICATION_CERT_POLICIES (1.3.6.1.4.1.311.21.10) | 
 | inline constexpr uint8_t kMSApplicationPoliciesOid[] = { | 
 |     0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x0a}; | 
 |  | 
 | // Parses the Extensions sequence as defined by RFC 5280. Extensions are added | 
 | // to the map |extensions| keyed by the OID. Parsing guarantees that each OID | 
 | // is unique. Note that certificate verification must consume each extension | 
 | // marked as critical. | 
 | // | 
 | // Returns true on success and fills |extensions|. The output will reference | 
 | // bytes in |extensions_tlv|, so that data must be kept alive. | 
 | // On failure |extensions| may be partially written to and should not be used. | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseExtensions( | 
 |     der::Input extensions_tlv, | 
 |     std::map<der::Input, ParsedExtension> *extensions); | 
 |  | 
 | // Removes the extension with OID |oid| from |unconsumed_extensions| and fills | 
 | // |extension| with the matching extension value. If there was no extension | 
 | // matching |oid| then returns |false|. | 
 | [[nodiscard]] OPENSSL_EXPORT bool ConsumeExtension( | 
 |     der::Input oid, | 
 |     std::map<der::Input, ParsedExtension> *unconsumed_extensions, | 
 |     ParsedExtension *extension); | 
 |  | 
 | struct ParsedBasicConstraints { | 
 |   bool is_ca = false; | 
 |   bool has_path_len = false; | 
 |   uint8_t path_len = 0; | 
 | }; | 
 |  | 
 | // Parses the BasicConstraints extension as defined by RFC 5280: | 
 | // | 
 | //    BasicConstraints ::= SEQUENCE { | 
 | //         cA                      BOOLEAN DEFAULT FALSE, | 
 | //         pathLenConstraint       INTEGER (0..MAX) OPTIONAL } | 
 | // | 
 | // The maximum allowed value of pathLenConstraints will be whatever can fit | 
 | // into a uint8_t. | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseBasicConstraints( | 
 |     der::Input basic_constraints_tlv, ParsedBasicConstraints *out); | 
 |  | 
 | // KeyUsageBit contains the index for a particular key usage. The index is | 
 | // measured from the most significant bit of a bit string. | 
 | // | 
 | // From RFC 5280 section 4.2.1.3: | 
 | // | 
 | //     KeyUsage ::= BIT STRING { | 
 | //          digitalSignature        (0), | 
 | //          nonRepudiation          (1), -- recent editions of X.509 have | 
 | //                               -- renamed this bit to contentCommitment | 
 | //          keyEncipherment         (2), | 
 | //          dataEncipherment        (3), | 
 | //          keyAgreement            (4), | 
 | //          keyCertSign             (5), | 
 | //          cRLSign                 (6), | 
 | //          encipherOnly            (7), | 
 | //          decipherOnly            (8) } | 
 | enum KeyUsageBit { | 
 |   KEY_USAGE_BIT_DIGITAL_SIGNATURE = 0, | 
 |   KEY_USAGE_BIT_NON_REPUDIATION = 1, | 
 |   KEY_USAGE_BIT_KEY_ENCIPHERMENT = 2, | 
 |   KEY_USAGE_BIT_DATA_ENCIPHERMENT = 3, | 
 |   KEY_USAGE_BIT_KEY_AGREEMENT = 4, | 
 |   KEY_USAGE_BIT_KEY_CERT_SIGN = 5, | 
 |   KEY_USAGE_BIT_CRL_SIGN = 6, | 
 |   KEY_USAGE_BIT_ENCIPHER_ONLY = 7, | 
 |   KEY_USAGE_BIT_DECIPHER_ONLY = 8, | 
 | }; | 
 |  | 
 | // Parses the KeyUsage extension as defined by RFC 5280. Returns true on | 
 | // success, and |key_usage| will alias data in |key_usage_tlv|. On failure | 
 | // returns false, and |key_usage| may have been modified. | 
 | // | 
 | // In addition to validating that key_usage_tlv is a BIT STRING, this does | 
 | // additional KeyUsage specific validations such as requiring at least 1 bit to | 
 | // be set. | 
 | // | 
 | // To test if a particular key usage is set, call, e.g.: | 
 | //     key_usage->AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE); | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseKeyUsage(der::Input key_usage_tlv, | 
 |                                                 der::BitString *key_usage); | 
 |  | 
 | struct AuthorityInfoAccessDescription { | 
 |   // The accessMethod DER OID value. | 
 |   der::Input access_method_oid; | 
 |   // The accessLocation DER TLV. | 
 |   der::Input access_location; | 
 | }; | 
 | // Parses the Authority Information Access extension defined by RFC 5280. | 
 | // Returns true on success, and |out_access_descriptions| will alias data | 
 | // in |authority_info_access_tlv|.On failure returns false, and | 
 | // out_access_descriptions may have been partially filled. | 
 | // | 
 | // No validation is performed on the contents of the | 
 | // AuthorityInfoAccessDescription fields. | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseAuthorityInfoAccess( | 
 |     der::Input authority_info_access_tlv, | 
 |     std::vector<AuthorityInfoAccessDescription> *out_access_descriptions); | 
 |  | 
 | // Parses the Authority Information Access extension defined by RFC 5280, | 
 | // extracting the caIssuers URIs and OCSP URIs. | 
 | // | 
 | // Returns true on success, and |out_ca_issuers_uris| and |out_ocsp_uris| will | 
 | // alias data in |authority_info_access_tlv|. On failure returns false, and | 
 | // |out_ca_issuers_uris| and |out_ocsp_uris| may have been partially filled. | 
 | // | 
 | // |out_ca_issuers_uris| is filled with the accessLocations of type | 
 | // uniformResourceIdentifier for the accessMethod id-ad-caIssuers. | 
 | // |out_ocsp_uris| is filled with the accessLocations of type | 
 | // uniformResourceIdentifier for the accessMethod id-ad-ocsp. | 
 | // | 
 | // The values in |out_ca_issuers_uris| and |out_ocsp_uris| are checked to be | 
 | // IA5String (ASCII strings), but no other validation is performed on them. | 
 | // | 
 | // accessMethods other than id-ad-caIssuers and id-ad-ocsp are silently ignored. | 
 | // accessLocation types other than uniformResourceIdentifier are silently | 
 | // ignored. | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseAuthorityInfoAccessURIs( | 
 |     der::Input authority_info_access_tlv, | 
 |     std::vector<std::string_view> *out_ca_issuers_uris, | 
 |     std::vector<std::string_view> *out_ocsp_uris); | 
 |  | 
 | // ParsedDistributionPoint represents a parsed DistributionPoint from RFC 5280. | 
 | // | 
 | //   DistributionPoint ::= SEQUENCE { | 
 | //    distributionPoint       [0]     DistributionPointName OPTIONAL, | 
 | //    reasons                 [1]     ReasonFlags OPTIONAL, | 
 | //    cRLIssuer               [2]     GeneralNames OPTIONAL } | 
 | struct OPENSSL_EXPORT ParsedDistributionPoint { | 
 |   ParsedDistributionPoint(); | 
 |   ParsedDistributionPoint(ParsedDistributionPoint &&other); | 
 |   ~ParsedDistributionPoint(); | 
 |  | 
 |   // The parsed fullName, if distributionPoint was present and was a fullName. | 
 |   std::unique_ptr<GeneralNames> distribution_point_fullname; | 
 |  | 
 |   // If present, the DER encoded value of the nameRelativeToCRLIssuer field. | 
 |   // This should be a RelativeDistinguishedName, but the parser does not | 
 |   // validate it. | 
 |   std::optional<der::Input> distribution_point_name_relative_to_crl_issuer; | 
 |  | 
 |   // If present, the DER encoded value of the reasons field. This should be a | 
 |   // ReasonFlags bitString, but the parser does not validate it. | 
 |   std::optional<der::Input> reasons; | 
 |  | 
 |   // If present, the DER encoded value of the cRLIssuer field. This should be a | 
 |   // GeneralNames, but the parser does not validate it. | 
 |   std::optional<der::Input> crl_issuer; | 
 | }; | 
 |  | 
 | // Parses the value of a CRL Distribution Points extension (sequence of | 
 | // DistributionPoint). Return true on success, and fills |distribution_points| | 
 | // with values that reference data in |distribution_points_tlv|. | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseCrlDistributionPoints( | 
 |     der::Input distribution_points_tlv, | 
 |     std::vector<ParsedDistributionPoint> *distribution_points); | 
 |  | 
 | // Represents the AuthorityKeyIdentifier extension defined by RFC 5280 section | 
 | // 4.2.1.1. | 
 | // | 
 | //    AuthorityKeyIdentifier ::= SEQUENCE { | 
 | //       keyIdentifier             [0] KeyIdentifier           OPTIONAL, | 
 | //       authorityCertIssuer       [1] GeneralNames            OPTIONAL, | 
 | //       authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  } | 
 | // | 
 | //    KeyIdentifier ::= OCTET STRING | 
 | struct OPENSSL_EXPORT ParsedAuthorityKeyIdentifier { | 
 |   ParsedAuthorityKeyIdentifier(); | 
 |   ~ParsedAuthorityKeyIdentifier(); | 
 |   ParsedAuthorityKeyIdentifier(ParsedAuthorityKeyIdentifier &&other); | 
 |   ParsedAuthorityKeyIdentifier &operator=(ParsedAuthorityKeyIdentifier &&other); | 
 |  | 
 |   // The keyIdentifier, which is an OCTET STRING. | 
 |   std::optional<der::Input> key_identifier; | 
 |  | 
 |   // The authorityCertIssuer, which should be a GeneralNames, but this is not | 
 |   // enforced by ParseAuthorityKeyIdentifier. | 
 |   std::optional<der::Input> authority_cert_issuer; | 
 |  | 
 |   // The DER authorityCertSerialNumber, which should be a | 
 |   // CertificateSerialNumber (an INTEGER) but this is not enforced by | 
 |   // ParseAuthorityKeyIdentifier. | 
 |   std::optional<der::Input> authority_cert_serial_number; | 
 | }; | 
 |  | 
 | // Parses the value of an authorityKeyIdentifier extension. Returns true on | 
 | // success and fills |authority_key_identifier| with values that reference data | 
 | // in |extension_value|. On failure the state of |authority_key_identifier| is | 
 | // not guaranteed. | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseAuthorityKeyIdentifier( | 
 |     der::Input extension_value, | 
 |     ParsedAuthorityKeyIdentifier *authority_key_identifier); | 
 |  | 
 | // Parses the value of a subjectKeyIdentifier extension. Returns true on | 
 | // success and |subject_key_identifier| references data in |extension_value|. | 
 | // On failure the state of |subject_key_identifier| is not guaranteed. | 
 | [[nodiscard]] OPENSSL_EXPORT bool ParseSubjectKeyIdentifier( | 
 |     der::Input extension_value, der::Input *subject_key_identifier); | 
 |  | 
 | BSSL_NAMESPACE_END | 
 |  | 
 | #endif  // BSSL_PKI_PARSE_CERTIFICATE_H_ |