chromium/chrome/common/net/x509_certificate_model.cc

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/net/x509_certificate_model.h"

#include <string_view>

#include "base/check.h"
#include "base/containers/adapters.h"
#include "base/containers/fixed_flat_map.h"
#include "base/i18n/number_formatting.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/grit/generated_resources.h"
#include "components/strings/grit/components_strings.h"
#include "components/url_formatter/url_formatter.h"
#include "crypto/sha2.h"
#include "net/base/ip_address.h"
#include "net/cert/ct_objects_extractor.h"
#include "net/cert/time_conversions.h"
#include "net/cert/x509_util.h"
#include "third_party/boringssl/src/include/openssl/bn.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/mem.h"
#include "third_party/boringssl/src/include/openssl/rsa.h"
#include "third_party/boringssl/src/pki/cert_errors.h"
#include "third_party/boringssl/src/pki/certificate_policies.h"
#include "third_party/boringssl/src/pki/extended_key_usage.h"
#include "third_party/boringssl/src/pki/input.h"
#include "third_party/boringssl/src/pki/parse_certificate.h"
#include "third_party/boringssl/src/pki/parse_name.h"
#include "third_party/boringssl/src/pki/parse_values.h"
#include "third_party/boringssl/src/pki/parser.h"
#include "third_party/boringssl/src/pki/signature_algorithm.h"
#include "third_party/boringssl/src/pki/verify_signed_data.h"
#include "ui/base/l10n/l10n_util.h"

namespace x509_certificate_model {

namespace {

// 2.5.4.46 NAME 'dnQualifier'
constexpr uint8_t kTypeDnQualifierOid[] =;
// 2.5.4.15 NAME 'businessCategory'
constexpr uint8_t kTypeBusinessCategory[] =;
// 2.5.4.17 NAME 'postalCode'
constexpr uint8_t kTypePostalCode[] =;

// TODO(mattm): we can probably just remove these RFC 1274 OIDs.
//
// ccitt is {0} but not explicitly defined in the RFC 1274.
// RFC 1274:
// data OBJECT IDENTIFIER ::= {ccitt 9}
// pss OBJECT IDENTIFIER ::= {data 2342}
// ucl OBJECT IDENTIFIER ::= {pss 19200300}
// pilot OBJECT IDENTIFIER ::= {ucl 100}
// pilotAttributeType OBJECT IDENTIFIER ::= {pilot 1}
// userid ::= {pilotAttributeType 1}
constexpr uint8_t kRFC1274UidOid[] =;
// rfc822Mailbox :: = {pilotAttributeType 3}
constexpr uint8_t kRFC1274MailOid[] =;

// jurisdictionLocalityName (OID: 1.3.6.1.4.1.311.60.2.1.1)
constexpr uint8_t kEVJurisdictionLocalityName[] =;
// jurisdictionStateOrProvinceName (OID: 1.3.6.1.4.1.311.60.2.1.2)
constexpr uint8_t kEVJurisdictionStateOrProvinceName[] =;
// jurisdictionCountryName (OID: 1.3.6.1.4.1.311.60.2.1.3)
constexpr uint8_t kEVJurisdictionCountryName[] =;

// From RFC 5280:
//     id-ce-issuerAltName OBJECT IDENTIFIER ::=  { id-ce 18 }
// In dotted notation: 2.5.29.18
constexpr uint8_t kIssuerAltNameOid[] =;
// From RFC 5280:
//     id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::=  { id-ce 9 }
// In dotted notation: 2.5.29.9
constexpr uint8_t kSubjectDirectoryAttributesOid[] =;

// From RFC 3447:
// pkcs-1    OBJECT IDENTIFIER ::= {
//     iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1
// }
// rsaEncryption    OBJECT IDENTIFIER ::= { pkcs-1 1 }
constexpr uint8_t kPkcs1RsaEncryption[] =;
// md2WithRSAEncryption       OBJECT IDENTIFIER ::= { pkcs-1 2 }
constexpr uint8_t kPkcs1Md2WithRsaEncryption[] =;
// From RFC 2314: md4WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 3 }
constexpr uint8_t kPkcs1Md4WithRsaEncryption[] =;
// md5WithRSAEncryption       OBJECT IDENTIFIER ::= { pkcs-1 4 }
constexpr uint8_t kPkcs1Md5WithRsaEncryption[] =;
// sha1WithRSAEncryption      OBJECT IDENTIFIER ::= { pkcs-1 5 }
constexpr uint8_t kPkcs1Sha1WithRsaEncryption[] =;
// sha256WithRSAEncryption    OBJECT IDENTIFIER ::= { pkcs-1 11 }
constexpr uint8_t kPkcs1Sha256WithRsaEncryption[] =;
// sha384WithRSAEncryption    OBJECT IDENTIFIER ::= { pkcs-1 12 }
constexpr uint8_t kPkcs1Sha384WithRsaEncryption[] =;
// sha512WithRSAEncryption    OBJECT IDENTIFIER ::= { pkcs-1 13 }
constexpr uint8_t kPkcs1Sha512WithRsaEncryption[] =;
// From RFC 3279:
//   ansi-X9-62  OBJECT IDENTIFIER ::= {
//            iso(1) member-body(2) us(840) 10045 }
//   id-ecSigType OBJECT IDENTIFIER  ::=  {
//        ansi-X9-62 signatures(4) }
//   ecdsa-with-SHA1  OBJECT IDENTIFIER ::= {
//        id-ecSigType 1 }
constexpr uint8_t kAnsiX962EcdsaWithSha1[] =;
// From RFC 5758:
//    ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
//            us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
constexpr uint8_t kAnsiX962EcdsaWithSha256[] =;
//    ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
//            us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
constexpr uint8_t kAnsiX962EcdsaWithSha384[] =;
//    ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
//            us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
constexpr uint8_t kAnsiX962EcdsaWithSha512[] =;
// From RFC 3279:
//    ansi-X9-62 OBJECT IDENTIFIER ::=
//                            { iso(1) member-body(2) us(840) 10045 }
//    id-public-key-type OBJECT IDENTIFIER  ::= { ansi-X9.62 2 }
//    id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 }
constexpr uint8_t kAnsiX962EcPublicKey[] =;
// From RFC 5480:
//     secp256r1 OBJECT IDENTIFIER ::= {
//       iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
//       prime(1) 7 }
constexpr uint8_t kSecgEcSecp256r1[] =;
//     secp384r1 OBJECT IDENTIFIER ::= {
//       iso(1) identified-organization(3) certicom(132) curve(0) 34 }
constexpr uint8_t kSecgEcSecp384r1[] =;
//     secp521r1 OBJECT IDENTIFIER ::= {
//       iso(1) identified-organization(3) certicom(132) curve(0) 35 }
constexpr uint8_t kSecgEcSecp512r1[] =;

// Old Netscape OIDs. Do we still need all these?
// #define NETSCAPE_OID 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42
// #define NETSCAPE_CERT_EXT NETSCAPE_OID, 0x01
//
// CONST_OID nsExtCertType[] = { NETSCAPE_CERT_EXT, 0x01 };
constexpr uint8_t kNetscapeCertificateTypeOid[] =;

// CONST_OID nsExtBaseURL[] = { NETSCAPE_CERT_EXT, 0x02 };
constexpr uint8_t kNetscapeBaseURLOid[] =;

// CONST_OID nsExtRevocationURL[] = { NETSCAPE_CERT_EXT, 0x03 };
constexpr uint8_t kNetscapeRevocationURLOid[] =;

// CONST_OID nsExtCARevocationURL[] = { NETSCAPE_CERT_EXT, 0x04 };
constexpr uint8_t kNetscapeCARevocationURLOid[] =;

// CONST_OID nsExtCACertURL[] = { NETSCAPE_CERT_EXT, 0x06 };
constexpr uint8_t kNetscapeCACertURLOid[] =;

// CONST_OID nsExtCertRenewalURL[] = { NETSCAPE_CERT_EXT, 0x07 };
constexpr uint8_t kNetscapeRenewalURLOid[] =;

// CONST_OID nsExtCAPolicyURL[] = { NETSCAPE_CERT_EXT, 0x08 };
constexpr uint8_t kNetscapeCAPolicyURLOid[] =;

// CONST_OID nsExtSSLServerName[] = { NETSCAPE_CERT_EXT, 0x0c };
constexpr uint8_t kNetscapeSSLServerNameOid[] =;

// CONST_OID nsExtComment[] = { NETSCAPE_CERT_EXT, 0x0d };
constexpr uint8_t kNetscapeCommentOid[] =;

// CONST_OID nsExtLostPasswordURL[] = { NETSCAPE_CERT_EXT, 0x0e };
constexpr uint8_t kNetscapeLostPasswordURLOid[] =;

// CONST_OID nsExtCertRenewalTime[] = { NETSCAPE_CERT_EXT, 0x0f };
constexpr uint8_t kNetscapeRenewalTimeOid[] =;

constexpr uint8_t kNetscapeServerGatedCrypto[] =;

// Microsoft OIDs. Do we still need all these?
//
// 1.3.6.1.4.1.311.20.2
constexpr uint8_t kMsCertExtCerttype[] =;

// 1.3.6.1.4.1.311.21.1
constexpr uint8_t kMsCertsrvCaVersion[] =;

// 1.3.6.1.4.1.311.20.2.3
constexpr uint8_t kMsNtPrincipalName[] =;

// 1.3.6.1.4.1.311.25.1
constexpr uint8_t kMsNtdsReplication[] =;

// 1.3.6.1.4.1.311.21.7
constexpr uint8_t kMsCertTemplate[] =;

// 1.3.6.1.4.1.311.2.1.21
constexpr uint8_t kEkuMsIndividualCodeSigning[] =;

// 1.3.6.1.4.1.311.2.1.22
constexpr uint8_t kEkuMsCommercialCodeSigning[] =;

// 1.3.6.1.4.1.311.10.3.1
constexpr uint8_t kEkuMsTrustListSigning[] =;

// 1.3.6.1.4.1.311.10.3.2
constexpr uint8_t kEkuMsTimeStamping[] =;

// 1.3.6.1.4.1.311.10.3.3
constexpr uint8_t kEkuMsServerGatedCrypto[] =;

// 1.3.6.1.4.1.311.10.3.4
constexpr uint8_t kEkuMsEncryptingFileSystem[] =;

// 1.3.6.1.4.1.311.10.3.4.1
constexpr uint8_t kEkuMsFileRecovery[] =;

// 1.3.6.1.4.1.311.10.3.5
constexpr uint8_t kEkuMsWindowsHardwareDriverVerification[] =;

// 1.3.6.1.4.1.311.10.3.10
constexpr uint8_t kEkuMsQualifiedSubordination[] =;

// 1.3.6.1.4.1.311.10.3.11
constexpr uint8_t kEkuMsKeyRecovery[] =;

// 1.3.6.1.4.1.311.10.3.12
constexpr uint8_t kEkuMsDocumentSigning[] =;

// 1.3.6.1.4.1.311.10.3.13
constexpr uint8_t kEkuMsLifetimeSigning[] =;

// 1.3.6.1.4.1.311.20.2.2
constexpr uint8_t kEkuMsSmartCardLogon[] =;

// 1.3.6.1.4.1.311.21.6
constexpr uint8_t kEkuMsKeyRecoveryAgent[] =;

// The certificate viewer may be used to view client certificates, so use the
// relaxed parsing mode. See crbug.com/770323 and crbug.com/788655.
constexpr auto kNameStringHandling =;

std::string ProcessRawBytesWithSeparators(base::span<const unsigned char> data,
                                          char hex_separator,
                                          char line_separator) {}

std::string ProcessRawBytes(base::span<const uint8_t> data) {}

OptionalStringOrError FindAttributeOfType(
    bssl::der::Input oid,
    const bssl::RelativeDistinguishedName& rdn) {}

// Returns the value of the most general name of |oid| type.
// Distinguished Names are specified in least to most specific.
OptionalStringOrError FindFirstNameOfType(bssl::der::Input oid,
                                          const bssl::RDNSequence& rdns) {}

// Returns the value of the most specific name of |oid| type.
// Distinguished Names are specified in least to most specific.
OptionalStringOrError FindLastNameOfType(bssl::der::Input oid,
                                         const bssl::RDNSequence& rdns) {}

// Returns a string containing the dotted numeric form of |oid| prefixed by
// "OID.", or an empty string on error.
std::string OidToNumericString(bssl::der::Input oid) {}

constexpr auto kOidStringMap =;

std::optional<std::string> GetOidText(bssl::der::Input oid) {}

std::string GetOidTextOrNumeric(bssl::der::Input oid) {}

std::string ProcessRDN(const bssl::RelativeDistinguishedName& rdn) {}

// Note: This was called ProcessName in the x509_certificate_model_nss impl.
OptionalStringOrError RDNSequenceToStringMultiLine(
    const bssl::RDNSequence& rdns) {}

std::optional<std::string> ProcessIA5String(bssl::der::Input extension_data) {}

// Returns a comma-separated string of the strings in |string_map| for the bits
// in |bitfield| that are set.
// string_map may contain -1 for reserved positions that should not be set.
std::optional<std::string> ProcessBitField(bssl::der::BitString bitfield,
                                           base::span<const int> string_map,
                                           char separator) {}

// Returns nullopt on error, or empty string if no bits were set.
std::optional<std::string> ProcessBitStringValue(
    bssl::der::Input value,
    base::span<const int> string_map,
    char separator) {}

std::optional<std::string> ProcessBitStringExtension(
    bssl::der::Input extension_data,
    base::span<const int> string_map,
    char separator) {}

std::optional<std::string> ProcessNSCertTypeExtension(
    bssl::der::Input extension_data) {}

std::optional<std::string> ProcessKeyUsageExtension(
    bssl::der::Input extension_data) {}

std::optional<std::string> ProcessBasicConstraints(
    bssl::der::Input extension_data) {}

std::optional<std::string> ProcessExtKeyUsage(bssl::der::Input extension_data) {}

OptionalStringOrError ProcessNameValue(bssl::der::Input name_value) {}

std::string FormatGeneralName(std::u16string key, std::string_view value) {}

std::string FormatGeneralName(int key_string_id, std::string_view value) {}

bool ParseOtherName(bssl::der::Input other_name,
                    bssl::der::Input* type,
                    bssl::der::Input* value) {}

std::optional<std::string> ProcessGeneralNames(
    const bssl::GeneralNames& names) {}

std::optional<std::string> ProcessGeneralNamesTlv(
    bssl::der::Input extension_data) {}

std::optional<std::string> ProcessGeneralNamesValue(
    bssl::der::Input general_names_value) {}

std::optional<std::string> ProcessSubjectKeyId(
    bssl::der::Input extension_data) {}

std::optional<std::string> ProcessAuthorityKeyId(
    bssl::der::Input extension_data) {}

std::optional<std::string> ProcessUserNoticeDisplayText(
    CBS_ASN1_TAG tag,
    bssl::der::Input value) {}

std::optional<std::string> ProcessUserNotice(bssl::der::Input qualifier) {}

std::optional<std::string> ProcessCertificatePolicies(
    bssl::der::Input extension_data) {}

std::optional<std::string> ProcessCrlDistributionPoints(
    bssl::der::Input extension_data) {}

std::optional<std::string> ProcessAuthorityInfoAccess(
    bssl::der::Input extension_data) {}

std::string ProcessAlgorithmIdentifier(bssl::der::Input algorithm_tlv) {}

bool ParseSubjectPublicKeyInfo(bssl::der::Input spki_tlv,
                               bssl::der::Input* algorithm_tlv,
                               bssl::der::Input* subject_public_key_value) {}

std::vector<uint8_t> BIGNUMBytes(const BIGNUM* bn) {}

}  // namespace

X509CertificateModel::X509CertificateModel(
    bssl::UniquePtr<CRYPTO_BUFFER> cert_data,
    std::string nickname)
    :{}

X509CertificateModel::X509CertificateModel(X509CertificateModel&& other) =
    default;

X509CertificateModel::~X509CertificateModel() = default;

std::string X509CertificateModel::HashCertSHA256() const {}

std::string X509CertificateModel::GetTitle() const {}

std::string X509CertificateModel::GetVersion() const {}

std::string X509CertificateModel::GetSerialNumberHexified() const {}

bool X509CertificateModel::GetTimes(base::Time* not_before,
                                    base::Time* not_after) const {}

OptionalStringOrError X509CertificateModel::GetIssuerCommonName() const {}

OptionalStringOrError X509CertificateModel::GetIssuerOrgName() const {}

OptionalStringOrError X509CertificateModel::GetIssuerOrgUnitName() const {}

OptionalStringOrError X509CertificateModel::GetSubjectCommonName() const {}

OptionalStringOrError X509CertificateModel::GetSubjectOrgName() const {}

OptionalStringOrError X509CertificateModel::GetSubjectOrgUnitName() const {}

OptionalStringOrError X509CertificateModel::GetIssuerName() const {}

OptionalStringOrError X509CertificateModel::GetSubjectName() const {}

std::vector<Extension> X509CertificateModel::GetExtensions(
    std::string_view critical_label,
    std::string_view non_critical_label) const {}

bool X509CertificateModel::ParseExtensions(
    const bssl::der::Input& extensions_tlv) {}

std::string X509CertificateModel::ProcessExtension(
    std::string_view critical_label,
    std::string_view non_critical_label,
    const bssl::ParsedExtension& extension) const {}

std::optional<std::string> X509CertificateModel::ProcessExtensionData(
    const bssl::ParsedExtension& extension) const {}

std::string X509CertificateModel::ProcessSecAlgorithmSignature() const {}

std::string X509CertificateModel::ProcessSecAlgorithmSubjectPublicKey() const {}

std::string X509CertificateModel::ProcessSecAlgorithmSignatureWrap() const {}

std::string X509CertificateModel::ProcessSubjectPublicKeyInfo() const {}

std::string X509CertificateModel::HashSpkiSHA256() const {}

std::string X509CertificateModel::ProcessRawBitsSignatureWrap() const {}

// TODO(crbug.com/41453265): move to anonymous namespace once
// x509_certificate_model_nss is removed.
std::string ProcessIDN(const std::string& input) {}

std::string ProcessRawSubjectPublicKeyInfo(base::span<const uint8_t> spki_der) {}

}  // namespace x509_certificate_model