summaryrefslogtreecommitdiff
path: root/chromium/net/cert
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-01-25 11:39:07 +0100
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2016-01-25 15:20:42 +0000
commit6c91641271e536ffaa88a1dff5127e42ee99a91e (patch)
tree703d9dd49602377ddc90cbf886aad37913f2496b /chromium/net/cert
parentb145b7fafd36f0c260d6a768c81fc14e32578099 (diff)
downloadqtwebengine-chromium-6c91641271e536ffaa88a1dff5127e42ee99a91e.tar.gz
BASELINE: Update Chromium to 49.0.2623.23
Also adds missing printing sources. Change-Id: I3726b8f0c7d6751c9fc846096c571fadca7108cd Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/net/cert')
-rw-r--r--chromium/net/cert/asn1_util.cc285
-rw-r--r--chromium/net/cert/asn1_util.h44
-rw-r--r--chromium/net/cert/cert_database_nss.cc33
-rw-r--r--chromium/net/cert/cert_net_fetcher.h3
-rw-r--r--chromium/net/cert/cert_verifier.cc3
-rw-r--r--chromium/net/cert/cert_verify_proc.cc102
-rw-r--r--chromium/net/cert/cert_verify_proc.h1
-rw-r--r--chromium/net/cert/cert_verify_proc_android.cc2
-rw-r--r--chromium/net/cert/cert_verify_proc_mac.cc79
-rw-r--r--chromium/net/cert/cert_verify_proc_nss.cc5
-rw-r--r--chromium/net/cert/cert_verify_proc_openssl.cc2
-rw-r--r--chromium/net/cert/cert_verify_proc_unittest.cc163
-rw-r--r--chromium/net/cert/cert_verify_proc_whitelist.cc492
-rw-r--r--chromium/net/cert/cert_verify_proc_whitelist.h1
-rw-r--r--chromium/net/cert/cert_verify_proc_win.cc12
-rw-r--r--chromium/net/cert/cert_verify_result.cc1
-rw-r--r--chromium/net/cert/cert_verify_result.h1
-rw-r--r--chromium/net/cert/crl_set.h3
-rw-r--r--chromium/net/cert/ct_known_logs.cc43
-rw-r--r--chromium/net/cert/ct_known_logs.h8
-rw-r--r--chromium/net/cert/ct_known_logs_static.h13
-rw-r--r--chromium/net/cert/ct_log_response_parser.cc52
-rw-r--r--chromium/net/cert/ct_log_response_parser.h7
-rw-r--r--chromium/net/cert/ct_log_response_parser_unittest.cc51
-rw-r--r--chromium/net/cert/ct_log_verifier.cc141
-rw-r--r--chromium/net/cert/ct_log_verifier.h34
-rw-r--r--chromium/net/cert/ct_log_verifier_nss.cc2
-rw-r--r--chromium/net/cert/ct_log_verifier_openssl.cc2
-rw-r--r--chromium/net/cert/ct_log_verifier_unittest.cc427
-rw-r--r--chromium/net/cert/ct_log_verifier_util.cc36
-rw-r--r--chromium/net/cert/ct_log_verifier_util.h30
-rw-r--r--chromium/net/cert/ct_objects_extractor_nss.cc14
-rw-r--r--chromium/net/cert/ct_objects_extractor_unittest.cc4
-rw-r--r--chromium/net/cert/ct_policy_enforcer.cc (renamed from chromium/net/cert/cert_policy_enforcer.cc)65
-rw-r--r--chromium/net/cert/ct_policy_enforcer.h (renamed from chromium/net/cert/cert_policy_enforcer.h)12
-rw-r--r--chromium/net/cert/ct_policy_enforcer_unittest.cc (renamed from chromium/net/cert/cert_policy_enforcer_unittest.cc)106
-rw-r--r--chromium/net/cert/ct_serialization.cc4
-rw-r--r--chromium/net/cert/ct_serialization_unittest.cc2
-rw-r--r--chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc5
-rw-r--r--chromium/net/cert/ct_verifier.h3
-rw-r--r--chromium/net/cert/ev_root_ca_metadata.cc5
-rw-r--r--chromium/net/cert/ev_root_ca_metadata.h1
-rw-r--r--chromium/net/cert/internal/certificate_policies.cc178
-rw-r--r--chromium/net/cert/internal/certificate_policies.h36
-rw-r--r--chromium/net/cert/internal/certificate_policies_unittest.cc150
-rw-r--r--chromium/net/cert/internal/name_constraints.cc569
-rw-r--r--chromium/net/cert/internal/name_constraints.h138
-rw-r--r--chromium/net/cert/internal/name_constraints_unittest.cc1276
-rw-r--r--chromium/net/cert/internal/parse_certificate.cc247
-rw-r--r--chromium/net/cert/internal/parse_certificate.h156
-rw-r--r--chromium/net/cert/internal/parse_certificate_unittest.cc493
-rw-r--r--chromium/net/cert/internal/signature_algorithm.cc37
-rw-r--r--chromium/net/cert/internal/signature_algorithm.h8
-rw-r--r--chromium/net/cert/internal/signature_algorithm_unittest.cc100
-rw-r--r--chromium/net/cert/internal/signature_policy.h2
-rw-r--r--chromium/net/cert/internal/test_helpers.cc16
-rw-r--r--chromium/net/cert/internal/test_helpers.h12
-rw-r--r--chromium/net/cert/internal/verify_certificate_chain.cc549
-rw-r--r--chromium/net/cert/internal/verify_certificate_chain.h86
-rw-r--r--chromium/net/cert/internal/verify_certificate_chain_unittest.cc246
-rw-r--r--chromium/net/cert/internal/verify_name_match.cc73
-rw-r--r--chromium/net/cert/internal/verify_name_match.h20
-rw-r--r--chromium/net/cert/internal/verify_name_match_unittest.cc100
-rw-r--r--chromium/net/cert/internal/verify_signed_data_unittest.cc13
-rw-r--r--chromium/net/cert/jwk_serializer_nss.cc6
-rw-r--r--chromium/net/cert/jwk_serializer_openssl.cc8
-rw-r--r--chromium/net/cert/jwk_serializer_unittest.cc33
-rw-r--r--chromium/net/cert/merkle_consistency_proof.cc27
-rw-r--r--chromium/net/cert/merkle_consistency_proof.h45
-rw-r--r--chromium/net/cert/multi_log_ct_verifier.cc2
-rw-r--r--chromium/net/cert/multi_log_ct_verifier.h10
-rw-r--r--chromium/net/cert/multi_log_ct_verifier_unittest.cc4
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.cc41
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.h6
-rw-r--r--chromium/net/cert/nss_cert_database.cc18
-rw-r--r--chromium/net/cert/nss_cert_database.h6
-rw-r--r--chromium/net/cert/nss_cert_database_chromeos.cc8
-rw-r--r--chromium/net/cert/nss_cert_database_chromeos.h1
-rw-r--r--chromium/net/cert/nss_profile_filter_chromeos.cc8
-rw-r--r--chromium/net/cert/nss_profile_filter_chromeos_unittest.cc6
-rw-r--r--chromium/net/cert/pem_tokenizer.h3
-rw-r--r--chromium/net/cert/signed_certificate_timestamp.h1
-rw-r--r--chromium/net/cert/signed_tree_head.h2
-rw-r--r--chromium/net/cert/test_root_certs.h1
-rw-r--r--chromium/net/cert/test_root_certs_nss.cc1
-rw-r--r--chromium/net/cert/test_root_certs_win.cc6
-rw-r--r--chromium/net/cert/x509_cert_types.h1
-rw-r--r--chromium/net/cert/x509_certificate.cc8
-rw-r--r--chromium/net/cert/x509_certificate.h19
-rw-r--r--chromium/net/cert/x509_certificate_ios.cc16
-rw-r--r--chromium/net/cert/x509_certificate_known_roots_mac.h560
-rw-r--r--chromium/net/cert/x509_certificate_known_roots_win.h2701
-rw-r--r--chromium/net/cert/x509_certificate_mac.cc11
-rw-r--r--chromium/net/cert/x509_certificate_net_log_param.cc5
-rw-r--r--chromium/net/cert/x509_certificate_nss.cc20
-rw-r--r--chromium/net/cert/x509_certificate_openssl.cc18
-rw-r--r--chromium/net/cert/x509_certificate_unittest.cc2
-rw-r--r--chromium/net/cert/x509_certificate_win.cc22
-rw-r--r--chromium/net/cert/x509_util.h9
-rw-r--r--chromium/net/cert/x509_util_android.cc12
-rw-r--r--chromium/net/cert/x509_util_nss.cc13
-rw-r--r--chromium/net/cert/x509_util_nss.h4
-rw-r--r--chromium/net/cert/x509_util_nss_certs.cc10
-rw-r--r--chromium/net/cert/x509_util_openssl.cc35
-rw-r--r--chromium/net/cert/x509_util_openssl_unittest.cc41
105 files changed, 7865 insertions, 2689 deletions
diff --git a/chromium/net/cert/asn1_util.cc b/chromium/net/cert/asn1_util.cc
index 4bc37a67757..315ca75e648 100644
--- a/chromium/net/cert/asn1_util.cc
+++ b/chromium/net/cert/asn1_util.cc
@@ -4,98 +4,20 @@
#include "net/cert/asn1_util.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
+
namespace net {
namespace asn1 {
-bool ParseElement(base::StringPiece* in,
- unsigned tag_value,
- base::StringPiece* out,
- unsigned *out_header_len) {
- const uint8_t* data = reinterpret_cast<const uint8_t*>(in->data());
-
- // We don't support kAny and kOptional at the same time.
- if ((tag_value & kAny) && (tag_value & kOptional))
- return false;
-
- if (in->empty() && (tag_value & kOptional)) {
- if (out_header_len)
- *out_header_len = 0;
- if (out)
- *out = base::StringPiece();
- return true;
- }
-
- if (in->size() < 2)
- return false;
-
- if (tag_value != kAny &&
- static_cast<unsigned char>(data[0]) != (tag_value & 0xff)) {
- if (tag_value & kOptional) {
- if (out_header_len)
- *out_header_len = 0;
- if (out)
- *out = base::StringPiece();
- return true;
- }
- return false;
- }
-
- size_t len = 0;
- if ((data[1] & 0x80) == 0) {
- // short form length
- if (out_header_len)
- *out_header_len = 2;
- len = static_cast<size_t>(data[1]) + 2;
- } else {
- // long form length
- const unsigned num_bytes = data[1] & 0x7f;
- if (num_bytes == 0 || num_bytes > 2)
- return false;
- if (in->size() < 2 + num_bytes)
- return false;
- len = data[2];
- if (num_bytes == 2) {
- if (len == 0) {
- // the length encoding must be minimal.
- return false;
- }
- len <<= 8;
- len += data[3];
- }
- if (len < 128) {
- // the length should have been encoded in short form. This distinguishes
- // DER from BER encoding.
- return false;
- }
- if (out_header_len)
- *out_header_len = 2 + num_bytes;
- len += 2 + num_bytes;
- }
-
- if (in->size() < len)
- return false;
- if (out)
- *out = base::StringPiece(in->data(), len);
- in->remove_prefix(len);
- return true;
-}
+namespace {
-bool GetElement(base::StringPiece* in,
- unsigned tag_value,
- base::StringPiece* out) {
- unsigned header_len;
- if (!ParseElement(in, tag_value, out, &header_len))
- return false;
- if (out)
- out->remove_prefix(header_len);
- return true;
-}
-
-// SeekToSPKI changes |cert| so that it points to a suffix of the
-// TBSCertificate where the suffix begins at the start of the ASN.1
-// SubjectPublicKeyInfo value.
-static bool SeekToSPKI(base::StringPiece* cert) {
+// Parses input |in| which should point to the beginning of a Certificate, and
+// sets |*tbs_certificate| ready to parse the SubjectPublicKeyInfo. If parsing
+// fails, this function returns false and |*tbs_certificate| is left in an
+// undefined state.
+bool SeekToSPKI(der::Input in, der::Parser* tbs_certificate) {
// From RFC 5280, section 4.1
// Certificate ::= SEQUENCE {
// tbsCertificate TBSCertificate,
@@ -110,50 +32,55 @@ static bool SeekToSPKI(base::StringPiece* cert) {
// validity Validity,
// subject Name,
// subjectPublicKeyInfo SubjectPublicKeyInfo,
+ // ... }
- base::StringPiece certificate;
- if (!GetElement(cert, kSEQUENCE, &certificate))
+ der::Parser parser(in);
+ der::Parser certificate;
+ if (!parser.ReadSequence(&certificate))
return false;
// We don't allow junk after the certificate.
- if (!cert->empty())
+ if (parser.HasMore())
return false;
- base::StringPiece tbs_certificate;
- if (!GetElement(&certificate, kSEQUENCE, &tbs_certificate))
+ if (!certificate.ReadSequence(tbs_certificate))
return false;
- if (!GetElement(&tbs_certificate,
- kOptional | kConstructed | kContextSpecific | 0,
- NULL)) {
+ bool unused;
+ if (!tbs_certificate->SkipOptionalTag(
+ der::kTagConstructed | der::kTagContextSpecific | 0, &unused)) {
return false;
}
// serialNumber
- if (!GetElement(&tbs_certificate, kINTEGER, NULL))
+ if (!tbs_certificate->SkipTag(der::kInteger))
return false;
// signature
- if (!GetElement(&tbs_certificate, kSEQUENCE, NULL))
+ if (!tbs_certificate->SkipTag(der::kSequence))
return false;
// issuer
- if (!GetElement(&tbs_certificate, kSEQUENCE, NULL))
+ if (!tbs_certificate->SkipTag(der::kSequence))
return false;
// validity
- if (!GetElement(&tbs_certificate, kSEQUENCE, NULL))
+ if (!tbs_certificate->SkipTag(der::kSequence))
return false;
// subject
- if (!GetElement(&tbs_certificate, kSEQUENCE, NULL))
+ if (!tbs_certificate->SkipTag(der::kSequence))
return false;
- *cert = tbs_certificate;
return true;
}
+} // namespace
+
bool ExtractSPKIFromDERCert(base::StringPiece cert,
base::StringPiece* spki_out) {
- if (!SeekToSPKI(&cert))
+ der::Parser parser;
+ if (!SeekToSPKI(der::Input(cert), &parser))
return false;
- if (!ParseElement(&cert, kSEQUENCE, spki_out, NULL))
+ der::Input spki;
+ if (!parser.ReadRawTLV(&spki))
return false;
+ *spki_out = spki.AsStringPiece();
return true;
}
@@ -169,18 +96,20 @@ bool ExtractSubjectPublicKeyFromSPKI(base::StringPiece spki,
// parameters ANY DEFINED BY algorithm OPTIONAL }
// Step into SubjectPublicKeyInfo sequence.
- base::StringPiece spki_contents;
- if (!asn1::GetElement(&spki, asn1::kSEQUENCE, &spki_contents))
+ der::Parser parser((der::Input(spki)));
+ der::Parser spki_parser;
+ if (!parser.ReadSequence(&spki_parser))
return false;
// Step over algorithm field (a SEQUENCE).
- base::StringPiece algorithm;
- if (!asn1::GetElement(&spki_contents, asn1::kSEQUENCE, &algorithm))
+ if (!spki_parser.SkipTag(der::kSequence))
return false;
// Extract the subjectPublicKey field.
- if (!asn1::GetElement(&spki_contents, asn1::kBITSTRING, spk_out))
+ der::Input spk;
+ if (!spki_parser.ReadTag(der::kBitString, &spk))
return false;
+ *spk_out = spk.AsStringPiece();
return true;
}
@@ -190,7 +119,9 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert,
urls_out->clear();
std::vector<base::StringPiece> tmp_urls_out;
- if (!SeekToSPKI(&cert))
+ bool present;
+ der::Parser tbs_cert_parser;
+ if (!SeekToSPKI(der::Input(cert), &tbs_cert_parser))
return false;
// From RFC 5280, section 4.1
@@ -199,63 +130,71 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert,
// subjectPublicKeyInfo SubjectPublicKeyInfo,
// issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
// subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
- // extensions [3] EXPLICIT Extensions OPTIONAL
+ // extensions [3] EXPLICIT Extensions OPTIONAL }
// subjectPublicKeyInfo
- if (!GetElement(&cert, kSEQUENCE, NULL))
+ if (!tbs_cert_parser.SkipTag(der::kSequence))
return false;
// issuerUniqueID
- if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 1, NULL))
+ if (!tbs_cert_parser.SkipOptionalTag(
+ der::kTagConstructed | der::kTagContextSpecific | 1, &present)) {
return false;
+ }
// subjectUniqueID
- if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 2, NULL))
+ if (!tbs_cert_parser.SkipOptionalTag(
+ der::kTagConstructed | der::kTagContextSpecific | 2, &present)) {
return false;
+ }
- base::StringPiece extensions_seq;
- if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 3,
- &extensions_seq)) {
+ der::Input extensions;
+ if (!tbs_cert_parser.ReadOptionalTag(
+ der::kTagConstructed | der::kTagContextSpecific | 3, &extensions,
+ &present)) {
return false;
}
- if (extensions_seq.empty())
+ if (!present)
return true;
// Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
// Extension ::= SEQUENCE {
// extnID OBJECT IDENTIFIER,
// critical BOOLEAN DEFAULT FALSE,
- // extnValue OCTET STRING
+ // extnValue OCTET STRING }
- // |extensions_seq| was EXPLICITly tagged, so we still need to remove the
+ // |extensions| was EXPLICITly tagged, so we still need to remove the
// ASN.1 SEQUENCE header.
- base::StringPiece extensions;
- if (!GetElement(&extensions_seq, kSEQUENCE, &extensions))
+ der::Parser explicit_extensions_parser(extensions);
+ der::Parser extensions_parser;
+ if (!explicit_extensions_parser.ReadSequence(&extensions_parser))
return false;
- while (extensions.size() > 0) {
- base::StringPiece extension;
- if (!GetElement(&extensions, kSEQUENCE, &extension))
+ if (explicit_extensions_parser.HasMore())
+ return false;
+
+ while (extensions_parser.HasMore()) {
+ der::Parser extension_parser;
+ if (!extensions_parser.ReadSequence(&extension_parser))
return false;
- base::StringPiece oid;
- if (!GetElement(&extension, kOID, &oid))
+ der::Input oid;
+ if (!extension_parser.ReadTag(der::kOid, &oid))
return false;
// kCRLDistributionPointsOID is the DER encoding of the OID for the X.509
// CRL Distribution Points extension.
static const uint8_t kCRLDistributionPointsOID[] = {0x55, 0x1d, 0x1f};
- if (oid.size() != sizeof(kCRLDistributionPointsOID) ||
- memcmp(oid.data(), kCRLDistributionPointsOID, oid.size()) != 0) {
+ if (!oid.Equals(der::Input(kCRLDistributionPointsOID)))
continue;
- }
// critical
- GetElement(&extension, kBOOLEAN, NULL);
+ if (!extension_parser.SkipOptionalTag(der::kBool, &present))
+ return false;
// extnValue
- base::StringPiece extension_value;
- if (!GetElement(&extension, kOCTETSTRING, &extension_value))
+ der::Input extension_value;
+ if (!extension_parser.ReadTag(der::kOctetString, &extension_value))
return false;
// RFC 5280, section 4.2.1.13.
@@ -267,56 +206,80 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert,
// reasons [1] ReasonFlags OPTIONAL,
// cRLIssuer [2] GeneralNames OPTIONAL }
- base::StringPiece distribution_points;
- if (!GetElement(&extension_value, kSEQUENCE, &distribution_points))
+ der::Parser extension_value_parser(extension_value);
+ der::Parser distribution_points_parser;
+ if (!extension_value_parser.ReadSequence(&distribution_points_parser))
+ return false;
+ if (extension_value_parser.HasMore())
return false;
- while (distribution_points.size() > 0) {
- base::StringPiece distrib_point;
- if (!GetElement(&distribution_points, kSEQUENCE, &distrib_point))
+ while (distribution_points_parser.HasMore()) {
+ der::Parser distrib_point_parser;
+ if (!distribution_points_parser.ReadSequence(&distrib_point_parser))
return false;
- base::StringPiece name;
- if (!GetElement(&distrib_point, kContextSpecific | kConstructed | 0,
- &name)) {
- // If it doesn't contain a name then we skip it.
- continue;
+ der::Input name;
+ if (!distrib_point_parser.ReadOptionalTag(
+ der::kTagContextSpecific | der::kTagConstructed | 0, &name,
+ &present)) {
+ return false;
}
-
- if (GetElement(&distrib_point, kContextSpecific | 1, NULL)) {
- // If it contains a subset of reasons then we skip it. We aren't
- // interested in subsets of CRLs and the RFC states that there MUST be
- // a CRL that covers all reasons.
+ // If it doesn't contain a name then we skip it.
+ if (!present)
continue;
- }
- if (GetElement(&distrib_point,
- kContextSpecific | kConstructed | 2, NULL)) {
- // If it contains a alternative issuer, then we skip it.
+ if (!distrib_point_parser.SkipOptionalTag(der::kTagContextSpecific | 1,
+ &present)) {
+ return false;
+ }
+ // If it contains a subset of reasons then we skip it. We aren't
+ // interested in subsets of CRLs and the RFC states that there MUST be
+ // a CRL that covers all reasons.
+ if (present)
continue;
+
+ if (!distrib_point_parser.SkipOptionalTag(
+ der::kTagContextSpecific | der::kTagConstructed | 2, &present)) {
+ return false;
}
+ // If it contains a alternative issuer, then we skip it.
+ if (present)
+ continue;
// DistributionPointName ::= CHOICE {
// fullName [0] GeneralNames,
// nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
- base::StringPiece general_names;
- if (!GetElement(&name,
- kContextSpecific | kConstructed | 0, &general_names)) {
- continue;
+ der::Input general_names;
+ if (!der::Parser(name).ReadOptionalTag(
+ der::kTagContextSpecific | der::kTagConstructed | 0,
+ &general_names, &present)) {
+ return false;
}
+ if (!present)
+ continue;
// GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
// GeneralName ::= CHOICE {
// ...
// uniformResourceIdentifier [6] IA5String,
- // ...
- while (general_names.size() > 0) {
- base::StringPiece url;
- if (GetElement(&general_names, kContextSpecific | 6, &url)) {
- tmp_urls_out.push_back(url);
+ // ... }
+ der::Parser general_names_parser(general_names);
+ while (general_names_parser.HasMore()) {
+ der::Input url;
+ if (!general_names_parser.ReadOptionalTag(der::kTagContextSpecific | 6,
+ &url, &present)) {
+ return false;
+ }
+ if (present) {
+ // This does not validate that |url| is a valid IA5String.
+ tmp_urls_out.push_back(url.AsStringPiece());
} else {
- if (!GetElement(&general_names, kAny, NULL))
+ der::Tag unused_tag;
+ der::Input unused_value;
+ if (!general_names_parser.ReadTagAndValue(&unused_tag,
+ &unused_value)) {
return false;
+ }
}
}
}
diff --git a/chromium/net/cert/asn1_util.h b/chromium/net/cert/asn1_util.h
index fdd765d8ed8..23bc2d2cf90 100644
--- a/chromium/net/cert/asn1_util.h
+++ b/chromium/net/cert/asn1_util.h
@@ -14,50 +14,6 @@ namespace net {
namespace asn1 {
-// These are the DER encodings of the tag byte for ASN.1 objects.
-static const unsigned kBOOLEAN = 0x01;
-static const unsigned kINTEGER = 0x02;
-static const unsigned kBITSTRING = 0x03;
-static const unsigned kOCTETSTRING = 0x04;
-static const unsigned kOID = 0x06;
-static const unsigned kENUMERATED = 0x0A;
-static const unsigned kSEQUENCE = 0x30;
-
-// These are flags that can be ORed with the above tag numbers.
-static const unsigned kContextSpecific = 0x80;
-static const unsigned kConstructed = 0x20;
-
-// kAny matches any tag value;
-static const unsigned kAny = 0x10000;
-// kOptional denotes an optional element.
-static const unsigned kOptional = 0x20000;
-
-// ParseElement parses a DER encoded ASN1 element from |in|, requiring that
-// it have the given |tag_value|. It returns true on success. The following
-// limitations are imposed:
-// 1) tag numbers > 31 are not permitted.
-// 2) lengths > 65535 are not permitted.
-// On successful return:
-// |in| is advanced over the element
-// |out| contains the element, including the tag and length bytes.
-// |out_header_len| contains the length of the tag and length bytes in |out|.
-//
-// If |tag_value & kOptional| is true then *out_header_len can be zero after a
-// true return value if the element was not found.
-bool ParseElement(base::StringPiece* in,
- unsigned tag_value,
- base::StringPiece* out,
- unsigned *out_header_len);
-
-// GetElement performs the same actions as ParseElement, except that the header
-// bytes are not included in the output.
-//
-// If |tag_value & kOptional| is true then this function cannot distinguish
-// between a missing optional element and an empty one.
-NET_EXPORT_PRIVATE bool GetElement(base::StringPiece* in,
- unsigned tag_value,
- base::StringPiece* out);
-
// ExtractSPKIFromDERCert parses the DER encoded certificate in |cert| and
// extracts the bytes of the SubjectPublicKeyInfo. On successful return,
// |spki_out| is set to contain the SPKI, pointing into |cert|.
diff --git a/chromium/net/cert/cert_database_nss.cc b/chromium/net/cert/cert_database_nss.cc
index 49d27f2b07c..1ff8862e20d 100644
--- a/chromium/net/cert/cert_database_nss.cc
+++ b/chromium/net/cert/cert_database_nss.cc
@@ -8,6 +8,8 @@
#include <pk11pub.h>
#include <secmod.h>
+#include <vector>
+
#include "base/logging.h"
#include "base/observer_list_threadsafe.h"
#include "crypto/nss_util.h"
@@ -15,6 +17,10 @@
#include "net/base/net_errors.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util_nss.h"
+#include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h"
+
+// PSM = Mozilla's Personal Security Manager.
+namespace psm = mozilla_security_manager;
namespace net {
@@ -49,30 +55,9 @@ int CertDatabase::CheckUserCert(X509Certificate* cert_obj) {
}
int CertDatabase::AddUserCert(X509Certificate* cert_obj) {
- CERTCertificate* cert = cert_obj->os_cert_handle();
- CK_OBJECT_HANDLE key;
- crypto::ScopedPK11Slot slot(PK11_KeyForCertExists(cert, &key, NULL));
- if (!slot.get())
- return ERR_NO_PRIVATE_KEY_FOR_CERT;
-
- std::string nickname = x509_util::GetUniqueNicknameForSlot(
- cert_obj->GetDefaultNickname(USER_CERT),
- &cert->derSubject,
- slot.get());
-
- SECStatus rv;
- {
- crypto::AutoNSSWriteLock lock;
- rv = PK11_ImportCert(slot.get(), cert, key, nickname.c_str(), PR_FALSE);
- }
-
- if (rv != SECSuccess) {
- LOG(ERROR) << "Couldn't import user certificate. " << PORT_GetError();
- return ERR_ADD_USER_CERT_FAILED;
- }
-
- NotifyObserversOfCertAdded(cert_obj);
- return OK;
+ CertificateList cert_list;
+ cert_list.push_back(cert_obj);
+ return psm::ImportUserCert(cert_list);
}
} // namespace net
diff --git a/chromium/net/cert/cert_net_fetcher.h b/chromium/net/cert/cert_net_fetcher.h
index 2d19e14a27e..afe878e2a03 100644
--- a/chromium/net/cert/cert_net_fetcher.h
+++ b/chromium/net/cert/cert_net_fetcher.h
@@ -5,9 +5,12 @@
#ifndef NET_CERT_CERT_NET_FETCHER_H_
#define NET_CERT_CERT_NET_FETCHER_H_
+#include <stdint.h>
+
#include <vector>
#include "base/callback.h"
+#include "base/macros.h"
#include "net/base/net_errors.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/cert/cert_verifier.cc b/chromium/net/cert/cert_verifier.cc
index 3cd4a78a341..79bd0ef6bec 100644
--- a/chromium/net/cert/cert_verifier.cc
+++ b/chromium/net/cert/cert_verifier.cc
@@ -25,8 +25,7 @@ scoped_ptr<CertVerifier> CertVerifier::CreateDefault() {
return scoped_ptr<CertVerifier>();
#else
return make_scoped_ptr(
- new MultiThreadedCertVerifier(CertVerifyProc::CreateDefault()))
- .Pass();
+ new MultiThreadedCertVerifier(CertVerifyProc::CreateDefault()));
#endif
}
diff --git a/chromium/net/cert/cert_verify_proc.cc b/chromium/net/cert/cert_verify_proc.cc
index bb379ff000c..bdb4b871b4d 100644
--- a/chromium/net/cert/cert_verify_proc.cc
+++ b/chromium/net/cert/cert_verify_proc.cc
@@ -9,6 +9,7 @@
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_macros.h"
#include "base/sha1.h"
+#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "build/build_config.h"
@@ -165,6 +166,18 @@ bool ExaminePublicKeys(const scoped_refptr<X509Certificate>& cert,
return weak_key;
}
+// Beginning with Ballot 118, ratified in the Baseline Requirements v1.2.1,
+// CAs MUST NOT issue SHA-1 certificates beginning on 1 January 2016.
+bool IsPastSHA1DeprecationDate(const X509Certificate& cert) {
+ const base::Time& start = cert.valid_start();
+ if (start.is_max() || start.is_null())
+ return true;
+ // 2016-01-01 00:00:00 UTC.
+ const base::Time kSHA1DeprecationDate =
+ base::Time::FromInternalValue(INT64_C(13096080000000000));
+ return start >= kSHA1DeprecationDate;
+}
+
} // namespace
// static
@@ -262,8 +275,19 @@ int CertVerifyProc::Verify(X509Certificate* cert,
rv = MapCertStatusToNetError(verify_result->cert_status);
}
+ if (verify_result->has_sha1)
+ verify_result->cert_status |= CERT_STATUS_SHA1_SIGNATURE_PRESENT;
+
// Flag certificates using weak signature algorithms.
- if (verify_result->has_md5) {
+ // The CA/Browser Forum Baseline Requirements (beginning with v1.2.1)
+ // prohibits SHA-1 certificates from being issued beginning on
+ // 1 January 2016. Ideally, all of SHA-1 in new certificates would be
+ // disabled on this date, but enterprises need more time to transition.
+ // As the risk is greatest for publicly trusted certificates, prevent
+ // those certificates from being trusted from that date forward.
+ if (verify_result->has_md5 ||
+ (verify_result->has_sha1_leaf && verify_result->is_issued_by_known_root &&
+ IsPastSHA1DeprecationDate(*cert))) {
verify_result->cert_status |= CERT_STATUS_WEAK_SIGNATURE_ALGORITHM;
// Avoid replacing a more serious error, such as an OS/library failure,
// by ensuring that if verification failed, it failed with a certificate
@@ -272,9 +296,6 @@ int CertVerifyProc::Verify(X509Certificate* cert,
rv = MapCertStatusToNetError(verify_result->cert_status);
}
- if (verify_result->has_sha1)
- verify_result->cert_status |= CERT_STATUS_SHA1_SIGNATURE_PRESENT;
-
// Flag certificates from publicly-trusted CAs that are issued to intranet
// hosts. While the CA/Browser Forum Baseline Requirements (v1.1) permit
// these to be issued until 1 November 2015, they represent a real risk for
@@ -537,7 +558,8 @@ static bool CheckNameConstraints(const std::vector<std::string>& dns_names,
if (i->size() <= (1 /* period before domain */ + domain_length))
continue;
- const char* suffix = &dns_name[i->size() - domain_length - 1];
+ std::string suffix =
+ base::ToLowerASCII(&(*i)[i->size() - domain_length - 1]);
if (suffix[0] != '.')
continue;
if (memcmp(&suffix[1], domains[j], domain_length) != 0)
@@ -601,41 +623,41 @@ bool CertVerifyProc::HasNameConstraintsViolation(
};
static const PublicKeyDomainLimitation kLimits[] = {
- // C=FR, ST=France, L=Paris, O=PM/SGDN, OU=DCSSI,
- // CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr
- {
- {0x79, 0x23, 0xd5, 0x8d, 0x0f, 0xe0, 0x3c, 0xe6, 0xab, 0xad,
- 0xae, 0x27, 0x1a, 0x6d, 0x94, 0xf4, 0x14, 0xd1, 0xa8, 0x73},
- kDomainsANSSI,
- },
- // C=IN, O=India PKI, CN=CCA India 2007
- // Expires: July 4th 2015.
- {
- {0xfe, 0xe3, 0x95, 0x21, 0x2d, 0x5f, 0xea, 0xfc, 0x7e, 0xdc,
- 0xcf, 0x88, 0x3f, 0x1e, 0xc0, 0x58, 0x27, 0xd8, 0xb8, 0xe4},
- kDomainsIndiaCCA,
- },
- // C=IN, O=India PKI, CN=CCA India 2011
- // Expires: March 11 2016.
- {
- {0xf1, 0x42, 0xf6, 0xa2, 0x7d, 0x29, 0x3e, 0xa8, 0xf9, 0x64,
- 0x52, 0x56, 0xed, 0x07, 0xa8, 0x63, 0xf2, 0xdb, 0x1c, 0xdf},
- kDomainsIndiaCCA,
- },
- // C=IN, O=India PKI, CN=CCA India 2014
- // Expires: March 5 2024.
- {
- {0x36, 0x8c, 0x4a, 0x1e, 0x2d, 0xb7, 0x81, 0xe8, 0x6b, 0xed,
- 0x5a, 0x0a, 0x42, 0xb8, 0xc5, 0xcf, 0x6d, 0xb3, 0x57, 0xe1},
- kDomainsIndiaCCA,
- },
- // Not a real certificate - just for testing. This is the SPKI hash of
- // the keys used in net/data/ssl/certificates/name_constraint_*.crt.
- {
- {0x61, 0xec, 0x82, 0x8b, 0xdb, 0x5c, 0x78, 0x2a, 0x8f, 0xcc,
- 0x4f, 0x0f, 0x14, 0xbb, 0x85, 0x31, 0x93, 0x9f, 0xf7, 0x3d},
- kDomainsTest,
- },
+ // C=FR, ST=France, L=Paris, O=PM/SGDN, OU=DCSSI,
+ // CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr
+ {
+ {0x79, 0x23, 0xd5, 0x8d, 0x0f, 0xe0, 0x3c, 0xe6, 0xab, 0xad, 0xae,
+ 0x27, 0x1a, 0x6d, 0x94, 0xf4, 0x14, 0xd1, 0xa8, 0x73},
+ kDomainsANSSI,
+ },
+ // C=IN, O=India PKI, CN=CCA India 2007
+ // Expires: July 4th 2015.
+ {
+ {0xfe, 0xe3, 0x95, 0x21, 0x2d, 0x5f, 0xea, 0xfc, 0x7e, 0xdc, 0xcf,
+ 0x88, 0x3f, 0x1e, 0xc0, 0x58, 0x27, 0xd8, 0xb8, 0xe4},
+ kDomainsIndiaCCA,
+ },
+ // C=IN, O=India PKI, CN=CCA India 2011
+ // Expires: March 11 2016.
+ {
+ {0xf1, 0x42, 0xf6, 0xa2, 0x7d, 0x29, 0x3e, 0xa8, 0xf9, 0x64, 0x52,
+ 0x56, 0xed, 0x07, 0xa8, 0x63, 0xf2, 0xdb, 0x1c, 0xdf},
+ kDomainsIndiaCCA,
+ },
+ // C=IN, O=India PKI, CN=CCA India 2014
+ // Expires: March 5 2024.
+ {
+ {0x36, 0x8c, 0x4a, 0x1e, 0x2d, 0xb7, 0x81, 0xe8, 0x6b, 0xed, 0x5a,
+ 0x0a, 0x42, 0xb8, 0xc5, 0xcf, 0x6d, 0xb3, 0x57, 0xe1},
+ kDomainsIndiaCCA,
+ },
+ // Not a real certificate - just for testing. This is the SPKI hash of
+ // the keys used in net/data/ssl/certificates/name_constraint_*.crt.
+ {
+ {0x48, 0x49, 0x4a, 0xc5, 0x5a, 0x3e, 0xcd, 0xc5, 0x62, 0x9f, 0xef,
+ 0x23, 0x14, 0xad, 0x05, 0xa9, 0x2a, 0x5c, 0x39, 0xc0},
+ kDomainsTest,
+ },
};
for (unsigned i = 0; i < arraysize(kLimits); ++i) {
diff --git a/chromium/net/cert/cert_verify_proc.h b/chromium/net/cert/cert_verify_proc.h
index fdc1205b849..629fde8bf38 100644
--- a/chromium/net/cert/cert_verify_proc.h
+++ b/chromium/net/cert/cert_verify_proc.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/cert/x509_cert_types.h"
diff --git a/chromium/net/cert/cert_verify_proc_android.cc b/chromium/net/cert/cert_verify_proc_android.cc
index d35f10863e0..3825b20a475 100644
--- a/chromium/net/cert/cert_verify_proc_android.cc
+++ b/chromium/net/cert/cert_verify_proc_android.cc
@@ -101,6 +101,8 @@ bool VerifyFromAndroidTrustManager(const std::vector<std::string>& cert_bytes,
sig_alg == NID_dsaWithSHA1_2 || sig_alg == NID_sha1WithRSA ||
sig_alg == NID_ecdsa_with_SHA1) {
verify_result->has_sha1 = true;
+ if (i == 0)
+ verify_result->has_sha1_leaf = true;
}
}
diff --git a/chromium/net/cert/cert_verify_proc_mac.cc b/chromium/net/cert/cert_verify_proc_mac.cc
index c0eb0683ffa..c4e0c41ba92 100644
--- a/chromium/net/cert/cert_verify_proc_mac.cc
+++ b/chromium/net/cert/cert_verify_proc_mac.cc
@@ -8,9 +8,11 @@
#include <CoreServices/CoreServices.h>
#include <Security/Security.h>
+#include <set>
#include <string>
#include <vector>
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/mac/mac_logging.h"
#include "base/mac/scoped_cftyperef.h"
@@ -19,6 +21,7 @@
#include "base/synchronization/lock.h"
#include "crypto/mac_security_services_lock.h"
#include "crypto/sha2.h"
+#include "net/base/hash_value.h"
#include "net/base/net_errors.h"
#include "net/cert/asn1_util.h"
#include "net/cert/cert_status_flags.h"
@@ -27,7 +30,6 @@
#include "net/cert/crl_set.h"
#include "net/cert/test_root_certs.h"
#include "net/cert/x509_certificate.h"
-#include "net/cert/x509_certificate_known_roots_mac.h"
#include "net/cert/x509_util_mac.h"
// From 10.7.2 libsecurity_keychain-55035/lib/SecTrustPriv.h, for use with
@@ -190,6 +192,7 @@ void GetCertChainInfo(CFArrayRef cert_chain,
verify_result->has_md4 = false;
verify_result->has_md5 = false;
verify_result->has_sha1 = false;
+ verify_result->has_sha1_leaf = false;
SecCertificateRef verified_cert = NULL;
std::vector<SecCertificateRef> verified_chain;
@@ -250,8 +253,10 @@ void GetCertChainInfo(CFArrayRef cert_chain,
CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) ||
CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1)) {
verify_result->has_sha1 = true;
- if (i == 0)
+ if (i == 0) {
+ verify_result->has_sha1_leaf = true;
*leaf_is_weak = true;
+ }
}
}
if (!verified_cert) {
@@ -353,20 +358,6 @@ bool CheckRevocationWithCRLSet(CFArrayRef chain, CRLSet* crl_set) {
return true;
}
-// IsIssuedByKnownRoot returns true if the given chain is rooted at a root CA
-// that we recognise as a standard root.
-// static
-bool IsIssuedByKnownRoot(CFArrayRef chain) {
- int n = CFArrayGetCount(chain);
- if (n < 1)
- return false;
- SecCertificateRef root_ref = reinterpret_cast<SecCertificateRef>(
- const_cast<void*>(CFArrayGetValueAtIndex(chain, n - 1)));
- SHA1HashValue hash = X509Certificate::CalculateFingerprint(root_ref);
- return IsSHA1HashInSortedArray(
- hash, &kKnownRootCertSHA1Hashes[0][0], sizeof(kKnownRootCertSHA1Hashes));
-}
-
// Builds and evaluates a SecTrustRef for the certificate chain contained
// in |cert_array|, using the verification policies in |trust_policies|. On
// success, returns OK, and updates |trust_ref|, |trust_result|,
@@ -466,6 +457,59 @@ int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array,
return OK;
}
+// Helper class for managing the set of OS X Known Roots. This is only safe
+// to initialize while the crypto::GetMacSecurityServicesLock() is held, due
+// to calling into Security.framework functions; however, once initialized,
+// it can be called at any time.
+// In practice, due to lazy initialization, it's best to just always guard
+// accesses with the lock.
+class OSXKnownRootHelper {
+ public:
+ // IsIssuedByKnownRoot returns true if the given chain is rooted at a root CA
+ // that we recognise as a standard root.
+ bool IsIssuedByKnownRoot(CFArrayRef chain) {
+ // If there are no known roots, then an API failure occurred. For safety,
+ // assume that all certificates are issued by known roots.
+ if (known_roots_.empty())
+ return true;
+
+ CFIndex n = CFArrayGetCount(chain);
+ if (n < 1)
+ return false;
+ SecCertificateRef root_ref = reinterpret_cast<SecCertificateRef>(
+ const_cast<void*>(CFArrayGetValueAtIndex(chain, n - 1)));
+ SHA256HashValue hash = X509Certificate::CalculateFingerprint256(root_ref);
+ return known_roots_.find(hash) != known_roots_.end();
+ }
+
+ private:
+ friend struct base::DefaultLazyInstanceTraits<OSXKnownRootHelper>;
+
+ OSXKnownRootHelper() {
+ CFArrayRef cert_array = NULL;
+ OSStatus rv = SecTrustSettingsCopyCertificates(
+ kSecTrustSettingsDomainSystem, &cert_array);
+ if (rv != noErr) {
+ LOG(ERROR) << "Unable to determine trusted roots; assuming all roots are "
+ << "trusted! Error " << rv;
+ return;
+ }
+ base::ScopedCFTypeRef<CFArrayRef> scoped_array(cert_array);
+ for (CFIndex i = 0, size = CFArrayGetCount(cert_array); i < size; ++i) {
+ SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
+ const_cast<void*>(CFArrayGetValueAtIndex(cert_array, i)));
+ known_roots_.insert(X509Certificate::CalculateFingerprint256(cert));
+ }
+ }
+
+ ~OSXKnownRootHelper() {}
+
+ std::set<SHA256HashValue, SHA256HashValueLessThan> known_roots_;
+};
+
+base::LazyInstance<OSXKnownRootHelper>::Leaky g_known_roots =
+ LAZY_INSTANCE_INITIALIZER;
+
} // namespace
CertVerifyProcMac::CertVerifyProcMac() {}
@@ -743,7 +787,8 @@ int CertVerifyProcMac::VerifyInternal(
verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM;
AppendPublicKeyHashes(completed_chain, &verify_result->public_key_hashes);
- verify_result->is_issued_by_known_root = IsIssuedByKnownRoot(completed_chain);
+ verify_result->is_issued_by_known_root =
+ g_known_roots.Get().IsIssuedByKnownRoot(completed_chain);
if (IsCertStatusError(verify_result->cert_status))
return MapCertStatusToNetError(verify_result->cert_status);
diff --git a/chromium/net/cert/cert_verify_proc_nss.cc b/chromium/net/cert/cert_verify_proc_nss.cc
index 9ee65ee4b34..ca8e8116f0e 100644
--- a/chromium/net/cert/cert_verify_proc_nss.cc
+++ b/chromium/net/cert/cert_verify_proc_nss.cc
@@ -15,6 +15,7 @@
#include <sslerr.h>
#include "base/logging.h"
+#include "base/macros.h"
#include "build/build_config.h"
#include "crypto/nss_util.h"
#include "crypto/scoped_nss_types.h"
@@ -165,7 +166,7 @@ void GetCertChainInfo(CERTCertList* cert_list,
CERTCertificate* verified_cert = NULL;
std::vector<CERTCertificate*> verified_chain;
- int i = 0;
+ size_t i = 0;
for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
!CERT_LIST_END(node, cert_list);
node = CERT_LIST_NEXT(node), ++i) {
@@ -215,6 +216,8 @@ void GetCertChainInfo(CERTCertList* cert_list,
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
verify_result->has_sha1 = true;
+ if (i == 0)
+ verify_result->has_sha1_leaf = true;
break;
default:
break;
diff --git a/chromium/net/cert/cert_verify_proc_openssl.cc b/chromium/net/cert/cert_verify_proc_openssl.cc
index 286b21b98bb..824a95cdc45 100644
--- a/chromium/net/cert/cert_verify_proc_openssl.cc
+++ b/chromium/net/cert/cert_verify_proc_openssl.cc
@@ -125,6 +125,8 @@ void GetCertChainInfo(X509_STORE_CTX* store_ctx,
sig_alg == NID_dsaWithSHA1_2 || sig_alg == NID_sha1WithRSA ||
sig_alg == NID_ecdsa_with_SHA1) {
verify_result->has_sha1 = true;
+ if (i == 0)
+ verify_result->has_sha1_leaf = true;
}
}
}
diff --git a/chromium/net/cert/cert_verify_proc_unittest.cc b/chromium/net/cert/cert_verify_proc_unittest.cc
index 502cfb5bb71..bdeec339d02 100644
--- a/chromium/net/cert/cert_verify_proc_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_unittest.cc
@@ -10,6 +10,7 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "crypto/sha2.h"
@@ -46,21 +47,18 @@ unsigned char paypal_null_fingerprint[] = {
0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7
};
-// Mock CertVerifyProc that will set |verify_result->is_issued_by_known_root|
-// for all certificates that are Verified.
-class WellKnownCaCertVerifyProc : public CertVerifyProc {
+// Mock CertVerifyProc that sets the CertVerifyResult to a given value for
+// all certificates that are Verify()'d
+class MockCertVerifyProc : public CertVerifyProc {
public:
- // Initialize a CertVerifyProc that will set
- // |verify_result->is_issued_by_known_root| to |is_well_known|.
- explicit WellKnownCaCertVerifyProc(bool is_well_known)
- : is_well_known_(is_well_known) {}
-
+ explicit MockCertVerifyProc(const CertVerifyResult& result)
+ : result_(result) {}
// CertVerifyProc implementation:
bool SupportsAdditionalTrustAnchors() const override { return false; }
bool SupportsOCSPStapling() const override { return false; }
protected:
- ~WellKnownCaCertVerifyProc() override {}
+ ~MockCertVerifyProc() override {}
private:
int VerifyInternal(X509Certificate* cert,
@@ -71,12 +69,12 @@ class WellKnownCaCertVerifyProc : public CertVerifyProc {
const CertificateList& additional_trust_anchors,
CertVerifyResult* verify_result) override;
- const bool is_well_known_;
+ const CertVerifyResult result_;
- DISALLOW_COPY_AND_ASSIGN(WellKnownCaCertVerifyProc);
+ DISALLOW_COPY_AND_ASSIGN(MockCertVerifyProc);
};
-int WellKnownCaCertVerifyProc::VerifyInternal(
+int MockCertVerifyProc::VerifyInternal(
X509Certificate* cert,
const std::string& hostname,
const std::string& ocsp_response,
@@ -84,7 +82,8 @@ int WellKnownCaCertVerifyProc::VerifyInternal(
CRLSet* crl_set,
const CertificateList& additional_trust_anchors,
CertVerifyResult* verify_result) {
- verify_result->is_issued_by_known_root = is_well_known_;
+ *verify_result = result_;
+ verify_result->verified_cert = cert;
return OK;
}
@@ -580,6 +579,11 @@ TEST_F(CertVerifyProcTest, NameConstraintsOk) {
&verify_result);
EXPECT_EQ(OK, error);
EXPECT_EQ(0U, verify_result.cert_status);
+
+ error = Verify(leaf.get(), "foo.test2.example.com", flags, NULL,
+ empty_cert_list_, &verify_result);
+ EXPECT_EQ(OK, error);
+ EXPECT_EQ(0U, verify_result.cert_status);
}
TEST_F(CertVerifyProcTest, NameConstraintsFailure) {
@@ -841,20 +845,102 @@ TEST_F(CertVerifyProcTest, IntranetHostsRejected) {
int error = 0;
// Intranet names for public CAs should be flagged:
- verify_proc_ = new WellKnownCaCertVerifyProc(true);
+ CertVerifyResult dummy_result;
+ dummy_result.is_issued_by_known_root = true;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
error =
Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result);
EXPECT_EQ(OK, error);
EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
// However, if the CA is not well known, these should not be flagged:
- verify_proc_ = new WellKnownCaCertVerifyProc(false);
+ dummy_result.Reset();
+ dummy_result.is_issued_by_known_root = false;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
error =
Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result);
EXPECT_EQ(OK, error);
EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
}
+// Test that a SHA-1 certificate from a publicly trusted CA issued after
+// 1 January 2016 is rejected, but those issued before that date, or with
+// SHA-1 in the intermediate, is not rejected.
+TEST_F(CertVerifyProcTest, VerifyRejectsSHA1AfterDeprecation) {
+ CertVerifyResult dummy_result;
+ CertVerifyResult verify_result;
+ int error = 0;
+ scoped_refptr<X509Certificate> cert;
+
+ // Publicly trusted SHA-1 leaf certificates issued before 1 January 2016
+ // are accepted.
+ verify_result.Reset();
+ dummy_result.Reset();
+ dummy_result.is_issued_by_known_root = true;
+ dummy_result.has_sha1 = true;
+ dummy_result.has_sha1_leaf = true;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
+ cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
+ "sha1_dec_2015.pem",
+ X509Certificate::FORMAT_AUTO);
+ ASSERT_TRUE(cert);
+ error = Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_,
+ &verify_result);
+ EXPECT_EQ(OK, error);
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
+
+ // Publicly trusted SHA-1 leaf certificates issued on/after 1 January 2016
+ // are rejected.
+ verify_result.Reset();
+ dummy_result.Reset();
+ dummy_result.is_issued_by_known_root = true;
+ dummy_result.has_sha1 = true;
+ dummy_result.has_sha1_leaf = true;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
+ cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
+ "sha1_jan_2016.pem",
+ X509Certificate::FORMAT_AUTO);
+ ASSERT_TRUE(cert);
+ error = Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_,
+ &verify_result);
+ EXPECT_EQ(ERR_CERT_WEAK_SIGNATURE_ALGORITHM, error);
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
+
+ // Enterprise issued SHA-1 leaf certificates issued on/after 1 January 2016
+ // remain accepted until SHA-1 is disabled.
+ verify_result.Reset();
+ dummy_result.Reset();
+ dummy_result.is_issued_by_known_root = false;
+ dummy_result.has_sha1 = true;
+ dummy_result.has_sha1_leaf = true;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
+ cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
+ "sha1_jan_2016.pem",
+ X509Certificate::FORMAT_AUTO);
+ ASSERT_TRUE(cert);
+ error = Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_,
+ &verify_result);
+ EXPECT_EQ(OK, error);
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
+
+ // Publicly trusted SHA-1 intermediates issued on/after 1 January 2016 are,
+ // unfortunately, accepted. This can arise due to OS path building quirks.
+ verify_result.Reset();
+ dummy_result.Reset();
+ dummy_result.is_issued_by_known_root = true;
+ dummy_result.has_sha1 = true;
+ dummy_result.has_sha1_leaf = false;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
+ cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
+ "sha1_jan_2016.pem",
+ X509Certificate::FORMAT_AUTO);
+ ASSERT_TRUE(cert);
+ error = Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_,
+ &verify_result);
+ EXPECT_EQ(OK, error);
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
+}
+
// Test that the certificate returned in CertVerifyResult is able to reorder
// certificates that are not ordered from end-entity to root. While this is
// a protocol violation if sent during a TLS handshake, if multiple sources
@@ -1280,7 +1366,8 @@ enum ExpectedAlgorithms {
EXPECT_MD2 = 1 << 0,
EXPECT_MD4 = 1 << 1,
EXPECT_MD5 = 1 << 2,
- EXPECT_SHA1 = 1 << 3
+ EXPECT_SHA1 = 1 << 3,
+ EXPECT_SHA1_LEAF = 1 << 4,
};
struct WeakDigestTestData {
@@ -1348,6 +1435,8 @@ TEST_P(CertVerifyProcWeakDigestTest, Verify) {
EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD4), verify_result.has_md4);
EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD5), verify_result.has_md5);
EXPECT_EQ(!!(data.expected_algorithms & EXPECT_SHA1), verify_result.has_sha1);
+ EXPECT_EQ(!!(data.expected_algorithms & EXPECT_SHA1_LEAF),
+ verify_result.has_sha1_leaf);
EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
@@ -1393,15 +1482,15 @@ TEST_P(CertVerifyProcWeakDigestTest, Verify) {
// The signature algorithm of the root CA should not matter.
const WeakDigestTestData kVerifyRootCATestData[] = {
- { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_SHA1 },
+ {"weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
- { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_SHA1 },
+ // MD4 is not supported by OS X / NSS
+ {"weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#endif
- { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_SHA1 },
+ {"weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
};
#if defined(OS_ANDROID)
#define MAYBE_VerifyRoot DISABLED_VerifyRoot
@@ -1414,15 +1503,15 @@ INSTANTIATE_TEST_CASE_P(MAYBE_VerifyRoot,
// The signature algorithm of intermediates should be properly detected.
const WeakDigestTestData kVerifyIntermediateCATestData[] = {
- { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_MD5 | EXPECT_SHA1 },
+ {"weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_MD5 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
- { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_MD4 | EXPECT_SHA1 },
+ // MD4 is not supported by OS X / NSS
+ {"weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_MD4 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#endif
- { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_MD2 | EXPECT_SHA1 },
+ {"weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_MD2 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
};
// Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled.
#if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_ANDROID)
@@ -1461,15 +1550,15 @@ WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity,
// Incomplete chains should still report the status of the intermediate.
const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = {
- { NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
- EXPECT_MD5 | EXPECT_SHA1 },
+ {NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
+ EXPECT_MD5 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
- { NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
- EXPECT_MD4 | EXPECT_SHA1 },
+ // MD4 is not supported by OS X / NSS
+ {NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
+ EXPECT_MD4 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#endif
- { NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
- EXPECT_MD2 | EXPECT_SHA1 },
+ {NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
+ EXPECT_MD2 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
};
// Disabled on NSS - libpkix does not return constructed chains on error,
// preventing us from detecting/inspecting the verified chain.
diff --git a/chromium/net/cert/cert_verify_proc_whitelist.cc b/chromium/net/cert/cert_verify_proc_whitelist.cc
index 99623278590..c2437f8c4de 100644
--- a/chromium/net/cert/cert_verify_proc_whitelist.cc
+++ b/chromium/net/cert/cert_verify_proc_whitelist.cc
@@ -22,10 +22,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xa0, 0xa8, 0xbb, 0xa5, 0x0a, 0x72, 0xd4, 0xe1,
0x83, 0x9a, 0x94, 0xfb, 0x1a, 0x58, 0x5a, 0xd7,
0x2a, 0x7a, 0xac, 0x3c, 0x72, 0x56, 0x1f, 0xc0 },
- { 0x00, 0xc6, 0x81, 0x13, 0x16, 0xbd, 0x9c, 0x91,
- 0x98, 0x6e, 0xa9, 0x7e, 0x2c, 0x30, 0xab, 0xef,
- 0xa0, 0xd5, 0x68, 0x04, 0x89, 0x0d, 0x65, 0x8d,
- 0xff, 0x08, 0x59, 0x11, 0x6e, 0xb4, 0xc2, 0x32 },
{ 0x00, 0xde, 0xff, 0x68, 0x2e, 0x35, 0x10, 0x22,
0xcc, 0x3b, 0xbb, 0x4e, 0xb5, 0x88, 0x0a, 0x97,
0x27, 0x88, 0x0a, 0xf3, 0x52, 0xfb, 0xbe, 0x2f,
@@ -78,10 +74,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4d, 0x8e, 0x3b, 0xc9, 0xc8, 0x7c, 0x02, 0x4e,
0x4b, 0xb7, 0x0d, 0xc6, 0x30, 0x1b, 0xcd, 0xe3,
0x24, 0x12, 0xb4, 0xce, 0x8c, 0x0c, 0x14, 0x58 },
- { 0x03, 0xde, 0x42, 0xaf, 0x1f, 0x30, 0x9f, 0x95,
- 0xf6, 0xc8, 0x91, 0x03, 0xea, 0x98, 0x7e, 0x84,
- 0xd3, 0x18, 0x6b, 0x60, 0x65, 0xf9, 0x60, 0x7a,
- 0x06, 0x6a, 0x30, 0x2b, 0x58, 0x05, 0xeb, 0x3b },
{ 0x03, 0xe0, 0x6e, 0x0b, 0x7a, 0x2c, 0xba, 0xe4,
0xb6, 0x8b, 0xce, 0x5f, 0x83, 0xe7, 0xa9, 0x31,
0x6e, 0xd7, 0x82, 0x3e, 0x8d, 0x94, 0x85, 0x38,
@@ -102,10 +94,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x55, 0xdf, 0xe2, 0x54, 0xc8, 0x20, 0xa0, 0x77,
0xff, 0x11, 0xca, 0xfc, 0x83, 0xb5, 0x0e, 0x0a,
0x13, 0xf1, 0x3d, 0x59, 0xd3, 0xca, 0x6c, 0xaf },
- { 0x04, 0x71, 0x57, 0x2c, 0x03, 0x03, 0x7d, 0xee,
- 0x2b, 0x40, 0x09, 0x6e, 0xe8, 0xaa, 0x37, 0x82,
- 0xc6, 0xfa, 0x81, 0x42, 0xcc, 0xa2, 0x68, 0x19,
- 0x09, 0xda, 0xe8, 0xc4, 0x66, 0xd0, 0x58, 0x4e },
{ 0x04, 0x80, 0x71, 0x3a, 0x76, 0x91, 0x7e, 0xb1,
0x7f, 0xb5, 0x4c, 0x93, 0xee, 0xd3, 0xfd, 0x8a,
0x98, 0x2b, 0xd9, 0x06, 0x9c, 0x69, 0xab, 0xea,
@@ -254,10 +242,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x23, 0x4a, 0x86, 0xc7, 0x0d, 0x49, 0x8c, 0x62,
0x60, 0x7f, 0x37, 0x44, 0xea, 0x71, 0xf1, 0x83,
0x1d, 0xcf, 0xca, 0xf3, 0xaf, 0x15, 0x56, 0x9c },
- { 0x0f, 0x43, 0xfc, 0x12, 0x47, 0x01, 0xfe, 0x29,
- 0xb7, 0x14, 0xf3, 0x05, 0xe2, 0x61, 0xb6, 0x32,
- 0x04, 0x82, 0xc0, 0x09, 0x6f, 0xfe, 0xad, 0x35,
- 0xe1, 0xf8, 0xe6, 0x32, 0xc6, 0x4d, 0x7b, 0x20 },
{ 0x0f, 0x57, 0xed, 0x67, 0x2b, 0xac, 0x50, 0x14,
0x89, 0xe4, 0xf4, 0xab, 0x4b, 0x1d, 0xb1, 0x75,
0x81, 0xfe, 0xb8, 0x76, 0x0f, 0xfb, 0xc0, 0x8a,
@@ -298,14 +282,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x5f, 0xdc, 0xac, 0x20, 0xa2, 0x36, 0xf8, 0x6e,
0x94, 0xe5, 0xee, 0x58, 0x59, 0xd8, 0xfd, 0x45,
0xe9, 0xe9, 0xc5, 0xa6, 0xc5, 0xc0, 0xa4, 0x13 },
- { 0x13, 0xbd, 0x07, 0x7b, 0x8a, 0x9f, 0x46, 0xff,
- 0x8f, 0x2f, 0xfd, 0x23, 0x6e, 0x53, 0xa7, 0x2c,
- 0x3b, 0x87, 0xf3, 0x4c, 0xc9, 0xdb, 0xb5, 0x81,
- 0x7e, 0x4d, 0xba, 0x1b, 0xd3, 0xbc, 0x9e, 0x5f },
- { 0x13, 0xe0, 0x1b, 0xe5, 0x72, 0xdc, 0x11, 0xfa,
- 0xc3, 0xb4, 0x7a, 0xe6, 0x8f, 0x92, 0xdc, 0x00,
- 0xf1, 0x00, 0xbf, 0x77, 0x53, 0x7b, 0x89, 0x47,
- 0xf4, 0xc1, 0x1c, 0x25, 0xa0, 0xb6, 0xf9, 0xf6 },
{ 0x14, 0x21, 0x28, 0xa6, 0x65, 0x1c, 0xdc, 0x18,
0x70, 0xc2, 0x67, 0x5e, 0xc0, 0xb0, 0xef, 0x32,
0xb5, 0xd4, 0xc1, 0x55, 0x35, 0x8e, 0x7e, 0xd9,
@@ -334,14 +310,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xbf, 0x2f, 0x83, 0xc2, 0x80, 0xd1, 0x24, 0x6d,
0xce, 0x02, 0xa6, 0x28, 0x31, 0x26, 0xc6, 0x17,
0xe4, 0x17, 0xd2, 0xb7, 0xea, 0xc1, 0x19, 0x24 },
- { 0x15, 0x75, 0x93, 0x18, 0x80, 0x19, 0x6d, 0xe8,
- 0x0d, 0x97, 0xfe, 0xf1, 0x85, 0xd2, 0x7a, 0xf6,
- 0xad, 0x6b, 0x5b, 0x04, 0x0d, 0x87, 0x6c, 0xdf,
- 0x4a, 0x39, 0xb5, 0xb7, 0x8e, 0x96, 0xb7, 0xd5 },
- { 0x15, 0xb0, 0xd9, 0xbe, 0xd6, 0x2b, 0xd8, 0x96,
- 0x11, 0x59, 0xfe, 0x7e, 0x88, 0x92, 0xf8, 0xe8,
- 0xeb, 0xb0, 0xce, 0x81, 0xe6, 0x8d, 0xea, 0xdd,
- 0x29, 0x0f, 0xdd, 0xce, 0xd0, 0x9d, 0xe7, 0xf1 },
{ 0x15, 0xcf, 0x2f, 0x78, 0xe6, 0x79, 0x62, 0x2c,
0x06, 0x78, 0xdc, 0x5b, 0xa8, 0x03, 0x84, 0x7a,
0xbd, 0xb5, 0xea, 0x64, 0x31, 0x65, 0x3e, 0xc2,
@@ -362,18 +330,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xfd, 0x9a, 0x79, 0xf2, 0xfb, 0xba, 0x9a, 0xca,
0x46, 0xce, 0xad, 0x95, 0x43, 0x05, 0xfe, 0xe5,
0xb1, 0x3b, 0x5d, 0x53, 0xdb, 0x7c, 0x1d, 0xb1 },
- { 0x17, 0x29, 0xb3, 0x34, 0x7a, 0x7d, 0x93, 0x73,
- 0x17, 0xe3, 0xda, 0x5c, 0xc7, 0xf7, 0xb0, 0xd8,
- 0xfd, 0x97, 0x72, 0x24, 0x7a, 0x57, 0x99, 0x93,
- 0x9a, 0x44, 0xd3, 0xa9, 0x7a, 0x50, 0xb9, 0xd9 },
{ 0x17, 0x3d, 0xe2, 0x60, 0xe2, 0x2d, 0x76, 0x9d,
0x2d, 0x54, 0x99, 0xc8, 0x22, 0x0d, 0x86, 0xed,
0xe3, 0x48, 0xda, 0x1e, 0x57, 0xc1, 0xe7, 0xc8,
0x15, 0x07, 0xfb, 0x3e, 0x6b, 0xd7, 0x3b, 0x7f },
- { 0x17, 0x46, 0x68, 0x4e, 0x66, 0x21, 0x77, 0x68,
- 0x70, 0xde, 0x55, 0x65, 0xdf, 0xd3, 0x3a, 0x30,
- 0x92, 0x77, 0x18, 0x59, 0x6c, 0x01, 0x30, 0xf8,
- 0x77, 0x4b, 0xe9, 0x9c, 0xd2, 0xa2, 0x51, 0x06 },
{ 0x17, 0x59, 0x7e, 0x00, 0x45, 0x6c, 0x38, 0x32,
0xe1, 0x85, 0x1c, 0x30, 0x0c, 0xd5, 0x52, 0xc2,
0xe7, 0x73, 0x35, 0x8c, 0xf0, 0xf6, 0x88, 0x58,
@@ -442,10 +402,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x38, 0x5d, 0xe1, 0xde, 0x16, 0xb2, 0x22, 0x6e,
0x88, 0x3d, 0x9c, 0x34, 0x66, 0x3e, 0x1b, 0x64,
0xe8, 0x5b, 0x98, 0x0e, 0xaf, 0xf0, 0xb9, 0xd3 },
- { 0x1c, 0x74, 0xba, 0x75, 0xe5, 0x1b, 0x48, 0x29,
- 0x54, 0xc3, 0x8b, 0xf4, 0xd5, 0x1e, 0xfc, 0x70,
- 0xa0, 0xa0, 0x4d, 0x41, 0x3a, 0xc1, 0xff, 0x8e,
- 0xb9, 0x90, 0x39, 0x9d, 0x1f, 0x1a, 0xa9, 0xc4 },
{ 0x1c, 0x76, 0xbb, 0xca, 0x37, 0x71, 0x77, 0x5b,
0xb9, 0xb0, 0xc3, 0x33, 0x71, 0x70, 0x32, 0x69,
0x06, 0x16, 0x77, 0xca, 0x7b, 0x18, 0x99, 0xef,
@@ -474,10 +430,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x85, 0xa7, 0x9b, 0xba, 0x45, 0xce, 0x76, 0x4b,
0x2d, 0xa8, 0x1f, 0x99, 0x1f, 0x5f, 0x01, 0xd9,
0xeb, 0x7e, 0x3c, 0x99, 0x9b, 0x78, 0x75, 0x0e },
- { 0x1f, 0x7d, 0x37, 0x52, 0x93, 0x22, 0x7d, 0x04,
- 0x97, 0x5b, 0x78, 0x97, 0xdc, 0x17, 0x25, 0x39,
- 0x64, 0xdc, 0xd7, 0xd0, 0x06, 0x7e, 0x84, 0xc6,
- 0xd8, 0x47, 0x9d, 0xfa, 0x27, 0x6e, 0xbe, 0xd0 },
{ 0x1f, 0xc7, 0xf8, 0x10, 0x4e, 0x27, 0xff, 0x2a,
0x45, 0x56, 0xf9, 0x1e, 0x05, 0x42, 0x17, 0xc5,
0x8f, 0x69, 0x3f, 0x70, 0x36, 0x25, 0x9e, 0x39,
@@ -486,10 +438,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xcc, 0xd4, 0xe6, 0xad, 0xe1, 0xcb, 0x75, 0x13,
0x8d, 0xd6, 0xd9, 0x06, 0xfe, 0xf3, 0x49, 0xc0,
0xc9, 0x86, 0xa5, 0x1b, 0x29, 0xb9, 0xe5, 0x2d },
- { 0x20, 0x15, 0x60, 0x8b, 0x8e, 0x86, 0xba, 0x63,
- 0x12, 0x01, 0xc2, 0x12, 0x20, 0x99, 0x57, 0xaf,
- 0xcb, 0x6e, 0xdf, 0x27, 0x22, 0xc6, 0x1b, 0x00,
- 0xe2, 0xfc, 0x92, 0x46, 0xa8, 0xd5, 0x20, 0x4e },
{ 0x20, 0xf1, 0x85, 0xbc, 0x7f, 0xa7, 0x61, 0x16,
0x6e, 0xa3, 0xa9, 0x98, 0x8f, 0xb1, 0x0b, 0x24,
0xc7, 0x01, 0xef, 0xdd, 0xab, 0xe4, 0x74, 0x05,
@@ -518,10 +466,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xf7, 0x8d, 0xa6, 0xc8, 0xb1, 0xd7, 0x2c, 0x3b,
0xa8, 0x31, 0x9a, 0x46, 0xf8, 0x19, 0x2d, 0x1e,
0x19, 0xb9, 0xe2, 0x9a, 0xba, 0x18, 0xee, 0x87 },
- { 0x22, 0x2e, 0xc2, 0x75, 0xe6, 0x8a, 0x31, 0x7d,
- 0x60, 0x80, 0x67, 0x9d, 0xdf, 0x56, 0x78, 0x6a,
- 0xbd, 0x2b, 0x11, 0xf2, 0x5a, 0x17, 0x15, 0x33,
- 0xcf, 0xbd, 0x59, 0xee, 0x0d, 0xfa, 0x4e, 0xe4 },
{ 0x22, 0x7a, 0x2b, 0xff, 0xab, 0xde, 0xe1, 0x8c,
0x2c, 0x54, 0xe6, 0xe9, 0xb5, 0x8a, 0xbd, 0xbf,
0x93, 0x07, 0xa4, 0x06, 0x2e, 0xda, 0x97, 0xd4,
@@ -542,10 +486,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x16, 0x2a, 0x9c, 0xa0, 0x6e, 0x88, 0x01, 0xe1,
0x19, 0xbd, 0xff, 0x54, 0x35, 0x4a, 0x3f, 0x68,
0x43, 0xcf, 0x2a, 0x2f, 0xa6, 0x01, 0x75, 0x8e },
- { 0x23, 0xf0, 0xdd, 0xd8, 0x9b, 0x42, 0x82, 0xa6,
- 0x7f, 0xd0, 0x57, 0x56, 0xfd, 0xc5, 0xd1, 0x8c,
- 0x1e, 0x5d, 0xcc, 0xef, 0xcf, 0x42, 0x65, 0x06,
- 0x6d, 0xfb, 0x4a, 0xbd, 0x30, 0xd9, 0xe9, 0x77 },
{ 0x23, 0xf7, 0xe4, 0xa3, 0x5b, 0xcc, 0xe7, 0x40,
0x36, 0xd9, 0xc8, 0x6f, 0x7f, 0x61, 0x1d, 0x85,
0xf3, 0x7c, 0xb6, 0x2c, 0x43, 0x24, 0x7d, 0x13,
@@ -570,10 +510,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x74, 0xe5, 0xe3, 0xd4, 0x3b, 0x27, 0xad, 0x66,
0x62, 0x0b, 0x90, 0xcb, 0x91, 0x62, 0xc4, 0x68,
0x5f, 0xa2, 0x6d, 0x85, 0xf5, 0xa4, 0x3a, 0xa0 },
- { 0x25, 0x8c, 0x68, 0x91, 0xf0, 0x89, 0xb5, 0x09,
- 0x4b, 0xe3, 0x3d, 0x6c, 0x82, 0x21, 0x5e, 0x72,
- 0x65, 0xac, 0xa9, 0x3f, 0x7c, 0x9b, 0x41, 0x45,
- 0xd0, 0x8a, 0xff, 0x1f, 0x48, 0x30, 0x58, 0xaa },
{ 0x26, 0x03, 0xcb, 0xdf, 0x69, 0x75, 0xe3, 0x68,
0x83, 0x7f, 0x95, 0x1a, 0x00, 0x49, 0xfd, 0xc3,
0xc4, 0xb2, 0x39, 0xf0, 0x82, 0xf6, 0xbf, 0x89,
@@ -618,10 +554,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xe6, 0xa6, 0xa3, 0x5a, 0x9d, 0x40, 0x00, 0x0a,
0x31, 0x8d, 0x7d, 0xdf, 0x5f, 0x5a, 0x2f, 0x4d,
0x3d, 0x18, 0xbe, 0xba, 0xd3, 0x96, 0x91, 0xec },
- { 0x29, 0x7a, 0xc8, 0x25, 0xc1, 0x98, 0x06, 0xfb,
- 0x88, 0x1f, 0xd9, 0x1c, 0x61, 0x2d, 0x6c, 0xc2,
- 0x1b, 0x28, 0xe4, 0xa5, 0x72, 0xcf, 0xb7, 0x16,
- 0x04, 0xe5, 0x54, 0x41, 0x4d, 0xfd, 0xea, 0xdc },
{ 0x29, 0xa8, 0x28, 0x26, 0x64, 0x3d, 0x5a, 0x98,
0xc4, 0x7d, 0xf3, 0xa7, 0x8f, 0xbb, 0x84, 0x49,
0xb3, 0xe6, 0xd3, 0xcc, 0xe6, 0x2c, 0xf4, 0x57,
@@ -630,18 +562,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x39, 0xa4, 0x04, 0xde, 0x35, 0xac, 0x84, 0xab,
0x81, 0xaf, 0xec, 0x36, 0x17, 0xe7, 0xe1, 0xbf,
0x34, 0x67, 0xd4, 0x19, 0x25, 0x5d, 0xd8, 0x17 },
- { 0x2a, 0x6b, 0x9f, 0x6f, 0xdc, 0x43, 0xbf, 0x65,
- 0xe2, 0xa1, 0x0e, 0xde, 0x36, 0x64, 0xc8, 0x3f,
- 0xcb, 0xec, 0x13, 0x9a, 0x6e, 0x6c, 0xc5, 0xc8,
- 0x32, 0xd3, 0x27, 0x89, 0x5b, 0x52, 0x0e, 0xa2 },
{ 0x2a, 0xa6, 0x47, 0x8c, 0xc7, 0x5d, 0x67, 0xa8,
0xca, 0x55, 0xb2, 0xe1, 0x63, 0xfd, 0xbb, 0xbc,
0x9d, 0x74, 0xb4, 0xe5, 0xf3, 0x7b, 0x7d, 0xbd,
0x13, 0xc9, 0x4e, 0x85, 0x8d, 0x40, 0xda, 0xd0 },
- { 0x2a, 0xc0, 0x65, 0xae, 0x39, 0x6b, 0x87, 0x54,
- 0x9c, 0x3f, 0x09, 0xe5, 0x8f, 0x16, 0x4b, 0x24,
- 0x2e, 0xc5, 0x9d, 0x13, 0x92, 0xb1, 0xb2, 0x50,
- 0x14, 0xbf, 0x47, 0x94, 0xac, 0x13, 0x01, 0xb0 },
{ 0x2b, 0xf1, 0xe3, 0xf0, 0x37, 0x5a, 0x9a, 0x21,
0xc0, 0x7a, 0x92, 0x18, 0x04, 0x2f, 0x18, 0x77,
0x3f, 0x43, 0xea, 0xb0, 0xf5, 0xc0, 0x00, 0x26,
@@ -662,10 +586,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xc3, 0x73, 0x58, 0xcd, 0x5f, 0x71, 0xd1, 0x23,
0xbb, 0x19, 0x77, 0x28, 0x85, 0x87, 0xc7, 0x3f,
0x84, 0xb0, 0x8f, 0xf8, 0xaa, 0x01, 0x9a, 0x69 },
- { 0x2d, 0xb5, 0x36, 0x48, 0xa6, 0x14, 0x69, 0x57,
- 0x01, 0xc7, 0xc5, 0x1e, 0x35, 0xff, 0x38, 0xd6,
- 0x4f, 0x27, 0xa2, 0x7d, 0x55, 0xdf, 0xf4, 0xb1,
- 0x4a, 0xc4, 0x50, 0xc7, 0x5e, 0xb1, 0x18, 0x6e },
{ 0x2d, 0xd5, 0xe6, 0xd3, 0x73, 0x36, 0x34, 0x2f,
0x01, 0x1e, 0xb9, 0x7a, 0x2b, 0x77, 0x38, 0x9d,
0xe6, 0xd2, 0x23, 0x8d, 0x87, 0x69, 0x65, 0x08,
@@ -674,10 +594,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xad, 0xe6, 0x7e, 0x9c, 0xa7, 0x05, 0xeb, 0xb4,
0xc2, 0xe9, 0x40, 0xae, 0x1b, 0x9d, 0x62, 0x35,
0x72, 0x18, 0x04, 0x58, 0x31, 0xe9, 0x8f, 0xde },
- { 0x2e, 0x43, 0x2a, 0x54, 0x5d, 0xfe, 0x2d, 0xa3,
- 0xad, 0x00, 0xcc, 0x87, 0x89, 0x23, 0xa1, 0x85,
- 0xd6, 0xa3, 0xf9, 0x67, 0x5c, 0x36, 0xdc, 0x3c,
- 0xd3, 0x70, 0x2a, 0xef, 0xeb, 0x27, 0x0c, 0x85 },
{ 0x2e, 0x5d, 0xd2, 0x55, 0x09, 0x6d, 0x64, 0x83,
0x10, 0x5c, 0xb6, 0x03, 0x6c, 0x59, 0x17, 0x57,
0xfd, 0x98, 0x49, 0x70, 0x66, 0x05, 0x3f, 0x83,
@@ -690,10 +606,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x01, 0x7c, 0x6c, 0x79, 0x90, 0xe3, 0xf9, 0xa4,
0x0d, 0x46, 0x9f, 0x76, 0x50, 0x59, 0x81, 0xc8,
0x6f, 0x95, 0x55, 0x4f, 0x48, 0x7a, 0x52, 0x76 },
- { 0x2f, 0x79, 0xd6, 0xf6, 0xa3, 0x2f, 0x1b, 0xee,
- 0x22, 0x37, 0xa0, 0x18, 0xe6, 0xae, 0xc4, 0xf4,
- 0x9e, 0x2c, 0x5c, 0x3c, 0xdb, 0xb6, 0x99, 0xe1,
- 0x6f, 0x8e, 0xf4, 0x14, 0xee, 0xff, 0x8d, 0xa3 },
{ 0x2f, 0xef, 0xa7, 0xcb, 0x12, 0x6b, 0x81, 0xc9,
0x47, 0x4d, 0x3e, 0x2c, 0x9b, 0x97, 0x3a, 0x83,
0x69, 0xbb, 0x08, 0x43, 0x41, 0xd3, 0x82, 0xd3,
@@ -718,10 +630,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x74, 0x2d, 0x6b, 0xe8, 0x40, 0x0a, 0xde, 0x51,
0xb2, 0x09, 0x83, 0xf6, 0x83, 0xa2, 0xaa, 0xee,
0xb2, 0x5f, 0x58, 0xdf, 0x98, 0x1b, 0xde, 0x0d },
- { 0x31, 0xed, 0x8a, 0x8c, 0xc6, 0xee, 0x5e, 0x88,
- 0x4f, 0x21, 0x4f, 0x26, 0x7f, 0xe3, 0xa2, 0x27,
- 0xd4, 0xe6, 0xed, 0x36, 0xa7, 0x7f, 0xa2, 0x24,
- 0x6f, 0x0a, 0xd0, 0x77, 0x8a, 0x6b, 0x3f, 0x97 },
{ 0x32, 0x36, 0x98, 0x50, 0x9d, 0x8f, 0x8b, 0xfb,
0xd4, 0xf9, 0x04, 0xbd, 0x1d, 0x84, 0x64, 0x12,
0xc5, 0x27, 0xb7, 0x70, 0x06, 0x2a, 0xad, 0xdf,
@@ -742,10 +650,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xb9, 0xe6, 0x63, 0x0d, 0x9f, 0xe7, 0x1f, 0x17,
0xb6, 0xc2, 0x25, 0xa6, 0x5c, 0x76, 0x08, 0x15,
0xe4, 0x08, 0x74, 0x6c, 0x33, 0x1a, 0xb4, 0xf6 },
- { 0x33, 0xc9, 0x15, 0x03, 0xbc, 0x7e, 0xbe, 0x5a,
- 0x5d, 0xd0, 0xcf, 0xbb, 0x37, 0x52, 0x64, 0xdd,
- 0x5a, 0x31, 0x1e, 0x48, 0xf4, 0x26, 0x6b, 0x32,
- 0x50, 0x8a, 0x02, 0x5d, 0x04, 0xfa, 0xdf, 0x38 },
{ 0x33, 0xd1, 0x6c, 0xd9, 0xe8, 0x2e, 0xdf, 0xfd,
0x0b, 0x3a, 0xfb, 0x46, 0xa6, 0x84, 0xc5, 0xa0,
0xd1, 0x2f, 0x2b, 0x40, 0x58, 0x6d, 0x53, 0x2f,
@@ -798,18 +702,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x44, 0xd6, 0xab, 0x39, 0xb7, 0xa8, 0x18, 0xf8,
0x17, 0x6e, 0x65, 0x20, 0xdc, 0x86, 0x3d, 0xce,
0x43, 0xb3, 0x98, 0xc3, 0x0b, 0x5e, 0xdb, 0x09 },
- { 0x37, 0x07, 0x9d, 0x98, 0x72, 0x7c, 0x42, 0xa4,
- 0x1d, 0x66, 0x18, 0xfc, 0xcd, 0xc6, 0xff, 0xa1,
- 0x5e, 0xd3, 0xb2, 0xfe, 0xc7, 0xac, 0x0a, 0x09,
- 0x7b, 0x74, 0xc5, 0x72, 0xbb, 0xcd, 0xa8, 0xd7 },
{ 0x37, 0x87, 0x37, 0xcd, 0x85, 0x19, 0xba, 0xc5,
0x32, 0x2f, 0xdb, 0x28, 0xf4, 0x4a, 0x43, 0xc5,
0x09, 0xa5, 0x44, 0x7a, 0xd2, 0x68, 0x3b, 0xa1,
0x90, 0x05, 0xe3, 0x1b, 0x0d, 0x54, 0x8c, 0x6d },
- { 0x37, 0x99, 0x0f, 0x5b, 0x5c, 0x71, 0x11, 0x89,
- 0x98, 0xf9, 0xc8, 0xe1, 0x54, 0x65, 0x69, 0x16,
- 0x1a, 0x82, 0xbb, 0xfb, 0x4b, 0x4f, 0xc4, 0xca,
- 0xa3, 0xf4, 0xb7, 0xe7, 0x4a, 0xf5, 0x15, 0xfe },
{ 0x37, 0xc9, 0x7a, 0x48, 0xf5, 0xee, 0x3e, 0x68,
0xcc, 0x24, 0xb5, 0x4e, 0x7c, 0x4d, 0x9f, 0x91,
0xc7, 0xd1, 0x8b, 0x8d, 0xb6, 0x1e, 0x04, 0xee,
@@ -846,10 +742,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x82, 0xd5, 0x85, 0xd5, 0xe0, 0x82, 0xc4, 0xb3,
0xad, 0x03, 0xcd, 0xb6, 0xb5, 0x05, 0xca, 0x80,
0x47, 0x19, 0x88, 0xec, 0x4c, 0x58, 0x99, 0x9e },
- { 0x3a, 0xd4, 0x7c, 0xb3, 0x47, 0x3f, 0x59, 0x51,
- 0x5b, 0xac, 0x6a, 0xfa, 0x30, 0x44, 0x8f, 0xb9,
- 0x5d, 0x7f, 0x4b, 0xf1, 0x14, 0x48, 0x53, 0x87,
- 0xd0, 0x4c, 0x50, 0x15, 0x19, 0xbb, 0x77, 0xc3 },
{ 0x3a, 0xea, 0x2c, 0xef, 0xae, 0x63, 0x44, 0xff,
0xae, 0x67, 0x49, 0x4c, 0x68, 0x4e, 0x1e, 0xbf,
0x87, 0x95, 0x40, 0xb5, 0x3d, 0x40, 0xf5, 0x16,
@@ -858,10 +750,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xca, 0x6c, 0x31, 0xb3, 0x78, 0x39, 0xc9, 0x50,
0x76, 0x63, 0x70, 0xd7, 0xf4, 0xb6, 0x4a, 0xd0,
0x18, 0x55, 0xca, 0xcf, 0xe3, 0x51, 0x2f, 0xc3 },
- { 0x3b, 0x4a, 0x9f, 0x55, 0x6c, 0xca, 0xc7, 0x0c,
- 0xa1, 0xf3, 0x3a, 0xf6, 0xde, 0xcc, 0x66, 0xca,
- 0xfd, 0x2d, 0x30, 0x1d, 0x49, 0x7b, 0x49, 0x0b,
- 0x30, 0x80, 0x46, 0x35, 0xba, 0xd2, 0x56, 0x94 },
{ 0x3b, 0x6e, 0x3b, 0xb7, 0x00, 0x04, 0xbd, 0x78,
0xc9, 0x69, 0xa7, 0xfb, 0xd5, 0x11, 0x33, 0xa2,
0xb3, 0xc4, 0xdf, 0xb6, 0xba, 0x38, 0x5d, 0xce,
@@ -890,22 +778,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xf8, 0x91, 0x85, 0x31, 0xa7, 0x7c, 0xf9, 0xbf,
0x5c, 0xa1, 0x85, 0x0c, 0x82, 0x02, 0x69, 0xd7,
0xb2, 0xc8, 0xec, 0xd0, 0x54, 0x3a, 0x61, 0x65 },
- { 0x3e, 0x6f, 0x37, 0x53, 0xf1, 0xab, 0x10, 0x62,
- 0x60, 0xdb, 0xef, 0xa6, 0x8e, 0xc5, 0x85, 0x01,
- 0x29, 0x1d, 0x1e, 0xb4, 0x00, 0x28, 0x8f, 0x06,
- 0xed, 0xf2, 0x9f, 0x8f, 0x8f, 0x66, 0xb0, 0x1a },
{ 0x3e, 0x8e, 0x9b, 0xad, 0x8e, 0xd9, 0xb5, 0x72,
0x38, 0x2e, 0x59, 0x8d, 0x2d, 0x73, 0x67, 0xe1,
0xfd, 0x6a, 0xf6, 0x95, 0x25, 0x00, 0x9d, 0x67,
0xb4, 0xe8, 0xaf, 0x80, 0xd9, 0x15, 0x85, 0x49 },
- { 0x3e, 0xc1, 0xc3, 0x43, 0xc6, 0x60, 0x05, 0x10,
- 0x57, 0x97, 0x47, 0xa7, 0x1a, 0xea, 0xb3, 0x04,
- 0x1a, 0x71, 0x8e, 0x4f, 0xc6, 0xe2, 0x96, 0xfe,
- 0xb7, 0x50, 0xa3, 0x12, 0x38, 0x72, 0x6e, 0xa5 },
- { 0x3e, 0xd6, 0x85, 0x47, 0x65, 0x07, 0x91, 0x35,
- 0xaa, 0xee, 0xb7, 0xd8, 0xa3, 0x79, 0x17, 0xdc,
- 0x71, 0x74, 0x5e, 0xa6, 0x0f, 0xa9, 0x62, 0x1b,
- 0xaa, 0x30, 0x7f, 0xbe, 0x71, 0xa7, 0x3c, 0x43 },
{ 0x3f, 0x27, 0xbd, 0xca, 0x9b, 0x0e, 0x42, 0xf3,
0xf6, 0xd0, 0x91, 0x2c, 0x92, 0xe2, 0xda, 0x65,
0xcb, 0x35, 0x8f, 0x0b, 0x8f, 0x80, 0x5b, 0xec,
@@ -938,10 +814,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x65, 0xa7, 0x39, 0xa0, 0x0c, 0x85, 0xf3, 0x44,
0x58, 0x79, 0xd6, 0x5e, 0x1d, 0x42, 0x2e, 0xed,
0x07, 0x65, 0x5a, 0x8e, 0x3e, 0xc3, 0x18, 0xcf },
- { 0x41, 0x1e, 0x5a, 0x18, 0x2a, 0x48, 0x3c, 0x67,
- 0x0f, 0x89, 0xac, 0xee, 0xa6, 0xda, 0xa1, 0xf9,
- 0xa6, 0x22, 0x7e, 0xdf, 0x04, 0x9c, 0x05, 0xe3,
- 0xc4, 0xcf, 0xf7, 0x28, 0x42, 0x45, 0x9a, 0xa2 },
{ 0x41, 0x29, 0x6b, 0x9f, 0xaa, 0xd6, 0x41, 0x33,
0xfc, 0xcb, 0xa6, 0xba, 0x74, 0x54, 0x11, 0xec,
0xc9, 0x11, 0xfd, 0x8e, 0xd5, 0x41, 0x90, 0x0f,
@@ -990,14 +862,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4a, 0x58, 0x1f, 0x4f, 0x10, 0x91, 0xab, 0xef,
0x33, 0x2d, 0x8a, 0x7c, 0xef, 0x60, 0xe6, 0x8d,
0xaf, 0x84, 0x13, 0x23, 0x26, 0x12, 0x90, 0xf0 },
- { 0x44, 0xc2, 0x00, 0x2e, 0xea, 0xbe, 0x55, 0xaa,
- 0x9b, 0xf9, 0x7c, 0xf3, 0xef, 0xd4, 0xfb, 0x06,
- 0xec, 0xe5, 0x10, 0xb4, 0xab, 0xe9, 0xac, 0xb8,
- 0x2c, 0x36, 0xef, 0x23, 0x5b, 0x9d, 0xc8, 0xa1 },
- { 0x45, 0x60, 0xdb, 0xdb, 0x1c, 0x43, 0x68, 0x50,
- 0xef, 0xb0, 0x03, 0x1e, 0xf8, 0x2b, 0x9f, 0x70,
- 0x88, 0x21, 0x9e, 0xce, 0xd2, 0x69, 0x56, 0x1f,
- 0xb4, 0xd1, 0xb0, 0x18, 0x3c, 0x44, 0xc2, 0xb5 },
{ 0x45, 0x63, 0xcf, 0x13, 0xc2, 0x49, 0x2c, 0xaa,
0x92, 0xf5, 0x5b, 0x17, 0x26, 0x3a, 0xdd, 0x72,
0x04, 0xa8, 0x0f, 0xe6, 0x24, 0x0c, 0x4d, 0x63,
@@ -1010,10 +874,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xd5, 0xda, 0xfc, 0x05, 0xeb, 0x0c, 0x53, 0x65,
0x82, 0x3a, 0x91, 0xa9, 0x8b, 0x7d, 0xbe, 0x81,
0xab, 0x5f, 0x17, 0x8b, 0x2d, 0xa4, 0xad, 0x9e },
- { 0x45, 0xcc, 0x74, 0xa3, 0xdb, 0xcb, 0x59, 0xa1,
- 0x35, 0x35, 0x39, 0xfa, 0x5b, 0x1a, 0xf9, 0x74,
- 0x6b, 0xa5, 0xc7, 0xf0, 0xf1, 0x6f, 0x7c, 0xc1,
- 0xf7, 0x0c, 0x71, 0x32, 0x38, 0x82, 0x7e, 0x37 },
{ 0x46, 0x9b, 0xd8, 0x04, 0xe9, 0x98, 0xae, 0x27,
0x9a, 0xc3, 0xfe, 0x1b, 0x52, 0x88, 0x46, 0xe7,
0xae, 0xc7, 0x6c, 0x56, 0xb8, 0x0b, 0x40, 0xf3,
@@ -1034,18 +894,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x8b, 0xf5, 0xdd, 0xa4, 0xc3, 0xe9, 0x9e, 0x7f,
0xa3, 0x10, 0x9b, 0x67, 0xbd, 0x0c, 0x9b, 0x1f,
0x40, 0x75, 0x96, 0x65, 0xb9, 0xec, 0x3f, 0xf2 },
- { 0x48, 0x09, 0x80, 0xfc, 0xeb, 0x50, 0xeb, 0x37,
- 0x4c, 0x91, 0x6c, 0xb2, 0xa4, 0x3a, 0xfb, 0xd5,
- 0x35, 0x21, 0x1a, 0xea, 0x9b, 0x12, 0xb7, 0xa4,
- 0x5a, 0xaf, 0x90, 0xba, 0x9c, 0xa4, 0x70, 0x0f },
- { 0x48, 0x4b, 0x8b, 0xc1, 0xe6, 0xcb, 0xba, 0x3f,
- 0x01, 0xf7, 0xa9, 0x34, 0x5a, 0x88, 0x4c, 0xf5,
- 0xf1, 0x5d, 0x82, 0xda, 0x56, 0x98, 0xb6, 0xb3,
- 0x71, 0xe4, 0xdc, 0x6b, 0xbd, 0x6c, 0x8a, 0xe8 },
- { 0x48, 0x5c, 0xf2, 0xb0, 0xa5, 0xe6, 0x9a, 0x0a,
- 0x9a, 0xab, 0x03, 0xff, 0x82, 0xbd, 0x6b, 0x7b,
- 0x2e, 0xdf, 0x8e, 0x1b, 0x54, 0x45, 0x8e, 0x14,
- 0x2a, 0xeb, 0x88, 0xba, 0xa8, 0x84, 0x0e, 0x5b },
{ 0x48, 0xc5, 0xd4, 0xff, 0x5d, 0x08, 0x4a, 0xc1,
0x95, 0xb1, 0xa6, 0xa2, 0x19, 0xf8, 0x1b, 0xbd,
0xf9, 0xd2, 0xe5, 0xc0, 0x70, 0xec, 0x97, 0xdf,
@@ -1126,10 +974,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xa9, 0xaa, 0x3b, 0x7b, 0x02, 0x7d, 0x71, 0x4c,
0x0f, 0x76, 0x07, 0xc3, 0x56, 0x73, 0x3b, 0xa2,
0x21, 0xaa, 0xe4, 0x09, 0x47, 0xf7, 0xfa, 0xcb },
- { 0x4d, 0x25, 0x2e, 0x6e, 0x1a, 0x15, 0x9a, 0xc2,
- 0x22, 0xb3, 0x2e, 0x9d, 0xd0, 0x31, 0x56, 0x7b,
- 0x69, 0x31, 0x4b, 0xe8, 0xe8, 0x21, 0x1c, 0x1f,
- 0xb3, 0xc8, 0xb5, 0x3c, 0x26, 0x0a, 0x74, 0xe5 },
{ 0x4d, 0x54, 0x4d, 0x4e, 0x41, 0xc0, 0xfb, 0x15,
0x5f, 0x04, 0x7d, 0x7f, 0xb1, 0xef, 0x29, 0xd1,
0x1b, 0xdf, 0xec, 0xa9, 0xd4, 0x11, 0xaf, 0x8b,
@@ -1142,18 +986,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x81, 0x79, 0x67, 0x53, 0xdd, 0x20, 0x20, 0xb1,
0x10, 0x54, 0x09, 0x32, 0xf7, 0x4f, 0x97, 0x41,
0xd9, 0x6c, 0x1d, 0xb9, 0x50, 0x5d, 0x5f, 0xf1 },
- { 0x4e, 0x33, 0x78, 0xec, 0x23, 0x7c, 0x01, 0xa3,
- 0xcd, 0x85, 0x9e, 0x1d, 0xc9, 0x29, 0xd6, 0xa6,
- 0xef, 0xb6, 0x36, 0x7a, 0x72, 0x58, 0x41, 0xcf,
- 0x54, 0x13, 0x25, 0xc0, 0x61, 0xf8, 0xbf, 0xd4 },
{ 0x4e, 0x48, 0xc1, 0x6c, 0x9d, 0x0d, 0xe5, 0xdd,
0x8c, 0x9c, 0x36, 0x37, 0x35, 0xdd, 0xfb, 0xc3,
0xdb, 0xd2, 0x6e, 0xa0, 0xae, 0xcd, 0xe1, 0xc7,
0x62, 0xbb, 0x56, 0xbb, 0x3f, 0xe4, 0xfa, 0x74 },
- { 0x4e, 0x6e, 0x0a, 0x27, 0x52, 0x69, 0x22, 0x88,
- 0x98, 0x02, 0xb5, 0x98, 0x9e, 0xf0, 0x8a, 0xe1,
- 0x67, 0x02, 0x62, 0x0e, 0x8d, 0x12, 0x90, 0xb9,
- 0x36, 0x9e, 0xf0, 0x32, 0x9a, 0xdb, 0xa6, 0x8c },
{ 0x4f, 0x19, 0xdd, 0x12, 0x92, 0x4c, 0xe0, 0xc1,
0x4f, 0x82, 0xc0, 0x56, 0xc7, 0xd4, 0x2b, 0xac,
0x43, 0xd0, 0x13, 0x3a, 0xaf, 0x89, 0xc1, 0xef,
@@ -1234,10 +1070,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x08, 0x60, 0x96, 0x78, 0xc4, 0x3b, 0xdd, 0xab,
0x90, 0x28, 0xba, 0x6c, 0x17, 0x68, 0x4c, 0x51,
0x22, 0x42, 0x62, 0x43, 0xcb, 0x61, 0x2a, 0x29 },
- { 0x53, 0xed, 0x84, 0xe5, 0xc9, 0xad, 0x2b, 0xd1,
- 0xcb, 0x2c, 0xc8, 0x36, 0x52, 0xea, 0x0c, 0xc3,
- 0x71, 0xcd, 0x53, 0x4b, 0xd5, 0x97, 0xce, 0x7e,
- 0x07, 0x37, 0xa0, 0xab, 0x10, 0x65, 0x73, 0xaa },
{ 0x54, 0x41, 0xfb, 0xb0, 0x5d, 0x6d, 0x4a, 0xed,
0xe0, 0x3b, 0x48, 0x2f, 0x51, 0x95, 0x1c, 0x7e,
0xf0, 0x73, 0x45, 0x53, 0xce, 0xc7, 0x80, 0xfb,
@@ -1262,10 +1094,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x58, 0x4d, 0x9e, 0x7b, 0x57, 0x92, 0xa4, 0x03,
0xc2, 0x1d, 0x39, 0xd6, 0xe1, 0xf5, 0xe8, 0xed,
0x37, 0xb9, 0x3f, 0xa6, 0x1d, 0x88, 0x35, 0x16 },
- { 0x56, 0x65, 0xc2, 0xe5, 0x64, 0x33, 0x29, 0x85,
- 0xb8, 0xd2, 0xc4, 0xfb, 0x61, 0x14, 0x57, 0xd8,
- 0xd5, 0x65, 0x9a, 0xe0, 0x05, 0x87, 0x4c, 0x6f,
- 0x30, 0x34, 0xd2, 0x9f, 0x2a, 0x9a, 0x78, 0x32 },
{ 0x56, 0x96, 0x18, 0xd5, 0x4e, 0x3c, 0x61, 0x1b,
0x79, 0x7e, 0xeb, 0x01, 0xdf, 0x9c, 0x1c, 0x5c,
0x14, 0x6d, 0x87, 0xb3, 0xb1, 0x29, 0xba, 0x42,
@@ -1282,10 +1110,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x62, 0x9c, 0x3c, 0x7c, 0x78, 0xef, 0xbe, 0xf2,
0x75, 0x06, 0x56, 0x65, 0xb2, 0x41, 0x1c, 0x0e,
0x5f, 0xcf, 0xbc, 0x7e, 0xb4, 0xbe, 0x34, 0x0b },
- { 0x58, 0x36, 0x98, 0x46, 0xc0, 0x25, 0x15, 0x0e,
- 0xcf, 0xb2, 0x2c, 0xce, 0xb8, 0xe4, 0xde, 0x9a,
- 0xc3, 0xd0, 0x2d, 0x9e, 0x23, 0x6c, 0x02, 0xef,
- 0xb5, 0x5f, 0x63, 0xeb, 0xaf, 0xea, 0xf7, 0x5b },
{ 0x59, 0x43, 0x09, 0x51, 0x02, 0x8b, 0x87, 0x78,
0x01, 0x67, 0xc9, 0x56, 0x47, 0x9a, 0x81, 0x5f,
0x91, 0xbc, 0x6c, 0x00, 0xc2, 0xe5, 0x0c, 0x35,
@@ -1378,10 +1202,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x79, 0x92, 0xc5, 0x8f, 0xac, 0x32, 0xe3, 0x0c,
0x01, 0x9e, 0xaf, 0x41, 0xe0, 0xb3, 0x85, 0x7e,
0xa9, 0x00, 0xa1, 0x61, 0x08, 0xeb, 0x34, 0xde },
- { 0x60, 0x28, 0x6b, 0x5f, 0xb1, 0xa4, 0x7f, 0x8c,
- 0x79, 0x3e, 0xbe, 0x0a, 0x4f, 0x9e, 0xa0, 0xef,
- 0xb6, 0xff, 0xf7, 0xd0, 0x1c, 0x79, 0x10, 0xef,
- 0xf7, 0x4e, 0xd3, 0xb2, 0x88, 0xf4, 0xe6, 0x27 },
{ 0x60, 0xca, 0x81, 0xe3, 0x5b, 0x9a, 0x6f, 0x07,
0xe1, 0x3c, 0x02, 0xae, 0x41, 0x15, 0xb0, 0x00,
0x54, 0x30, 0xcf, 0x46, 0x0e, 0xfc, 0x7d, 0xba,
@@ -1406,18 +1226,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4d, 0xf9, 0x1e, 0x31, 0x32, 0x2e, 0x57, 0x74,
0x69, 0x1e, 0x0c, 0x41, 0xfa, 0x0d, 0x2f, 0x25,
0x7a, 0xd7, 0xf9, 0xf0, 0x25, 0x98, 0x14, 0x45 },
- { 0x63, 0x65, 0xeb, 0x4e, 0x37, 0xea, 0x23, 0x8b,
- 0xbc, 0x40, 0xa7, 0x65, 0x1e, 0xdd, 0x9a, 0x1c,
- 0x65, 0xfc, 0x54, 0xe3, 0xb8, 0x8f, 0xa7, 0xa0,
- 0x6d, 0x92, 0xc6, 0x13, 0xae, 0xde, 0xd6, 0x5d },
{ 0x63, 0x6a, 0x25, 0xbd, 0xdb, 0xb6, 0x5e, 0x7c,
0xc0, 0xe6, 0x1f, 0x91, 0xca, 0xfe, 0xb1, 0xfe,
0x5d, 0xd2, 0x67, 0xac, 0x67, 0x32, 0x25, 0xcc,
0x81, 0x8e, 0xa0, 0x2b, 0x9c, 0xc9, 0x4b, 0xe2 },
- { 0x64, 0x87, 0xc9, 0x20, 0xb1, 0x30, 0x16, 0xf4,
- 0xa0, 0xaa, 0xd3, 0x9f, 0xe1, 0x97, 0x8b, 0xec,
- 0xe9, 0xf4, 0xfa, 0x13, 0xed, 0x0c, 0x42, 0x4d,
- 0xaa, 0x41, 0x6b, 0xaa, 0x75, 0x89, 0x62, 0x01 },
{ 0x64, 0xd4, 0x92, 0x41, 0x6e, 0xe0, 0x55, 0x57,
0x9c, 0x46, 0x3b, 0x21, 0x1a, 0xfe, 0xf7, 0x46,
0xc3, 0x30, 0xca, 0x05, 0xf4, 0x4d, 0x85, 0x90,
@@ -1434,10 +1246,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x38, 0x07, 0x1a, 0xee, 0xde, 0xf8, 0xe1, 0x83,
0xe2, 0x37, 0x38, 0x46, 0x97, 0x26, 0xeb, 0x99,
0x68, 0x0c, 0xd2, 0x44, 0x72, 0x73, 0x6b, 0xec },
- { 0x66, 0x49, 0xe0, 0x34, 0xc6, 0x9d, 0x14, 0x24,
- 0xd2, 0x8c, 0x42, 0x68, 0xba, 0x95, 0x1e, 0xe1,
- 0xb4, 0x8a, 0xe1, 0x5f, 0xeb, 0xe7, 0xd6, 0xbe,
- 0x9d, 0x75, 0xf6, 0xa4, 0xac, 0x7a, 0xc2, 0x53 },
{ 0x66, 0x50, 0xb2, 0xea, 0x64, 0x4c, 0x3f, 0x4e,
0x8c, 0x9e, 0x3c, 0x46, 0xac, 0xea, 0xc4, 0x52,
0x33, 0xd8, 0x66, 0xe3, 0x98, 0xff, 0x90, 0xeb,
@@ -1566,14 +1374,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x8c, 0xc5, 0x2a, 0x48, 0x0a, 0xc0, 0x6d, 0x69,
0x71, 0xc5, 0xa3, 0xda, 0x97, 0xcf, 0x3e, 0xf0,
0x1a, 0xf2, 0x9d, 0x74, 0x72, 0x62, 0x31, 0xe2 },
- { 0x6e, 0xb8, 0xa7, 0xba, 0x7f, 0xc2, 0x1c, 0x62,
- 0x40, 0x3f, 0x63, 0x76, 0xbb, 0x10, 0x44, 0x82,
- 0x48, 0x8d, 0xa9, 0xc1, 0x41, 0x4a, 0xe3, 0xab,
- 0x06, 0xe0, 0x1e, 0xd7, 0x32, 0x42, 0xab, 0xd7 },
- { 0x6e, 0xeb, 0x39, 0xda, 0xd7, 0x3f, 0xc5, 0x99,
- 0x72, 0x42, 0x17, 0xcf, 0xf0, 0x21, 0xd5, 0xac,
- 0x4e, 0x7e, 0x2b, 0xf4, 0x76, 0xea, 0xf4, 0xfd,
- 0x4d, 0x7b, 0xfb, 0x6e, 0x4f, 0x18, 0xc1, 0x73 },
{ 0x6f, 0x3b, 0xb3, 0x4b, 0x5d, 0x32, 0x91, 0xdf,
0xb3, 0xe4, 0x12, 0x71, 0xa1, 0xd7, 0x30, 0xcd,
0xbc, 0xff, 0xc1, 0x0b, 0x68, 0x05, 0x9d, 0xcc,
@@ -1622,10 +1422,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x0e, 0xdf, 0xa3, 0x41, 0x1f, 0xbc, 0x9b, 0xad,
0x31, 0x65, 0xbe, 0x66, 0x0f, 0x34, 0x0a, 0xa2,
0x30, 0x8a, 0x5a, 0x33, 0x23, 0xfa, 0xbf, 0xa7 },
- { 0x73, 0x46, 0x99, 0x89, 0x4a, 0xd4, 0xb5, 0xa8,
- 0xa2, 0xdd, 0x9a, 0xb4, 0xfd, 0x5f, 0x63, 0x25,
- 0x30, 0x3b, 0x49, 0x16, 0x4c, 0xa8, 0xd8, 0xe7,
- 0xba, 0x99, 0x77, 0x81, 0x7e, 0x4a, 0xe2, 0x4f },
{ 0x73, 0x9d, 0x17, 0x23, 0x23, 0xf2, 0xb2, 0x84,
0x07, 0x0a, 0xce, 0x43, 0x09, 0x8c, 0x8b, 0x21,
0xc4, 0x7a, 0x53, 0xf9, 0x98, 0x5f, 0x2f, 0xad,
@@ -1646,10 +1442,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x00, 0xb4, 0x14, 0x73, 0xca, 0x44, 0xe6, 0x87,
0x96, 0x38, 0x74, 0x3d, 0x8f, 0xee, 0x66, 0xee,
0x71, 0x8c, 0x18, 0xd8, 0xf1, 0x12, 0x15, 0xd1 },
- { 0x75, 0xbb, 0x15, 0x25, 0x09, 0xb7, 0x19, 0x04,
- 0xe4, 0x40, 0x0f, 0xb4, 0x23, 0xa5, 0x80, 0xaa,
- 0xe1, 0xdd, 0xb7, 0x68, 0xf6, 0xfd, 0x36, 0xe6,
- 0x30, 0x94, 0xeb, 0xe3, 0x92, 0x15, 0xf3, 0x90 },
{ 0x75, 0xe9, 0xa1, 0x5d, 0x94, 0x88, 0x0c, 0x66,
0x14, 0x82, 0xcf, 0xc1, 0x96, 0x4c, 0xbc, 0xe2,
0xb1, 0xca, 0x7a, 0x9f, 0x81, 0xd4, 0x07, 0x30,
@@ -1666,10 +1458,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x83, 0x98, 0x71, 0x0f, 0x02, 0x20, 0xfa, 0xf3,
0x30, 0x1d, 0x54, 0x49, 0x38, 0xfb, 0x24, 0x19,
0x2d, 0xec, 0x32, 0xf7, 0x44, 0xe4, 0x22, 0x10 },
- { 0x76, 0xcd, 0xf0, 0x78, 0xa8, 0x89, 0x1f, 0x1b,
- 0x3d, 0x0a, 0xa7, 0x1d, 0x6e, 0x18, 0xd7, 0x6a,
- 0x4d, 0x20, 0x7a, 0xaf, 0x84, 0xc6, 0x12, 0x95,
- 0x0e, 0xdf, 0xcd, 0x92, 0x82, 0xa1, 0x11, 0x44 },
{ 0x77, 0x95, 0x6b, 0x48, 0xcd, 0xd9, 0x15, 0x0b,
0xd8, 0x7d, 0x8d, 0x81, 0x50, 0x60, 0xac, 0x8c,
0x84, 0x81, 0x3a, 0x53, 0x87, 0x1a, 0x58, 0x6a,
@@ -1682,10 +1470,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x7e, 0xd5, 0x33, 0xc9, 0x9c, 0xc8, 0x25, 0x08,
0xeb, 0xa6, 0xac, 0x3a, 0x0b, 0xe5, 0xbc, 0xbf,
0x7a, 0xc9, 0x94, 0x95, 0x2b, 0x6d, 0x35, 0x07 },
- { 0x77, 0xb9, 0x6a, 0x00, 0x77, 0x15, 0xa0, 0x8c,
- 0x6a, 0x22, 0xdb, 0x14, 0xc7, 0xf4, 0xf1, 0xd7,
- 0xf4, 0xa7, 0x41, 0xce, 0x47, 0x32, 0xec, 0xf8,
- 0x3e, 0x74, 0xc1, 0xc9, 0x63, 0x22, 0x83, 0xcd },
{ 0x77, 0xdd, 0xc8, 0x1b, 0xd2, 0x8b, 0x9d, 0x46,
0x1e, 0x7d, 0x3c, 0xd4, 0xa8, 0x12, 0x2a, 0xa9,
0x8a, 0x24, 0x60, 0xfb, 0xa0, 0x8f, 0x1b, 0x7b,
@@ -1746,14 +1530,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xf8, 0xa9, 0xb4, 0xd9, 0x8e, 0xa2, 0x9a, 0xe4,
0xa5, 0xa4, 0x24, 0x72, 0xf5, 0x91, 0xca, 0x11,
0xfb, 0x5e, 0x11, 0x21, 0x06, 0x28, 0x63, 0x96 },
- { 0x7c, 0x63, 0xb8, 0x8e, 0x58, 0x19, 0x07, 0x0f,
- 0xc1, 0x4a, 0xdb, 0x67, 0xd6, 0xda, 0xa1, 0x29,
- 0x83, 0x14, 0x30, 0x4a, 0x9c, 0x05, 0x30, 0x18,
- 0x02, 0x7d, 0xf8, 0x36, 0x91, 0x4d, 0x73, 0xd4 },
- { 0x7c, 0xa0, 0x86, 0x8b, 0xeb, 0xae, 0x8a, 0xca,
- 0x9d, 0x0f, 0x75, 0x38, 0x65, 0xc3, 0x2a, 0x0d,
- 0x2d, 0xd4, 0xf1, 0x48, 0x6e, 0x37, 0x34, 0xa6,
- 0xa3, 0x71, 0x0e, 0xcc, 0x3e, 0x57, 0xf9, 0xed },
{ 0x7c, 0xf9, 0x2f, 0x75, 0xbb, 0xe7, 0xa1, 0x4d,
0x86, 0x93, 0xf9, 0x93, 0xc3, 0xd1, 0xa6, 0x08,
0xdb, 0xe0, 0xd1, 0x8f, 0x80, 0x8e, 0x21, 0x2d,
@@ -1766,10 +1542,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xdd, 0xd6, 0x03, 0xb1, 0x75, 0xc9, 0xb2, 0x05,
0xac, 0x0b, 0x55, 0x3a, 0x4b, 0xf5, 0xfb, 0x08,
0xc2, 0x46, 0xec, 0xf9, 0xc8, 0x49, 0xdb, 0x28 },
- { 0x7f, 0x86, 0xd3, 0xaa, 0x7e, 0xa7, 0x5c, 0x18,
- 0x03, 0x9d, 0x6a, 0xf9, 0x9c, 0xef, 0x75, 0x04,
- 0xce, 0x7b, 0x05, 0x05, 0x9b, 0xbf, 0xe7, 0x3f,
- 0xcd, 0xec, 0xfc, 0x71, 0xb2, 0x53, 0x8d, 0x72 },
{ 0x7f, 0x95, 0x9b, 0x06, 0x34, 0xda, 0x94, 0xfa,
0xca, 0xda, 0xb0, 0x21, 0xcf, 0x94, 0x20, 0x78,
0x16, 0x00, 0x36, 0x13, 0xef, 0x09, 0xeb, 0x54,
@@ -1834,10 +1606,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x95, 0xe2, 0x5f, 0x91, 0xa5, 0xfb, 0x0f, 0x2a,
0xfc, 0xba, 0x7e, 0x09, 0xb2, 0x17, 0x27, 0xee,
0xd8, 0x13, 0x0c, 0xde, 0x8f, 0x08, 0x0f, 0xca },
- { 0x82, 0xd1, 0x9b, 0xd8, 0x0a, 0x88, 0x6b, 0x28,
- 0x61, 0xc3, 0x09, 0x97, 0x4c, 0x1c, 0x99, 0x3d,
- 0xbe, 0xc3, 0x7e, 0x30, 0x85, 0xc1, 0x47, 0xc4,
- 0x1f, 0x23, 0xd9, 0xf1, 0x20, 0xd8, 0x9b, 0x68 },
{ 0x82, 0xe1, 0xbd, 0xb3, 0xdc, 0x4f, 0x02, 0x36,
0x3a, 0x79, 0x6b, 0x60, 0xa8, 0x8e, 0x4e, 0x71,
0xbd, 0x33, 0xb0, 0xbe, 0x4c, 0xc5, 0xb8, 0x33,
@@ -1866,10 +1634,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xcf, 0x81, 0xb7, 0xd5, 0xff, 0x51, 0xa7, 0xa5,
0x6a, 0x84, 0x78, 0x3a, 0x2d, 0xf7, 0x43, 0x61,
0xff, 0x2e, 0xee, 0x0f, 0x92, 0x12, 0xc1, 0x59 },
- { 0x84, 0x26, 0xbc, 0x06, 0xdb, 0xb5, 0x18, 0x71,
- 0x34, 0x66, 0xc7, 0x6a, 0xea, 0x52, 0x1b, 0xce,
- 0x39, 0xd3, 0x91, 0xa8, 0x89, 0xcb, 0xba, 0x9b,
- 0x7b, 0x72, 0xdc, 0xda, 0x89, 0xf3, 0x46, 0x55 },
{ 0x84, 0x7b, 0x5f, 0x1e, 0xeb, 0x2a, 0x44, 0x13,
0xc8, 0xfa, 0x37, 0x98, 0x21, 0x97, 0x37, 0xe1,
0x92, 0xba, 0x72, 0x72, 0xa1, 0x08, 0xb7, 0x17,
@@ -1914,14 +1678,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xe8, 0x1c, 0x27, 0xd1, 0xca, 0xf2, 0x74, 0xb1,
0x7d, 0x72, 0x0d, 0xf8, 0x07, 0x8b, 0x6f, 0x2a,
0x5c, 0x3b, 0xb8, 0xd8, 0xdf, 0xf0, 0x55, 0x00 },
- { 0x87, 0xeb, 0xcb, 0xb0, 0x73, 0x7a, 0xe3, 0x27,
- 0xc6, 0xbe, 0x9d, 0x3f, 0xa2, 0xc7, 0x5d, 0x1e,
- 0xea, 0x0a, 0xe6, 0x6d, 0x20, 0xd3, 0x8a, 0xf6,
- 0xed, 0x76, 0xe6, 0xb1, 0x49, 0x9c, 0x83, 0x1f },
- { 0x88, 0x51, 0x76, 0x78, 0x61, 0xc9, 0x72, 0x7d,
- 0x92, 0x77, 0x63, 0x62, 0x78, 0xfb, 0x94, 0x1b,
- 0x88, 0x85, 0xd9, 0x99, 0x02, 0x48, 0xbf, 0x91,
- 0x45, 0x9e, 0x52, 0x7c, 0xe7, 0xf0, 0x6c, 0xf6 },
{ 0x88, 0x76, 0x88, 0xdc, 0x6e, 0x9f, 0xe3, 0xdb,
0x05, 0x05, 0x7f, 0xc6, 0x38, 0xeb, 0x8b, 0x29,
0x4c, 0x3d, 0x8e, 0x0a, 0xae, 0x17, 0x51, 0xf7,
@@ -2002,10 +1758,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x81, 0x0d, 0x6e, 0x19, 0xf5, 0xf8, 0x8e, 0xa2,
0xc6, 0x5d, 0xb7, 0xa2, 0xe8, 0xa5, 0x06, 0xf7,
0xdf, 0x99, 0x55, 0x81, 0x7d, 0xdd, 0xeb, 0xc8 },
- { 0x8d, 0x74, 0xc0, 0xd6, 0x6b, 0xb2, 0xee, 0xb2,
- 0x6b, 0x9a, 0x55, 0x74, 0x38, 0x5d, 0xa7, 0xb4,
- 0x14, 0x0a, 0xf0, 0x70, 0x47, 0xd2, 0xfe, 0x64,
- 0x3d, 0x1d, 0x1a, 0xe5, 0xb1, 0x96, 0x90, 0x43 },
{ 0x8d, 0x85, 0xda, 0x44, 0x6f, 0x5c, 0x79, 0x54,
0xbd, 0xf7, 0x6c, 0x09, 0x0c, 0xd2, 0x46, 0x68,
0xff, 0x23, 0x3c, 0xcd, 0xf6, 0x6b, 0x94, 0xda,
@@ -2182,10 +1934,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x60, 0x71, 0xd3, 0x82, 0x18, 0x1a, 0xf6, 0xcb,
0x25, 0xbd, 0xc5, 0x87, 0x5e, 0x29, 0xf0, 0xf4,
0xd7, 0x19, 0xa9, 0xd3, 0x5b, 0x5b, 0xd6, 0xbf },
- { 0x99, 0xb1, 0x38, 0xbb, 0x53, 0xc5, 0x4d, 0x1c,
- 0x7a, 0xc2, 0x9a, 0x57, 0x85, 0xc8, 0xb1, 0x9f,
- 0xdd, 0xc3, 0x7d, 0x99, 0x4a, 0x3e, 0x6c, 0x31,
- 0xf7, 0x50, 0xa1, 0xbf, 0xeb, 0xe9, 0xfe, 0xf9 },
{ 0x99, 0xb4, 0x6c, 0x68, 0x90, 0x62, 0x37, 0x40,
0x23, 0xdb, 0x68, 0x19, 0xf8, 0x89, 0xd3, 0xc1,
0xbb, 0x8a, 0x83, 0x8c, 0x6b, 0x51, 0x7e, 0x32,
@@ -2258,18 +2006,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xfe, 0x1f, 0xd8, 0xdf, 0x2d, 0x36, 0xdd, 0xef,
0x00, 0xc8, 0xfc, 0x7b, 0xf7, 0xb7, 0xfd, 0x7e,
0x8d, 0x45, 0x92, 0xab, 0xf3, 0xc4, 0x21, 0xde },
- { 0x9e, 0x85, 0xd4, 0xac, 0x8b, 0x36, 0x0e, 0x4d,
- 0xb2, 0xed, 0x37, 0x34, 0x10, 0x16, 0xe3, 0x7b,
- 0xd5, 0x5c, 0x2d, 0x59, 0x79, 0x5d, 0x0a, 0x7c,
- 0x26, 0xa4, 0x4e, 0x7e, 0x80, 0x98, 0x3e, 0x75 },
{ 0x9e, 0x98, 0xf7, 0xda, 0x04, 0x74, 0xd4, 0x86,
0x5a, 0xc7, 0x05, 0xd4, 0xd7, 0xab, 0xbe, 0xb7,
0x1a, 0xef, 0xba, 0x2c, 0xf2, 0xe0, 0x82, 0xf0,
0x5f, 0xed, 0x53, 0x62, 0x41, 0x4b, 0xd3, 0x93 },
- { 0x9e, 0xea, 0x28, 0xdf, 0x01, 0x4d, 0x91, 0x24,
- 0x4f, 0xf9, 0x31, 0x4f, 0x43, 0x4a, 0x84, 0x7b,
- 0x65, 0x89, 0xc1, 0xf2, 0x03, 0x58, 0x33, 0x9d,
- 0x79, 0xfc, 0xa6, 0x76, 0x63, 0x2d, 0xff, 0xfe },
{ 0x9f, 0x24, 0x5c, 0x0a, 0x0e, 0xc6, 0x3a, 0xaa,
0xcb, 0xf9, 0x69, 0xc6, 0xfc, 0x24, 0xa1, 0x07,
0x15, 0x83, 0xb7, 0x79, 0xa5, 0x8a, 0xb6, 0x23,
@@ -2282,18 +2022,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xb6, 0x2f, 0xa6, 0xe3, 0x23, 0x95, 0xeb, 0xe8,
0x33, 0x34, 0x46, 0x00, 0x43, 0x6d, 0xac, 0xc9,
0xb5, 0x69, 0x21, 0x4e, 0xeb, 0x8c, 0x0a, 0xf0 },
- { 0x9f, 0xf9, 0x38, 0x40, 0xb0, 0x1f, 0x96, 0xb6,
- 0xf3, 0xc3, 0x10, 0xa0, 0x21, 0x90, 0xad, 0xc3,
- 0x3a, 0x15, 0x69, 0x39, 0x5b, 0xbc, 0xee, 0x11,
- 0x6a, 0x15, 0xe1, 0x58, 0xa6, 0x2b, 0xa5, 0x0b },
{ 0xa0, 0x05, 0x20, 0xb9, 0x68, 0xbf, 0xcb, 0x63,
0x40, 0x87, 0x9f, 0xa8, 0x43, 0x82, 0x0c, 0xec,
0x95, 0x45, 0x86, 0x0f, 0xe2, 0x9e, 0x2f, 0x8f,
0xee, 0x00, 0xb0, 0x0f, 0xf8, 0x43, 0x42, 0x74 },
- { 0xa0, 0x44, 0xf2, 0xc0, 0x41, 0xf4, 0x18, 0x5b,
- 0xc0, 0xfe, 0x1a, 0xd3, 0xe0, 0xa3, 0xe0, 0xc2,
- 0x7e, 0x24, 0xf4, 0x58, 0xdc, 0xb7, 0xd9, 0x07,
- 0x39, 0xb6, 0x4a, 0x68, 0x94, 0x45, 0xd4, 0xb6 },
{ 0xa0, 0x77, 0x42, 0xd5, 0xb2, 0x99, 0x96, 0x65,
0x06, 0x76, 0x2e, 0x02, 0xe4, 0x20, 0xf1, 0xa9,
0xc4, 0xab, 0x73, 0x29, 0xae, 0x29, 0x5f, 0x01,
@@ -2306,10 +2038,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x37, 0x14, 0xd5, 0xb3, 0x44, 0x5d, 0x88, 0xbe,
0x81, 0xff, 0x5e, 0x1d, 0x16, 0x07, 0x3d, 0xc1,
0x16, 0x6b, 0xb5, 0x44, 0x8f, 0xf6, 0x52, 0xdf },
- { 0xa0, 0xc8, 0xa5, 0x3f, 0xd7, 0x58, 0x3e, 0x43,
- 0x91, 0xbe, 0xb8, 0xd0, 0xfe, 0xd8, 0x43, 0x1f,
- 0x61, 0xb8, 0x52, 0xc1, 0xbe, 0x43, 0xab, 0x91,
- 0x61, 0x4b, 0xbb, 0xeb, 0x3b, 0x4f, 0x47, 0x4e },
{ 0xa1, 0x50, 0x03, 0x2f, 0x4e, 0xf5, 0xd4, 0xfe,
0xb0, 0xae, 0x4a, 0xe1, 0xcd, 0x54, 0x35, 0xba,
0x04, 0xa9, 0xb6, 0xa0, 0xf9, 0x0e, 0x2f, 0x3c,
@@ -2354,18 +2082,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4f, 0xdc, 0x08, 0x15, 0xb8, 0x6e, 0xa3, 0x03,
0x34, 0x3c, 0xf8, 0xc1, 0x0f, 0x37, 0x27, 0x83,
0x27, 0x14, 0x86, 0xb9, 0xc9, 0x3b, 0x63, 0x67 },
- { 0xa5, 0xdb, 0xaf, 0x01, 0xd3, 0xd5, 0x79, 0xee,
- 0x8a, 0x48, 0x8e, 0xe8, 0xd7, 0x44, 0x09, 0x58,
- 0xf7, 0xbf, 0x97, 0xa2, 0xbc, 0xa8, 0xd9, 0x71,
- 0xf6, 0xf8, 0x97, 0x10, 0xbc, 0x2d, 0x10, 0x6f },
{ 0xa6, 0x21, 0xae, 0x36, 0x54, 0xac, 0xfd, 0x17,
0x23, 0x30, 0x70, 0xe9, 0xb1, 0x8d, 0xfd, 0x91,
0x6a, 0x55, 0x2e, 0x6a, 0x8b, 0x82, 0x42, 0xbd,
0x57, 0xbb, 0xcd, 0xf4, 0xe6, 0x5e, 0x99, 0x76 },
- { 0xa6, 0x26, 0x87, 0xde, 0x88, 0x0c, 0xf3, 0x35,
- 0xae, 0x42, 0x4d, 0x4a, 0xde, 0x29, 0xc7, 0xec,
- 0x33, 0xbf, 0xb9, 0xf8, 0x6e, 0xc7, 0xfc, 0xaf,
- 0x61, 0x9d, 0x71, 0x7c, 0x86, 0xb8, 0xfb, 0xbc },
{ 0xa6, 0x33, 0x5d, 0xf3, 0xab, 0xa5, 0xea, 0xdf,
0xbd, 0xc9, 0xc2, 0xdc, 0x9d, 0x6b, 0xe6, 0x0b,
0xb6, 0x2d, 0xf2, 0xfe, 0x24, 0xec, 0x7b, 0xa7,
@@ -2402,10 +2122,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x32, 0xed, 0xb3, 0xc8, 0xd6, 0x8c, 0xe1, 0x35,
0x1a, 0x48, 0xb5, 0x6f, 0x70, 0x11, 0xbb, 0x99,
0x20, 0xcf, 0xca, 0x75, 0x7e, 0x57, 0xc6, 0xc4 },
- { 0xa7, 0x86, 0x18, 0xd8, 0xa7, 0xf0, 0x08, 0xaf,
- 0xdc, 0x72, 0x44, 0x98, 0x2c, 0x11, 0x34, 0xc5,
- 0xdc, 0x91, 0xec, 0x94, 0x25, 0xbf, 0xef, 0xc8,
- 0xcc, 0x0a, 0xf8, 0xf8, 0xc7, 0x59, 0x61, 0xc2 },
{ 0xa8, 0x53, 0xad, 0xc1, 0xc2, 0x18, 0x59, 0xaf,
0x7c, 0x46, 0x2b, 0x4a, 0xa0, 0xa5, 0x74, 0xca,
0x9f, 0xee, 0xfb, 0x18, 0x5a, 0x1f, 0xdb, 0xb6,
@@ -2414,10 +2130,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x11, 0x6f, 0x6a, 0x8b, 0x01, 0xe2, 0x95, 0xcd,
0x60, 0x72, 0x69, 0x5a, 0xb1, 0x65, 0x4b, 0x7b,
0xf9, 0xc4, 0x7e, 0x06, 0x20, 0x25, 0x6f, 0x81 },
- { 0xa8, 0xc6, 0xb0, 0x72, 0x2a, 0x0d, 0x13, 0xdc,
- 0x8b, 0x7f, 0xbb, 0x20, 0xbc, 0x66, 0xe6, 0x03,
- 0x0e, 0x4b, 0xde, 0x99, 0xea, 0xca, 0x9c, 0x96,
- 0x5d, 0x34, 0x65, 0xc9, 0xab, 0xff, 0x64, 0x11 },
{ 0xa8, 0xdf, 0xf0, 0x6a, 0x17, 0x35, 0xb4, 0x6d,
0x17, 0xda, 0xeb, 0xc3, 0x43, 0x43, 0x18, 0x31,
0x3b, 0x2d, 0x9e, 0x7c, 0x3e, 0xf4, 0x8f, 0x28,
@@ -2430,18 +2142,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x56, 0x21, 0x2d, 0xb3, 0xab, 0x34, 0x89, 0x6e,
0x91, 0x70, 0x93, 0x11, 0x3e, 0x47, 0xca, 0x35,
0x96, 0x2e, 0xac, 0xca, 0x9c, 0xb3, 0x86, 0xf0 },
- { 0xa9, 0x20, 0x6f, 0x6d, 0x45, 0x43, 0xed, 0x74,
- 0x4a, 0x5f, 0x15, 0x4a, 0xcb, 0x44, 0x50, 0x89,
- 0x6b, 0x62, 0x5d, 0x7e, 0x32, 0x33, 0x85, 0xa9,
- 0xfd, 0x25, 0x63, 0x93, 0x2f, 0x9c, 0xcc, 0x1b },
- { 0xa9, 0x4c, 0xc9, 0xde, 0x55, 0x52, 0xa6, 0xd9,
- 0x6f, 0xe4, 0x10, 0xbe, 0x03, 0x97, 0x6f, 0x6b,
- 0x0d, 0x4d, 0xa0, 0x5d, 0x73, 0x7a, 0xd2, 0xa3,
- 0x1e, 0x0b, 0xad, 0x90, 0x82, 0xa5, 0x77, 0xb1 },
- { 0xa9, 0x5c, 0x06, 0x3e, 0x9e, 0x35, 0x84, 0xe5,
- 0x99, 0x88, 0xf0, 0x73, 0x86, 0x4c, 0x18, 0x76,
- 0xb5, 0xdf, 0x9b, 0x44, 0xc6, 0x1b, 0x4a, 0x8b,
- 0xe4, 0x83, 0xbe, 0x05, 0xcf, 0xd1, 0xa1, 0xa6 },
{ 0xa9, 0x71, 0x2f, 0x85, 0xed, 0x2e, 0x25, 0xad,
0xa5, 0x7d, 0xc1, 0xf0, 0xf8, 0x6d, 0xe1, 0x07,
0xb5, 0xe2, 0xf0, 0x36, 0x09, 0x53, 0xf1, 0xed,
@@ -2470,10 +2170,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xec, 0xce, 0x7f, 0x5e, 0x61, 0x59, 0x9a, 0xf5,
0x26, 0x69, 0xbf, 0x59, 0x50, 0x7f, 0x8e, 0xf1,
0x99, 0x13, 0xc4, 0x2e, 0xe1, 0x29, 0xda, 0xf0 },
- { 0xab, 0xa7, 0x8e, 0x90, 0xf3, 0x24, 0x17, 0xae,
- 0xc2, 0x8e, 0xea, 0x30, 0x22, 0xa2, 0xe2, 0xb7,
- 0x66, 0x1a, 0xc7, 0x23, 0xc8, 0x7e, 0x0d, 0xbc,
- 0xe2, 0x33, 0xe2, 0x16, 0x8f, 0xcf, 0x91, 0xb3 },
{ 0xab, 0xeb, 0x6a, 0xa0, 0xd1, 0xb0, 0xe0, 0x49,
0xd6, 0x9d, 0xf8, 0x3a, 0xdd, 0x19, 0xf7, 0x26,
0x8a, 0x38, 0xde, 0x6c, 0x00, 0x72, 0x60, 0x68,
@@ -2486,10 +2182,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x5a, 0xd4, 0xa3, 0xba, 0x3d, 0x4b, 0x01, 0x84,
0x91, 0xf3, 0x66, 0x1a, 0x37, 0x9b, 0x3d, 0xfe,
0xdd, 0x6f, 0xd3, 0xc3, 0x2e, 0xfa, 0x84, 0x7d },
- { 0xac, 0x8c, 0x6f, 0x03, 0xe4, 0xba, 0xcf, 0x72,
- 0x20, 0x25, 0xdb, 0x54, 0xd0, 0xfa, 0xae, 0x7d,
- 0xbe, 0x51, 0x37, 0x97, 0x37, 0x39, 0x45, 0x05,
- 0xf0, 0x86, 0xaa, 0x89, 0xe2, 0xd4, 0xf7, 0x3b },
{ 0xac, 0x90, 0x98, 0xf6, 0x4f, 0xe1, 0x03, 0xc8,
0xc1, 0x40, 0x30, 0xdb, 0xce, 0xdd, 0x63, 0xd1,
0xd1, 0x7c, 0x33, 0x8e, 0xbd, 0x1d, 0x7d, 0xe5,
@@ -2610,10 +2302,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xa0, 0x49, 0xfe, 0x83, 0xf3, 0xd2, 0x9b, 0x38,
0x5b, 0x90, 0xd3, 0xd0, 0x0b, 0xa8, 0x57, 0xd6,
0x2f, 0x19, 0x67, 0x81, 0xdd, 0xa3, 0xd1, 0x85 },
- { 0xb4, 0x2c, 0x64, 0xf0, 0x25, 0xdf, 0x8f, 0x37,
- 0x0e, 0xb7, 0xa4, 0x69, 0x94, 0x2b, 0x97, 0xe2,
- 0xf8, 0xb5, 0xf4, 0xbf, 0xac, 0xc4, 0xcf, 0x17,
- 0xd2, 0xa0, 0x8f, 0xca, 0x57, 0xbb, 0xc4, 0x9b },
{ 0xb4, 0xae, 0x2a, 0x6b, 0xfc, 0xa5, 0x31, 0xc9,
0x9c, 0x69, 0xb3, 0x5a, 0xfe, 0x67, 0x54, 0xfc,
0x49, 0x27, 0x5b, 0x6c, 0xca, 0xcd, 0xc8, 0x26,
@@ -2666,14 +2354,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4f, 0x2b, 0x81, 0xf7, 0xf7, 0x21, 0x06, 0x73,
0xe9, 0x73, 0x08, 0xaf, 0xf1, 0x24, 0x3f, 0x26,
0x99, 0x5a, 0x25, 0xfa, 0x23, 0x0c, 0xfe, 0x4c },
- { 0xb7, 0x45, 0x85, 0x05, 0xc5, 0x17, 0x90, 0x14,
- 0x9c, 0x5e, 0x98, 0x00, 0xfd, 0x22, 0x74, 0x8a,
- 0x1d, 0x44, 0x66, 0x5f, 0x68, 0x34, 0xba, 0x84,
- 0x4e, 0x9a, 0x0c, 0x32, 0x31, 0x4a, 0x57, 0x21 },
- { 0xb7, 0x9f, 0xca, 0x4d, 0x47, 0x92, 0xec, 0x5e,
- 0x5a, 0x74, 0x06, 0x59, 0x81, 0x3a, 0x0f, 0x46,
- 0x08, 0xea, 0xf9, 0xba, 0x9c, 0xbb, 0xa8, 0xa0,
- 0xf8, 0xda, 0xe1, 0xdd, 0xbb, 0xe6, 0x1e, 0x77 },
{ 0xb7, 0xa2, 0xae, 0x06, 0x06, 0xaa, 0x2c, 0xfb,
0x27, 0x01, 0xb3, 0xb2, 0x77, 0xf4, 0xd7, 0x12,
0x54, 0x70, 0x48, 0x7e, 0xfd, 0x94, 0x05, 0x85,
@@ -2694,10 +2374,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x62, 0xb6, 0x2f, 0x36, 0x50, 0xdb, 0x00, 0xa3,
0x45, 0xf4, 0x6a, 0x0e, 0x8e, 0x01, 0x1a, 0x20,
0x01, 0x3f, 0xd8, 0xed, 0xce, 0x25, 0x27, 0x0d },
- { 0xb9, 0xcc, 0x92, 0xf7, 0x8c, 0x2c, 0x19, 0x57,
- 0xdb, 0xb6, 0xc4, 0xa5, 0xe4, 0x25, 0x44, 0x68,
- 0xfb, 0xcd, 0x88, 0xb1, 0xfd, 0x9f, 0x98, 0xfa,
- 0x6d, 0x76, 0x08, 0x70, 0x9e, 0xbe, 0x92, 0x8d },
{ 0xba, 0x18, 0x2c, 0x1b, 0x75, 0xd8, 0xdf, 0xd1,
0x18, 0x92, 0xe4, 0x77, 0x59, 0x59, 0xad, 0x8a,
0x8c, 0x78, 0x2c, 0xef, 0x60, 0xec, 0xea, 0xbe,
@@ -2714,10 +2390,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x51, 0x61, 0x13, 0x55, 0x2c, 0x17, 0xab, 0x77,
0x82, 0xa7, 0xeb, 0xba, 0xea, 0x0b, 0xe3, 0x9f,
0x58, 0x92, 0x84, 0x1f, 0x1f, 0x74, 0xd2, 0x98 },
- { 0xbb, 0x13, 0xdf, 0x73, 0xb6, 0xe8, 0x89, 0x77,
- 0x7c, 0x4d, 0x85, 0xec, 0x93, 0xb8, 0x3e, 0xa8,
- 0xbb, 0x95, 0x43, 0xf9, 0xfc, 0x08, 0xc2, 0xb3,
- 0x1c, 0x02, 0xac, 0x72, 0xb3, 0x1a, 0x09, 0x0d },
{ 0xbb, 0x5c, 0xb3, 0x78, 0xb7, 0xb9, 0x48, 0x7f,
0xa6, 0x1b, 0xc0, 0x91, 0x3d, 0xa1, 0xdf, 0x26,
0xa1, 0xcf, 0xef, 0xf7, 0x45, 0x2d, 0x9b, 0xa3,
@@ -2734,14 +2406,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x8c, 0xa8, 0xbc, 0x2c, 0x62, 0xfb, 0xcc, 0x40,
0x17, 0xff, 0x24, 0x96, 0x98, 0xbe, 0xed, 0xfb,
0x1e, 0xf3, 0x6f, 0x37, 0x5f, 0xb3, 0x9f, 0x72 },
- { 0xbc, 0x1a, 0x3b, 0x83, 0x46, 0xa5, 0x18, 0x4e,
- 0x8f, 0xe2, 0xa9, 0x36, 0xd6, 0xd9, 0xce, 0x2c,
- 0xbe, 0x3a, 0x92, 0x05, 0x54, 0xe0, 0x60, 0xf9,
- 0x07, 0x97, 0xf9, 0x8f, 0xee, 0x62, 0xa8, 0x52 },
- { 0xbc, 0x98, 0x39, 0xc8, 0xb9, 0x22, 0xf6, 0x54,
- 0x57, 0x67, 0xa2, 0xba, 0x46, 0x5a, 0x5b, 0xea,
- 0x9a, 0xa1, 0x84, 0x11, 0x52, 0x99, 0x4a, 0x6c,
- 0xf4, 0x67, 0x83, 0xae, 0x49, 0x98, 0xaf, 0xcc },
{ 0xbd, 0x2e, 0x2f, 0x37, 0xc9, 0x66, 0xc3, 0x86,
0xd9, 0x70, 0x44, 0xfd, 0xe3, 0xe3, 0xf9, 0x00,
0xfb, 0x1a, 0x0b, 0x04, 0x03, 0xb5, 0x81, 0x72,
@@ -2750,10 +2414,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x2a, 0xa7, 0xa7, 0x5f, 0x77, 0x63, 0xa8, 0x38,
0xcf, 0x4b, 0xa1, 0x7f, 0xb3, 0x64, 0x72, 0xba,
0x12, 0x69, 0x8c, 0x45, 0xdf, 0x88, 0xe8, 0x46 },
- { 0xbe, 0x2e, 0x88, 0xc5, 0xee, 0x30, 0x7b, 0xa5,
- 0x41, 0x73, 0xa6, 0x00, 0x2b, 0x99, 0x16, 0x92,
- 0xc8, 0xbd, 0x1d, 0x40, 0x8a, 0x59, 0x2f, 0x70,
- 0x7b, 0xb1, 0xaf, 0x56, 0xf5, 0xb9, 0xd7, 0x42 },
{ 0xbe, 0x41, 0x0a, 0x51, 0xd3, 0x44, 0x17, 0x76,
0x91, 0xb3, 0x42, 0x64, 0x10, 0xa4, 0x41, 0xaf,
0xd1, 0xc9, 0x40, 0xb1, 0xb2, 0x7c, 0xf5, 0x29,
@@ -2762,10 +2422,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xb6, 0x20, 0x4f, 0x20, 0x13, 0x1b, 0x01, 0xff,
0x28, 0xb7, 0xdd, 0xff, 0x36, 0x2e, 0x42, 0x9b,
0xfd, 0xf8, 0x8f, 0x36, 0x37, 0x58, 0x24, 0x51 },
- { 0xbe, 0xac, 0x00, 0x60, 0x68, 0x7e, 0xb2, 0x5a,
- 0x9b, 0xed, 0x21, 0xa1, 0x99, 0x97, 0xaf, 0xff,
- 0x67, 0x7c, 0x89, 0x61, 0xdc, 0x00, 0xe2, 0x3b,
- 0x4c, 0x1e, 0x27, 0x7f, 0xf8, 0x58, 0xc0, 0x92 },
{ 0xbe, 0xb9, 0x09, 0x0c, 0x92, 0xd1, 0x6b, 0xd0,
0x5a, 0xf3, 0x91, 0x5a, 0x39, 0xcc, 0x2a, 0xfa,
0x9f, 0x6a, 0x8a, 0x6f, 0xbe, 0xd4, 0xfe, 0x54,
@@ -2814,10 +2470,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xf7, 0xbd, 0x38, 0x95, 0x54, 0x60, 0xc3, 0xfc,
0x43, 0x55, 0x0d, 0x97, 0x7f, 0x25, 0xe3, 0x43,
0xd4, 0x9c, 0xd4, 0xaf, 0xad, 0xf2, 0x09, 0x3c },
- { 0xc0, 0xd3, 0xdc, 0x9a, 0x2d, 0x13, 0x9d, 0x38,
- 0xce, 0x02, 0xc0, 0x78, 0xf3, 0xc2, 0x92, 0x5d,
- 0x89, 0x1d, 0x24, 0xe4, 0x36, 0x13, 0xcb, 0xee,
- 0x3f, 0x18, 0xa2, 0xc8, 0x60, 0x98, 0x84, 0xb2 },
{ 0xc0, 0xfe, 0xb7, 0x2a, 0x5f, 0x33, 0x16, 0x5c,
0x0d, 0xc7, 0xc4, 0x24, 0x7e, 0x23, 0xf3, 0x8c,
0xc6, 0x1f, 0x25, 0x24, 0x42, 0xb2, 0xf6, 0x13,
@@ -2938,10 +2590,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x8a, 0x88, 0x16, 0x10, 0x63, 0x70, 0x86, 0xf8,
0x8d, 0x9a, 0x11, 0x5e, 0x00, 0x92, 0x46, 0xd2,
0x7f, 0x48, 0x9f, 0xa7, 0x18, 0x51, 0x88, 0xa8 },
- { 0xc7, 0xf8, 0x85, 0xe4, 0x1a, 0xa5, 0x3b, 0x8c,
- 0xb8, 0xe4, 0xe5, 0x59, 0xc4, 0x04, 0x3a, 0x87,
- 0xda, 0xfb, 0x78, 0x7a, 0x0d, 0x2b, 0x2e, 0xf1,
- 0xbc, 0xc0, 0x55, 0x71, 0xb7, 0x5d, 0x4e, 0x29 },
{ 0xc7, 0xff, 0x8e, 0xfd, 0xec, 0xdf, 0x00, 0xd1,
0xfc, 0x8d, 0x55, 0x2d, 0x2a, 0x70, 0x70, 0xe5,
0xe3, 0x3d, 0x42, 0xe5, 0x90, 0xf5, 0x86, 0xc6,
@@ -2974,10 +2622,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xb6, 0x1b, 0x90, 0x92, 0xa9, 0xaa, 0x96, 0x81,
0x62, 0x36, 0x55, 0xa6, 0x6f, 0x4f, 0xcb, 0xc4,
0xd3, 0xa6, 0x7e, 0xfd, 0x56, 0x72, 0x48, 0x30 },
- { 0xc9, 0x7e, 0x4d, 0x81, 0xe7, 0x4e, 0x3d, 0x0a,
- 0x5e, 0xe0, 0x9c, 0x6f, 0x76, 0x9b, 0x95, 0x7e,
- 0x70, 0x04, 0xad, 0x2c, 0x9f, 0xc6, 0x66, 0x8a,
- 0x69, 0xd6, 0xca, 0x29, 0xe0, 0x66, 0xe7, 0xfe },
{ 0xca, 0x55, 0x6f, 0x82, 0xc9, 0x68, 0x4c, 0x9a,
0xf3, 0x55, 0x7d, 0x3e, 0x2d, 0x88, 0xaf, 0x92,
0xed, 0x25, 0x9c, 0x20, 0xff, 0xd1, 0xdd, 0xe9,
@@ -3014,10 +2658,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x49, 0xc8, 0xb7, 0xa8, 0x14, 0x8f, 0x26, 0xd7,
0x71, 0x08, 0x3e, 0xc5, 0x18, 0xf9, 0xb6, 0x6f,
0xf5, 0x47, 0xf2, 0x82, 0x2d, 0x11, 0x93, 0x6d },
- { 0xcc, 0x4e, 0x09, 0x63, 0x13, 0xdf, 0xa0, 0xcc,
- 0x24, 0x77, 0xa3, 0xa5, 0xb7, 0x9a, 0xef, 0x0a,
- 0x45, 0x54, 0x58, 0x69, 0xa7, 0xf8, 0x8a, 0x29,
- 0x14, 0x96, 0x06, 0x4b, 0x69, 0x76, 0xe1, 0x4d },
{ 0xcc, 0x65, 0xcd, 0xc5, 0x33, 0x62, 0xd4, 0x21,
0x62, 0x7e, 0xae, 0xf5, 0xd0, 0xc8, 0xe4, 0xc4,
0xe2, 0x40, 0xad, 0xe0, 0xc9, 0xd4, 0x20, 0xbe,
@@ -3054,10 +2694,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x85, 0xf5, 0xb6, 0x4e, 0x65, 0x22, 0x8d, 0x03,
0xfc, 0x77, 0x93, 0xd9, 0x49, 0x42, 0xf8, 0x8a,
0x1c, 0x72, 0xbb, 0x7b, 0x61, 0x14, 0x51, 0xd5 },
- { 0xcf, 0x03, 0x40, 0x17, 0x5b, 0x25, 0x03, 0xc8,
- 0xfa, 0x5d, 0x52, 0xed, 0x42, 0x5b, 0xf3, 0x7e,
- 0x69, 0xc1, 0x80, 0xe5, 0x75, 0xad, 0xc1, 0xa2,
- 0x6a, 0x47, 0x81, 0x97, 0x71, 0xb6, 0x8f, 0x7d },
{ 0xcf, 0x92, 0x77, 0xce, 0xea, 0x50, 0x1a, 0x49,
0x66, 0x04, 0x3e, 0xf2, 0xb0, 0xf8, 0x86, 0x2a,
0xc9, 0x00, 0x93, 0x89, 0x78, 0x08, 0x26, 0x22,
@@ -3082,14 +2718,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xbb, 0x8b, 0xaf, 0x57, 0xf5, 0xc4, 0x5b, 0x69,
0x16, 0x8c, 0x3a, 0x6e, 0xe3, 0xfb, 0xcd, 0xf3,
0xec, 0x2a, 0x77, 0xe8, 0x7c, 0x7c, 0x50, 0x09 },
- { 0xd1, 0xfa, 0xd9, 0xa8, 0xe6, 0x2e, 0x06, 0xcf,
- 0x9b, 0x40, 0x3a, 0xdf, 0x51, 0xed, 0x60, 0x75,
- 0xec, 0xe7, 0x61, 0xa1, 0x0d, 0xd6, 0xa4, 0xd8,
- 0xde, 0x08, 0x82, 0x2f, 0xbb, 0x08, 0x22, 0xfd },
- { 0xd2, 0x3f, 0xeb, 0x93, 0x47, 0x60, 0xb8, 0xdf,
- 0x4e, 0xe6, 0xb0, 0xe8, 0xbb, 0x4f, 0x5d, 0x31,
- 0x5d, 0x40, 0x5b, 0xf0, 0x56, 0x18, 0x2e, 0x5d,
- 0x5f, 0x70, 0x20, 0x31, 0x94, 0x61, 0x8a, 0x05 },
{ 0xd2, 0x56, 0x79, 0xcb, 0x58, 0x3b, 0xa0, 0x10,
0x8f, 0x74, 0x97, 0xe3, 0x21, 0xc6, 0x5c, 0x4d,
0xc2, 0xca, 0x0f, 0x28, 0x20, 0xc7, 0xfc, 0xdb,
@@ -3102,18 +2730,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4c, 0x2d, 0xfe, 0x94, 0xcb, 0x44, 0x50, 0x37,
0x1e, 0x72, 0x36, 0xbd, 0xbd, 0x1c, 0x81, 0x13,
0xff, 0x36, 0x0f, 0xa4, 0xa1, 0x58, 0x1e, 0xfc },
- { 0xd2, 0xd1, 0x84, 0xca, 0x5b, 0x97, 0xac, 0x7b,
- 0xd3, 0x4e, 0x78, 0x42, 0x4c, 0xa0, 0xc2, 0xb3,
- 0x9c, 0x35, 0x08, 0x52, 0xcc, 0xb1, 0x33, 0xe5,
- 0xa1, 0x87, 0xf7, 0x61, 0x7d, 0x00, 0xb0, 0x2c },
{ 0xd2, 0xe8, 0xa1, 0x23, 0x7a, 0x93, 0xf5, 0x78,
0xd1, 0xba, 0x8f, 0x09, 0xe4, 0xff, 0x10, 0x7b,
0x62, 0x35, 0x78, 0x85, 0x42, 0xaa, 0x61, 0x83,
0xd1, 0x76, 0xdb, 0xf1, 0xc8, 0x8d, 0xcf, 0xb6 },
- { 0xd3, 0x10, 0x0b, 0xc8, 0x42, 0x8b, 0xa2, 0x3a,
- 0xe1, 0x3b, 0x41, 0xea, 0xa2, 0x95, 0xbf, 0xbf,
- 0xd6, 0x97, 0xf5, 0x0b, 0x81, 0xca, 0xef, 0x6a,
- 0x30, 0xa4, 0xd1, 0x99, 0x47, 0x1b, 0x9f, 0x32 },
{ 0xd3, 0x22, 0xe0, 0xc4, 0x4e, 0xa7, 0x92, 0xc0,
0x00, 0x13, 0x01, 0xa6, 0x32, 0xa1, 0x1d, 0x50,
0x6e, 0xa9, 0x17, 0xde, 0xed, 0xca, 0x8e, 0xd0,
@@ -3134,10 +2754,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x3b, 0xb9, 0x9f, 0x80, 0x68, 0xcf, 0xee, 0x86,
0xa4, 0xb9, 0xf0, 0x89, 0xe0, 0x2d, 0x0c, 0x6c,
0xb6, 0xd4, 0xa3, 0x94, 0x6c, 0x6b, 0x16, 0x7a },
- { 0xd5, 0x50, 0xb9, 0xa6, 0xd5, 0xc3, 0xf5, 0x25,
- 0x7c, 0x99, 0xb9, 0x94, 0x43, 0x69, 0x88, 0x3d,
- 0xa1, 0x1d, 0xbe, 0x23, 0xb9, 0x6e, 0x19, 0x34,
- 0xed, 0xed, 0x52, 0x1b, 0x73, 0x55, 0xe4, 0x44 },
{ 0xd5, 0x83, 0x94, 0x96, 0xcd, 0xc8, 0x5b, 0xe3,
0xd1, 0xf1, 0xac, 0x65, 0x2e, 0xfa, 0x92, 0xbe,
0xa3, 0xb0, 0x61, 0xc1, 0x3d, 0xad, 0x5a, 0x82,
@@ -3154,10 +2770,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xaa, 0x7e, 0x87, 0x8e, 0x6a, 0x85, 0x09, 0x1b,
0xaa, 0x07, 0x8d, 0x26, 0x8b, 0xbd, 0xb4, 0x9f,
0x09, 0x67, 0x94, 0x08, 0x61, 0x2d, 0x1e, 0xfe },
- { 0xd6, 0x46, 0x08, 0xb1, 0x5f, 0x71, 0xfc, 0x3b,
- 0x91, 0x90, 0xa2, 0x00, 0xee, 0x3c, 0xb5, 0xbc,
- 0xd9, 0xfc, 0x5b, 0x99, 0xfb, 0x67, 0x74, 0x9d,
- 0x18, 0x87, 0xd9, 0x17, 0xd8, 0x50, 0x01, 0x0b },
{ 0xd6, 0x83, 0xd0, 0x6e, 0xb9, 0x28, 0x74, 0x43,
0xe5, 0x01, 0xec, 0xf7, 0x1d, 0xad, 0xa6, 0x80,
0x35, 0x88, 0x71, 0xd1, 0x2a, 0x53, 0xfb, 0xcc,
@@ -3190,10 +2802,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x0b, 0x84, 0xd9, 0xa1, 0x7b, 0x1e, 0x90, 0x24,
0xf6, 0x27, 0xc1, 0xec, 0xc3, 0x5e, 0xc7, 0xe6,
0x71, 0xc1, 0x42, 0x92, 0xa7, 0xb8, 0x8b, 0x43 },
- { 0xd8, 0x55, 0x49, 0xfc, 0xd2, 0x4d, 0x36, 0xcb,
- 0x3f, 0x7c, 0x18, 0x06, 0x3f, 0x97, 0x5a, 0x16,
- 0x9f, 0xe3, 0xa1, 0xfb, 0x8d, 0x0a, 0x35, 0x9f,
- 0xd3, 0x5c, 0x28, 0x7b, 0xb2, 0xaf, 0x50, 0xca },
{ 0xd8, 0x7a, 0x9d, 0xf7, 0x19, 0x1e, 0x29, 0xc8,
0x04, 0x1e, 0x4c, 0x19, 0x3c, 0x03, 0xa8, 0xa7,
0x12, 0x5f, 0x16, 0x6e, 0xa6, 0xcb, 0x21, 0x1f,
@@ -3218,10 +2826,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4a, 0x3e, 0xd7, 0xfc, 0x55, 0x8c, 0x58, 0x45,
0x64, 0x51, 0x60, 0xda, 0xb3, 0x53, 0x85, 0xc1,
0x38, 0xbc, 0x89, 0x9c, 0x4d, 0xad, 0x8b, 0x36 },
- { 0xd9, 0xd0, 0xd9, 0x6e, 0xb3, 0x28, 0xe0, 0xc1,
- 0x77, 0x8b, 0x56, 0xa9, 0x2f, 0x71, 0x24, 0x3b,
- 0x6c, 0x0d, 0xb4, 0x5c, 0x62, 0x51, 0x32, 0xdd,
- 0x82, 0xca, 0x11, 0xa0, 0x97, 0xe7, 0x91, 0xc6 },
{ 0xd9, 0xe8, 0xcc, 0xda, 0x78, 0xfb, 0x8d, 0x5d,
0xbc, 0xe6, 0x94, 0x15, 0x57, 0x61, 0xf4, 0xd0,
0x2c, 0x30, 0xcc, 0x8d, 0x7a, 0xea, 0x0e, 0x11,
@@ -3242,22 +2846,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xe5, 0x38, 0x9a, 0x26, 0x08, 0x1c, 0x99, 0x8b,
0x5f, 0xfa, 0x67, 0xdd, 0x45, 0x97, 0xf8, 0xca,
0x67, 0xef, 0x10, 0x6a, 0xd7, 0x5f, 0x34, 0x9f },
- { 0xdb, 0xa1, 0x23, 0x67, 0x1f, 0xed, 0x4b, 0x28,
- 0x70, 0x33, 0xa4, 0xb0, 0x06, 0x8f, 0xc7, 0x14,
- 0xa5, 0xfc, 0x9c, 0x02, 0x6e, 0xf5, 0x65, 0x0b,
- 0x42, 0xde, 0x25, 0x85, 0x9a, 0x12, 0x6a, 0xd1 },
{ 0xdb, 0xa2, 0x21, 0xc2, 0xab, 0x44, 0xb5, 0x2c,
0x0b, 0x83, 0x36, 0xc4, 0x69, 0xfa, 0xa8, 0x56,
0xd6, 0xc3, 0xec, 0xdc, 0x6c, 0x24, 0x6b, 0xe3,
0xca, 0xc7, 0xe0, 0xf6, 0x28, 0x4b, 0x5b, 0xda },
- { 0xdc, 0x3d, 0x81, 0xc3, 0x01, 0xbc, 0xde, 0xc5,
- 0x38, 0xef, 0xc7, 0xfa, 0x6a, 0x4e, 0x5a, 0x13,
- 0xe5, 0x17, 0xd2, 0xa4, 0x61, 0x22, 0x2d, 0xed,
- 0x98, 0x3e, 0x75, 0x56, 0x4d, 0x0e, 0x68, 0x84 },
- { 0xdc, 0x42, 0x4a, 0x70, 0x87, 0x80, 0x95, 0x98,
- 0x7a, 0x5b, 0xcd, 0x17, 0x1a, 0xa5, 0x13, 0x67,
- 0x7b, 0xda, 0x56, 0xdf, 0x35, 0xb6, 0x81, 0xc7,
- 0x07, 0x84, 0x0f, 0xdc, 0xea, 0xc5, 0xe4, 0x0f },
{ 0xdc, 0x90, 0x90, 0x55, 0x0c, 0x93, 0x42, 0xe2,
0xfa, 0xe2, 0x42, 0x26, 0xa4, 0xf9, 0xb3, 0xf6,
0x93, 0xf4, 0xd1, 0x46, 0x52, 0x79, 0xc3, 0x7b,
@@ -3274,10 +2866,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xf0, 0xfd, 0xdb, 0x6b, 0x37, 0xfe, 0x00, 0x28,
0xde, 0x8b, 0x7d, 0x3c, 0xe5, 0x79, 0x1b, 0x45,
0x0d, 0xd2, 0x83, 0xb2, 0x0a, 0xdb, 0x05, 0xd2 },
- { 0xde, 0x45, 0x46, 0xc0, 0x24, 0x51, 0xa5, 0xb5,
- 0xad, 0x85, 0xea, 0x53, 0x2f, 0x09, 0x6f, 0xdf,
- 0x1e, 0x2b, 0x41, 0x71, 0xd9, 0x6a, 0x1d, 0xc3,
- 0x93, 0x6a, 0x19, 0x74, 0xf0, 0x58, 0xf0, 0xb2 },
{ 0xde, 0x5c, 0x3d, 0x09, 0x58, 0xa6, 0x12, 0xbd,
0x6d, 0x48, 0x09, 0x15, 0x03, 0x3d, 0x97, 0x15,
0x58, 0xdf, 0x35, 0xce, 0xb1, 0xc9, 0x18, 0xe6,
@@ -3314,26 +2902,14 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xc4, 0xba, 0x83, 0x99, 0xd4, 0xd8, 0xd5, 0xa0,
0xd1, 0x98, 0x57, 0x8f, 0x42, 0x99, 0xfd, 0xfd,
0xaf, 0xf7, 0x8c, 0x3f, 0x67, 0x71, 0xf3, 0x94 },
- { 0xe0, 0x65, 0x19, 0x10, 0x41, 0x74, 0x08, 0xbe,
- 0x2b, 0x0c, 0xfd, 0x3d, 0x9e, 0xaa, 0xeb, 0xca,
- 0x32, 0x1f, 0x61, 0x6d, 0xda, 0x48, 0xcb, 0x4f,
- 0x09, 0x10, 0x9d, 0x67, 0x19, 0x45, 0xa1, 0x1c },
{ 0xe0, 0x8b, 0x2c, 0xc2, 0x7a, 0xe8, 0xe2, 0xef,
0x1a, 0x33, 0x01, 0x7a, 0x9a, 0xc2, 0x5d, 0xda,
0xfb, 0x5e, 0xa1, 0x12, 0xc9, 0x56, 0xb0, 0x02,
0xfe, 0x6c, 0x79, 0x80, 0x14, 0xaa, 0x90, 0x65 },
- { 0xe0, 0xa0, 0x7b, 0x39, 0x6d, 0x25, 0x7f, 0xab,
- 0xb4, 0xe3, 0x22, 0xd8, 0x79, 0x94, 0x88, 0x37,
- 0x28, 0x7a, 0xaa, 0x99, 0xad, 0x14, 0xd7, 0x8d,
- 0x3a, 0x2f, 0x9d, 0xfe, 0x5c, 0x97, 0x28, 0xbf },
{ 0xe0, 0xa9, 0xd9, 0x63, 0x6e, 0xfa, 0x36, 0xa7,
0x72, 0xac, 0xb5, 0xd0, 0x22, 0xfc, 0xa9, 0x73,
0x71, 0xb4, 0x4f, 0x7b, 0x80, 0x4b, 0x03, 0x97,
0xfb, 0x6c, 0x37, 0x1a, 0x22, 0x5b, 0xda, 0x78 },
- { 0xe0, 0xbb, 0xef, 0x7e, 0xe4, 0x37, 0xb0, 0x59,
- 0xe0, 0x3b, 0x52, 0x9b, 0xe6, 0xb4, 0x09, 0x6d,
- 0x56, 0xc7, 0x4e, 0x90, 0x67, 0xb0, 0x5f, 0x87,
- 0xaa, 0x6a, 0x5a, 0x61, 0x93, 0x40, 0xa7, 0xc3 },
{ 0xe0, 0xdd, 0xe1, 0x29, 0xd2, 0x60, 0xc3, 0xda,
0xb6, 0x91, 0xd8, 0x1d, 0xab, 0xad, 0x73, 0x4c,
0x9a, 0xdc, 0x61, 0xd2, 0x0c, 0x1a, 0xe1, 0xb6,
@@ -3374,10 +2950,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x7e, 0x1f, 0x45, 0x5b, 0x85, 0xc0, 0x6f, 0x0d,
0x80, 0x9e, 0x75, 0xa5, 0x5c, 0x6b, 0x05, 0x48,
0x16, 0xe0, 0x19, 0x89, 0x9a, 0x3a, 0x02, 0xff },
- { 0xe3, 0x1f, 0xa0, 0xbd, 0xe8, 0x58, 0x9e, 0xdd,
- 0xda, 0x1c, 0x5d, 0x1a, 0xa9, 0xc5, 0x81, 0x86,
- 0xc3, 0x14, 0x36, 0x85, 0x67, 0xbd, 0xf9, 0xdc,
- 0xd5, 0x37, 0xaa, 0xe3, 0xcf, 0xf8, 0x77, 0x52 },
{ 0xe3, 0xc8, 0xfc, 0x63, 0x7b, 0x7b, 0xb0, 0xcc,
0x67, 0x4a, 0x5a, 0x4c, 0x3b, 0x4d, 0x35, 0x62,
0xeb, 0x8a, 0xa0, 0x0d, 0x7a, 0xd2, 0xc8, 0xa9,
@@ -3426,18 +2998,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xfa, 0x2b, 0xfb, 0x76, 0xc2, 0x2d, 0xfa, 0x71,
0xbc, 0x3d, 0xa4, 0x8f, 0x67, 0x1e, 0xf7, 0x7c,
0x00, 0xaa, 0x8e, 0x45, 0x9b, 0x7c, 0xc8, 0x2a },
- { 0xe8, 0x1a, 0x87, 0x45, 0xad, 0x86, 0xf6, 0x5f,
- 0xa0, 0xd8, 0x51, 0xfc, 0xb7, 0x2e, 0x3e, 0xf5,
- 0x4d, 0x51, 0xbc, 0x60, 0xb9, 0x68, 0x0c, 0xb2,
- 0x5e, 0xb2, 0xf3, 0xac, 0x44, 0xea, 0xa7, 0xa4 },
{ 0xe8, 0x21, 0x3c, 0x45, 0x51, 0x81, 0x61, 0xbc,
0x36, 0x37, 0x3d, 0xcd, 0x2d, 0x4b, 0x21, 0xb7,
0x6a, 0x7c, 0x06, 0x6d, 0xf5, 0x52, 0x6e, 0x88,
0x8b, 0x6e, 0xed, 0x09, 0xa9, 0xee, 0xd0, 0x62 },
- { 0xe8, 0x6e, 0xe6, 0x9d, 0x51, 0xbe, 0x64, 0xf8,
- 0x28, 0xfc, 0x22, 0xcc, 0xe5, 0xbc, 0xc1, 0x1d,
- 0x24, 0xa5, 0xf1, 0x77, 0xf9, 0xba, 0x99, 0x51,
- 0x92, 0x71, 0xa4, 0xf3, 0x9f, 0x0c, 0x51, 0x7c },
{ 0xe8, 0xa6, 0x09, 0xec, 0x44, 0xf9, 0x3c, 0x12,
0xe0, 0x81, 0xe5, 0x94, 0x3b, 0x5e, 0xa0, 0x48,
0x68, 0x14, 0x48, 0x33, 0x32, 0x5d, 0xaa, 0x64,
@@ -3470,10 +3034,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x5a, 0x76, 0x07, 0x64, 0x3e, 0x15, 0x26, 0x0d,
0x1c, 0x93, 0xfd, 0x9b, 0xe0, 0xfa, 0xb1, 0x0b,
0x76, 0xdc, 0x96, 0x86, 0xf6, 0x54, 0xc6, 0xe5 },
- { 0xec, 0x01, 0x78, 0xd1, 0xca, 0x3b, 0x94, 0x52,
- 0xaa, 0x5c, 0xd5, 0xd3, 0x75, 0x45, 0x6b, 0xab,
- 0xf0, 0xdc, 0x0e, 0xd2, 0x29, 0x91, 0x5d, 0x1a,
- 0x8f, 0x49, 0x6d, 0xf2, 0xa2, 0xa0, 0x98, 0x71 },
{ 0xec, 0x27, 0x05, 0x63, 0xb0, 0x5a, 0x06, 0xe5,
0xaa, 0xa5, 0xe6, 0xd5, 0xbb, 0xcc, 0x17, 0xcd,
0x1c, 0xb5, 0xb2, 0xa9, 0x4d, 0x93, 0x84, 0x75,
@@ -3534,10 +3094,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x51, 0x6b, 0xf6, 0x39, 0x5d, 0xbd, 0x29, 0x33,
0x7c, 0xfc, 0xb7, 0xd4, 0x26, 0x64, 0x10, 0xa1,
0xf5, 0xda, 0x08, 0x08, 0xe0, 0x96, 0xf4, 0x55 },
- { 0xef, 0x7e, 0x8c, 0xcd, 0x7b, 0xcf, 0xb7, 0x1d,
- 0x2a, 0xa7, 0xbc, 0xdd, 0x8f, 0xd2, 0xd2, 0xd1,
- 0x55, 0x77, 0x9d, 0xe8, 0x68, 0x43, 0x20, 0x44,
- 0x35, 0x1e, 0x98, 0x02, 0xcc, 0xa2, 0x90, 0xaf },
{ 0xef, 0xaf, 0xca, 0x84, 0x90, 0x30, 0x7b, 0x0f,
0x62, 0x2b, 0xf4, 0x3a, 0x0e, 0xb3, 0xc5, 0x1a,
0xcb, 0xdd, 0xde, 0xdc, 0x23, 0x92, 0xf1, 0x61,
@@ -3554,10 +3110,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x8d, 0x77, 0x2e, 0xba, 0xfa, 0x5b, 0xf5, 0x32,
0x92, 0x47, 0x77, 0x88, 0xdc, 0x12, 0x80, 0x32,
0x76, 0xb0, 0x00, 0xc4, 0x41, 0x91, 0x03, 0xf0 },
- { 0xf0, 0x15, 0x95, 0xf5, 0xa4, 0x66, 0x88, 0x78,
- 0xf6, 0xc7, 0x98, 0xa5, 0xd2, 0xf1, 0x35, 0x23,
- 0xf3, 0xaf, 0xb2, 0x0e, 0xf7, 0x6f, 0xe5, 0x77,
- 0x6f, 0xce, 0x47, 0xd3, 0x40, 0x9d, 0xf3, 0xc2 },
{ 0xf0, 0x2f, 0x9d, 0xa4, 0x5d, 0x9e, 0xb9, 0x86,
0x19, 0x4e, 0x06, 0xf5, 0xe6, 0x18, 0x95, 0x45,
0x12, 0xc9, 0x02, 0x6e, 0x7c, 0xa7, 0xb5, 0x1e,
@@ -3586,10 +3138,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x26, 0xaa, 0x5a, 0x6b, 0xf5, 0xc4, 0xde, 0x59,
0x1c, 0xf1, 0x65, 0x0f, 0xa8, 0x22, 0xf1, 0x34,
0xd9, 0x2d, 0x54, 0x8f, 0x15, 0x77, 0x73, 0xd6 },
- { 0xf2, 0x06, 0x59, 0x72, 0x49, 0x8d, 0x5e, 0x12,
- 0x79, 0x8e, 0x1e, 0x1f, 0xf3, 0xe1, 0x1d, 0xe4,
- 0x23, 0x3a, 0xbb, 0xbd, 0x30, 0x8a, 0x58, 0x07,
- 0x60, 0x58, 0x48, 0x18, 0x6e, 0x44, 0x11, 0x7f },
{ 0xf2, 0x54, 0x76, 0xf3, 0xab, 0x8e, 0x5e, 0x0b,
0x9b, 0xb6, 0x1d, 0x4c, 0xe4, 0x50, 0x7f, 0xa3,
0x52, 0x93, 0xc6, 0x64, 0x15, 0xd7, 0xd1, 0x91,
@@ -3634,10 +3182,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xd3, 0xc5, 0x60, 0x17, 0x6f, 0x3d, 0x77, 0xfd,
0xc5, 0x1e, 0x5f, 0x57, 0xb5, 0xe4, 0x8a, 0xe7,
0xa4, 0xb9, 0x70, 0x0a, 0x11, 0xd4, 0x69, 0x3a },
- { 0xf6, 0x41, 0xe7, 0xe0, 0x1b, 0xf4, 0xf2, 0xb0,
- 0xd0, 0xc4, 0x8b, 0xa6, 0x38, 0xa0, 0x2e, 0x26,
- 0xbd, 0xdb, 0xd7, 0x7b, 0xc5, 0xe9, 0x72, 0x61,
- 0x94, 0xdb, 0x1a, 0xea, 0x4f, 0x2f, 0xd7, 0x71 },
{ 0xf6, 0x54, 0x6b, 0x2f, 0xfe, 0x2b, 0xae, 0xf7,
0x35, 0xe8, 0x25, 0x67, 0xa6, 0xe2, 0x36, 0x75,
0x03, 0x94, 0xc1, 0x19, 0x14, 0x09, 0x87, 0x0c,
@@ -3698,10 +3242,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xad, 0x25, 0x74, 0x25, 0xaa, 0xe7, 0x20, 0x01,
0x40, 0x05, 0xb4, 0x15, 0x91, 0x2d, 0xbb, 0x8c,
0x0b, 0xc9, 0x99, 0xaf, 0x48, 0x48, 0xcf, 0xe5 },
- { 0xf9, 0x0e, 0x7c, 0x21, 0x81, 0xba, 0x53, 0x4d,
- 0xcf, 0x5b, 0xb6, 0xdb, 0xf7, 0xf9, 0xad, 0xa3,
- 0xff, 0x98, 0xde, 0x50, 0x0c, 0xbd, 0x42, 0x12,
- 0xc0, 0xd1, 0xfa, 0x05, 0x82, 0x80, 0xfd, 0x57 },
{ 0xf9, 0xa7, 0xdd, 0xd3, 0xff, 0x51, 0xaf, 0x30,
0x7f, 0x95, 0x4f, 0x7b, 0x44, 0xdb, 0xd2, 0x42,
0x83, 0xcf, 0x97, 0xb6, 0x25, 0xbe, 0x76, 0x6b,
@@ -3714,10 +3254,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xa7, 0x9b, 0x05, 0x48, 0x67, 0x6c, 0x18, 0x48,
0x5a, 0xf1, 0x10, 0x4c, 0xca, 0x9b, 0xb6, 0xb8,
0xdd, 0x9b, 0x5a, 0x54, 0x3c, 0xb6, 0xc6, 0x2e },
- { 0xfa, 0xe4, 0x72, 0x1e, 0x39, 0x47, 0xa5, 0x0d,
- 0xd0, 0x4d, 0x16, 0xac, 0xef, 0xf3, 0x55, 0xc0,
- 0x87, 0xb7, 0xe2, 0x24, 0x6b, 0xe6, 0x0f, 0xbc,
- 0x26, 0x2a, 0x53, 0x52, 0xad, 0xac, 0x18, 0x01 },
{ 0xfb, 0x44, 0x15, 0x70, 0x4c, 0x1d, 0x61, 0x55,
0x10, 0x6d, 0x88, 0xf3, 0xb2, 0x0f, 0xec, 0x9f,
0x6e, 0x82, 0x0c, 0x82, 0x24, 0xfe, 0xe3, 0x5e,
@@ -3750,10 +3286,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xd0, 0xa9, 0xdf, 0xcc, 0xe9, 0x03, 0x12, 0xc7,
0x52, 0xe1, 0xb5, 0x2e, 0xb6, 0x54, 0xc4, 0x2c,
0x36, 0x94, 0x4b, 0x90, 0x2a, 0x30, 0x41, 0x07 },
- { 0xfc, 0x55, 0x86, 0x91, 0xda, 0xff, 0xe1, 0xe3,
- 0x53, 0x8d, 0x38, 0xa6, 0xd3, 0xa9, 0xe6, 0xe7,
- 0xc9, 0x9d, 0x24, 0x0c, 0x86, 0x89, 0x66, 0x73,
- 0x56, 0x27, 0x99, 0x72, 0xfb, 0x4f, 0x30, 0x85 },
{ 0xfc, 0x56, 0xdb, 0xa1, 0xe7, 0xaf, 0xbd, 0xaa,
0x07, 0x33, 0xc6, 0x91, 0x1c, 0x5f, 0x1f, 0x18,
0x28, 0xcb, 0x12, 0x98, 0x31, 0x40, 0x1a, 0x3c,
@@ -3832,14 +3364,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xaf, 0x3f, 0x5c, 0xf4, 0x22, 0x5a, 0x8e, 0xaf },
};
const uint8_t kCNNICEVWhitelist[][crypto::kSHA256Length] = {
- { 0x0e, 0x56, 0x71, 0x6d, 0xd3, 0xc1, 0x83, 0xaa,
- 0x5d, 0xe0, 0xd3, 0x96, 0x89, 0x88, 0x94, 0xf0,
- 0x03, 0xaa, 0xff, 0x06, 0x2e, 0x15, 0x82, 0x33,
- 0xef, 0xfb, 0x5b, 0xc9, 0xe8, 0x33, 0x71, 0x4b },
- { 0x0f, 0x07, 0xaa, 0xd7, 0xac, 0x55, 0x6f, 0x85,
- 0x86, 0xcb, 0xf3, 0x47, 0x8f, 0x2e, 0xc0, 0xb5,
- 0x29, 0xca, 0x46, 0x5b, 0x19, 0x3f, 0xc2, 0xa6,
- 0xe1, 0x93, 0x28, 0x3a, 0xd8, 0xd7, 0xa5, 0x50 },
{ 0x23, 0x86, 0x51, 0xab, 0x70, 0xb7, 0x11, 0xa0,
0x65, 0x55, 0x4e, 0x5d, 0x63, 0x6a, 0x34, 0x2c,
0x8a, 0x6b, 0xfe, 0x46, 0x0e, 0x4e, 0x7b, 0x4c,
@@ -3852,18 +3376,10 @@ const uint8_t kCNNICEVWhitelist[][crypto::kSHA256Length] = {
0xaa, 0x33, 0x43, 0x60, 0xa6, 0x6a, 0xc3, 0xa7,
0x3f, 0xa8, 0xd8, 0xd3, 0x60, 0x0d, 0x89, 0x4e,
0xb0, 0xc7, 0xd2, 0x84, 0x23, 0xc6, 0x78, 0x57 },
- { 0x61, 0xa7, 0x62, 0xef, 0x47, 0xbc, 0xa4, 0xee,
- 0x77, 0xa5, 0xc8, 0xaf, 0x03, 0x98, 0x9a, 0x9d,
- 0xea, 0xca, 0x4d, 0x82, 0x8a, 0x53, 0xd9, 0x23,
- 0xe7, 0x0b, 0xfb, 0xc7, 0x25, 0x4a, 0xc7, 0x70 },
{ 0x63, 0x80, 0x65, 0xec, 0x95, 0xf1, 0xea, 0x81,
0xd9, 0x5b, 0xa4, 0xdb, 0x9e, 0xa9, 0xa2, 0xef,
0xe2, 0xd6, 0xcd, 0x78, 0x75, 0x88, 0x67, 0x04,
0x5c, 0x06, 0xb6, 0x48, 0xa5, 0xda, 0x89, 0xb2 },
- { 0x67, 0xc3, 0xc0, 0xa1, 0x60, 0xe9, 0x28, 0x5e,
- 0x35, 0xa4, 0x22, 0xbb, 0x43, 0x4b, 0xff, 0xff,
- 0xee, 0x28, 0x79, 0xc6, 0xc0, 0xa5, 0x69, 0x36,
- 0x56, 0xe7, 0x73, 0xa6, 0xdd, 0x68, 0x5f, 0x0e },
{ 0x80, 0xf3, 0xeb, 0x58, 0xea, 0x6a, 0xa2, 0x85,
0x11, 0xb0, 0x9b, 0x68, 0xf2, 0xde, 0xf9, 0xb4,
0xaf, 0xa9, 0x9c, 0x97, 0x44, 0xc0, 0xbe, 0x4e,
@@ -3880,10 +3396,6 @@ const uint8_t kCNNICEVWhitelist[][crypto::kSHA256Length] = {
0xb2, 0x7c, 0x6a, 0x62, 0xe3, 0xc4, 0x23, 0x5b,
0xd8, 0x3c, 0xc5, 0xe0, 0x06, 0xe9, 0x2a, 0x55,
0xe4, 0xa9, 0x86, 0xe6, 0x30, 0x53, 0x57, 0xe3 },
- { 0xaf, 0xbb, 0x40, 0x3c, 0xad, 0x0d, 0x19, 0xcc,
- 0x26, 0xae, 0x5b, 0x1e, 0x31, 0x0a, 0xc1, 0xae,
- 0x79, 0x47, 0x1b, 0xad, 0x2b, 0xd7, 0x7b, 0xe4,
- 0x0f, 0x12, 0x50, 0x4c, 0x42, 0xe5, 0x22, 0x0b },
{ 0xb2, 0xba, 0x3b, 0x49, 0xb8, 0xe5, 0x84, 0x51,
0x81, 0x6b, 0x10, 0x83, 0x6c, 0x4f, 0x1c, 0xa6,
0xa3, 0x39, 0x37, 0xce, 0xb8, 0xf0, 0xc0, 0x4b,
@@ -3908,10 +3420,6 @@ const uint8_t kCNNICEVWhitelist[][crypto::kSHA256Length] = {
0x23, 0xb9, 0xa9, 0x60, 0xb5, 0xe9, 0x67, 0x0c,
0xcc, 0x34, 0x6d, 0x89, 0x93, 0x8f, 0xfa, 0x5d,
0xf7, 0x98, 0x65, 0xe4, 0x13, 0xd6, 0x31, 0x54 },
- { 0xee, 0x3d, 0x0b, 0xc5, 0xa6, 0x5a, 0xf5, 0x8d,
- 0x43, 0x2d, 0x08, 0x63, 0x7b, 0xe0, 0xb7, 0xba,
- 0x49, 0xc2, 0x32, 0x61, 0x8d, 0xa9, 0xc8, 0x97,
- 0x3f, 0x88, 0x56, 0x8c, 0x88, 0x89, 0xd1, 0xad },
{ 0xf3, 0xcb, 0x8e, 0xa4, 0xe8, 0xf2, 0xa7, 0x00,
0x9c, 0x23, 0x3a, 0x64, 0x88, 0x71, 0xdb, 0x46,
0x04, 0xd5, 0x45, 0x4b, 0xc5, 0x55, 0x9e, 0x9b,
diff --git a/chromium/net/cert/cert_verify_proc_whitelist.h b/chromium/net/cert/cert_verify_proc_whitelist.h
index c4a5aae0c6a..47ce9831848 100644
--- a/chromium/net/cert/cert_verify_proc_whitelist.h
+++ b/chromium/net/cert/cert_verify_proc_whitelist.h
@@ -5,6 +5,7 @@
#ifndef NET_CERT_CERT_VERIFY_PROC_WHITELIST_H_
#define NET_CERT_CERT_VERIFY_PROC_WHITELIST_H_
+#include <stddef.h>
#include <stdint.h>
#include "crypto/sha2.h"
diff --git a/chromium/net/cert/cert_verify_proc_win.cc b/chromium/net/cert/cert_verify_proc_win.cc
index 4eada6f4b49..cb1db7d9b84 100644
--- a/chromium/net/cert/cert_verify_proc_win.cc
+++ b/chromium/net/cert/cert_verify_proc_win.cc
@@ -281,9 +281,9 @@ bool IsIssuedByKnownRoot(PCCERT_CHAIN_CONTEXT chain_context) {
PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement;
PCCERT_CONTEXT cert = element[num_elements - 1]->pCertContext;
- SHA1HashValue hash = X509Certificate::CalculateFingerprint(cert);
- return IsSHA1HashInSortedArray(
- hash, &kKnownRootCertSHA1Hashes[0][0], sizeof(kKnownRootCertSHA1Hashes));
+ SHA256HashValue hash = X509Certificate::CalculateFingerprint256(cert);
+ return IsSHA256HashInSortedArray(hash, &kKnownRootCertSHA256Hashes[0][0],
+ sizeof(kKnownRootCertSHA256Hashes));
}
// Saves some information about the certificate chain |chain_context| in
@@ -295,7 +295,7 @@ void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context,
return;
PCERT_SIMPLE_CHAIN first_chain = chain_context->rgpChain[0];
- int num_elements = first_chain->cElement;
+ DWORD num_elements = first_chain->cElement;
PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement;
PCCERT_CONTEXT verified_cert = NULL;
@@ -316,7 +316,7 @@ void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context,
num_elements -= 1;
}
- for (int i = 0; i < num_elements; ++i) {
+ for (DWORD i = 0; i < num_elements; ++i) {
PCCERT_CONTEXT cert = element[i]->pCertContext;
if (i == 0) {
verified_cert = cert;
@@ -341,6 +341,8 @@ void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context,
// id-dsa-with-sha1: 1.2.840.10040.4.3
// ecdsa-with-SHA1: 1.2.840.10045.4.1
verify_result->has_sha1 = true;
+ if (i == 0)
+ verify_result->has_sha1_leaf = true;
}
}
diff --git a/chromium/net/cert/cert_verify_result.cc b/chromium/net/cert/cert_verify_result.cc
index b2413e6755d..2a418938e71 100644
--- a/chromium/net/cert/cert_verify_result.cc
+++ b/chromium/net/cert/cert_verify_result.cc
@@ -22,6 +22,7 @@ void CertVerifyResult::Reset() {
has_md4 = false;
has_md5 = false;
has_sha1 = false;
+ has_sha1_leaf = false;
is_issued_by_known_root = false;
is_issued_by_additional_trust_anchor = false;
common_name_fallback_used = false;
diff --git a/chromium/net/cert/cert_verify_result.h b/chromium/net/cert/cert_verify_result.h
index 9e673255293..104fc6eec46 100644
--- a/chromium/net/cert/cert_verify_result.h
+++ b/chromium/net/cert/cert_verify_result.h
@@ -48,6 +48,7 @@ class NET_EXPORT CertVerifyResult {
bool has_md4;
bool has_md5;
bool has_sha1;
+ bool has_sha1_leaf;
// If the certificate was successfully verified then this contains the
// hashes, in several hash algorithms, of the SubjectPublicKeyInfos of the
diff --git a/chromium/net/cert/crl_set.h b/chromium/net/cert/crl_set.h
index f54e346b460..2a84d2ae17c 100644
--- a/chromium/net/cert/crl_set.h
+++ b/chromium/net/cert/crl_set.h
@@ -5,6 +5,9 @@
#ifndef NET_CERT_CRL_SET_H_
#define NET_CERT_CRL_SET_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <utility>
#include <vector>
diff --git a/chromium/net/cert/ct_known_logs.cc b/chromium/net/cert/ct_known_logs.cc
index 381d4dd1013..eddeb55a8a9 100644
--- a/chromium/net/cert/ct_known_logs.cc
+++ b/chromium/net/cert/ct_known_logs.cc
@@ -4,28 +4,63 @@
#include "net/cert/ct_known_logs.h"
-#include <string>
+#include <algorithm>
+#include "base/logging.h"
#include "base/macros.h"
-#include "base/strings/string_piece.h"
+#include "crypto/sha2.h"
#include "net/cert/ct_known_logs_static.h"
+
+#if !defined(OS_NACL)
#include "net/cert/ct_log_verifier.h"
+#endif
namespace net {
namespace ct {
-std::vector<scoped_refptr<CTLogVerifier>> CreateLogVerifiersForKnownLogs() {
- std::vector<scoped_refptr<CTLogVerifier>> verifiers;
+namespace {
+
+int log_ids_compare(const char* log_id, const char* lookup_id) {
+ return strncmp(log_id, lookup_id, crypto::kSHA256Length) < 0;
+}
+
+} // namespace
+
+#if !defined(OS_NACL)
+std::vector<scoped_refptr<const CTLogVerifier>>
+CreateLogVerifiersForKnownLogs() {
+ std::vector<scoped_refptr<const CTLogVerifier>> verifiers;
for (size_t i = 0; i < arraysize(kCTLogList); ++i) {
const CTLogInfo& log(kCTLogList[i]);
base::StringPiece key(log.log_key, log.log_key_length);
verifiers.push_back(CTLogVerifier::Create(key, log.log_name, log.log_url));
+ // Make sure no null logs enter verifiers. Parsing of all known logs should
+ // succeed.
+ CHECK(verifiers.back().get());
}
return verifiers;
}
+#endif
+
+bool IsLogOperatedByGoogle(base::StringPiece log_id) {
+ // No callers should provide a log_id that's not of the expected length
+ // (log IDs are SHA-256 hashes of the key and are always 32 bytes).
+ // Without this DCHECK (i.e. in production) this function would always
+ // return false.
+ DCHECK_EQ(log_id.size(), arraysize(kGoogleLogIDs[0]) - 1);
+
+ auto p = std::lower_bound(kGoogleLogIDs, kGoogleLogIDs + kNumGoogleLogs,
+ log_id.data(), &log_ids_compare);
+ if ((p == kGoogleLogIDs + kNumGoogleLogs) ||
+ log_id != base::StringPiece(*p, crypto::kSHA256Length)) {
+ return false;
+ }
+
+ return true;
+}
} // namespace ct
diff --git a/chromium/net/cert/ct_known_logs.h b/chromium/net/cert/ct_known_logs.h
index e6bbfc15b85..48904c2cc54 100644
--- a/chromium/net/cert/ct_known_logs.h
+++ b/chromium/net/cert/ct_known_logs.h
@@ -8,6 +8,8 @@
#include <vector>
#include "base/memory/ref_counted.h"
+#include "base/strings/string_piece.h"
+#include "build/build_config.h"
#include "net/base/net_export.h"
namespace net {
@@ -16,10 +18,14 @@ class CTLogVerifier;
namespace ct {
+#if !defined(OS_NACL)
// CreateLogVerifiersForKnownLogs returns a vector of CT logs for all the known
// and trusted logs.
-NET_EXPORT std::vector<scoped_refptr<CTLogVerifier>>
+NET_EXPORT std::vector<scoped_refptr<const CTLogVerifier>>
CreateLogVerifiersForKnownLogs();
+#endif
+
+NET_EXPORT bool IsLogOperatedByGoogle(base::StringPiece log_id);
} // namespace ct
diff --git a/chromium/net/cert/ct_known_logs_static.h b/chromium/net/cert/ct_known_logs_static.h
index d67b9fd72e5..a1e30f1fc6d 100644
--- a/chromium/net/cert/ct_known_logs_static.h
+++ b/chromium/net/cert/ct_known_logs_static.h
@@ -6,6 +6,8 @@
#ifndef NET_CERT_CT_KNOWN_LOGS_STATIC_H_
#define NET_CERT_CT_KNOWN_LOGS_STATIC_H_
+#include <stddef.h>
+
struct CTLogInfo {
const char* const log_key;
const size_t log_key_length;
@@ -101,4 +103,15 @@ const CTLogInfo kCTLogList[] = {
const size_t kNumKnownCTLogs = 8;
+// The list is sorted.
+const char kGoogleLogIDs[][33] = {
+ "\x68\xf6\x98\xf8\x1f\x64\x82\xbe\x3a\x8c\xee\xb9\x28\x1d\x4c\xfc\x71"
+ "\x51\x5d\x67\x93\xd4\x44\xd1\x0a\x67\xac\xbb\x4f\x4f\xfb\xc4",
+ "\xa4\xb9\x09\x90\xb4\x18\x58\x14\x87\xbb\x13\xa2\xcc\x67\x70\x0a\x3c"
+ "\x35\x98\x04\xf9\x1b\xdf\xb8\xe3\x77\xcd\x0e\xc8\x0d\xdc\x10",
+ "\xee\x4b\xbd\xb7\x75\xce\x60\xba\xe1\x42\x69\x1f\xab\xe1\x9e\x66\xa3"
+ "\x0f\x7e\x5f\xb0\x72\xd8\x83\x00\xc4\x7b\x89\x7a\xa8\xfd\xcb"};
+
+const size_t kNumGoogleLogs = 3;
+
#endif // NET_CERT_CT_KNOWN_LOGS_STATIC_H_
diff --git a/chromium/net/cert/ct_log_response_parser.cc b/chromium/net/cert/ct_log_response_parser.cc
index 0069fc70848..628eef286be 100644
--- a/chromium/net/cert/ct_log_response_parser.cc
+++ b/chromium/net/cert/ct_log_response_parser.cc
@@ -7,6 +7,7 @@
#include "base/base64.h"
#include "base/json/json_value_converter.h"
#include "base/logging.h"
+#include "base/memory/scoped_vector.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
#include "base/values.h"
@@ -101,6 +102,33 @@ bool IsJsonSTHStructurallyValid(const JsonSignedTreeHead& sth) {
return true;
}
+// Structure for making JSON decoding easier. The string fields
+// are base64-encoded so will require further decoding.
+struct JsonConsistencyProof {
+ ScopedVector<std::string> proof_nodes;
+
+ static void RegisterJSONConverter(
+ base::JSONValueConverter<JsonConsistencyProof>* converter);
+};
+
+bool ConvertIndividualProofNode(const base::Value* value, std::string* result) {
+ std::string b64_encoded_node;
+ if (!value->GetAsString(&b64_encoded_node))
+ return false;
+
+ if (!ConvertSHA256RootHash(b64_encoded_node, result))
+ return false;
+
+ return true;
+}
+
+void JsonConsistencyProof::RegisterJSONConverter(
+ base::JSONValueConverter<JsonConsistencyProof>* converter) {
+ converter->RegisterRepeatedCustomValue<std::string>(
+ "consistency", &JsonConsistencyProof::proof_nodes,
+ &ConvertIndividualProofNode);
+}
+
} // namespace
bool FillSignedTreeHead(const base::Value& json_signed_tree_head,
@@ -127,6 +155,30 @@ bool FillSignedTreeHead(const base::Value& json_signed_tree_head,
return true;
}
+bool FillConsistencyProof(const base::Value& json_consistency_proof,
+ std::vector<std::string>* consistency_proof) {
+ JsonConsistencyProof parsed_proof;
+ base::JSONValueConverter<JsonConsistencyProof> converter;
+ if (!converter.Convert(json_consistency_proof, &parsed_proof)) {
+ DVLOG(1) << "Invalid consistency proof.";
+ return false;
+ }
+
+ const base::DictionaryValue* dict_value = NULL;
+ if (!json_consistency_proof.GetAsDictionary(&dict_value) ||
+ !dict_value->HasKey("consistency")) {
+ DVLOG(1) << "Missing consistency field.";
+ return false;
+ }
+
+ consistency_proof->reserve(parsed_proof.proof_nodes.size());
+ for (std::string* proof_node : parsed_proof.proof_nodes) {
+ consistency_proof->push_back(*proof_node);
+ }
+
+ return true;
+}
+
} // namespace ct
} // namespace net
diff --git a/chromium/net/cert/ct_log_response_parser.h b/chromium/net/cert/ct_log_response_parser.h
index b7a012bde05..403f8bfb050 100644
--- a/chromium/net/cert/ct_log_response_parser.h
+++ b/chromium/net/cert/ct_log_response_parser.h
@@ -5,6 +5,9 @@
#ifndef NET_CERT_CT_LOG_RESPONSE_PARSER_H_
#define NET_CERT_CT_LOG_RESPONSE_PARSER_H_
+#include <string>
+#include <vector>
+
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -24,6 +27,10 @@ struct SignedTreeHead;
NET_EXPORT bool FillSignedTreeHead(const base::Value& json_signed_tree_head,
SignedTreeHead* signed_tree_head);
+NET_EXPORT bool FillConsistencyProof(
+ const base::Value& json_signed_tree_head,
+ std::vector<std::string>* consistency_proof);
+
} // namespace ct
} // namespace net
diff --git a/chromium/net/cert/ct_log_response_parser_unittest.cc b/chromium/net/cert/ct_log_response_parser_unittest.cc
index 9f02699d744..fad759019ac 100644
--- a/chromium/net/cert/ct_log_response_parser_unittest.cc
+++ b/chromium/net/cert/ct_log_response_parser_unittest.cc
@@ -23,7 +23,7 @@ namespace ct {
namespace {
scoped_ptr<base::Value> ParseJson(const std::string& json) {
base::JSONReader json_reader;
- return json_reader.Read(json).Pass();
+ return json_reader.Read(json);
}
}
@@ -33,7 +33,7 @@ TEST(CTLogResponseParserTest, ParsesValidJsonSTH) {
EXPECT_TRUE(FillSignedTreeHead(*sample_sth_json.get(), &tree_head));
SignedTreeHead sample_sth;
- GetSampleSignedTreeHead(&sample_sth);
+ ASSERT_TRUE(GetSampleSignedTreeHead(&sample_sth));
ASSERT_EQ(SignedTreeHead::V1, tree_head.version);
ASSERT_EQ(sample_sth.timestamp, tree_head.timestamp);
@@ -95,6 +95,53 @@ TEST(CTLogResponseParserTest, FailsToParseIncorrectLengthRootHash) {
ASSERT_FALSE(FillSignedTreeHead(*too_short_hash_json.get(), &tree_head));
}
+TEST(CTLogResponseParserTest, ParsesConsistencyProofSuccessfully) {
+ std::string first(32, 'a');
+ std::string second(32, 'b');
+ std::string third(32, 'c');
+
+ std::vector<std::string> raw_nodes;
+ raw_nodes.push_back(first);
+ raw_nodes.push_back(second);
+ raw_nodes.push_back(third);
+ scoped_ptr<base::Value> sample_consistency_proof =
+ ParseJson(CreateConsistencyProofJsonString(raw_nodes));
+
+ std::vector<std::string> output;
+
+ ASSERT_TRUE(FillConsistencyProof(*sample_consistency_proof.get(), &output));
+
+ EXPECT_EQ(output[0], first);
+ EXPECT_EQ(output[1], second);
+ EXPECT_EQ(output[2], third);
+}
+
+TEST(CTLogResponseParserTest, FailsOnInvalidProofJson) {
+ std::vector<std::string> output;
+
+ scoped_ptr<base::Value> badly_encoded =
+ ParseJson(std::string("{\"consistency\": [\"notbase64\"]}"));
+ EXPECT_FALSE(FillConsistencyProof(*badly_encoded.get(), &output));
+
+ scoped_ptr<base::Value> not_a_string =
+ ParseJson(std::string("{\"consistency\": [42, 16]}"));
+ EXPECT_FALSE(FillConsistencyProof(*badly_encoded.get(), &output));
+
+ scoped_ptr<base::Value> missing_consistency = ParseJson(std::string("{}"));
+ EXPECT_FALSE(FillConsistencyProof(*missing_consistency.get(), &output));
+
+ scoped_ptr<base::Value> not_a_dict = ParseJson(std::string("[]"));
+ EXPECT_FALSE(FillConsistencyProof(*not_a_dict.get(), &output));
+}
+
+TEST(CTLogResponseParserTest, ParsesProofJsonWithExtraFields) {
+ std::vector<std::string> output;
+
+ scoped_ptr<base::Value> badly_encoded =
+ ParseJson(std::string("{\"consistency\": [], \"somethingelse\": 3}"));
+ EXPECT_TRUE(FillConsistencyProof(*badly_encoded.get(), &output));
+}
+
} // namespace ct
} // namespace net
diff --git a/chromium/net/cert/ct_log_verifier.cc b/chromium/net/cert/ct_log_verifier.cc
index 7dbde12c4b2..0f70678add0 100644
--- a/chromium/net/cert/ct_log_verifier.cc
+++ b/chromium/net/cert/ct_log_verifier.cc
@@ -4,14 +4,32 @@
#include "net/cert/ct_log_verifier.h"
+#include <string.h>
+
#include "base/logging.h"
+#include "net/cert/ct_log_verifier_util.h"
#include "net/cert/ct_serialization.h"
+#include "net/cert/merkle_consistency_proof.h"
#include "net/cert/signed_tree_head.h"
namespace net {
+namespace {
+
+// The SHA-256 hash of the empty string.
+const unsigned char kSHA256EmptyStringHash[ct::kSthRootHashLength] = {
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4,
+ 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b,
+ 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55};
+
+bool IsPowerOfTwo(uint64_t n) {
+ return n != 0 && (n & (n - 1)) == 0;
+}
+
+} // namespace
+
// static
-scoped_refptr<CTLogVerifier> CTLogVerifier::Create(
+scoped_refptr<const CTLogVerifier> CTLogVerifier::Create(
const base::StringPiece& public_key,
const base::StringPiece& description,
const base::StringPiece& url) {
@@ -35,7 +53,7 @@ CTLogVerifier::CTLogVerifier(const base::StringPiece& description,
}
bool CTLogVerifier::Verify(const ct::LogEntry& entry,
- const ct::SignedCertificateTimestamp& sct) {
+ const ct::SignedCertificateTimestamp& sct) const {
if (sct.log_id != key_id()) {
DVLOG(1) << "SCT is not signed by this log.";
return false;
@@ -60,7 +78,7 @@ bool CTLogVerifier::Verify(const ct::LogEntry& entry,
}
bool CTLogVerifier::VerifySignedTreeHead(
- const ct::SignedTreeHead& signed_tree_head) {
+ const ct::SignedTreeHead& signed_tree_head) const {
if (!SignatureParametersMatch(signed_tree_head.signature))
return false;
@@ -68,13 +86,18 @@ bool CTLogVerifier::VerifySignedTreeHead(
ct::EncodeTreeHeadSignature(signed_tree_head, &serialized_data);
if (VerifySignature(serialized_data,
signed_tree_head.signature.signature_data)) {
+ if (signed_tree_head.tree_size == 0) {
+ // Root hash must equate SHA256 hash of the empty string.
+ return (memcmp(signed_tree_head.sha256_root_hash, kSHA256EmptyStringHash,
+ ct::kSthRootHashLength) == 0);
+ }
return true;
}
return false;
}
bool CTLogVerifier::SignatureParametersMatch(
- const ct::DigitallySigned& signature) {
+ const ct::DigitallySigned& signature) const {
if (!signature.SignatureParametersMatch(hash_algorithm_,
signature_algorithm_)) {
DVLOG(1) << "Mismatched hash or signature algorithm. Hash: "
@@ -87,4 +110,114 @@ bool CTLogVerifier::SignatureParametersMatch(
return true;
}
+bool CTLogVerifier::VerifyConsistencyProof(
+ const ct::MerkleConsistencyProof& proof,
+ const std::string& old_tree_hash,
+ const std::string& new_tree_hash) const {
+ // Proof does not originate from this log.
+ if (key_id_ != proof.log_id)
+ return false;
+
+ // Cannot prove consistency from a tree of a certain size to a tree smaller
+ // than that - only the other way around.
+ if (proof.first_tree_size > proof.second_tree_size)
+ return false;
+
+ // If the proof is between trees of the same size, then the 'proof'
+ // is really just a statement that the tree hasn't changed. If this
+ // is the case, there should be no proof nodes, and both the old
+ // and new hash should be equivalent.
+ if (proof.first_tree_size == proof.second_tree_size)
+ return proof.nodes.empty() && old_tree_hash == new_tree_hash;
+
+ // It is possible to call this method to prove consistency between the
+ // initial state of a log (i.e. an empty tree) and a later root. In that
+ // case, the only valid proof is an empty proof.
+ if (proof.first_tree_size == 0)
+ return proof.nodes.empty();
+
+ // Implement the algorithm described in
+ // https://tools.ietf.org/html/draft-ietf-trans-rfc6962-bis-11#section-9.4.2
+ //
+ // It maintains a pair of hashes |fr| and |sr|, initialized to the same
+ // value. Each node in |proof| will be hashed to the left of both |fr| and
+ // |sr| or to the right of only |sr|. The proof is then valid if |fr| is
+ // |old_tree_hash| and |sr| is |new_tree_hash|, proving that tree nodes which
+ // make up |old_tree_hash| are a prefix of |new_tree_hash|.
+
+ // At this point, the algorithm's preconditions must be satisfied.
+ DCHECK_LT(0u, proof.first_tree_size);
+ DCHECK_LT(proof.first_tree_size, proof.second_tree_size);
+
+ // 1. If "first" is an exact power of 2, then prepend "first_hash" to the
+ // "consistency_path" array.
+ base::StringPiece first_proof_node = old_tree_hash;
+ std::vector<std::string>::const_iterator iter = proof.nodes.begin();
+ if (!IsPowerOfTwo(proof.first_tree_size)) {
+ if (iter == proof.nodes.end())
+ return false;
+ first_proof_node = *iter;
+ ++iter;
+ }
+ // iter now points to the second node in the modified proof.nodes.
+
+ // 2. Set "fn" to "first - 1" and "sn" to "second - 1".
+ uint64_t fn = proof.first_tree_size - 1;
+ uint64_t sn = proof.second_tree_size - 1;
+
+ // 3. If "LSB(fn)" is set, then right-shift both "fn" and "sn" equally until
+ // "LSB(fn)" is not set.
+ while (fn & 1) {
+ fn >>= 1;
+ sn >>= 1;
+ }
+
+ // 4. Set both "fr" and "sr" to the first value in the "consistency_path"
+ // array.
+ std::string fr = first_proof_node.as_string();
+ std::string sr = first_proof_node.as_string();
+
+ // 5. For each subsequent value "c" in the "consistency_path" array:
+ for (; iter != proof.nodes.end(); ++iter) {
+ // The proof should end exactly when |sn| becomes zero. This check is
+ // missing from the draft specification. It and the additional check below
+ // ensure the proof is consistent with the tree sizes but is not necessary
+ // to ensure |old_tree_hash| is a prefix of |new_tree_hash|.
+ if (sn == 0)
+ return false;
+ // If "LSB(fn)" is set, or if "fn" is equal to "sn", then:
+ if ((fn & 1) || fn == sn) {
+ // 1. Set "fr" to "HASH(0x01 || c || fr)"
+ // Set "sr" to "HASH(0x01 || c || sr)"
+ fr = ct::internal::HashNodes(*iter, fr);
+ sr = ct::internal::HashNodes(*iter, sr);
+
+ // 2. If "LSB(fn)" is not set, then right-shift both "fn" and "sn" equally
+ // until either "LSB(fn)" is set or "fn" is "0".
+ while (!(fn & 1) && fn != 0) {
+ fn >>= 1;
+ sn >>= 1;
+ }
+ } else { // Otherwise:
+ // Set "sr" to "HASH(0x01 || sr || c)"
+ sr = ct::internal::HashNodes(sr, *iter);
+ }
+
+ // Finally, right-shift both "fn" and "sn" one time.
+ fn >>= 1;
+ sn >>= 1;
+ }
+
+ // 6. After completing iterating through the "consistency_path" array as
+ // described above, verify that the "fr" calculated is equal to the
+ // "first_hash" supplied and that the "sr" calculated is equal to the
+ // "second_hash" supplied.
+ //
+ // The proof should also end exactly when |sn| becomes zero. This check is
+ // missing from the draft specification. It and the additional check above
+ // ensure the proof is consistent with the tree sizes but is not necessary to
+ // ensure |old_tree_hash| is a prefix of |new_tree_hash|.
+ return fr == old_tree_hash && sr == new_tree_hash && sn == 0;
+}
+
} // namespace net
diff --git a/chromium/net/cert/ct_log_verifier.h b/chromium/net/cert/ct_log_verifier.h
index 0a9b3eff03d..9f50c1423a6 100644
--- a/chromium/net/cert/ct_log_verifier.h
+++ b/chromium/net/cert/ct_log_verifier.h
@@ -25,11 +25,18 @@ typedef struct SECKEYPublicKeyStr SECKEYPublicKey;
namespace net {
namespace ct {
+
struct SignedTreeHead;
+struct MerkleConsistencyProof;
+
} // namespace ct
-// Class for verifying Signed Certificate Timestamps (SCTs) provided by a
-// specific log (whose identity is provided during construction).
+// Class for verifying signatures of a single Certificate Transparency
+// log, whose identity is provided during construction.
+// Currently can verify Signed Certificate Timestamp (SCT) and Signed
+// Tree Head (STH) signatures.
+// Immutable: Does not hold any state beyond the log information it was
+// initialized with.
class NET_EXPORT CTLogVerifier
: public base::RefCountedThreadSafe<CTLogVerifier> {
public:
@@ -37,7 +44,7 @@ class NET_EXPORT CTLogVerifier
// using |public_key|, which is a DER-encoded SubjectPublicKeyInfo.
// If |public_key| refers to an unsupported public key, returns NULL.
// |description| is a textual description of the log.
- static scoped_refptr<CTLogVerifier> Create(
+ static scoped_refptr<const CTLogVerifier> Create(
const base::StringPiece& public_key,
const base::StringPiece& description,
const base::StringPiece& url);
@@ -49,12 +56,21 @@ class NET_EXPORT CTLogVerifier
// Returns the log's URL
const GURL& url() const { return url_; }
- // Verifies that |sct| contains a valid signature for |entry|.
+ // Verifies that |sct| is valid for |entry| and was signed by this log.
bool Verify(const ct::LogEntry& entry,
- const ct::SignedCertificateTimestamp& sct);
+ const ct::SignedCertificateTimestamp& sct) const;
+
+ // Verifies that |signed_tree_head| is a valid Signed Tree Head (RFC 6962,
+ // Section 3.5) for this log.
+ bool VerifySignedTreeHead(const ct::SignedTreeHead& signed_tree_head) const;
- // Returns true if the signature in |signed_tree_head| verifies.
- bool VerifySignedTreeHead(const ct::SignedTreeHead& signed_tree_head);
+ // Verifies that |proof| is a valid consistency proof (RFC 6962, Section
+ // 2.1.2) for this log, and which proves that |old_tree_hash| has
+ // been fully incorporated into the Merkle tree represented by
+ // |new_tree_hash|.
+ bool VerifyConsistencyProof(const ct::MerkleConsistencyProof& proof,
+ const std::string& old_tree_hash,
+ const std::string& new_tree_hash) const;
private:
FRIEND_TEST_ALL_PREFIXES(CTLogVerifierTest, VerifySignature);
@@ -70,11 +86,11 @@ class NET_EXPORT CTLogVerifier
// that |signature| contains the raw signature data (eg: without any
// DigitallySigned struct encoding).
bool VerifySignature(const base::StringPiece& data_to_sign,
- const base::StringPiece& signature);
+ const base::StringPiece& signature) const;
// Returns true if the signature and hash algorithms in |signature|
// match those of the log
- bool SignatureParametersMatch(const ct::DigitallySigned& signature);
+ bool SignatureParametersMatch(const ct::DigitallySigned& signature) const;
std::string key_id_;
std::string description_;
diff --git a/chromium/net/cert/ct_log_verifier_nss.cc b/chromium/net/cert/ct_log_verifier_nss.cc
index 75a87d610f6..fec7dc832da 100644
--- a/chromium/net/cert/ct_log_verifier_nss.cc
+++ b/chromium/net/cert/ct_log_verifier_nss.cc
@@ -117,7 +117,7 @@ bool CTLogVerifier::Init(const base::StringPiece& public_key) {
}
bool CTLogVerifier::VerifySignature(const base::StringPiece& data_to_sign,
- const base::StringPiece& signature) {
+ const base::StringPiece& signature) const {
SECItem sig_data;
sig_data.data = reinterpret_cast<unsigned char*>(const_cast<char*>(
signature.data()));
diff --git a/chromium/net/cert/ct_log_verifier_openssl.cc b/chromium/net/cert/ct_log_verifier_openssl.cc
index af875a58738..5fe41fd7769 100644
--- a/chromium/net/cert/ct_log_verifier_openssl.cc
+++ b/chromium/net/cert/ct_log_verifier_openssl.cc
@@ -86,7 +86,7 @@ bool CTLogVerifier::Init(const base::StringPiece& public_key) {
}
bool CTLogVerifier::VerifySignature(const base::StringPiece& data_to_sign,
- const base::StringPiece& signature) {
+ const base::StringPiece& signature) const {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
const EVP_MD* hash_alg = GetEvpAlg(hash_algorithm_);
diff --git a/chromium/net/cert/ct_log_verifier_unittest.cc b/chromium/net/cert/ct_log_verifier_unittest.cc
index 4f0fdcccc7e..3ee926353af 100644
--- a/chromium/net/cert/ct_log_verifier_unittest.cc
+++ b/chromium/net/cert/ct_log_verifier_unittest.cc
@@ -4,9 +4,16 @@
#include "net/cert/ct_log_verifier.h"
+#include <stdint.h>
+
#include <string>
+#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
+#include "crypto/secure_hash.h"
+#include "net/base/hash_value.h"
+#include "net/cert/ct_log_verifier_util.h"
+#include "net/cert/merkle_consistency_proof.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/signed_tree_head.h"
#include "net/test/ct_test_util.h"
@@ -14,20 +21,222 @@
namespace net {
+namespace {
+
+// Calculate the power of two nearest to, but less than, |n|.
+// |n| must be at least 2.
+uint64_t CalculateNearestPowerOfTwo(uint64_t n) {
+ DCHECK_GT(n, 1u);
+
+ uint64_t ret = UINT64_C(1) << 63;
+ while (ret >= n)
+ ret >>= 1;
+
+ return ret;
+}
+
+// The following structures, TestVector and ProofTestVector are used for
+// definining test proofs later on.
+
+// A single hash node.
+struct TestVector {
+ const char* const str;
+ size_t length_bytes;
+};
+
+// A single consistency proof. Contains the old and new tree sizes
+// (snapshot1 and snapshot2), the length of the proof (proof_length) and
+// at most 3 proof nodes (all test proofs will be for a tree of size 8).
+struct ProofTestVector {
+ uint64_t snapshot1;
+ uint64_t snapshot2;
+ size_t proof_length;
+ TestVector proof[3];
+};
+
+// All test data replicated from
+// https://github.com/google/certificate-transparency/blob/c41b090ecc14ddd6b3531dc7e5ce36b21e253fdd/cpp/merkletree/merkle_tree_test.cc
+// A hash of the empty string.
+const TestVector kSHA256EmptyTreeHash = {
+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 32};
+
+// Node hashes for a sample tree of size 8 (each element in this array is
+// a node hash, not leaf data; order represents order of the nodes in the tree).
+const TestVector kSHA256Roots[8] = {
+ {"6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", 32},
+ {"fac54203e7cc696cf0dfcb42c92a1d9dbaf70ad9e621f4bd8d98662f00e3c125", 32},
+ {"aeb6bcfe274b70a14fb067a5e5578264db0fa9b51af5e0ba159158f329e06e77", 32},
+ {"d37ee418976dd95753c1c73862b9398fa2a2cf9b4ff0fdfe8b30cd95209614b7", 32},
+ {"4e3bbb1f7b478dcfe71fb631631519a3bca12c9aefca1612bfce4c13a86264d4", 32},
+ {"76e67dadbcdf1e10e1b74ddc608abd2f98dfb16fbce75277b5232a127f2087ef", 32},
+ {"ddb89be403809e325750d3d263cd78929c2942b7942a34b77e122c9594a74c8c", 32},
+ {"5dc9da79a70659a9ad559cb701ded9a2ab9d823aad2f4960cfe370eff4604328", 32}};
+
+// A collection of consistency proofs between various sub-trees of the tree
+// defined by |kSHA256Roots|.
+const ProofTestVector kSHA256Proofs[4] = {
+ // Empty consistency proof between trees of the same size (1).
+ {1, 1, 0, {{"", 0}, {"", 0}, {"", 0}}},
+ // Consistency proof between tree of size 1 and tree of size 8, with 3
+ // nodes in the proof.
+ {1,
+ 8,
+ 3,
+ {{"96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7", 32},
+ {"5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e", 32},
+ {"6b47aaf29ee3c2af9af889bc1fb9254dabd31177f16232dd6aab035ca39bf6e4",
+ 32}}},
+ // Consistency proof between tree of size 6 and tree of size 8, with 3
+ // nodes in the proof.
+ {6,
+ 8,
+ 3,
+ {{"0ebc5d3437fbe2db158b9f126a1d118e308181031d0a949f8dededebc558ef6a", 32},
+ {"ca854ea128ed050b41b35ffc1b87b8eb2bde461e9e3b5596ece6b9d5975a0ae0", 32},
+ {"d37ee418976dd95753c1c73862b9398fa2a2cf9b4ff0fdfe8b30cd95209614b7",
+ 32}}},
+ // Consistency proof between tree of size 2 and tree of size 5, with 2
+ // nodes in the proof.
+ {2,
+ 5,
+ 2,
+ {{"5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e", 32},
+ {"bc1a0643b12e4d2d7c77918f44e0f4f79a838b6cf9ec5b5c283e1f4d88599e6b", 32},
+ {"", 0}}}};
+
+// Decodes a hexadecimal string into the binary data it represents.
+std::string HexToBytes(const char* hex_data, size_t hex_data_length) {
+ std::vector<uint8_t> output;
+ std::string result;
+ std::string hex_data_input(hex_data, hex_data_length);
+ if (base::HexStringToBytes(hex_data, &output))
+ result.assign(reinterpret_cast<const char*>(&output[0]), output.size());
+ return result;
+}
+
+std::string GetEmptyTreeHash() {
+ return HexToBytes(kSHA256EmptyTreeHash.str,
+ kSHA256EmptyTreeHash.length_bytes);
+}
+
+// Creates a ct::MerkleConsistencyProof and returns the result of
+// calling log->VerifyConsistencyProof with that proof and snapshots.
+bool VerifyConsistencyProof(scoped_refptr<const CTLogVerifier> log,
+ uint64_t old_tree_size,
+ const std::string& old_tree_root,
+ uint64_t new_tree_size,
+ const std::string& new_tree_root,
+ const std::vector<std::string>& proof) {
+ return log->VerifyConsistencyProof(
+ ct::MerkleConsistencyProof(log->key_id(), proof, old_tree_size,
+ new_tree_size),
+ old_tree_root, new_tree_root);
+}
+
class CTLogVerifierTest : public ::testing::Test {
public:
CTLogVerifierTest() {}
void SetUp() override {
log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog",
- "https://ct.example.com").Pass();
+ "https://ct.example.com");
ASSERT_TRUE(log_);
ASSERT_EQ(log_->key_id(), ct::GetTestPublicKeyId());
}
+ // Given a consistency proof between two snapshots of the tree, asserts that
+ // it verifies and no other combination of snapshots and proof nodes verifies.
+ void VerifierConsistencyCheck(int snapshot1,
+ int snapshot2,
+ const std::string& root1,
+ const std::string& root2,
+ const std::vector<std::string>& proof) {
+ // Verify the original consistency proof.
+ EXPECT_TRUE(
+ VerifyConsistencyProof(log_, snapshot1, root1, snapshot2, root2, proof))
+ << " " << snapshot1 << " " << snapshot2;
+
+ if (proof.empty()) {
+ // For simplicity test only non-trivial proofs that have root1 != root2
+ // snapshot1 != 0 and snapshot1 != snapshot2.
+ return;
+ }
+
+ // Wrong snapshot index: The proof checking code should not accept
+ // as a valid proof a proof for a tree size different than the original
+ // size it was produced for.
+ // Test that this is not the case for off-by-one changes.
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1 - 1, root1, snapshot2,
+ root2, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1 + 1, root1, snapshot2,
+ root2, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1 ^ 2, root1, snapshot2,
+ root2, proof));
+
+ // Test that the proof is not accepted for trees with wrong tree height.
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2 * 2,
+ root2, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2 / 2,
+ root2, proof));
+
+ // Test that providing the wrong input root fails checking an
+ // otherwise-valid proof.
+ const std::string wrong_root("WrongRoot");
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ wrong_root, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, wrong_root, snapshot2,
+ root2, proof));
+ // Test that swapping roots fails checking an otherwise-valid proof (that
+ // the right root is used for each calculation).
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root2, snapshot2,
+ root1, proof));
+
+ // Variations of wrong proofs, all of which should be rejected.
+ std::vector<std::string> wrong_proof;
+ // Empty proof.
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+
+ // Modify a single element in the proof.
+ for (size_t j = 0; j < proof.size(); ++j) {
+ wrong_proof = proof;
+ wrong_proof[j] = GetEmptyTreeHash();
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+ }
+
+ // Add garbage at the end of the proof.
+ wrong_proof = proof;
+ wrong_proof.push_back(std::string());
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+ wrong_proof.pop_back();
+
+ wrong_proof.push_back(proof.back());
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+ wrong_proof.pop_back();
+
+ // Remove a node from the end.
+ wrong_proof.pop_back();
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+
+ // Add garbage in the beginning of the proof.
+ wrong_proof.clear();
+ wrong_proof.push_back(std::string());
+ wrong_proof.insert(wrong_proof.end(), proof.begin(), proof.end());
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+
+ wrong_proof[0] = proof[0];
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+ }
+
protected:
- scoped_refptr<CTLogVerifier> log_;
+ scoped_refptr<const CTLogVerifier> log_;
};
TEST_F(CTLogVerifierTest, VerifiesCertSCT) {
@@ -77,17 +286,29 @@ TEST_F(CTLogVerifierTest, FailsInvalidLogID) {
EXPECT_FALSE(log_->Verify(cert_entry, *cert_sct.get()));
}
-TEST_F(CTLogVerifierTest, SetsValidSTH) {
+TEST_F(CTLogVerifierTest, VerifiesValidSTH) {
ct::SignedTreeHead sth;
- ct::GetSampleSignedTreeHead(&sth);
- ASSERT_TRUE(log_->VerifySignedTreeHead(sth));
+ ASSERT_TRUE(ct::GetSampleSignedTreeHead(&sth));
+ EXPECT_TRUE(log_->VerifySignedTreeHead(sth));
}
-TEST_F(CTLogVerifierTest, DoesNotSetInvalidSTH) {
+TEST_F(CTLogVerifierTest, DoesNotVerifyInvalidSTH) {
ct::SignedTreeHead sth;
- ct::GetSampleSignedTreeHead(&sth);
+ ASSERT_TRUE(ct::GetSampleSignedTreeHead(&sth));
sth.sha256_root_hash[0] = '\x0';
- ASSERT_FALSE(log_->VerifySignedTreeHead(sth));
+ EXPECT_FALSE(log_->VerifySignedTreeHead(sth));
+}
+
+TEST_F(CTLogVerifierTest, VerifiesValidEmptySTH) {
+ ct::SignedTreeHead sth;
+ ASSERT_TRUE(ct::GetSampleEmptySignedTreeHead(&sth));
+ EXPECT_TRUE(log_->VerifySignedTreeHead(sth));
+}
+
+TEST_F(CTLogVerifierTest, DoesNotVerifyInvalidEmptySTH) {
+ ct::SignedTreeHead sth;
+ ASSERT_TRUE(ct::GetBadEmptySignedTreeHead(&sth));
+ EXPECT_FALSE(log_->VerifySignedTreeHead(sth));
}
// Test that excess data after the public key is rejected.
@@ -95,9 +316,197 @@ TEST_F(CTLogVerifierTest, ExcessDataInPublicKey) {
std::string key = ct::GetTestPublicKey();
key += "extra";
- scoped_refptr<CTLogVerifier> log =
+ scoped_refptr<const CTLogVerifier> log =
CTLogVerifier::Create(key, "testlog", "https://ct.example.com");
EXPECT_FALSE(log);
}
+TEST_F(CTLogVerifierTest, VerifiesConsistencyProofEdgeCases_EmptyProof) {
+ std::vector<std::string> empty_proof;
+ std::string root1(GetEmptyTreeHash()), root2(GetEmptyTreeHash());
+
+ // Snapshots that are always consistent, because they are either
+ // from an empty tree to a non-empty one or for trees of the same
+ // size.
+ EXPECT_TRUE(VerifyConsistencyProof(log_, 0, root1, 0, root2, empty_proof));
+ EXPECT_TRUE(VerifyConsistencyProof(log_, 0, root1, 1, root2, empty_proof));
+ EXPECT_TRUE(VerifyConsistencyProof(log_, 1, root1, 1, root2, empty_proof));
+
+ // Invalid consistency proofs.
+ // Time travel to the past.
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 1, root1, 0, root2, empty_proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 2, root1, 1, root2, empty_proof));
+ // Proof between two trees of different size can never be empty.
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 1, root1, 2, root2, empty_proof));
+}
+
+TEST_F(CTLogVerifierTest, VerifiesConsistencyProofEdgeCases_MismatchingRoots) {
+ std::vector<std::string> empty_proof;
+ std::string root2;
+ const std::string empty_tree_hash(GetEmptyTreeHash());
+
+ // Roots don't match.
+ EXPECT_FALSE(
+ VerifyConsistencyProof(log_, 0, empty_tree_hash, 0, root2, empty_proof));
+ EXPECT_FALSE(
+ VerifyConsistencyProof(log_, 1, empty_tree_hash, 1, root2, empty_proof));
+}
+
+TEST_F(CTLogVerifierTest,
+ VerifiesConsistencyProofEdgeCases_MatchingRootsNonEmptyProof) {
+ const std::string empty_tree_hash(GetEmptyTreeHash());
+
+ std::vector<std::string> proof;
+ proof.push_back(empty_tree_hash);
+
+ // Roots match and the tree size is either the same or the old tree size is 0,
+ // but the proof is not empty (the verification code should not accept
+ // proofs with redundant nodes in this case).
+ proof.push_back(empty_tree_hash);
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 0, empty_tree_hash, 0,
+ empty_tree_hash, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 0, empty_tree_hash, 1,
+ empty_tree_hash, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 1, empty_tree_hash, 1,
+ empty_tree_hash, proof));
+}
+
+TEST_F(CTLogVerifierTest, VerifiesValidConsistencyProofs) {
+ std::vector<std::string> proof;
+ std::string root1, root2;
+
+ // Known good proofs.
+ for (size_t i = 0; i < arraysize(kSHA256Proofs); ++i) {
+ proof.clear();
+ for (size_t j = 0; j < kSHA256Proofs[i].proof_length; ++j) {
+ const TestVector& v = kSHA256Proofs[i].proof[j];
+ proof.push_back(HexToBytes(v.str, v.length_bytes));
+ }
+ const uint64_t snapshot1 = kSHA256Proofs[i].snapshot1;
+ const uint64_t snapshot2 = kSHA256Proofs[i].snapshot2;
+ const TestVector& old_root = kSHA256Roots[snapshot1 - 1];
+ const TestVector& new_root = kSHA256Roots[snapshot2 - 1];
+ VerifierConsistencyCheck(
+ snapshot1, snapshot2, HexToBytes(old_root.str, old_root.length_bytes),
+ HexToBytes(new_root.str, new_root.length_bytes), proof);
+ }
+}
+
+const char kLeafPrefix[] = {'\x00'};
+
+// Reference implementation of RFC6962.
+// This allows generation of arbitrary-sized Merkle trees and consistency
+// proofs between them for testing the consistency proof validation
+// code.
+class TreeHasher {
+ public:
+ static std::string HashEmpty() {
+ return HexToBytes(kSHA256EmptyTreeHash.str,
+ kSHA256EmptyTreeHash.length_bytes);
+ }
+
+ static std::string HashLeaf(const std::string& leaf) {
+ SHA256HashValue sha256;
+ memset(sha256.data, 0, sizeof(sha256.data));
+
+ scoped_ptr<crypto::SecureHash> hash(
+ crypto::SecureHash::Create(crypto::SecureHash::SHA256));
+ hash->Update(kLeafPrefix, 1);
+ hash->Update(leaf.data(), leaf.size());
+ hash->Finish(sha256.data, sizeof(sha256.data));
+
+ return std::string(reinterpret_cast<const char*>(sha256.data),
+ sizeof(sha256.data));
+ }
+};
+
+// Reference implementation of Merkle hash, for cross-checking.
+// Recursively calculates the hash of the root given the leaf data
+// specified in |inputs|.
+std::string ReferenceMerkleTreeHash(std::string* inputs, uint64_t input_size) {
+ if (!input_size)
+ return TreeHasher::HashEmpty();
+ if (input_size == 1)
+ return TreeHasher::HashLeaf(inputs[0]);
+
+ const uint64_t split = CalculateNearestPowerOfTwo(input_size);
+
+ return ct::internal::HashNodes(
+ ReferenceMerkleTreeHash(&inputs[0], split),
+ ReferenceMerkleTreeHash(&inputs[split], input_size - split));
+}
+
+// Reference implementation of snapshot consistency. Returns a
+// consistency proof between two snapshots of the tree designated
+// by |inputs|.
+// Call with have_root1 = true.
+std::vector<std::string> ReferenceSnapshotConsistency(std::string* inputs,
+ uint64_t snapshot2,
+ uint64_t snapshot1,
+ bool have_root1) {
+ std::vector<std::string> proof;
+ if (snapshot1 == 0 || snapshot1 > snapshot2)
+ return proof;
+ if (snapshot1 == snapshot2) {
+ // Consistency proof for two equal subtrees is empty.
+ if (!have_root1) {
+ // Record the hash of this subtree unless it's the root for which
+ // the proof was originally requested. (This happens when the snapshot1
+ // tree is balanced.)
+ proof.push_back(ReferenceMerkleTreeHash(inputs, snapshot1));
+ }
+ return proof;
+ }
+
+ // 0 < snapshot1 < snapshot2
+ const uint64_t split = CalculateNearestPowerOfTwo(snapshot2);
+
+ std::vector<std::string> subproof;
+ if (snapshot1 <= split) {
+ // Root of snapshot1 is in the left subtree of snapshot2.
+ // Prove that the left subtrees are consistent.
+ subproof =
+ ReferenceSnapshotConsistency(inputs, split, snapshot1, have_root1);
+ proof.insert(proof.end(), subproof.begin(), subproof.end());
+ // Record the hash of the right subtree (only present in snapshot2).
+ proof.push_back(ReferenceMerkleTreeHash(&inputs[split], snapshot2 - split));
+ } else {
+ // Snapshot1 root is at the same level as snapshot2 root.
+ // Prove that the right subtrees are consistent. The right subtree
+ // doesn't contain the root of snapshot1, so set have_root1 = false.
+ subproof = ReferenceSnapshotConsistency(&inputs[split], snapshot2 - split,
+ snapshot1 - split, false);
+ proof.insert(proof.end(), subproof.begin(), subproof.end());
+ // Record the hash of the left subtree (equal in both trees).
+ proof.push_back(ReferenceMerkleTreeHash(&inputs[0], split));
+ }
+ return proof;
+}
+
+// "brute-force" test generating a tree of 256 entries, generating
+// a consistency proof for each snapshot of each sub-tree up to that
+// size and making sure it verifies.
+TEST_F(CTLogVerifierTest,
+ VerifiesValidConsistencyProofsFromReferenceGenerator) {
+ std::vector<std::string> data;
+ for (int i = 0; i < 256; ++i)
+ data.push_back(std::string(1, i));
+
+ std::vector<std::string> proof;
+ std::string root1, root2;
+ // More tests with reference proof generator.
+ for (size_t tree_size = 1; tree_size <= data.size() / 2; ++tree_size) {
+ root2 = ReferenceMerkleTreeHash(data.data(), tree_size);
+ // Repeat for each snapshot in range.
+ for (size_t snapshot = 1; snapshot <= tree_size; ++snapshot) {
+ proof =
+ ReferenceSnapshotConsistency(data.data(), tree_size, snapshot, true);
+ root1 = ReferenceMerkleTreeHash(data.data(), snapshot);
+ VerifierConsistencyCheck(snapshot, tree_size, root1, root2, proof);
+ }
+ }
+}
+
+} // namespace
+
} // namespace net
diff --git a/chromium/net/cert/ct_log_verifier_util.cc b/chromium/net/cert/ct_log_verifier_util.cc
new file mode 100644
index 00000000000..9e8097f5133
--- /dev/null
+++ b/chromium/net/cert/ct_log_verifier_util.cc
@@ -0,0 +1,36 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/ct_log_verifier_util.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_util.h"
+#include "crypto/secure_hash.h"
+#include "crypto/sha2.h"
+
+namespace net {
+
+namespace ct {
+
+namespace internal {
+
+std::string HashNodes(const std::string& lh, const std::string& rh) {
+ scoped_ptr<crypto::SecureHash> hash(
+ crypto::SecureHash::Create(crypto::SecureHash::SHA256));
+
+ hash->Update("\01", 1);
+ hash->Update(lh.data(), lh.size());
+ hash->Update(rh.data(), rh.size());
+
+ std::string result;
+ hash->Finish(base::WriteInto(&result, crypto::kSHA256Length + 1),
+ crypto::kSHA256Length);
+ return result;
+}
+
+} // namespace internal
+
+} // namespace ct
+
+} // namespace net
diff --git a/chromium/net/cert/ct_log_verifier_util.h b/chromium/net/cert/ct_log_verifier_util.h
new file mode 100644
index 00000000000..9894afe59ea
--- /dev/null
+++ b/chromium/net/cert/ct_log_verifier_util.h
@@ -0,0 +1,30 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_CERT_CT_LOG_VERIFIER_UTIL_H_
+#define NET_CERT_CT_LOG_VERIFIER_UTIL_H_
+
+#include <stdint.h>
+
+#include <string>
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace ct {
+
+namespace internal {
+
+// Hash |lh| and |rh| to produce a node hash according to
+// http://tools.ietf.org/html/rfc6962#section-2.1
+NET_EXPORT std::string HashNodes(const std::string& lh, const std::string& rh);
+
+} // namespace internal
+
+} // namespace ct
+
+} // namespace net
+
+#endif
diff --git a/chromium/net/cert/ct_objects_extractor_nss.cc b/chromium/net/cert/ct_objects_extractor_nss.cc
index b4c1da3dfe6..76a3be51d2e 100644
--- a/chromium/net/cert/ct_objects_extractor_nss.cc
+++ b/chromium/net/cert/ct_objects_extractor_nss.cc
@@ -10,12 +10,15 @@
#include <secoid.h>
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/sha1.h"
#include "crypto/scoped_nss_types.h"
#include "crypto/sha2.h"
#include "net/cert/asn1_util.h"
#include "net/cert/scoped_nss_types.h"
#include "net/cert/signed_certificate_timestamp.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
namespace net {
@@ -147,14 +150,13 @@ bool GetCertOctetStringExtension(CERTCertificate* cert,
if (rv != SECSuccess)
return false;
- base::StringPiece raw_data(reinterpret_cast<char*>(extension.data),
- extension.len);
- base::StringPiece parsed_data;
- if (!asn1::GetElement(&raw_data, asn1::kOCTETSTRING, &parsed_data) ||
- raw_data.size() > 0) { // Decoding failure or raw data left
+ der::Parser parser(der::Input(extension.data, extension.len));
+ der::Input parsed_extension;
+ if (!parser.ReadTag(der::kOctetString, &parsed_extension) ||
+ parser.HasMore()) { // Decoding failure or raw data left
rv = SECFailure;
} else {
- parsed_data.CopyToString(extension_data);
+ *extension_data = parsed_extension.AsString();
}
SECITEM_FreeItem(&extension, PR_FALSE);
diff --git a/chromium/net/cert/ct_objects_extractor_unittest.cc b/chromium/net/cert/ct_objects_extractor_unittest.cc
index 7640e5bdb0d..5bb59ba3db0 100644
--- a/chromium/net/cert/ct_objects_extractor_unittest.cc
+++ b/chromium/net/cert/ct_objects_extractor_unittest.cc
@@ -32,7 +32,7 @@ class CTObjectsExtractorTest : public ::testing::Test {
der_test_cert.length());
log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog",
- "https://ct.example.com").Pass();
+ "https://ct.example.com");
ASSERT_TRUE(log_);
}
@@ -52,7 +52,7 @@ class CTObjectsExtractorTest : public ::testing::Test {
protected:
CertificateList precert_chain_;
scoped_refptr<X509Certificate> test_cert_;
- scoped_refptr<CTLogVerifier> log_;
+ scoped_refptr<const CTLogVerifier> log_;
};
// Test that an SCT can be extracted and the extracted SCT contains the
diff --git a/chromium/net/cert/cert_policy_enforcer.cc b/chromium/net/cert/ct_policy_enforcer.cc
index 070f8691ee6..d9c92421bf8 100644
--- a/chromium/net/cert/cert_policy_enforcer.cc
+++ b/chromium/net/cert/ct_policy_enforcer.cc
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/cert/cert_policy_enforcer.h"
+#include "net/cert/ct_policy_enforcer.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/build_time.h"
@@ -13,9 +14,11 @@
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
#include "base/values.h"
#include "base/version.h"
#include "net/cert/ct_ev_whitelist.h"
+#include "net/cert/ct_known_logs.h"
#include "net/cert/ct_verify_result.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/x509_certificate.h"
@@ -43,6 +46,11 @@ bool IsBuildTimely() {
#endif
}
+bool IsGoogleIssuedSCT(
+ const scoped_refptr<ct::SignedCertificateTimestamp>& sct) {
+ return ct::IsLogOperatedByGoogle(sct->log_id);
+}
+
// Returns a rounded-down months difference of |start| and |end|,
// together with an indication of whether the last month was
// a full month, because the range starts specified in the policy
@@ -75,12 +83,10 @@ void RoundedDownMonthDifference(const base::Time& start,
bool HasRequiredNumberOfSCTs(const X509Certificate& cert,
const ct::CTVerifyResult& ct_result) {
- // TODO(eranm): Count the number of *independent* SCTs once the information
- // about log operators is available, crbug.com/425174
size_t num_valid_scts = ct_result.verified_scts.size();
- size_t num_embedded_scts =
+ size_t num_embedded_scts = base::checked_cast<size_t>(
std::count_if(ct_result.verified_scts.begin(),
- ct_result.verified_scts.end(), IsEmbeddedSCT);
+ ct_result.verified_scts.end(), IsEmbeddedSCT));
size_t num_non_embedded_scts = num_valid_scts - num_embedded_scts;
// If at least two valid SCTs were delivered by means other than embedding
@@ -117,10 +123,22 @@ bool HasRequiredNumberOfSCTs(const X509Certificate& cert,
return num_embedded_scts >= num_required_embedded_scts;
}
+// Returns true if |verified_scts| contains SCTs from at least one log that is
+// operated by Google and at least one log that is not operated by Google. This
+// is required for SCTs after July 1st, 2015, as documented at
+// http://dev.chromium.org/Home/chromium-security/root-ca-policy/EVCTPlanMay2015edition.pdf
+bool HasEnoughDiverseSCTs(const ct::SCTList& verified_scts) {
+ size_t num_google_issued_scts = base::checked_cast<size_t>(std::count_if(
+ verified_scts.begin(), verified_scts.end(), IsGoogleIssuedSCT));
+ return (num_google_issued_scts > 0) &&
+ (verified_scts.size() != num_google_issued_scts);
+}
+
enum CTComplianceStatus {
CT_NOT_COMPLIANT = 0,
CT_IN_WHITELIST = 1,
CT_ENOUGH_SCTS = 2,
+ CT_NOT_ENOUGH_DIVERSE_SCTS = 3,
CT_COMPLIANCE_MAX,
};
@@ -135,6 +153,9 @@ const char* ComplianceStatusToString(CTComplianceStatus status) {
case CT_ENOUGH_SCTS:
return "ENOUGH_SCTS";
break;
+ case CT_NOT_ENOUGH_DIVERSE_SCTS:
+ return "NOT_ENOUGH_DIVERSE_SCTS";
+ break;
case CT_COMPLIANCE_MAX:
break;
}
@@ -203,7 +224,24 @@ scoped_ptr<base::Value> NetLogComplianceCheckResultCallback(
details->whitelist_version.GetString());
}
}
- return dict.Pass();
+ return std::move(dict);
+}
+
+// Returns true if all SCTs in |verified_scts| were issued on, or after, the
+// date specified in kDiverseSCTRequirementStartDate
+bool AllSCTsPastDistinctSCTRequirementEnforcementDate(
+ const ct::SCTList& verified_scts) {
+ // The date when diverse SCTs requirement is effective from.
+ // 2015-07-01 00:00:00 UTC.
+ base::Time kDiverseSCTRequirementStartDate =
+ base::Time::FromInternalValue(13080182400000000);
+
+ for (const auto& it : verified_scts) {
+ if (it->timestamp < kDiverseSCTRequirementStartDate)
+ return false;
+ }
+
+ return true;
}
bool IsCertificateInWhitelist(const X509Certificate& cert,
@@ -241,17 +279,24 @@ void CheckCTEVPolicyCompliance(X509Certificate* cert,
return;
}
- if (HasRequiredNumberOfSCTs(*cert, ct_result)) {
- result->status = CT_ENOUGH_SCTS;
+ if (!HasRequiredNumberOfSCTs(*cert, ct_result)) {
+ result->status = CT_NOT_COMPLIANT;
+ return;
+ }
+
+ if (AllSCTsPastDistinctSCTRequirementEnforcementDate(
+ ct_result.verified_scts) &&
+ !HasEnoughDiverseSCTs(ct_result.verified_scts)) {
+ result->status = CT_NOT_ENOUGH_DIVERSE_SCTS;
return;
}
- result->status = CT_NOT_COMPLIANT;
+ result->status = CT_ENOUGH_SCTS;
}
} // namespace
-bool CertPolicyEnforcer::DoesConformToCTEVPolicy(
+bool CTPolicyEnforcer::DoesConformToCTEVPolicy(
X509Certificate* cert,
const ct::EVCertsWhitelist* ev_whitelist,
const ct::CTVerifyResult& ct_result,
diff --git a/chromium/net/cert/cert_policy_enforcer.h b/chromium/net/cert/ct_policy_enforcer.h
index ea24dbd91f1..8c29da5ecb3 100644
--- a/chromium/net/cert/cert_policy_enforcer.h
+++ b/chromium/net/cert/ct_policy_enforcer.h
@@ -1,8 +1,8 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_CERT_CERT_POLICY_ENFORCER_H
-#define NET_CERT_CERT_POLICY_ENFORCER_H
+#ifndef NET_CERT_CT_POLICY_ENFORCER_H
+#define NET_CERT_CT_POLICY_ENFORCER_H
#include <stddef.h>
@@ -22,10 +22,10 @@ class X509Certificate;
// Class for checking that a given certificate conforms to security-related
// policies.
-class NET_EXPORT CertPolicyEnforcer {
+class NET_EXPORT CTPolicyEnforcer {
public:
- CertPolicyEnforcer() {}
- virtual ~CertPolicyEnforcer() {}
+ CTPolicyEnforcer() {}
+ virtual ~CTPolicyEnforcer() {}
// Returns true if the collection of SCTs for the given certificate
// conforms with the CT/EV policy. Conformance details are logged to
@@ -41,4 +41,4 @@ class NET_EXPORT CertPolicyEnforcer {
} // namespace net
-#endif // NET_CERT_CERT_POLICY_ENFORCER_H
+#endif // NET_CERT_CT_POLICY_ENFORCER_H
diff --git a/chromium/net/cert/cert_policy_enforcer_unittest.cc b/chromium/net/cert/ct_policy_enforcer_unittest.cc
index bf706dd9b94..43552529333 100644
--- a/chromium/net/cert/cert_policy_enforcer_unittest.cc
+++ b/chromium/net/cert/ct_policy_enforcer_unittest.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/cert/cert_policy_enforcer.h"
+#include "net/cert/ct_policy_enforcer.h"
#include <string>
#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
#include "base/version.h"
+#include "crypto/sha2.h"
#include "net/base/test_data_directory.h"
#include "net/cert/ct_ev_whitelist.h"
#include "net/cert/ct_verify_result.h"
@@ -44,29 +46,72 @@ class DummyEVCertsWhitelist : public ct::EVCertsWhitelist {
bool canned_contains_response_;
};
-class CertPolicyEnforcerTest : public ::testing::Test {
+const char kGoogleAviatorLogID[] =
+ "\x68\xf6\x98\xf8\x1f\x64\x82\xbe\x3a\x8c\xee\xb9\x28\x1d\x4c\xfc\x71\x51"
+ "\x5d\x67\x93\xd4\x44\xd1\x0a\x67\xac\xbb\x4f\x4f\xfb\xc4";
+static_assert(arraysize(kGoogleAviatorLogID) - 1 == crypto::kSHA256Length,
+ "Incorrect log ID length.");
+
+class CTPolicyEnforcerTest : public ::testing::Test {
public:
void SetUp() override {
- policy_enforcer_.reset(new CertPolicyEnforcer);
+ policy_enforcer_.reset(new CTPolicyEnforcer);
std::string der_test_cert(ct::GetDerEncodedX509Cert());
chain_ = X509Certificate::CreateFromBytes(der_test_cert.data(),
der_test_cert.size());
ASSERT_TRUE(chain_.get());
+ google_log_id_ = std::string(kGoogleAviatorLogID, crypto::kSHA256Length);
+ non_google_log_id_.assign(crypto::kSHA256Length, 'A');
}
void FillResultWithSCTsOfOrigin(
ct::SignedCertificateTimestamp::Origin desired_origin,
- int num_scts,
+ size_t num_scts,
+ const std::vector<std::string>& desired_log_keys,
+ bool timestamp_past_enforcement_date,
ct::CTVerifyResult* result) {
- for (int i = 0; i < num_scts; ++i) {
+ for (size_t i = 0; i < num_scts; ++i) {
scoped_refptr<ct::SignedCertificateTimestamp> sct(
new ct::SignedCertificateTimestamp());
sct->origin = desired_origin;
+ if (i < desired_log_keys.size())
+ sct->log_id = desired_log_keys[i];
+ else
+ sct->log_id = non_google_log_id_;
+
+ if (timestamp_past_enforcement_date)
+ sct->timestamp =
+ base::Time::FromUTCExploded({2015, 8, 0, 15, 0, 0, 0, 0});
+ else
+ sct->timestamp =
+ base::Time::FromUTCExploded({2015, 6, 0, 15, 0, 0, 0, 0});
+
result->verified_scts.push_back(sct);
}
}
+ void FillResultWithSCTsOfOrigin(
+ ct::SignedCertificateTimestamp::Origin desired_origin,
+ size_t num_scts,
+ ct::CTVerifyResult* result) {
+ std::vector<std::string> desired_log_ids;
+ desired_log_ids.push_back(google_log_id_);
+ FillResultWithSCTsOfOrigin(desired_origin, num_scts, desired_log_ids, true,
+ result);
+ }
+
+ void FillResultWithRepeatedLogID(const std::string& desired_id,
+ size_t num_scts,
+ bool timestamp_past_enforcement_date,
+ ct::CTVerifyResult* result) {
+ std::vector<std::string> desired_log_ids(num_scts, desired_id);
+
+ FillResultWithSCTsOfOrigin(
+ ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, num_scts,
+ desired_log_ids, timestamp_past_enforcement_date, result);
+ }
+
void CheckCertificateCompliesWithExactNumberOfEmbeddedSCTs(
const base::Time& start,
const base::Time& end,
@@ -74,16 +119,17 @@ class CertPolicyEnforcerTest : public ::testing::Test {
scoped_refptr<X509Certificate> cert(
new X509Certificate("subject", "issuer", start, end));
ct::CTVerifyResult result;
+
for (size_t i = 0; i < required_scts - 1; ++i) {
FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED,
- 1, &result);
+ 1, std::vector<std::string>(), false, &result);
EXPECT_FALSE(policy_enforcer_->DoesConformToCTEVPolicy(
cert.get(), nullptr, result, BoundNetLog()))
<< " for: " << (end - start).InDays() << " and " << required_scts
<< " scts=" << result.verified_scts.size() << " i=" << i;
}
FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 1,
- &result);
+ std::vector<std::string>(), false, &result);
EXPECT_TRUE(policy_enforcer_->DoesConformToCTEVPolicy(
cert.get(), nullptr, result, BoundNetLog()))
<< " for: " << (end - start).InDays() << " and " << required_scts
@@ -91,11 +137,39 @@ class CertPolicyEnforcerTest : public ::testing::Test {
}
protected:
- scoped_ptr<CertPolicyEnforcer> policy_enforcer_;
+ scoped_ptr<CTPolicyEnforcer> policy_enforcer_;
scoped_refptr<X509Certificate> chain_;
+ std::string google_log_id_;
+ std::string non_google_log_id_;
};
-TEST_F(CertPolicyEnforcerTest, ConformsToCTEVPolicyWithNonEmbeddedSCTs) {
+TEST_F(CTPolicyEnforcerTest,
+ DoesNotConformToCTEVPolicyNotEnoughDiverseSCTsAllGoogle) {
+ ct::CTVerifyResult result;
+ FillResultWithRepeatedLogID(google_log_id_, 2, true, &result);
+
+ EXPECT_FALSE(policy_enforcer_->DoesConformToCTEVPolicy(
+ chain_.get(), nullptr, result, BoundNetLog()));
+}
+
+TEST_F(CTPolicyEnforcerTest,
+ DoesNotConformToCTEVPolicyNotEnoughDiverseSCTsAllNonGoogle) {
+ ct::CTVerifyResult result;
+ FillResultWithRepeatedLogID(non_google_log_id_, 2, true, &result);
+
+ EXPECT_FALSE(policy_enforcer_->DoesConformToCTEVPolicy(
+ chain_.get(), nullptr, result, BoundNetLog()));
+}
+
+TEST_F(CTPolicyEnforcerTest, ConformsToCTEVPolicyIfSCTBeforeEnforcementDate) {
+ ct::CTVerifyResult result;
+ FillResultWithRepeatedLogID(non_google_log_id_, 2, false, &result);
+
+ EXPECT_TRUE(policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr,
+ result, BoundNetLog()));
+}
+
+TEST_F(CTPolicyEnforcerTest, ConformsToCTEVPolicyWithNonEmbeddedSCTs) {
ct::CTVerifyResult result;
FillResultWithSCTsOfOrigin(
ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, 2, &result);
@@ -104,7 +178,7 @@ TEST_F(CertPolicyEnforcerTest, ConformsToCTEVPolicyWithNonEmbeddedSCTs) {
result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest, ConformsToCTEVPolicyWithEmbeddedSCTs) {
+TEST_F(CTPolicyEnforcerTest, ConformsToCTEVPolicyWithEmbeddedSCTs) {
// This chain_ is valid for 10 years - over 121 months - so requires 5 SCTs.
ct::CTVerifyResult result;
FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 5,
@@ -114,7 +188,7 @@ TEST_F(CertPolicyEnforcerTest, ConformsToCTEVPolicyWithEmbeddedSCTs) {
result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest, DoesNotConformToCTEVPolicyNotEnoughSCTs) {
+TEST_F(CTPolicyEnforcerTest, DoesNotConformToCTEVPolicyNotEnoughSCTs) {
scoped_refptr<ct::EVCertsWhitelist> non_including_whitelist(
new DummyEVCertsWhitelist(true, false));
// This chain_ is valid for 10 years - over 121 months - so requires 5 SCTs.
@@ -134,7 +208,7 @@ TEST_F(CertPolicyEnforcerTest, DoesNotConformToCTEVPolicyNotEnoughSCTs) {
chain_.get(), whitelist.get(), result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest, DoesNotConformToPolicyInvalidDates) {
+TEST_F(CTPolicyEnforcerTest, DoesNotConformToPolicyInvalidDates) {
scoped_refptr<X509Certificate> no_valid_dates_cert(new X509Certificate(
"subject", "issuer", base::Time(), base::Time::Now()));
ct::CTVerifyResult result;
@@ -149,7 +223,7 @@ TEST_F(CertPolicyEnforcerTest, DoesNotConformToPolicyInvalidDates) {
chain_.get(), whitelist.get(), result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest,
+TEST_F(CTPolicyEnforcerTest,
ConformsToPolicyExactNumberOfSCTsForValidityPeriod) {
// Test multiple validity periods
const struct TestData {
@@ -193,7 +267,7 @@ TEST_F(CertPolicyEnforcerTest,
}
}
-TEST_F(CertPolicyEnforcerTest, ConformsToPolicyByEVWhitelistPresence) {
+TEST_F(CTPolicyEnforcerTest, ConformsToPolicyByEVWhitelistPresence) {
scoped_refptr<ct::EVCertsWhitelist> whitelist(
new DummyEVCertsWhitelist(true, true));
@@ -204,7 +278,7 @@ TEST_F(CertPolicyEnforcerTest, ConformsToPolicyByEVWhitelistPresence) {
chain_.get(), whitelist.get(), result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest, IgnoresInvalidEVWhitelist) {
+TEST_F(CTPolicyEnforcerTest, IgnoresInvalidEVWhitelist) {
scoped_refptr<ct::EVCertsWhitelist> whitelist(
new DummyEVCertsWhitelist(false, true));
@@ -215,7 +289,7 @@ TEST_F(CertPolicyEnforcerTest, IgnoresInvalidEVWhitelist) {
chain_.get(), whitelist.get(), result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest, IgnoresNullEVWhitelist) {
+TEST_F(CTPolicyEnforcerTest, IgnoresNullEVWhitelist) {
ct::CTVerifyResult result;
FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 1,
&result);
diff --git a/chromium/net/cert/ct_serialization.cc b/chromium/net/cert/ct_serialization.cc
index 6ea3cedc20f..235d37e65ad 100644
--- a/chromium/net/cert/ct_serialization.cc
+++ b/chromium/net/cert/ct_serialization.cc
@@ -6,6 +6,8 @@
#include <stdint.h>
+#include <limits>
+
#include "base/logging.h"
namespace net {
@@ -360,7 +362,7 @@ bool DecodeSignedCertificateTimestamp(
return false;
}
- if (timestamp > static_cast<uint64_t>(kint64max)) {
+ if (timestamp > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
DVLOG(1) << "Timestamp value too big to cast to int64_t: " << timestamp;
return false;
}
diff --git a/chromium/net/cert/ct_serialization_unittest.cc b/chromium/net/cert/ct_serialization_unittest.cc
index 28ed04c7d18..74cc0e900d8 100644
--- a/chromium/net/cert/ct_serialization_unittest.cc
+++ b/chromium/net/cert/ct_serialization_unittest.cc
@@ -164,7 +164,7 @@ TEST_F(CtSerializationTest, FailsDecodingInvalidSignedCertificateTimestamp) {
TEST_F(CtSerializationTest, EncodesValidSignedTreeHead) {
ct::SignedTreeHead signed_tree_head;
- GetSampleSignedTreeHead(&signed_tree_head);
+ ASSERT_TRUE(GetSampleSignedTreeHead(&signed_tree_head));
std::string encoded;
ct::EncodeTreeHeadSignature(signed_tree_head, &encoded);
diff --git a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc
index 01efa0ab7d5..042f59fa16b 100644
--- a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc
+++ b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <string>
+#include <utility>
#include "base/base64.h"
#include "base/strings/string_number_conversions.h"
@@ -139,7 +140,7 @@ scoped_ptr<base::Value> NetLogSignedCertificateTimestampCallback(
dict->Set("unknown_logs_scts",
SCTListToPrintableValues(ct_result->unknown_logs_scts));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogRawSignedCertificateTimestampCallback(
@@ -154,7 +155,7 @@ scoped_ptr<base::Value> NetLogRawSignedCertificateTimestampCallback(
SetBinaryData("scts_from_tls_extension", *sct_list_from_tls_extension,
dict.get());
- return dict.Pass();
+ return std::move(dict);
}
} // namespace net
diff --git a/chromium/net/cert/ct_verifier.h b/chromium/net/cert/ct_verifier.h
index 40631048ac3..46a811a7960 100644
--- a/chromium/net/cert/ct_verifier.h
+++ b/chromium/net/cert/ct_verifier.h
@@ -21,6 +21,7 @@ class CTLogVerifier;
class X509Certificate;
// Interface for verifying Signed Certificate Timestamps over a certificate.
+// The only known (non-test) implementation currently is MultiLogCTVerifier.
class NET_EXPORT CTVerifier {
public:
class NET_EXPORT Observer {
@@ -30,6 +31,8 @@ class NET_EXPORT CTVerifier {
// Signed Certificate Timestamp, |cert| is the certificate it applies to.
// The certificate is needed to calculate the hash of the log entry,
// necessary for checking inclusion in the log.
+ // Note: The observer (whose implementation is expected to exist outside
+ // net/) may store the observed |cert| and |sct|.
virtual void OnSCTVerified(X509Certificate* cert,
const ct::SignedCertificateTimestamp* sct) = 0;
};
diff --git a/chromium/net/cert/ev_root_ca_metadata.cc b/chromium/net/cert/ev_root_ca_metadata.cc
index 8dd55f4e8c4..a5ac6e2231e 100644
--- a/chromium/net/cert/ev_root_ca_metadata.cc
+++ b/chromium/net/cert/ev_root_ca_metadata.cc
@@ -443,11 +443,6 @@ static const EVMetadata ev_root_ca_metadata[] = {
0x6c, 0x51, 0xf7, 0x0e, 0xe9, 0x0d, 0xda, 0xb9, 0xad, 0x8e } },
{"1.3.6.1.4.1.6449.1.2.1.5.1", ""},
},
- // UTN - DATACorp SGC
- { { { 0x58, 0x11, 0x9f, 0x0e, 0x12, 0x82, 0x87, 0xea, 0x50, 0xfd,
- 0xd9, 0x87, 0x45, 0x6f, 0x4f, 0x78, 0xdc, 0xfa, 0xd6, 0xd4 } },
- {"1.3.6.1.4.1.6449.1.2.1.5.1", ""},
- },
// UTN-USERFirst-Hardware
{ { { 0x04, 0x83, 0xed, 0x33, 0x99, 0xac, 0x36, 0x08, 0x05, 0x87,
0x22, 0xed, 0xbc, 0x5e, 0x46, 0x00, 0xe3, 0xbe, 0xf9, 0xd7 } },
diff --git a/chromium/net/cert/ev_root_ca_metadata.h b/chromium/net/cert/ev_root_ca_metadata.h
index 10227a2536c..508e188b132 100644
--- a/chromium/net/cert/ev_root_ca_metadata.h
+++ b/chromium/net/cert/ev_root_ca_metadata.h
@@ -16,6 +16,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/cert/x509_certificate.h"
diff --git a/chromium/net/cert/internal/certificate_policies.cc b/chromium/net/cert/internal/certificate_policies.cc
new file mode 100644
index 00000000000..4ff3a3a6595
--- /dev/null
+++ b/chromium/net/cert/internal/certificate_policies.cc
@@ -0,0 +1,178 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+
+#include "net/cert/internal/certificate_policies.h"
+
+#include "net/der/input.h"
+#include "net/der/parser.h"
+#include "net/der/tag.h"
+
+namespace net {
+
+namespace {
+
+// -- policyQualifierIds for Internet policy qualifiers
+//
+// id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
+// id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
+//
+// In dotted decimal form: 1.3.6.1.5.5.7.2.1
+const der::Input CpsPointerId() {
+ static const uint8_t cps_pointer_id[] = {0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x02, 0x01};
+ return der::Input(cps_pointer_id);
+}
+
+// id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
+//
+// In dotted decimal form: 1.3.6.1.5.5.7.2.2
+const der::Input UserNoticeId() {
+ static const uint8_t user_notice_id[] = {0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x02, 0x02};
+ return der::Input(user_notice_id);
+}
+
+// Ignores the policyQualifiers, but does some minimal correctness checking.
+// TODO(mattm): parse and return the policyQualifiers, since the cert viewer
+// still needs to display them.
+bool ParsePolicyQualifiers(const der::Input& policy_oid,
+ der::Parser* policy_qualifiers_sequence_parser) {
+ // If it is present, the policyQualifiers sequence should have at least 1
+ // element.
+ if (!policy_qualifiers_sequence_parser->HasMore())
+ return false;
+ while (policy_qualifiers_sequence_parser->HasMore()) {
+ der::Parser policy_information_parser;
+ if (!policy_qualifiers_sequence_parser->ReadSequence(
+ &policy_information_parser)) {
+ return false;
+ }
+ der::Input qualifier_oid;
+ if (!policy_information_parser.ReadTag(der::kOid, &qualifier_oid))
+ return false;
+ // RFC 5280 section 4.2.1.4: When qualifiers are used with the special
+ // policy anyPolicy, they MUST be limited to the qualifiers identified in
+ // this section.
+ if (policy_oid.Equals(AnyPolicy()) &&
+ !qualifier_oid.Equals(CpsPointerId()) &&
+ !qualifier_oid.Equals(UserNoticeId())) {
+ return false;
+ }
+ der::Tag tag;
+ der::Input value;
+ if (!policy_information_parser.ReadTagAndValue(&tag, &value))
+ return false;
+ // Should not have trailing data after qualifier.
+ if (policy_information_parser.HasMore())
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+const der::Input AnyPolicy() {
+ // id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
+ //
+ // id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+ //
+ // anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
+ //
+ // In dotted decimal form: 2.5.29.32.0
+ static const uint8_t any_policy[] = {0x55, 0x1D, 0x20, 0x00};
+ return der::Input(any_policy);
+}
+
+// RFC 5280 section 4.2.1.4. Certificate Policies:
+//
+// 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 }
+//
+// PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+//
+// Qualifier ::= CHOICE {
+// cPSuri CPSuri,
+// userNotice UserNotice }
+//
+// CPSuri ::= IA5String
+//
+// UserNotice ::= SEQUENCE {
+// noticeRef NoticeReference OPTIONAL,
+// explicitText DisplayText OPTIONAL }
+//
+// NoticeReference ::= SEQUENCE {
+// organization DisplayText,
+// noticeNumbers SEQUENCE OF INTEGER }
+//
+// DisplayText ::= CHOICE {
+// ia5String IA5String (SIZE (1..200)),
+// visibleString VisibleString (SIZE (1..200)),
+// bmpString BMPString (SIZE (1..200)),
+// utf8String UTF8String (SIZE (1..200)) }
+bool ParseCertificatePoliciesExtension(const der::Input& extension_value,
+ std::vector<der::Input>* policies) {
+ der::Parser extension_parser(extension_value);
+ der::Parser policies_sequence_parser;
+ if (!extension_parser.ReadSequence(&policies_sequence_parser))
+ return false;
+ // Should not have trailing data after certificatePolicies sequence.
+ if (extension_parser.HasMore())
+ return false;
+ // The certificatePolicies sequence should have at least 1 element.
+ if (!policies_sequence_parser.HasMore())
+ return false;
+
+ policies->clear();
+
+ while (policies_sequence_parser.HasMore()) {
+ der::Parser policy_information_parser;
+ if (!policies_sequence_parser.ReadSequence(&policy_information_parser))
+ return false;
+ der::Input policy_oid;
+ if (!policy_information_parser.ReadTag(der::kOid, &policy_oid))
+ return false;
+
+ // Build the |policies| vector in sorted order (sorted on DER encoded policy
+ // OID). Use a binary search to check whether a duplicate policy is present,
+ // and if not, where to insert the policy to maintain the sorted order.
+ std::vector<der::Input>::iterator i =
+ std::lower_bound(policies->begin(), policies->end(), policy_oid);
+ // RFC 5280 section 4.2.1.4: A certificate policy OID MUST NOT appear more
+ // than once in a certificate policies extension.
+ if (i != policies->end() && i->Equals(policy_oid))
+ return false;
+
+ policies->insert(i, policy_oid);
+
+ if (!policy_information_parser.HasMore())
+ continue;
+
+ der::Parser policy_qualifiers_sequence_parser;
+ if (!policy_information_parser.ReadSequence(
+ &policy_qualifiers_sequence_parser)) {
+ return false;
+ }
+ // Should not have trailing data after policyQualifiers sequence.
+ if (policy_information_parser.HasMore())
+ return false;
+ if (!ParsePolicyQualifiers(policy_oid, &policy_qualifiers_sequence_parser))
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace net
diff --git a/chromium/net/cert/internal/certificate_policies.h b/chromium/net/cert/internal/certificate_policies.h
new file mode 100644
index 00000000000..e2ac13fd4e0
--- /dev/null
+++ b/chromium/net/cert/internal/certificate_policies.h
@@ -0,0 +1,36 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_CERT_INTERNAL_CERTIFICATE_POLICIES_H_
+#define NET_CERT_INTERNAL_CERTIFICATE_POLICIES_H_
+
+#include <vector>
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace der {
+class Input;
+} // namespace der
+
+// Returns the DER-encoded OID, without tag or length, of the anyPolicy
+// certificate policy defined in RFC 5280 section 4.2.1.4.
+NET_EXPORT const der::Input AnyPolicy();
+
+// Parses a certificatePolicies extension and stores the policy OIDs in
+// |*policies|, in sorted order. If policyQualifiers are present,
+// they are ignored. (RFC 5280 section 4.2.1.4 says "optional qualifiers, which
+// MAY be present, are not expected to change the definition of the policy.",
+// furthermore policyQualifiers do not affect the success or failure of the
+// section 6 Certification Path Validation algorithm.)
+//
+// The returned values is only valid as long as |extension_value| is.
+NET_EXPORT bool ParseCertificatePoliciesExtension(
+ const der::Input& extension_value,
+ std::vector<der::Input>* policies);
+
+} // namespace net
+
+#endif // NET_CERT_INTERNAL_CERTIFICATE_POLICIES_H_
diff --git a/chromium/net/cert/internal/certificate_policies_unittest.cc b/chromium/net/cert/internal/certificate_policies_unittest.cc
new file mode 100644
index 00000000000..71137cb1f3e
--- /dev/null
+++ b/chromium/net/cert/internal/certificate_policies_unittest.cc
@@ -0,0 +1,150 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/internal/certificate_policies.h"
+
+#include "net/cert/internal/test_helpers.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+::testing::AssertionResult LoadTestData(const std::string& name,
+ std::string* result) {
+ std::string path = "net/data/certificate_policies_unittest/" + name;
+
+ const PemBlockMapping mappings[] = {
+ {"CERTIFICATE POLICIES", result},
+ };
+
+ return ReadTestDataFromPemFile(path, mappings);
+}
+
+const uint8_t policy_1_2_3_der[] = {0x2A, 0x03};
+const uint8_t policy_1_2_4_der[] = {0x2A, 0x04};
+
+} // namespace
+
+TEST(ParseCertificatePoliciesTest, InvalidEmpty) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("invalid-empty.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, InvalidIdentifierNotOid) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("invalid-policy_identifier_not_oid.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, AnyPolicy) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("anypolicy.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(1U, policies.size());
+ EXPECT_EQ(AnyPolicy(), policies[0]);
+}
+
+TEST(ParseCertificatePoliciesTest, AnyPolicyWithQualifier) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("anypolicy_with_qualifier.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(1U, policies.size());
+ EXPECT_EQ(AnyPolicy(), policies[0]);
+}
+
+TEST(ParseCertificatePoliciesTest, InvalidAnyPolicyWithCustomQualifier) {
+ std::string der;
+ ASSERT_TRUE(
+ LoadTestData("invalid-anypolicy_with_custom_qualifier.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, OnePolicy) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("policy_1_2_3.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(1U, policies.size());
+ EXPECT_EQ(der::Input(policy_1_2_3_der), policies[0]);
+}
+
+TEST(ParseCertificatePoliciesTest, OnePolicyWithQualifier) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("policy_1_2_3_with_qualifier.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(1U, policies.size());
+ EXPECT_EQ(der::Input(policy_1_2_3_der), policies[0]);
+}
+
+TEST(ParseCertificatePoliciesTest, OnePolicyWithCustomQualifier) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("policy_1_2_3_with_custom_qualifier.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(1U, policies.size());
+ EXPECT_EQ(der::Input(policy_1_2_3_der), policies[0]);
+}
+
+TEST(ParseCertificatePoliciesTest, InvalidPolicyWithDuplicatePolicyOid) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("invalid-policy_1_2_3_dupe.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, InvalidPolicyWithEmptyQualifiersSequence) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData(
+ "invalid-policy_1_2_3_with_empty_qualifiers_sequence.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, InvalidPolicyInformationHasUnconsumedData) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData(
+ "invalid-policy_1_2_3_policyinformation_unconsumed_data.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest,
+ InvalidPolicyQualifierInfoHasUnconsumedData) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData(
+ "invalid-policy_1_2_3_policyqualifierinfo_unconsumed_data.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, TwoPolicies) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("policy_1_2_3_and_1_2_4.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(2U, policies.size());
+ EXPECT_EQ(der::Input(policy_1_2_3_der), policies[0]);
+ EXPECT_EQ(der::Input(policy_1_2_4_der), policies[1]);
+}
+
+TEST(ParseCertificatePoliciesTest, TwoPoliciesWithQualifiers) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("policy_1_2_3_and_1_2_4_with_qualifiers.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(2U, policies.size());
+ EXPECT_EQ(der::Input(policy_1_2_3_der), policies[0]);
+ EXPECT_EQ(der::Input(policy_1_2_4_der), policies[1]);
+}
+
+} // namespace net
diff --git a/chromium/net/cert/internal/name_constraints.cc b/chromium/net/cert/internal/name_constraints.cc
new file mode 100644
index 00000000000..ade43a776ee
--- /dev/null
+++ b/chromium/net/cert/internal/name_constraints.cc
@@ -0,0 +1,569 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/internal/name_constraints.h"
+
+#include <limits.h>
+
+#include "base/strings/string_util.h"
+#include "net/cert/internal/verify_name_match.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
+#include "net/der/tag.h"
+
+namespace net {
+
+namespace {
+
+// The name types of GeneralName that are fully supported in name constraints.
+//
+// (The other types will have the minimal checking described by RFC 5280
+// section 4.2.1.10: If a name constraints extension that is marked as critical
+// imposes constraints on a particular name form, and an instance of
+// that name form appears in the subject field or subjectAltName
+// extension of a subsequent certificate, then the application MUST
+// either process the constraint or reject the certificate.)
+const int kSupportedNameTypes = GENERAL_NAME_DNS_NAME |
+ GENERAL_NAME_DIRECTORY_NAME |
+ GENERAL_NAME_IP_ADDRESS;
+
+// Controls wildcard handling of DNSNameMatches.
+// If WildcardMatchType is WILDCARD_PARTIAL_MATCH "*.bar.com" is considered to
+// match the constraint "foo.bar.com". If it is WILDCARD_FULL_MATCH, "*.bar.com"
+// will match "bar.com" but not "foo.bar.com".
+enum WildcardMatchType { WILDCARD_PARTIAL_MATCH, WILDCARD_FULL_MATCH };
+
+// Returns true if |name| falls in the subtree defined by |dns_constraint|.
+// RFC 5280 section 4.2.1.10:
+// DNS name restrictions are expressed as host.example.com. Any DNS
+// name that can be constructed by simply adding zero or more labels
+// to the left-hand side of the name satisfies the name constraint. For
+// example, www.host.example.com would satisfy the constraint but
+// host1.example.com would not.
+//
+// |wildcard_matching| controls handling of wildcard names (|name| starts with
+// "*."). Wildcard handling is not specified by RFC 5280, but certificate
+// verification allows it, name constraints must check it similarly.
+bool DNSNameMatches(base::StringPiece name,
+ base::StringPiece dns_constraint,
+ WildcardMatchType wildcard_matching) {
+ // Everything matches the empty DNS name constraint.
+ if (dns_constraint.empty())
+ return true;
+
+ // Normalize absolute DNS names by removing the trailing dot, if any.
+ if (!name.empty() && *name.rbegin() == '.')
+ name.remove_suffix(1);
+ if (!dns_constraint.empty() && *dns_constraint.rbegin() == '.')
+ dns_constraint.remove_suffix(1);
+
+ // Wildcard partial-match handling ("*.bar.com" matching name constraint
+ // "foo.bar.com"). This only handles the case where the the dnsname and the
+ // constraint match after removing the leftmost label, otherwise it is handled
+ // by falling through to the check of whether the dnsname is fully within or
+ // fully outside of the constraint.
+ if (wildcard_matching == WILDCARD_PARTIAL_MATCH && name.size() > 2 &&
+ name[0] == '*' && name[1] == '.') {
+ size_t dns_constraint_dot_pos = dns_constraint.find('.');
+ if (dns_constraint_dot_pos != std::string::npos) {
+ base::StringPiece dns_constraint_domain(
+ dns_constraint.begin() + dns_constraint_dot_pos + 1,
+ dns_constraint.size() - dns_constraint_dot_pos - 1);
+ base::StringPiece wildcard_domain(name.begin() + 2, name.size() - 2);
+ if (base::EqualsCaseInsensitiveASCII(wildcard_domain,
+ dns_constraint_domain)) {
+ return true;
+ }
+ }
+ }
+
+ if (!base::EndsWith(name, dns_constraint,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return false;
+ }
+ // Exact match.
+ if (name.size() == dns_constraint.size())
+ return true;
+ // Subtree match.
+ if (name.size() > dns_constraint.size() &&
+ name[name.size() - dns_constraint.size() - 1] == '.') {
+ return true;
+ }
+ // Trailing text matches, but not in a subtree (e.g., "foobar.com" is not a
+ // match for "bar.com").
+ return false;
+}
+
+// Return true if the bitmask |mask| contains only zeros after the first
+// |prefix_length| bits.
+bool IsSuffixZero(const std::vector<uint8_t>& mask, unsigned prefix_length) {
+ size_t zero_bits = mask.size() * CHAR_BIT - prefix_length;
+ size_t zero_bytes = zero_bits / CHAR_BIT;
+ std::vector<uint8_t> zeros(zero_bytes, 0);
+ if (memcmp(zeros.data(), mask.data() + mask.size() - zero_bytes, zero_bytes))
+ return false;
+ size_t leftover_bits = zero_bits % CHAR_BIT;
+ if (leftover_bits) {
+ uint8_t b = mask[mask.size() - zero_bytes - 1];
+ for (size_t i = 0; i < leftover_bits; ++i) {
+ if (b & (1 << i))
+ return false;
+ }
+ }
+ return true;
+}
+
+// Controls handling of unsupported name types in ParseGeneralName. (Unsupported
+// types are those not in kSupportedNameTypes.)
+// RECORD_UNSUPPORTED causes unsupported types to be recorded in
+// |present_name_types|.
+// IGNORE_UNSUPPORTED causes unsupported types to not be recorded.
+enum ParseGeneralNameUnsupportedTypeBehavior {
+ RECORD_UNSUPPORTED,
+ IGNORE_UNSUPPORTED,
+};
+
+// Controls parsing of iPAddress names in ParseGeneralName.
+// IP_ADDRESS_ONLY parses the iPAddress names as a 4 or 16 byte IP address.
+// IP_ADDRESS_AND_NETMASK parses the iPAddress names as 8 or 32 bytes containing
+// an IP address followed by a netmask.
+enum ParseGeneralNameIPAddressType {
+ IP_ADDRESS_ONLY,
+ IP_ADDRESS_AND_NETMASK,
+};
+
+// Parses a GeneralName value and adds it to |subtrees|.
+WARN_UNUSED_RESULT bool ParseGeneralName(
+ const der::Input& input,
+ ParseGeneralNameUnsupportedTypeBehavior unsupported_type_behavior,
+ ParseGeneralNameIPAddressType ip_address_type,
+ NameConstraints::GeneralNames* subtrees) {
+ der::Parser parser(input);
+ der::Tag tag;
+ der::Input value;
+ if (!parser.ReadTagAndValue(&tag, &value))
+ return false;
+ if (!der::IsContextSpecific(tag))
+ return false;
+ GeneralNameTypes name_type = GENERAL_NAME_NONE;
+ // GeneralName ::= CHOICE {
+ switch (der::GetTagNumber(tag)) {
+ // otherName [0] OtherName,
+ case 0:
+ if (!der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_OTHER_NAME;
+ break;
+ // rfc822Name [1] IA5String,
+ case 1:
+ if (der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_RFC822_NAME;
+ break;
+ // dNSName [2] IA5String,
+ case 2: {
+ if (der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_DNS_NAME;
+ const std::string s = value.AsString();
+ if (!base::IsStringASCII(s))
+ return false;
+ subtrees->dns_names.push_back(s);
+ break;
+ }
+ // x400Address [3] ORAddress,
+ case 3:
+ if (!der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_X400_ADDRESS;
+ break;
+ // directoryName [4] Name,
+ case 4:
+ if (!der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_DIRECTORY_NAME;
+ subtrees->directory_names.push_back(std::vector<uint8_t>(
+ value.UnsafeData(), value.UnsafeData() + value.Length()));
+ break;
+ // ediPartyName [5] EDIPartyName,
+ case 5:
+ if (!der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_EDI_PARTY_NAME;
+ break;
+ // uniformResourceIdentifier [6] IA5String,
+ case 6:
+ if (der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER;
+ break;
+ // iPAddress [7] OCTET STRING,
+ case 7:
+ if (der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_IP_ADDRESS;
+ if (ip_address_type == IP_ADDRESS_ONLY) {
+ // RFC 5280 section 4.2.1.6:
+ // When the subjectAltName extension contains an iPAddress, the address
+ // MUST be stored in the octet string in "network byte order", as
+ // specified in [RFC791]. The least significant bit (LSB) of each octet
+ // is the LSB of the corresponding byte in the network address. For IP
+ // version 4, as specified in [RFC791], the octet string MUST contain
+ // exactly four octets. For IP version 6, as specified in [RFC2460],
+ // the octet string MUST contain exactly sixteen octets.
+ if ((value.Length() != kIPv4AddressSize &&
+ value.Length() != kIPv6AddressSize)) {
+ return false;
+ }
+ subtrees->ip_addresses.push_back(std::vector<uint8_t>(
+ value.UnsafeData(), value.UnsafeData() + value.Length()));
+ } else {
+ DCHECK_EQ(ip_address_type, IP_ADDRESS_AND_NETMASK);
+ // RFC 5280 section 4.2.1.10:
+ // The syntax of iPAddress MUST be as described in Section 4.2.1.6 with
+ // the following additions specifically for name constraints. For IPv4
+ // addresses, the iPAddress field of GeneralName MUST contain eight (8)
+ // octets, encoded in the style of RFC 4632 (CIDR) to represent an
+ // address range [RFC4632]. For IPv6 addresses, the iPAddress field
+ // MUST contain 32 octets similarly encoded. For example, a name
+ // constraint for "class C" subnet 192.0.2.0 is represented as the
+ // octets C0 00 02 00 FF FF FF 00, representing the CIDR notation
+ // 192.0.2.0/24 (mask 255.255.255.0).
+ if (value.Length() != kIPv4AddressSize * 2 &&
+ value.Length() != kIPv6AddressSize * 2) {
+ return false;
+ }
+ const std::vector<uint8_t> mask(value.UnsafeData() + value.Length() / 2,
+ value.UnsafeData() + value.Length());
+ const unsigned mask_prefix_length = MaskPrefixLength(mask);
+ if (!IsSuffixZero(mask, mask_prefix_length))
+ return false;
+ subtrees->ip_address_ranges.push_back(std::make_pair(
+ std::vector<uint8_t>(value.UnsafeData(),
+ value.UnsafeData() + value.Length() / 2),
+ mask_prefix_length));
+ }
+ break;
+ // registeredID [8] OBJECT IDENTIFIER }
+ case 8:
+ if (der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_REGISTERED_ID;
+ break;
+ default:
+ return false;
+ }
+ DCHECK_NE(GENERAL_NAME_NONE, name_type);
+ if ((name_type & kSupportedNameTypes) ||
+ unsupported_type_behavior == RECORD_UNSUPPORTED) {
+ subtrees->present_name_types |= name_type;
+ }
+ return true;
+}
+
+// Parses a GeneralSubtrees |value| and store the contents in |subtrees|.
+// The individual values stored into |subtrees| are not validated by this
+// function.
+// NOTE: |subtrees| will be modified regardless of the return.
+WARN_UNUSED_RESULT bool ParseGeneralSubtrees(
+ const der::Input& value,
+ bool is_critical,
+ NameConstraints::GeneralNames* subtrees) {
+ // GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+ //
+ // GeneralSubtree ::= SEQUENCE {
+ // base GeneralName,
+ // minimum [0] BaseDistance DEFAULT 0,
+ // maximum [1] BaseDistance OPTIONAL }
+ //
+ // BaseDistance ::= INTEGER (0..MAX)
+ der::Parser sequence_parser(value);
+ // The GeneralSubtrees sequence should have at least 1 element.
+ if (!sequence_parser.HasMore())
+ return false;
+ while (sequence_parser.HasMore()) {
+ der::Parser subtree_sequence;
+ if (!sequence_parser.ReadSequence(&subtree_sequence))
+ return false;
+
+ der::Input raw_general_name;
+ if (!subtree_sequence.ReadRawTLV(&raw_general_name))
+ return false;
+
+ if (!ParseGeneralName(raw_general_name,
+ is_critical ? RECORD_UNSUPPORTED : IGNORE_UNSUPPORTED,
+ IP_ADDRESS_AND_NETMASK, subtrees)) {
+ return false;
+ }
+
+ // RFC 5280 section 4.2.1.10:
+ // Within this profile, the minimum and maximum fields are not used with any
+ // name forms, thus, the minimum MUST be zero, and maximum MUST be absent.
+ // However, if an application encounters a critical name constraints
+ // extension that specifies other values for minimum or maximum for a name
+ // form that appears in a subsequent certificate, the application MUST
+ // either process these fields or reject the certificate.
+
+ // Note that technically failing here isn't required: rather only need to
+ // fail if a name of this type actually appears in a subsequent cert and
+ // this extension was marked critical. However the minimum and maximum
+ // fields appear uncommon enough that implementing that isn't useful.
+ if (subtree_sequence.HasMore())
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+NameConstraints::GeneralNames::GeneralNames() {}
+
+NameConstraints::GeneralNames::~GeneralNames() {}
+
+NameConstraints::~NameConstraints() {}
+
+// static
+scoped_ptr<NameConstraints> NameConstraints::CreateFromDer(
+ const der::Input& extension_value,
+ bool is_critical) {
+ scoped_ptr<NameConstraints> name_constraints(new NameConstraints());
+ if (!name_constraints->Parse(extension_value, is_critical))
+ return nullptr;
+ return name_constraints;
+}
+
+bool NameConstraints::Parse(const der::Input& extension_value,
+ bool is_critical) {
+ der::Parser extension_parser(extension_value);
+ der::Parser sequence_parser;
+
+ // NameConstraints ::= SEQUENCE {
+ // permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ // excludedSubtrees [1] GeneralSubtrees OPTIONAL }
+ if (!extension_parser.ReadSequence(&sequence_parser))
+ return false;
+ if (extension_parser.HasMore())
+ return false;
+
+ bool had_permitted_subtrees = false;
+ der::Input permitted_subtrees_value;
+ if (!sequence_parser.ReadOptionalTag(der::ContextSpecificConstructed(0),
+ &permitted_subtrees_value,
+ &had_permitted_subtrees)) {
+ return false;
+ }
+ if (had_permitted_subtrees &&
+ !ParseGeneralSubtrees(permitted_subtrees_value, is_critical,
+ &permitted_subtrees_)) {
+ return false;
+ }
+
+ bool had_excluded_subtrees = false;
+ der::Input excluded_subtrees_value;
+ if (!sequence_parser.ReadOptionalTag(der::ContextSpecificConstructed(1),
+ &excluded_subtrees_value,
+ &had_excluded_subtrees)) {
+ return false;
+ }
+ if (had_excluded_subtrees &&
+ !ParseGeneralSubtrees(excluded_subtrees_value, is_critical,
+ &excluded_subtrees_)) {
+ return false;
+ }
+
+ // RFC 5280 section 4.2.1.10:
+ // Conforming CAs MUST NOT issue certificates where name constraints is an
+ // empty sequence. That is, either the permittedSubtrees field or the
+ // excludedSubtrees MUST be present.
+ if (!had_permitted_subtrees && !had_excluded_subtrees)
+ return false;
+
+ if (sequence_parser.HasMore())
+ return false;
+
+ return true;
+}
+
+bool NameConstraints::IsPermittedCert(
+ const der::Input& subject_rdn_sequence,
+ const der::Input& subject_alt_name_extnvalue_tlv) const {
+ // Subject Alternative Name handling:
+ //
+ // RFC 5280 section 4.2.1.6:
+ // id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
+ //
+ // SubjectAltName ::= GeneralNames
+ //
+ // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+
+ GeneralNames san_names;
+ if (subject_alt_name_extnvalue_tlv.Length()) {
+ der::Parser extnvalue_parser(subject_alt_name_extnvalue_tlv);
+ der::Input subject_alt_name_tlv;
+ if (!extnvalue_parser.ReadTag(der::kOctetString, &subject_alt_name_tlv))
+ return false;
+
+ der::Parser subject_alt_name_parser(subject_alt_name_tlv);
+ der::Parser san_sequence_parser;
+ if (!subject_alt_name_parser.ReadSequence(&san_sequence_parser))
+ return false;
+ // Should not have trailing data after subjectAltName sequence.
+ if (subject_alt_name_parser.HasMore())
+ return false;
+ // The subjectAltName sequence should have at least 1 element.
+ if (!san_sequence_parser.HasMore())
+ return false;
+
+ while (san_sequence_parser.HasMore()) {
+ der::Input raw_general_name;
+ if (!san_sequence_parser.ReadRawTLV(&raw_general_name))
+ return false;
+
+ if (!ParseGeneralName(raw_general_name, RECORD_UNSUPPORTED,
+ IP_ADDRESS_ONLY, &san_names))
+ return false;
+ }
+
+ // Check unsupported name types:
+ // ConstrainedNameTypes for the unsupported types will only be true if that
+ // type of name was present in a name constraint that was marked critical.
+ //
+ // RFC 5280 section 4.2.1.10:
+ // If a name constraints extension that is marked as critical
+ // imposes constraints on a particular name form, and an instance of
+ // that name form appears in the subject field or subjectAltName
+ // extension of a subsequent certificate, then the application MUST
+ // either process the constraint or reject the certificate.
+ if (ConstrainedNameTypes() & san_names.present_name_types &
+ ~kSupportedNameTypes) {
+ return false;
+ }
+
+ // Check supported name types:
+ for (const auto& dns_name : san_names.dns_names) {
+ if (!IsPermittedDNSName(dns_name))
+ return false;
+ }
+
+ for (const auto& directory_name : san_names.directory_names) {
+ if (!IsPermittedDirectoryName(
+ der::Input(directory_name.data(), directory_name.size()))) {
+ return false;
+ }
+ }
+
+ for (const auto& ip_address : san_names.ip_addresses) {
+ if (!IsPermittedIP(ip_address))
+ return false;
+ }
+ }
+
+ // Subject handling:
+
+ // RFC 5280 section 4.2.1.10:
+ // Legacy implementations exist where an electronic mail address is embedded
+ // in the subject distinguished name in an attribute of type emailAddress
+ // (Section 4.1.2.6). When constraints are imposed on the rfc822Name name
+ // form, but the certificate does not include a subject alternative name, the
+ // rfc822Name constraint MUST be applied to the attribute of type emailAddress
+ // in the subject distinguished name.
+ if (!subject_alt_name_extnvalue_tlv.Length() &&
+ (ConstrainedNameTypes() & GENERAL_NAME_RFC822_NAME)) {
+ bool contained_email_address = false;
+ if (!NameContainsEmailAddress(subject_rdn_sequence,
+ &contained_email_address)) {
+ return false;
+ }
+ if (contained_email_address)
+ return false;
+ }
+
+ // RFC 5280 4.1.2.6:
+ // If subject naming information is present only in the subjectAltName
+ // extension (e.g., a key bound only to an email address or URI), then the
+ // subject name MUST be an empty sequence and the subjectAltName extension
+ // MUST be critical.
+ // This code assumes that criticality condition is checked by the caller, and
+ // therefore only needs to avoid the IsPermittedDirectoryName check against an
+ // empty subject in such a case.
+ if (subject_alt_name_extnvalue_tlv.Length() &&
+ subject_rdn_sequence.Length() == 0) {
+ return true;
+ }
+
+ return IsPermittedDirectoryName(subject_rdn_sequence);
+}
+
+bool NameConstraints::IsPermittedDNSName(const std::string& name) const {
+ // If there are no name constraints for DNS names, all names are accepted.
+ if (!(ConstrainedNameTypes() & GENERAL_NAME_DNS_NAME))
+ return true;
+
+ for (const std::string& excluded_name : excluded_subtrees_.dns_names) {
+ // When matching wildcard hosts against excluded subtrees, consider it a
+ // match if the constraint would match any expansion of the wildcard. Eg,
+ // *.bar.com should match a constraint of foo.bar.com.
+ if (DNSNameMatches(name, excluded_name, WILDCARD_PARTIAL_MATCH))
+ return false;
+ }
+ for (const std::string& permitted_name : permitted_subtrees_.dns_names) {
+ // When matching wildcard hosts against permitted subtrees, consider it a
+ // match only if the constraint would match all expansions of the wildcard.
+ // Eg, *.bar.com should match a constraint of bar.com, but not foo.bar.com.
+ if (DNSNameMatches(name, permitted_name, WILDCARD_FULL_MATCH))
+ return true;
+ }
+
+ return false;
+}
+
+bool NameConstraints::IsPermittedDirectoryName(
+ const der::Input& name_rdn_sequence) const {
+ // If there are no name constraints for directory names, all names are
+ // accepted.
+ if (!(ConstrainedNameTypes() & GENERAL_NAME_DIRECTORY_NAME))
+ return true;
+
+ for (const auto& excluded_name : excluded_subtrees_.directory_names) {
+ if (VerifyNameInSubtree(
+ name_rdn_sequence,
+ der::Input(excluded_name.data(), excluded_name.size()))) {
+ return false;
+ }
+ }
+ for (const auto& permitted_name : permitted_subtrees_.directory_names) {
+ if (VerifyNameInSubtree(
+ name_rdn_sequence,
+ der::Input(permitted_name.data(), permitted_name.size()))) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool NameConstraints::IsPermittedIP(const IPAddressNumber& ip) const {
+ // If there are no name constraints for IP Address names, all names are
+ // accepted.
+ if (!(ConstrainedNameTypes() & GENERAL_NAME_IP_ADDRESS))
+ return true;
+
+ for (const auto& excluded_ip : excluded_subtrees_.ip_address_ranges) {
+ if (IPNumberMatchesPrefix(ip, excluded_ip.first, excluded_ip.second))
+ return false;
+ }
+ for (const auto& permitted_ip : permitted_subtrees_.ip_address_ranges) {
+ if (IPNumberMatchesPrefix(ip, permitted_ip.first, permitted_ip.second))
+ return true;
+ }
+
+ return false;
+}
+
+int NameConstraints::ConstrainedNameTypes() const {
+ return (permitted_subtrees_.present_name_types |
+ excluded_subtrees_.present_name_types);
+}
+
+} // namespace net
diff --git a/chromium/net/cert/internal/name_constraints.h b/chromium/net/cert/internal/name_constraints.h
new file mode 100644
index 00000000000..46cb0dade74
--- /dev/null
+++ b/chromium/net/cert/internal/name_constraints.h
@@ -0,0 +1,138 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_CERT_INTERNAL_NAME_CONSTRAINTS_H_
+#define NET_CERT_INTERNAL_NAME_CONSTRAINTS_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/base/ip_address_number.h"
+
+namespace net {
+
+namespace der {
+class Input;
+} // namespace der
+
+// Bitfield values for the GeneralName types defined in RFC 5280. The ordering
+// and exact values are not important, but match the order from the RFC for
+// convenience.
+enum GeneralNameTypes {
+ GENERAL_NAME_NONE = 0,
+ GENERAL_NAME_OTHER_NAME = 1 << 0,
+ GENERAL_NAME_RFC822_NAME = 1 << 1,
+ GENERAL_NAME_DNS_NAME = 1 << 2,
+ GENERAL_NAME_X400_ADDRESS = 1 << 3,
+ GENERAL_NAME_DIRECTORY_NAME = 1 << 4,
+ GENERAL_NAME_EDI_PARTY_NAME = 1 << 5,
+ GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER = 1 << 6,
+ GENERAL_NAME_IP_ADDRESS = 1 << 7,
+ GENERAL_NAME_REGISTERED_ID = 1 << 8,
+};
+
+// Parses a NameConstraints extension value and allows testing whether names are
+// allowed under those constraints as defined by RFC 5280 section 4.2.1.10.
+class NET_EXPORT NameConstraints {
+ public:
+ // Represents a GeneralNames structure. When processing GeneralNames, it is
+ // often necessary to know which types of names were present, and to check
+ // all the names of a certain type. Therefore, a bitfield of all the name
+ // types is kept, and the names are split into members for each type. Only
+ // name types that are handled by this code are stored (though all types are
+ // recorded in the bitfield.)
+ // TODO(mattm): This may need to be split out into a public class, since
+ // GeneralNames is used other places in a certificate also...
+ struct GeneralNames {
+ GeneralNames();
+ ~GeneralNames();
+
+ // ASCII hostnames.
+ std::vector<std::string> dns_names;
+
+ // DER-encoded Name values (not including the Sequence tag).
+ std::vector<std::vector<uint8_t>> directory_names;
+
+ // iPAddresses as sequences of octets in network byte order. This will be
+ // populated if the GeneralNames represents a Subject Alternative Name.
+ std::vector<std::vector<uint8_t>> ip_addresses;
+
+ // iPAddress ranges, as <IP, prefix length> pairs. This will be populated
+ // if the GeneralNames represents a Name Constraints.
+ std::vector<std::pair<std::vector<uint8_t>, unsigned>> ip_address_ranges;
+
+ // Which name types were present, as a bitfield of GeneralNameTypes.
+ // Includes both the supported and unsupported types (although unsupported
+ // ones may not be recorded depending on the context, like non-critical name
+ // constraints.)
+ int present_name_types = GENERAL_NAME_NONE;
+ };
+
+ ~NameConstraints();
+
+ // Parses a DER-encoded NameConstraints extension and initializes this object.
+ // |extension_value| should be the extnValue from the extension (not including
+ // the OCTET STRING tag). |is_critical| should be true if the extension was
+ // marked critical. Returns nullptr if parsing the the extension failed.
+ // The object lifetime is not bound to the lifetime of |extension_value| data.
+ static scoped_ptr<NameConstraints> CreateFromDer(
+ const der::Input& extension_value,
+ bool is_critical);
+
+ // Tests if a certificate is allowed by the name constraints.
+ // |subject_rdn_sequence| should be the DER-encoded value of the subject's
+ // RDNSequence (not including Sequence tag), and may be an empty ASN.1
+ // sequence. |subject_alt_name_extnvalue_tlv| should be the extnValue of the
+ // subjectAltName extension (including the OCTET STRING tag & length), or
+ // empty if the cert did not have a subjectAltName extension.
+ // Note that this method does not check hostname or IP address in commonName,
+ // which is deprecated (crbug.com/308330).
+ bool IsPermittedCert(const der::Input& subject_rdn_sequence,
+ const der::Input& subject_alt_name_extnvalue_tlv) const;
+
+ // Returns true if the ASCII hostname |name| is permitted.
+ // |name| may be a wildcard hostname (starts with "*."). Eg, "*.bar.com"
+ // would not be permitted if "bar.com" is permitted and "foo.bar.com" is
+ // excluded, while "*.baz.com" would only be permitted if "baz.com" is
+ // permitted.
+ bool IsPermittedDNSName(const std::string& name) const;
+
+ // Returns true if the directoryName |name_rdn_sequence| is permitted.
+ // |name_rdn_sequence| should be the DER-encoded RDNSequence value (not
+ // including the Sequence tag.)
+ bool IsPermittedDirectoryName(const der::Input& name_rdn_sequence) const;
+
+ // Returns true if the iPAddress |ip| is permitted.
+ bool IsPermittedIP(const IPAddressNumber& ip) const;
+
+ // Returns a bitfield of GeneralNameTypes of all the types constrained by this
+ // NameConstraints. Name types that aren't supported will only be present if
+ // the name constraint they appeared in was marked critical.
+ //
+ // RFC 5280 section 4.2.1.10 says:
+ // Applications conforming to this profile MUST be able to process name
+ // constraints that are imposed on the directoryName name form and SHOULD be
+ // able to process name constraints that are imposed on the rfc822Name,
+ // uniformResourceIdentifier, dNSName, and iPAddress name forms.
+ // If a name constraints extension that is marked as critical
+ // imposes constraints on a particular name form, and an instance of
+ // that name form appears in the subject field or subjectAltName
+ // extension of a subsequent certificate, then the application MUST
+ // either process the constraint or reject the certificate.
+ int ConstrainedNameTypes() const;
+
+ private:
+ bool Parse(const der::Input& extension_value,
+ bool is_critical) WARN_UNUSED_RESULT;
+
+ GeneralNames permitted_subtrees_;
+ GeneralNames excluded_subtrees_;
+};
+
+} // namespace net
+
+#endif // NET_CERT_INTERNAL_NAME_CONSTRAINTS_H_
diff --git a/chromium/net/cert/internal/name_constraints_unittest.cc b/chromium/net/cert/internal/name_constraints_unittest.cc
new file mode 100644
index 00000000000..8b550f7fc94
--- /dev/null
+++ b/chromium/net/cert/internal/name_constraints_unittest.cc
@@ -0,0 +1,1276 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/internal/name_constraints.h"
+
+#include "net/cert/internal/test_helpers.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+::testing::AssertionResult LoadTestData(const char* token,
+ const std::string& basename,
+ std::string* result) {
+ std::string path = "net/data/name_constraints_unittest/" + basename;
+
+ const PemBlockMapping mappings[] = {
+ {token, result},
+ };
+
+ return ReadTestDataFromPemFile(path, mappings);
+}
+
+::testing::AssertionResult LoadTestName(const std::string& basename,
+ std::string* result) {
+ return LoadTestData("NAME", basename, result);
+}
+
+::testing::AssertionResult LoadTestNameConstraint(const std::string& basename,
+ std::string* result) {
+ return LoadTestData("NAME CONSTRAINTS", basename, result);
+}
+
+::testing::AssertionResult LoadTestSubjectAltName(const std::string& basename,
+ std::string* result) {
+ return LoadTestData("SUBJECT ALTERNATIVE NAME", basename, result);
+}
+
+} // namespace
+
+class ParseNameConstraints
+ : public ::testing::TestWithParam<::testing::tuple<bool>> {
+ public:
+ bool is_critical() const { return ::testing::get<0>(GetParam()); }
+};
+
+// Run the tests with the name constraints marked critical and non-critical. For
+// supported name types, the results should be the same for both.
+INSTANTIATE_TEST_CASE_P(InstantiationName,
+ ParseNameConstraints,
+ ::testing::Values(true, false));
+
+TEST_P(ParseNameConstraints, DNSNames) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("permitted.example.com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("permitted.example.com."));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("a.permitted.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("apermitted.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("apermitted.example.com."));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("alsopermitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("excluded.permitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("a.excluded.permitted.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(
+ "stillnotpermitted.excluded.permitted.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(
+ "a.stillnotpermitted.excluded.permitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("extraneousexclusion.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(
+ "a.extraneousexclusion.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("other.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("other.com"));
+
+ // Wildcard names:
+ // Pattern could match excluded.permitted.example.com, thus should not be
+ // allowed.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.permitted.example.com"));
+ // Entirely within excluded name, obviously not allowed.
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("*.excluded.permitted.example.com"));
+ // Within permitted.example.com and cannot match any exclusion, thus these are
+ // allowed.
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("*.foo.permitted.example.com"));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("*.alsopermitted.example.com"));
+ // Matches permitted.example2.com, but also matches other .example2.com names
+ // which are not in either permitted or excluded, so not allowed.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.example2.com"));
+ // Partial wildcards are not supported, so these name are permitted even if
+ // it seems like they shouldn't be. It's fine, since certificate verification
+ // won't treat them as wildcard names either.
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("*xcluded.permitted.example.com"));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("exclude*.permitted.example.com"));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("excl*ded.permitted.example.com"));
+ // Garbage wildcard data.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*."));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.*"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(".*"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*"));
+ // Matches SAN with trailing dot.
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("permitted.example3.com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("permitted.example3.com."));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("a.permitted.example3.com"));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("a.permitted.example3.com."));
+
+ EXPECT_EQ(GENERAL_NAME_DNS_NAME, name_constraints->ConstrainedNameTypes());
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-permitted.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-dnsname.pem", &san));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-directoryname.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-ipaddress.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints,
+ DNSNamesWithMultipleLevelsBetweenExcludedAndPermitted) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname2.pem", &a));
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // Matches permitted exactly.
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("com"));
+ // Contained within permitted and doesn't match excluded (foo.bar.com).
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("bar.com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("baz.bar.com"));
+ // Matches excluded exactly.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.bar.com"));
+ // Contained within excluded.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("baz.foo.bar.com"));
+
+ // Cannot match anything within excluded.
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("*.baz.bar.com"));
+ // Wildcard hostnames only match a single label, so cannot match excluded
+ // which has two labels before .com.
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("*.com"));
+
+ // Partial match of foo.bar.com.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.bar.com"));
+ // All expansions of wildcard are within excluded.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.foo.bar.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesWithLeadingDot) {
+ std::string a;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("dnsname-permitted_with_leading_dot.pem", &a));
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // dNSName constraints should be specified as a host. A dNSName constraint
+ // with a leading "." doesn't make sense, though some certs include it
+ // (probably confusing it with the rules for uniformResourceIdentifier
+ // constraints). It should not match anything.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("bar.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.bar.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesExcludeOnly) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-excluded.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // Only "excluded.permitted.example.com" is excluded, but since no dNSNames
+ // are permitted, everything is excluded.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(""));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("permitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("excluded.permitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("a.excluded.permitted.example.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesExcludeAll) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-excludeall.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // "permitted.example.com" is in the permitted section, but since "" is
+ // excluded, nothing is permitted.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(""));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("permitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("foo.permitted.example.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesExcludeDot) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-exclude_dot.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // "." is excluded, which should match nothing.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("permitted.example.com"));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("foo.permitted.example.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesFailOnInvalidIA5String) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname.pem", &a));
+
+ size_t replace_location = a.find("permitted.example2.com");
+ ASSERT_NE(std::string::npos, replace_location);
+ a.replace(replace_location, 1, 1, -1);
+
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+}
+
+TEST_P(ParseNameConstraints, DirectoryNames) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("directoryname.pem", &constraints_der));
+
+ std::string name_us;
+ ASSERT_TRUE(LoadTestName("name-us.pem", &name_us));
+ std::string name_us_ca;
+ ASSERT_TRUE(LoadTestName("name-us-california.pem", &name_us_ca));
+ std::string name_us_ca_mountain_view;
+ ASSERT_TRUE(LoadTestName("name-us-california-mountain_view.pem",
+ &name_us_ca_mountain_view));
+ std::string name_us_az;
+ ASSERT_TRUE(LoadTestName("name-us-arizona.pem", &name_us_az));
+ std::string name_jp;
+ ASSERT_TRUE(LoadTestName("name-jp.pem", &name_jp));
+ std::string name_jp_tokyo;
+ ASSERT_TRUE(LoadTestName("name-jp-tokyo.pem", &name_jp_tokyo));
+ std::string name_de;
+ ASSERT_TRUE(LoadTestName("name-de.pem", &name_de));
+ std::string name_ca;
+ ASSERT_TRUE(LoadTestName("name-ca.pem", &name_ca));
+
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // Not in any permitted subtree.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_ca)));
+ // Within the permitted C=US subtree.
+ EXPECT_TRUE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us)));
+ // Within the permitted C=US subtree.
+ EXPECT_TRUE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_az)));
+ // Within the permitted C=US subtree, however the excluded C=US,ST=California
+ // subtree takes priority.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_ca)));
+ // Within the permitted C=US subtree as well as the permitted
+ // C=US,ST=California,L=Mountain View subtree, however the excluded
+ // C=US,ST=California subtree still takes priority.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_ca_mountain_view)));
+ // Not in any permitted subtree, and also inside the extraneous excluded C=DE
+ // subtree.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_de)));
+ // Not in any permitted subtree.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_jp)));
+ // Within the permitted C=JP,ST=Tokyo subtree.
+ EXPECT_TRUE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_jp_tokyo)));
+
+ EXPECT_EQ(GENERAL_NAME_DIRECTORY_NAME,
+ name_constraints->ConstrainedNameTypes());
+
+ // Within the permitted C=US subtree.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us), der::Input()));
+ // Within the permitted C=US subtree, however the excluded C=US,ST=California
+ // subtree takes priority.
+ EXPECT_FALSE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_ca), der::Input()));
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-permitted.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-dnsname.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-directoryname.pem", &san));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-ipaddress.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, DirectoryNamesExcludeOnly) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("directoryname-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_empty;
+ ASSERT_TRUE(LoadTestName("name-empty.pem", &name_empty));
+ std::string name_us;
+ ASSERT_TRUE(LoadTestName("name-us.pem", &name_us));
+ std::string name_us_ca;
+ ASSERT_TRUE(LoadTestName("name-us-california.pem", &name_us_ca));
+ std::string name_us_ca_mountain_view;
+ ASSERT_TRUE(LoadTestName("name-us-california-mountain_view.pem",
+ &name_us_ca_mountain_view));
+
+ // Only "C=US,ST=California" is excluded, but since no directoryNames are
+ // permitted, everything is excluded.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_empty)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_ca)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_ca_mountain_view)));
+}
+
+TEST_P(ParseNameConstraints, DirectoryNamesExcludeAll) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("directoryname-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_empty;
+ ASSERT_TRUE(LoadTestName("name-empty.pem", &name_empty));
+ std::string name_us;
+ ASSERT_TRUE(LoadTestName("name-us.pem", &name_us));
+ std::string name_us_ca;
+ ASSERT_TRUE(LoadTestName("name-us-california.pem", &name_us_ca));
+ std::string name_us_ca_mountain_view;
+ ASSERT_TRUE(LoadTestName("name-us-california-mountain_view.pem",
+ &name_us_ca_mountain_view));
+ std::string name_jp;
+ ASSERT_TRUE(LoadTestName("name-jp.pem", &name_jp));
+
+ // "C=US" is in the permitted section, but since an empty
+ // directoryName is excluded, nothing is permitted.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_empty)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_ca)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_jp)));
+}
+
+TEST_P(ParseNameConstraints, IPAdresses) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // IPv4 tests:
+ {
+ // Not in any permitted range.
+ const uint8_t ip4[] = {192, 169, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Within the permitted 192.168.0.0/255.255.0.0 range.
+ const uint8_t ip4[] = {192, 168, 0, 1};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Within the permitted 192.168.0.0/255.255.0.0 range, however the
+ // excluded 192.168.5.0/255.255.255.0 takes priority.
+ const uint8_t ip4[] = {192, 168, 5, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Within the permitted 192.168.0.0/255.255.0.0 range as well as the
+ // permitted 192.168.5.32/255.255.255.224 range, however the excluded
+ // 192.168.5.0/255.255.255.0 still takes priority.
+ const uint8_t ip4[] = {192, 168, 5, 33};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Not in any permitted range. (Just outside the
+ // 192.167.5.32/255.255.255.224 range.)
+ const uint8_t ip4[] = {192, 167, 5, 31};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Within the permitted 192.167.5.32/255.255.255.224 range.
+ const uint8_t ip4[] = {192, 167, 5, 32};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Within the permitted 192.167.5.32/255.255.255.224 range.
+ const uint8_t ip4[] = {192, 167, 5, 63};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Not in any permitted range. (Just outside the
+ // 192.167.5.32/255.255.255.224 range.)
+ const uint8_t ip4[] = {192, 167, 5, 64};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Not in any permitted range, and also inside the extraneous excluded
+ // 192.166.5.32/255.255.255.224 range.
+ const uint8_t ip4[] = {192, 166, 5, 32};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+
+ // IPv6 tests:
+ {
+ // Not in any permitted range.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 0, 0, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Within the permitted
+ // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: range.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 1};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Within the permitted
+ // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: range, however
+ // the excluded
+ // 102:304:506:708:90a:b0c:500:0/ffff:ffff:ffff:ffff:ffff:ffff:ff00:0 takes
+ // priority.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 0, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Within the permitted
+ // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: range as well
+ // as the permitted
+ // 102:304:506:708:90a:b0c:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0,
+ // however the excluded
+ // 102:304:506:708:90a:b0c:500:0/ffff:ffff:ffff:ffff:ffff:ffff:ff00:0 takes
+ // priority.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 33, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Not in any permitted range. (Just outside the
+ // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0
+ // range.)
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 11, 5, 31, 255, 255};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Within the permitted
+ // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0 range.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 5, 32, 0, 0};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Within the permitted
+ // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0 range.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 11, 5, 63, 255, 255};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Not in any permitted range. (Just outside the
+ // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0
+ // range.)
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 5, 64, 0, 0};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Not in any permitted range, and also inside the extraneous excluded
+ // 102:304:506:708:90a:b0a:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0 range.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 10, 5, 33, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+
+ EXPECT_EQ(GENERAL_NAME_IP_ADDRESS, name_constraints->ConstrainedNameTypes());
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-permitted.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-dnsname.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-directoryname.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-ipaddress.pem", &san));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, IPAdressesExcludeOnly) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-excluded.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // Only 192.168.5.0/255.255.255.0 is excluded, but since no iPAddresses
+ // are permitted, everything is excluded.
+ {
+ const uint8_t ip4[] = {192, 168, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 5, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 0, 0, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesExcludeAll) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-excludeall.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // 192.168.0.0/255.255.0.0 and
+ // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: are permitted,
+ // but since 0.0.0.0/0 and ::/0 are excluded nothing is permitted.
+ {
+ const uint8_t ip4[] = {192, 168, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {1, 1, 1, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip6[] = {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 0, 0, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesNetmaskPermitSingleHost) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-permit_singlehost.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ {
+ const uint8_t ip4[] = {0, 0, 0, 0};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 2};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 3};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 4};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {255, 255, 255, 255};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesNetmaskPermitPrefixLen31) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-permit_prefix31.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ {
+ const uint8_t ip4[] = {0, 0, 0, 0};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 2};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 3};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 4};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 5};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {255, 255, 255, 255};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesNetmaskPermitPrefixLen1) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-permit_prefix1.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ {
+ const uint8_t ip4[] = {0, 0, 0, 0};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {0x7F, 0xFF, 0xFF, 0xFF};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {0x80, 0, 0, 0};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {0xFF, 0xFF, 0xFF, 0xFF};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesNetmaskPermitAll) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-permit_all.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ {
+ const uint8_t ip4[] = {0, 0, 0, 0};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 1};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {255, 255, 255, 255};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesFailOnInvalidAddr) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-invalid_addr.pem", &a));
+
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+}
+
+TEST_P(ParseNameConstraints, IPAdressesFailOnInvalidMaskNotContiguous) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint(
+ "ipaddress-invalid_mask_not_contiguous_1.pem", &a));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+
+ ASSERT_TRUE(LoadTestNameConstraint(
+ "ipaddress-invalid_mask_not_contiguous_2.pem", &a));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+
+ ASSERT_TRUE(LoadTestNameConstraint(
+ "ipaddress-invalid_mask_not_contiguous_3.pem", &a));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+
+ ASSERT_TRUE(LoadTestNameConstraint(
+ "ipaddress-invalid_mask_not_contiguous_4.pem", &a));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+}
+
+TEST_P(ParseNameConstraints, OtherNamesInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("othername-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_OTHER_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-othername.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, OtherNamesInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("othername-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_OTHER_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-othername.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, Rfc822NamesInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("rfc822name-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_RFC822_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-rfc822name.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, Rfc822NamesInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("rfc822name-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_RFC822_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-rfc822name.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, X400AddresssInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("x400address-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_X400_ADDRESS,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-x400address.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, X400AddresssInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("x400address-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_X400_ADDRESS,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-x400address.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, EdiPartyNamesInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("edipartyname-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_EDI_PARTY_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-edipartyname.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, EdiPartyNamesInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("edipartyname-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_EDI_PARTY_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-edipartyname.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, URIsInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("uri-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-uri.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, URIsInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("uri-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-uri.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, RegisteredIDsInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("registeredid-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_REGISTERED_ID,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-registeredid.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, RegisteredIDsInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("registeredid-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_REGISTERED_ID,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-registeredid.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints,
+ failsOnGeneralSubtreeWithMinimumZeroEncodedUnnecessarily) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("dnsname-with_min_0.pem", &constraints_der));
+ // The value should not be in the DER encoding if it is the default. But this
+ // could be changed to allowed if there are buggy encoders out there that
+ // include it anyway.
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnGeneralSubtreeWithMinimum) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("dnsname-with_min_1.pem", &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints,
+ failsOnGeneralSubtreeWithMinimumZeroEncodedUnnecessarilyAndMaximum) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-with_min_0_and_max.pem",
+ &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnGeneralSubtreeWithMinimumAndMaximum) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-with_min_1_and_max.pem",
+ &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnGeneralSubtreeWithMaximum) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-with_max.pem", &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnEmptyExtensionValue) {
+ std::string constraints_der = "";
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnNoPermittedAndExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("invalid-no_subtrees.pem", &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnEmptyPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("invalid-empty_permitted_subtree.pem",
+ &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnEmptyExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("invalid-empty_excluded_subtree.pem",
+ &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, IsPermittedCertSubjectEmailAddressIsOk) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("directoryname.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_arizona_email;
+ ASSERT_TRUE(
+ LoadTestName("name-us-arizona-email.pem", &name_us_arizona_email));
+
+ // Name constraints don't contain rfc822Name, so emailAddress in subject is
+ // allowed regardless.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_arizona_email), der::Input()));
+}
+
+TEST_P(ParseNameConstraints, IsPermittedCertSubjectEmailAddressIsNotOk) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("rfc822name-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_arizona_email;
+ ASSERT_TRUE(
+ LoadTestName("name-us-arizona-email.pem", &name_us_arizona_email));
+
+ // Name constraints contain rfc822Name, so emailAddress in subject is not
+ // allowed if the constraints were critical.
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_arizona_email), der::Input()));
+}
+
+// Hostname in commonName is not allowed (crbug.com/308330), so these are tests
+// are not particularly interesting, just verifying that the commonName is
+// ignored for dNSName constraints.
+TEST_P(ParseNameConstraints, IsPermittedCertSubjectDnsNames) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("directoryname_and_dnsname.pem",
+ &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_az_foocom;
+ ASSERT_TRUE(LoadTestName("name-us-arizona-foo.com.pem", &name_us_az_foocom));
+ // The subject is within permitted directoryName constraints, so permitted.
+ // (The commonName hostname is not within permitted dNSName constraints, so
+ // this would not be permitted if hostnames in commonName were checked.)
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_foocom), der::Input()));
+
+ std::string name_us_az_permitted;
+ ASSERT_TRUE(LoadTestName("name-us-arizona-permitted.example.com.pem",
+ &name_us_az_permitted));
+ // The subject is in permitted directoryName and the commonName is within
+ // permitted dNSName constraints, so this should be permitted regardless if
+ // hostnames in commonName are checked or not.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_permitted), der::Input()));
+
+ std::string name_us_ca_permitted;
+ ASSERT_TRUE(LoadTestName("name-us-california-permitted.example.com.pem",
+ &name_us_ca_permitted));
+ // The subject is within the excluded C=US,ST=California directoryName, so
+ // this should not be allowed, regardless of checking the
+ // permitted.example.com in commonName.
+ EXPECT_FALSE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_ca_permitted), der::Input()));
+}
+
+// IP addresses in commonName are not allowed (crbug.com/308330), so these are
+// tests are not particularly interesting, just verifying that the commonName is
+// ignored for iPAddress constraints.
+TEST_P(ParseNameConstraints, IsPermittedCertSubjectIpAddresses) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint(
+ "directoryname_and_dnsname_and_ipaddress.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_az_1_1_1_1;
+ ASSERT_TRUE(LoadTestName("name-us-arizona-1.1.1.1.pem", &name_us_az_1_1_1_1));
+ // The subject is within permitted directoryName constraints, so permitted.
+ // (The commonName IP address is not within permitted iPAddresses constraints,
+ // so this would not be permitted if IP addresses in commonName were checked.)
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_1_1_1_1), der::Input()));
+
+ std::string name_us_az_192_168_1_1;
+ ASSERT_TRUE(
+ LoadTestName("name-us-arizona-192.168.1.1.pem", &name_us_az_192_168_1_1));
+ // The subject is in permitted directoryName and the commonName is within
+ // permitted iPAddress constraints, so this should be permitted regardless if
+ // IP addresses in commonName are checked or not.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_192_168_1_1), der::Input()));
+
+ std::string name_us_ca_192_168_1_1;
+ ASSERT_TRUE(LoadTestName("name-us-california-192.168.1.1.pem",
+ &name_us_ca_192_168_1_1));
+ // The subject is within the excluded C=US,ST=California directoryName, so
+ // this should not be allowed, regardless of checking the
+ // IP address in commonName.
+ EXPECT_FALSE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_ca_192_168_1_1), der::Input()));
+
+ std::string name_us_az_ipv6;
+ ASSERT_TRUE(LoadTestName("name-us-arizona-ipv6.pem", &name_us_az_ipv6));
+ // The subject is within permitted directoryName constraints, so permitted.
+ // (The commonName is an ipv6 address which wasn't supported in the past, but
+ // since commonName checking is ignored entirely, this is permitted.)
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_ipv6), der::Input()));
+}
+
+TEST_P(ParseNameConstraints, IsPermittedCertFailsOnEmptySubjectAltName) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_az;
+ ASSERT_TRUE(LoadTestName("name-us-arizona.pem", &name_us_az));
+
+ // No constraints on directoryName type, so name_us_az should be allowed when
+ // subjectAltName is not present.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az), der::Input()));
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-invalid-empty.pem", &san));
+ // Should fail if subjectAltName is present but empty.
+ EXPECT_FALSE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, IsPermittedCertFailsOnInvalidIpInSubjectAltName) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_az_192_168_1_1;
+ ASSERT_TRUE(
+ LoadTestName("name-us-arizona-192.168.1.1.pem", &name_us_az_192_168_1_1));
+
+ // Without the invalid subjectAltName, it passes.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_192_168_1_1), der::Input()));
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-invalid-ipaddress.pem", &san));
+ // Should fail if subjectAltName contains an invalid ip address.
+ EXPECT_FALSE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_192_168_1_1), der::Input(&san)));
+}
+
+} // namespace net
diff --git a/chromium/net/cert/internal/parse_certificate.cc b/chromium/net/cert/internal/parse_certificate.cc
index 9535459bb8a..74222e8fde0 100644
--- a/chromium/net/cert/internal/parse_certificate.cc
+++ b/chromium/net/cert/internal/parse_certificate.cc
@@ -4,6 +4,8 @@
#include "net/cert/internal/parse_certificate.h"
+#include <utility>
+
#include "net/der/input.h"
#include "net/der/parse_values.h"
#include "net/der/parser.h"
@@ -172,6 +174,17 @@ bool ParseValidity(const der::Input& validity_tlv,
return true;
}
+// Returns true if every bit in |bits| is zero (including empty).
+WARN_UNUSED_RESULT bool BitStringIsAllZeros(const der::BitString& bits) {
+ // Note that it is OK to read from the unused bits, since BitString parsing
+ // guarantees they are all zero.
+ for (size_t i = 0; i < bits.bytes().Length(); ++i) {
+ if (bits.bytes().UnsafeData()[i] != 0)
+ return false;
+ }
+ return true;
+}
+
} // namespace
ParsedTbsCertificate::ParsedTbsCertificate() {}
@@ -353,4 +366,238 @@ bool ParseTbsCertificate(const der::Input& tbs_tlv, ParsedTbsCertificate* out) {
return true;
}
+// From RFC 5280:
+//
+// 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
+// }
+bool ParseExtension(const der::Input& extension_tlv, ParsedExtension* out) {
+ der::Parser parser(extension_tlv);
+
+ // Extension ::= SEQUENCE {
+ der::Parser extension_parser;
+ if (!parser.ReadSequence(&extension_parser))
+ return false;
+
+ // extnID OBJECT IDENTIFIER,
+ if (!extension_parser.ReadTag(der::kOid, &out->oid))
+ return false;
+
+ // critical BOOLEAN DEFAULT FALSE,
+ out->critical = false;
+ bool has_critical;
+ der::Input critical;
+ if (!extension_parser.ReadOptionalTag(der::kBool, &critical, &has_critical))
+ return false;
+ if (has_critical) {
+ if (!der::ParseBool(critical, &out->critical))
+ return false;
+ if (!out->critical)
+ return false; // DER-encoding requires DEFAULT values be omitted.
+ }
+
+ // extnValue OCTET STRING
+ if (!extension_parser.ReadTag(der::kOctetString, &out->value))
+ return false;
+
+ // The Extension type does not have an extension point (everything goes in
+ // extnValue).
+ if (extension_parser.HasMore())
+ return false;
+
+ // By definition the input was a single Extension sequence, so there shouldn't
+ // be unconsumed data.
+ if (parser.HasMore())
+ return false;
+
+ return true;
+}
+
+der::Input KeyUsageOid() {
+ // From RFC 5280:
+ //
+ // id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
+ //
+ // In dotted notation: 2.5.29.15
+ static const uint8_t oid[] = {0x55, 0x1d, 0x0f};
+ return der::Input(oid);
+}
+
+der::Input SubjectAltNameOid() {
+ // From RFC 5280:
+ //
+ // id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
+ //
+ // In dotted notation: 2.5.29.17
+ static const uint8_t oid[] = {0x55, 0x1d, 0x11};
+ return der::Input(oid);
+}
+
+der::Input BasicConstraintsOid() {
+ // From RFC 5280:
+ //
+ // id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
+ //
+ // In dotted notation: 2.5.29.19
+ static const uint8_t oid[] = {0x55, 0x1d, 0x13};
+ return der::Input(oid);
+}
+
+der::Input NameConstraintsOid() {
+ // From RFC 5280:
+ //
+ // id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
+ //
+ // In dotted notation: 2.5.29.30
+ static const uint8_t oid[] = {0x55, 0x1d, 0x1e};
+ return der::Input(oid);
+}
+
+der::Input CertificatePoliciesOid() {
+ // From RFC 5280:
+ //
+ // id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+ //
+ // In dotted notation: 2.5.29.32
+ static const uint8_t oid[] = {0x55, 0x1d, 0x20};
+ return der::Input(oid);
+}
+
+der::Input PolicyConstraintsOid() {
+ // From RFC 5280:
+ //
+ // id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
+ //
+ // In dotted notation: 2.5.29.36
+ static const uint8_t oid[] = {0x55, 0x1d, 0x24};
+ return der::Input(oid);
+}
+
+der::Input ExtKeyUsageOid() {
+ // From RFC 5280:
+ //
+ // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
+ //
+ // In dotted notation: 2.5.29.37
+ static const uint8_t oid[] = {0x55, 0x1d, 0x25};
+ return der::Input(oid);
+}
+
+NET_EXPORT bool ParseExtensions(
+ const der::Input& extensions_tlv,
+ std::map<der::Input, ParsedExtension>* extensions) {
+ der::Parser parser(extensions_tlv);
+
+ // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ der::Parser extensions_parser;
+ if (!parser.ReadSequence(&extensions_parser))
+ return false;
+
+ // The Extensions SEQUENCE must contains at least 1 element (otherwise it
+ // should have been omitted).
+ if (!extensions_parser.HasMore())
+ return false;
+
+ extensions->clear();
+
+ while (extensions_parser.HasMore()) {
+ ParsedExtension extension;
+
+ der::Input extension_tlv;
+ if (!extensions_parser.ReadRawTLV(&extension_tlv))
+ return false;
+
+ if (!ParseExtension(extension_tlv, &extension))
+ return false;
+
+ bool is_duplicate =
+ !extensions->insert(std::make_pair(extension.oid, extension)).second;
+
+ // RFC 5280 says that an extension should not appear more than once.
+ if (is_duplicate)
+ return false;
+ }
+
+ // By definition the input was a single Extensions sequence, so there
+ // shouldn't be unconsumed data.
+ if (parser.HasMore())
+ return false;
+
+ return true;
+}
+
+bool ParseBasicConstraints(const der::Input& basic_constraints_tlv,
+ ParsedBasicConstraints* out) {
+ der::Parser parser(basic_constraints_tlv);
+
+ // BasicConstraints ::= SEQUENCE {
+ der::Parser sequence_parser;
+ if (!parser.ReadSequence(&sequence_parser))
+ return false;
+
+ // cA BOOLEAN DEFAULT FALSE,
+ out->is_ca = false;
+ bool has_ca;
+ der::Input ca;
+ if (!sequence_parser.ReadOptionalTag(der::kBool, &ca, &has_ca))
+ return false;
+ if (has_ca) {
+ if (!der::ParseBool(ca, &out->is_ca))
+ return false;
+ // TODO(eroman): Should reject if CA was set to false, since
+ // DER-encoding requires DEFAULT values be omitted. In
+ // practice however there are a lot of certificates that use
+ // the broken encoding.
+ }
+
+ // pathLenConstraint INTEGER (0..MAX) OPTIONAL }
+ der::Input encoded_path_len;
+ if (!sequence_parser.ReadOptionalTag(der::kInteger, &encoded_path_len,
+ &out->has_path_len)) {
+ return false;
+ }
+ if (out->has_path_len) {
+ if (!der::ParseUint8(encoded_path_len, &out->path_len))
+ return false;
+ } else {
+ // Default initialize to 0 as a precaution.
+ out->path_len = 0;
+ }
+
+ // There shouldn't be any unconsumed data in the extension.
+ if (sequence_parser.HasMore())
+ return false;
+
+ // By definition the input was a single BasicConstraints sequence, so there
+ // shouldn't be unconsumed data.
+ if (parser.HasMore())
+ return false;
+
+ return true;
+}
+
+bool ParseKeyUsage(const der::Input& key_usage_tlv, der::BitString* key_usage) {
+ der::Parser parser(key_usage_tlv);
+ if (!parser.ReadBitString(key_usage))
+ return false;
+
+ // By definition the input was a single BIT STRING.
+ if (parser.HasMore())
+ return false;
+
+ // RFC 5280 section 4.2.1.3:
+ //
+ // When the keyUsage extension appears in a certificate, at least
+ // one of the bits MUST be set to 1.
+ if (BitStringIsAllZeros(*key_usage))
+ return false;
+
+ return true;
+}
+
} // namespace net
diff --git a/chromium/net/cert/internal/parse_certificate.h b/chromium/net/cert/internal/parse_certificate.h
index 0f6b0bb0773..e7a1670af1b 100644
--- a/chromium/net/cert/internal/parse_certificate.h
+++ b/chromium/net/cert/internal/parse_certificate.h
@@ -5,7 +5,10 @@
#ifndef NET_CERT_INTERNAL_PARSE_CERTIFICATE_H_
#define NET_CERT_INTERNAL_PARSE_CERTIFICATE_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include <map>
+
#include "base/compiler_specific.h"
#include "net/base/net_export.h"
#include "net/der/input.h"
@@ -214,6 +217,157 @@ struct NET_EXPORT ParsedTbsCertificate {
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 NET_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.
+NET_EXPORT bool ParseExtension(const der::Input& extension_tlv,
+ ParsedExtension* out) WARN_UNUSED_RESULT;
+
+// From RFC 5280:
+//
+// id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
+//
+// In dotted notation: 2.5.29.15
+NET_EXPORT der::Input KeyUsageOid();
+
+// From RFC 5280:
+//
+// id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
+//
+// In dotted notation: 2.5.29.17
+NET_EXPORT der::Input SubjectAltNameOid();
+
+// From RFC 5280:
+//
+// id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
+//
+// In dotted notation: 2.5.29.19
+NET_EXPORT der::Input BasicConstraintsOid();
+
+// From RFC 5280:
+//
+// id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
+//
+// In dotted notation: 2.5.29.30
+NET_EXPORT der::Input NameConstraintsOid();
+
+// From RFC 5280:
+//
+// id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+//
+// In dotted notation: 2.5.29.32
+NET_EXPORT der::Input CertificatePoliciesOid();
+
+// From RFC 5280:
+//
+// id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
+//
+// In dotted notation: 2.5.29.36
+NET_EXPORT der::Input PolicyConstraintsOid();
+
+// From RFC 5280:
+//
+// id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
+//
+// In dotted notation: 2.5.29.37
+NET_EXPORT der::Input ExtKeyUsageOid();
+
+// 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.
+NET_EXPORT bool ParseExtensions(
+ const der::Input& extensions_tlv,
+ std::map<der::Input, ParsedExtension>* extensions) WARN_UNUSED_RESULT;
+
+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.
+NET_EXPORT bool ParseBasicConstraints(const der::Input& basic_constraints_tlv,
+ ParsedBasicConstraints* out)
+ WARN_UNUSED_RESULT;
+
+// 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);
+NET_EXPORT bool ParseKeyUsage(const der::Input& key_usage_tlv,
+ der::BitString* key_usage) WARN_UNUSED_RESULT;
+
} // namespace net
#endif // NET_CERT_INTERNAL_PARSE_CERTIFICATE_H_
diff --git a/chromium/net/cert/internal/parse_certificate_unittest.cc b/chromium/net/cert/internal/parse_certificate_unittest.cc
index cf6da4afc82..eea4d4024be 100644
--- a/chromium/net/cert/internal/parse_certificate_unittest.cc
+++ b/chromium/net/cert/internal/parse_certificate_unittest.cc
@@ -46,16 +46,14 @@ void EnsureParsingCertificateSucceeds(const std::string& file_name) {
// Parsing the certificate should succeed.
ParsedCertificate parsed;
- ASSERT_TRUE(ParseCertificate(InputFromString(&data), &parsed));
+ ASSERT_TRUE(ParseCertificate(der::Input(&data), &parsed));
// Ensure that the ParsedCertificate matches expectations.
EXPECT_EQ(0, parsed.signature_value.unused_bits());
- EXPECT_EQ(InputFromString(&expected_signature),
- parsed.signature_value.bytes());
- EXPECT_EQ(InputFromString(&expected_signature_algorithm),
+ EXPECT_EQ(der::Input(&expected_signature), parsed.signature_value.bytes());
+ EXPECT_EQ(der::Input(&expected_signature_algorithm),
parsed.signature_algorithm_tlv);
- EXPECT_EQ(InputFromString(&expected_tbs_certificate),
- parsed.tbs_certificate_tlv);
+ EXPECT_EQ(der::Input(&expected_tbs_certificate), parsed.tbs_certificate_tlv);
}
// Loads certificate data from the PEM file |file_name| and verifies that the
@@ -71,7 +69,7 @@ void EnsureParsingCertificateFails(const std::string& file_name) {
// Parsing the Certificate should fail.
ParsedCertificate parsed;
- ASSERT_FALSE(ParseCertificate(InputFromString(&data), &parsed));
+ ASSERT_FALSE(ParseCertificate(der::Input(&data), &parsed));
}
// Tests parsing a Certificate.
@@ -153,33 +151,33 @@ void EnsureParsingTbsSucceeds(const std::string& file_name,
// Parsing the TBSCertificate should succeed.
ParsedTbsCertificate parsed;
- ASSERT_TRUE(ParseTbsCertificate(InputFromString(&data), &parsed));
+ ASSERT_TRUE(ParseTbsCertificate(der::Input(&data), &parsed));
// Ensure that the ParsedTbsCertificate matches expectations.
EXPECT_EQ(expected_version, parsed.version);
- EXPECT_EQ(InputFromString(&expected_serial_number), parsed.serial_number);
- EXPECT_EQ(InputFromString(&expected_signature_algorithm),
+ EXPECT_EQ(der::Input(&expected_serial_number), parsed.serial_number);
+ EXPECT_EQ(der::Input(&expected_signature_algorithm),
parsed.signature_algorithm_tlv);
- EXPECT_EQ(InputFromString(&expected_issuer), parsed.issuer_tlv);
+ EXPECT_EQ(der::Input(&expected_issuer), parsed.issuer_tlv);
// In the test expectations PEM file, validity is described as a
// textual string of the parsed value (rather than as DER).
EXPECT_EQ(expected_validity_not_before, ToString(parsed.validity_not_before));
EXPECT_EQ(expected_validity_not_after, ToString(parsed.validity_not_after));
- EXPECT_EQ(InputFromString(&expected_subject), parsed.subject_tlv);
- EXPECT_EQ(InputFromString(&expected_spki), parsed.spki_tlv);
+ EXPECT_EQ(der::Input(&expected_subject), parsed.subject_tlv);
+ EXPECT_EQ(der::Input(&expected_spki), parsed.spki_tlv);
- EXPECT_EQ(InputFromString(&expected_issuer_unique_id),
+ EXPECT_EQ(der::Input(&expected_issuer_unique_id),
parsed.issuer_unique_id.bytes());
EXPECT_EQ(!expected_issuer_unique_id.empty(), parsed.has_issuer_unique_id);
- EXPECT_EQ(InputFromString(&expected_subject_unique_id),
+ EXPECT_EQ(der::Input(&expected_subject_unique_id),
parsed.subject_unique_id.bytes());
EXPECT_EQ(!expected_subject_unique_id.empty(), parsed.has_subject_unique_id);
- EXPECT_EQ(InputFromString(&expected_extensions), parsed.extensions_tlv);
+ EXPECT_EQ(der::Input(&expected_extensions), parsed.extensions_tlv);
EXPECT_EQ(!expected_extensions.empty(), parsed.has_extensions);
}
@@ -196,7 +194,7 @@ void EnsureParsingTbsFails(const std::string& file_name) {
// Parsing the TBSCertificate should fail.
ParsedTbsCertificate parsed;
- ASSERT_FALSE(ParseTbsCertificate(InputFromString(&data), &parsed));
+ ASSERT_FALSE(ParseTbsCertificate(der::Input(&data), &parsed));
}
// Tests parsing a TBSCertificate for v3 that contains no optional fields.
@@ -326,6 +324,467 @@ TEST(ParseTbsCertificateTest, ValidityRelaxed) {
EnsureParsingTbsFails("tbs_validity_relaxed.pem");
}
+// Reads a PEM file containing a block "EXTENSION". This input will be
+// passed to ParseExtension, and the results filled in |out|.
+bool ParseExtensionFromFile(const std::string& file_name,
+ ParsedExtension* out,
+ std::string* data) {
+ const PemBlockMapping mappings[] = {
+ {"EXTENSION", data},
+ };
+
+ EXPECT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
+ return ParseExtension(der::Input(data), out);
+}
+
+// Parses an Extension whose critical field is true (255).
+TEST(ParseExtensionTest, Critical) {
+ std::string data;
+ ParsedExtension extension;
+ ASSERT_TRUE(
+ ParseExtensionFromFile("extension_critical.pem", &extension, &data));
+
+ EXPECT_TRUE(extension.critical);
+
+ const uint8_t kExpectedOid[] = {0x55, 0x1d, 0x13};
+ EXPECT_EQ(der::Input(kExpectedOid), extension.oid);
+
+ const uint8_t kExpectedValue[] = {0x30, 0x00};
+ EXPECT_EQ(der::Input(kExpectedValue), extension.value);
+}
+
+// Parses an Extension whose critical field is false (omitted).
+TEST(ParseExtensionTest, NotCritical) {
+ std::string data;
+ ParsedExtension extension;
+ ASSERT_TRUE(
+ ParseExtensionFromFile("extension_not_critical.pem", &extension, &data));
+
+ EXPECT_FALSE(extension.critical);
+
+ const uint8_t kExpectedOid[] = {0x55, 0x1d, 0x13};
+ EXPECT_EQ(der::Input(kExpectedOid), extension.oid);
+
+ const uint8_t kExpectedValue[] = {0x30, 0x00};
+ EXPECT_EQ(der::Input(kExpectedValue), extension.value);
+}
+
+// Parses an Extension whose critical field is 0. This is in one sense FALSE,
+// however because critical has DEFAULT of false this is in fact invalid
+// DER-encoding.
+TEST(ParseExtensionTest, Critical0) {
+ std::string data;
+ ParsedExtension extension;
+ ASSERT_FALSE(
+ ParseExtensionFromFile("extension_critical_0.pem", &extension, &data));
+}
+
+// Parses an Extension whose critical field is 3. Under DER-encoding BOOLEAN
+// values must an octet of either all zero bits, or all 1 bits, so this is not
+// valid.
+TEST(ParseExtensionTest, Critical3) {
+ std::string data;
+ ParsedExtension extension;
+ ASSERT_FALSE(
+ ParseExtensionFromFile("extension_critical_3.pem", &extension, &data));
+}
+
+// Runs a test for extensions parsing. The input file is a PEM file which
+// contains a DER-encoded Extensions sequence, as well as the expected value
+// for each contained extension.
+void EnsureParsingExtensionsSucceeds(
+ const std::string& file_name,
+ std::map<der::Input, ParsedExtension>* extensions,
+ std::string* data) {
+ const PemBlockMapping mappings[] = {
+ // Test Input.
+ {"EXTENSIONS", data},
+ };
+
+ ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
+ ASSERT_TRUE(ParseExtensions(der::Input(data), extensions));
+}
+
+// Runs a test that verifies extensions parsing fails. The input file is a PEM
+// file which contains a DER-encoded Extensions sequence.
+void EnsureParsingExtensionsFails(const std::string& file_name) {
+ std::string data;
+
+ const PemBlockMapping mappings[] = {
+ {"EXTENSIONS", &data},
+ };
+
+ std::map<der::Input, ParsedExtension> extensions;
+ ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
+ ASSERT_FALSE(ParseExtensions(der::Input(&data), &extensions));
+}
+
+// Parses an Extensions that is an empty sequence.
+TEST(ParseExtensionsTest, EmptySequence) {
+ EnsureParsingExtensionsFails("extensions_empty_sequence.pem");
+}
+
+// Parses an Extensions that is not a sequence.
+TEST(ParseExtensionsTest, NotSequence) {
+ EnsureParsingExtensionsFails("extensions_not_sequence.pem");
+}
+
+// Parses an Extensions that has data after the sequence.
+TEST(ParseExtensionsTest, DataAfterSequence) {
+ EnsureParsingExtensionsFails("extensions_data_after_sequence.pem");
+}
+
+// Parses an Extensions that contains duplicated key usages.
+TEST(ParseExtensionsTest, DuplicateKeyUsage) {
+ EnsureParsingExtensionsFails("extensions_duplicate_key_usage.pem");
+}
+
+// Parses an Extensions that contains an unknown critical extension.
+TEST(ParseExtensionsTest, UnknownCritical) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_unknown_critical.pem",
+ &extensions, &data);
+
+ ASSERT_EQ(1u, extensions.size());
+ // This OID corresponds with
+ // 1.2.840.113554.4.1.72585.0 (https://davidben.net/oid)
+ const uint8_t oid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12,
+ 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00};
+
+ auto iter = extensions.find(der::Input(oid));
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_TRUE(iter->second.critical);
+ EXPECT_EQ(4u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains an unknown non-critical extension.
+TEST(ParseExtensionsTest, UnknownNonCritical) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_unknown_non_critical.pem",
+ &extensions, &data);
+
+ ASSERT_EQ(1u, extensions.size());
+ // This OID corresponds with
+ // 1.2.840.113554.4.1.72585.0 (https://davidben.net/oid)
+ const uint8_t oid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12,
+ 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00};
+
+ auto iter = extensions.find(der::Input(oid));
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(4u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains a basic constraints.
+TEST(ParseExtensionsTest, BasicConstraints) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_basic_constraints.pem",
+ &extensions, &data);
+
+ ASSERT_EQ(1u, extensions.size());
+
+ auto iter = extensions.find(BasicConstraintsOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_TRUE(iter->second.critical);
+ EXPECT_EQ(2u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains an extended key usages.
+TEST(ParseExtensionsTest, ExtendedKeyUsage) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_extended_key_usage.pem",
+ &extensions, &data);
+
+ ASSERT_EQ(1u, extensions.size());
+
+ auto iter = extensions.find(ExtKeyUsageOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(45u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains a key usage.
+TEST(ParseExtensionsTest, KeyUsage) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_key_usage.pem", &extensions,
+ &data);
+
+ ASSERT_EQ(1u, extensions.size());
+
+ auto iter = extensions.find(KeyUsageOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_TRUE(iter->second.critical);
+ EXPECT_EQ(4u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains a policies extension.
+TEST(ParseExtensionsTest, Policies) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_policies.pem", &extensions,
+ &data);
+
+ ASSERT_EQ(1u, extensions.size());
+
+ auto iter = extensions.find(CertificatePoliciesOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(95u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains a subjectaltname extension.
+TEST(ParseExtensionsTest, SubjectAltName) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_subject_alt_name.pem",
+ &extensions, &data);
+
+ ASSERT_EQ(1u, extensions.size());
+
+ auto iter = extensions.find(SubjectAltNameOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(23u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains multiple extensions, sourced from a
+// real-world certificate.
+TEST(ParseExtensionsTest, Real) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_real.pem", &extensions, &data);
+
+ ASSERT_EQ(7u, extensions.size());
+
+ auto iter = extensions.find(KeyUsageOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_TRUE(iter->second.critical);
+ EXPECT_EQ(4u, iter->second.value.Length());
+
+ iter = extensions.find(BasicConstraintsOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_TRUE(iter->second.critical);
+ EXPECT_EQ(8u, iter->second.value.Length());
+
+ iter = extensions.find(CertificatePoliciesOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(16u, iter->second.value.Length());
+
+ // TODO(eroman): Verify the other 4 extensions' values.
+}
+
+// Reads a PEM file containing a block "BASIC CONSTRAINTS". This input will
+// be passed to ParseExtension, and the results filled in |out|.
+bool ParseBasicConstraintsFromFile(const std::string& file_name,
+ ParsedBasicConstraints* out) {
+ std::string data;
+ const PemBlockMapping mappings[] = {
+ {"BASIC CONSTRAINTS", &data},
+ };
+
+ EXPECT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
+ return ParseBasicConstraints(der::Input(&data), out);
+}
+
+// Parses a BasicConstraints with no CA or pathlen.
+TEST(ParseBasicConstraintsTest, NotCa) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_not_ca.pem",
+ &constraints));
+ EXPECT_FALSE(constraints.is_ca);
+ EXPECT_FALSE(constraints.has_path_len);
+}
+
+// Parses a BasicConstraints with CA but no pathlen.
+TEST(ParseBasicConstraintsTest, CaNoPath) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_ca_no_path.pem",
+ &constraints));
+ EXPECT_TRUE(constraints.is_ca);
+ EXPECT_FALSE(constraints.has_path_len);
+}
+
+// Parses a BasicConstraints with CA and pathlen of 9.
+TEST(ParseBasicConstraintsTest, CaPath9) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_ca_path_9.pem",
+ &constraints));
+ EXPECT_TRUE(constraints.is_ca);
+ EXPECT_TRUE(constraints.has_path_len);
+ EXPECT_EQ(9u, constraints.path_len);
+}
+
+// Parses a BasicConstraints with CA and pathlen of 255 (largest allowed size).
+TEST(ParseBasicConstraintsTest, Pathlen255) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_pathlen_255.pem",
+ &constraints));
+ EXPECT_TRUE(constraints.is_ca);
+ EXPECT_TRUE(constraints.has_path_len);
+ EXPECT_EQ(255, constraints.path_len);
+}
+
+// Parses a BasicConstraints with CA and pathlen of 256 (too large).
+TEST(ParseBasicConstraintsTest, Pathlen256) {
+ ParsedBasicConstraints constraints;
+ ASSERT_FALSE(ParseBasicConstraintsFromFile(
+ "basic_constraints_pathlen_256.pem", &constraints));
+}
+
+// Parses a BasicConstraints with CA and a negative pathlen.
+TEST(ParseBasicConstraintsTest, NegativePath) {
+ ParsedBasicConstraints constraints;
+ ASSERT_FALSE(ParseBasicConstraintsFromFile(
+ "basic_constraints_negative_path.pem", &constraints));
+}
+
+// Parses a BasicConstraints with CA and pathlen that is very large (and
+// couldn't fit in a 64-bit integer).
+TEST(ParseBasicConstraintsTest, PathTooLarge) {
+ ParsedBasicConstraints constraints;
+ ASSERT_FALSE(ParseBasicConstraintsFromFile(
+ "basic_constraints_path_too_large.pem", &constraints));
+}
+
+// Parses a BasicConstraints with CA explicitly set to false. This violates
+// DER-encoding rules, however is commonly used, so it is accepted.
+TEST(ParseBasicConstraintsTest, CaFalse) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_ca_false.pem",
+ &constraints));
+ EXPECT_FALSE(constraints.is_ca);
+ EXPECT_FALSE(constraints.has_path_len);
+}
+
+// Parses a BasicConstraints with CA set to true and an unexpected NULL at
+// the end.
+TEST(ParseBasicConstraintsTest, UnconsumedData) {
+ ParsedBasicConstraints constraints;
+ ASSERT_FALSE(ParseBasicConstraintsFromFile(
+ "basic_constraints_unconsumed_data.pem", &constraints));
+}
+
+// Parses a BasicConstraints with CA omitted (false), but with a pathlen of 1.
+// This is valid DER for the ASN.1, however is not valid when interpreting the
+// BasicConstraints at a higher level.
+TEST(ParseBasicConstraintsTest, PathLenButNotCa) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile(
+ "basic_constraints_pathlen_not_ca.pem", &constraints));
+ EXPECT_FALSE(constraints.is_ca);
+ EXPECT_TRUE(constraints.has_path_len);
+ EXPECT_EQ(1u, constraints.path_len);
+}
+
+// Parses a KeyUsage with a single 0 bit.
+TEST(ParseKeyUsageTest, OneBitAllZeros) {
+ const uint8_t der[] = {
+ 0x03, 0x02, // BIT STRING
+ 0x07, // Number of unused bits
+ 0x00, // bits
+ };
+
+ der::BitString key_usage;
+ ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage));
+}
+
+// Parses a KeyUsage with 32 bits that are all 0.
+TEST(ParseKeyUsageTest, 32BitsAllZeros) {
+ const uint8_t der[] = {
+ 0x03, 0x05, // BIT STRING
+ 0x00, // Number of unused bits
+ 0x00, 0x00, 0x00, 0x00,
+ };
+
+ der::BitString key_usage;
+ ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage));
+}
+
+// Parses a KeyUsage with 32 bits, one of which is 1 (but not in recognized
+// set).
+TEST(ParseKeyUsageTest, 32BitsOneSet) {
+ const uint8_t der[] = {
+ 0x03, 0x05, // BIT STRING
+ 0x00, // Number of unused bits
+ 0x00, 0x00, 0x00, 0x02,
+ };
+
+ der::BitString key_usage;
+ ASSERT_TRUE(ParseKeyUsage(der::Input(der), &key_usage));
+
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_NON_REPUDIATION));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DATA_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_AGREEMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_CRL_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_ENCIPHER_ONLY));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DECIPHER_ONLY));
+}
+
+// Parses a KeyUsage containing bit string 101.
+TEST(ParseKeyUsageTest, ThreeBits) {
+ const uint8_t der[] = {
+ 0x03, 0x02, // BIT STRING
+ 0x05, // Number of unused bits
+ 0xA0, // bits
+ };
+
+ der::BitString key_usage;
+ ASSERT_TRUE(ParseKeyUsage(der::Input(der), &key_usage));
+
+ EXPECT_TRUE(key_usage.AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_NON_REPUDIATION));
+ EXPECT_TRUE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DATA_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_AGREEMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_CRL_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_ENCIPHER_ONLY));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DECIPHER_ONLY));
+}
+
+// Parses a KeyUsage containing DECIPHER_ONLY, which is the
+// only bit that doesn't fit in the first byte.
+TEST(ParseKeyUsageTest, DecipherOnly) {
+ const uint8_t der[] = {
+ 0x03, 0x03, // BIT STRING
+ 0x07, // Number of unused bits
+ 0x00, 0x80, // bits
+ };
+
+ der::BitString key_usage;
+ ASSERT_TRUE(ParseKeyUsage(der::Input(der), &key_usage));
+
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_NON_REPUDIATION));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DATA_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_AGREEMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_CRL_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_ENCIPHER_ONLY));
+ EXPECT_TRUE(key_usage.AssertsBit(KEY_USAGE_BIT_DECIPHER_ONLY));
+}
+
+// Parses an empty KeyUsage.
+TEST(ParseKeyUsageTest, Empty) {
+ const uint8_t der[] = {
+ 0x03, 0x01, // BIT STRING
+ 0x00, // Number of unused bits
+ };
+
+ der::BitString key_usage;
+ ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage));
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/cert/internal/signature_algorithm.cc b/chromium/net/cert/internal/signature_algorithm.cc
index 468fa16c3a6..38158fce771 100644
--- a/chromium/net/cert/internal/signature_algorithm.cc
+++ b/chromium/net/cert/internal/signature_algorithm.cc
@@ -4,6 +4,8 @@
#include "net/cert/internal/signature_algorithm.h"
+#include <utility>
+
#include "base/numerics/safe_math.h"
#include "net/der/input.h"
#include "net/der/parse_values.h"
@@ -540,10 +542,6 @@ RsaPssParameters::RsaPssParameters(DigestAlgorithm mgf1_hash,
: mgf1_hash_(mgf1_hash), salt_length_(salt_length) {
}
-bool RsaPssParameters::Equals(const RsaPssParameters* other) const {
- return mgf1_hash_ == other->mgf1_hash_ && salt_length_ == other->salt_length_;
-}
-
SignatureAlgorithm::~SignatureAlgorithm() {
}
@@ -611,34 +609,6 @@ scoped_ptr<SignatureAlgorithm> SignatureAlgorithm::CreateRsaPss(
make_scoped_ptr(new RsaPssParameters(mgf1_hash, salt_length))));
}
-bool SignatureAlgorithm::Equals(const SignatureAlgorithm& other) const {
- if (algorithm_ != other.algorithm_)
- return false;
-
- if (digest_ != other.digest_)
- return false;
-
- // Check that the parameters are equal.
- switch (algorithm_) {
- case SignatureAlgorithmId::RsaPss: {
- const RsaPssParameters* params1 = ParamsForRsaPss();
- const RsaPssParameters* params2 = other.ParamsForRsaPss();
- if (!params1 || !params2 || !params1->Equals(params2))
- return false;
- break;
- }
-
- // There shouldn't be any parameters.
- case SignatureAlgorithmId::RsaPkcs1:
- case SignatureAlgorithmId::Ecdsa:
- if (params_ || other.params_)
- return false;
- break;
- }
-
- return true;
-}
-
const RsaPssParameters* SignatureAlgorithm::ParamsForRsaPss() const {
if (algorithm_ == SignatureAlgorithmId::RsaPss)
return static_cast<RsaPssParameters*>(params_.get());
@@ -649,7 +619,6 @@ SignatureAlgorithm::SignatureAlgorithm(
SignatureAlgorithmId algorithm,
DigestAlgorithm digest,
scoped_ptr<SignatureAlgorithmParameters> params)
- : algorithm_(algorithm), digest_(digest), params_(params.Pass()) {
-}
+ : algorithm_(algorithm), digest_(digest), params_(std::move(params)) {}
} // namespace net
diff --git a/chromium/net/cert/internal/signature_algorithm.h b/chromium/net/cert/internal/signature_algorithm.h
index 9ecf252d671..de35a297473 100644
--- a/chromium/net/cert/internal/signature_algorithm.h
+++ b/chromium/net/cert/internal/signature_algorithm.h
@@ -7,8 +7,8 @@
#include <stdint.h>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
@@ -53,8 +53,6 @@ class NET_EXPORT RsaPssParameters : public SignatureAlgorithmParameters {
public:
RsaPssParameters(DigestAlgorithm mgf1_hash, uint32_t salt_length);
- bool Equals(const RsaPssParameters* other) const;
-
DigestAlgorithm mgf1_hash() const { return mgf1_hash_; }
uint32_t salt_length() const { return salt_length_; }
@@ -84,10 +82,6 @@ class NET_EXPORT SignatureAlgorithm {
DigestAlgorithm mgf1_hash,
uint32_t salt_length);
- // Returns true if |*this| is equivalent to |other|. This compares both the
- // algorithm ID and each parameter for equality.
- bool Equals(const SignatureAlgorithm& other) const WARN_UNUSED_RESULT;
-
// The following methods retrieve the parameters for the signature algorithm.
//
// The correct parameters should be chosen based on the algorithm ID. For
diff --git a/chromium/net/cert/internal/signature_algorithm_unittest.cc b/chromium/net/cert/internal/signature_algorithm_unittest.cc
index 8cc5517b3e9..32f5a0fc629 100644
--- a/chromium/net/cert/internal/signature_algorithm_unittest.cc
+++ b/chromium/net/cert/internal/signature_algorithm_unittest.cc
@@ -485,106 +485,6 @@ TEST(SignatureAlgorithmTest, ParseDerEcdsaWithSHA512NullParams) {
ASSERT_FALSE(ParseDer(kData, &algorithm));
}
-// Tests that two RSA algorithms with different digests are not equal.
-TEST(SignatureAlgorithmTest, EqualsRsaWithDifferentDigest) {
- scoped_ptr<SignatureAlgorithm> alg1 =
- SignatureAlgorithm::CreateRsaPkcs1(DigestAlgorithm::Sha1);
-
- scoped_ptr<SignatureAlgorithm> alg2 =
- SignatureAlgorithm::CreateRsaPkcs1(DigestAlgorithm::Sha256);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
-// Tests that two ECDSA algorithms with different digests are not equal.
-TEST(SignatureAlgorithmTest, EqualsEcdsaWithDifferentDigest) {
- scoped_ptr<SignatureAlgorithm> alg1 =
- SignatureAlgorithm::CreateEcdsa(DigestAlgorithm::Sha1);
-
- scoped_ptr<SignatureAlgorithm> alg2 =
- SignatureAlgorithm::CreateEcdsa(DigestAlgorithm::Sha256);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
-// Tests that an ECDSA algorithm is not equal to an RSA algorithm (even though
-// digests match).
-TEST(SignatureAlgorithmTest, EqualsEcdsaNotEqualRsa) {
- scoped_ptr<SignatureAlgorithm> alg1 =
- SignatureAlgorithm::CreateEcdsa(DigestAlgorithm::Sha256);
-
- scoped_ptr<SignatureAlgorithm> alg2 =
- SignatureAlgorithm::CreateRsaPkcs1(DigestAlgorithm::Sha256);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
-// Tests that two identical ECDSA algorithms are equal - both use SHA-256.
-TEST(SignatureAlgorithmTest, EqualsEcdsaMatch) {
- scoped_ptr<SignatureAlgorithm> alg1 =
- SignatureAlgorithm::CreateEcdsa(DigestAlgorithm::Sha256);
-
- scoped_ptr<SignatureAlgorithm> alg2 =
- SignatureAlgorithm::CreateEcdsa(DigestAlgorithm::Sha256);
-
- ASSERT_TRUE(alg1->Equals(*alg2));
-}
-
-// Tests that two identical RSA algorithms are equal - both use SHA-512
-TEST(SignatureAlgorithmTest, EqualsRsaPkcs1Match) {
- scoped_ptr<SignatureAlgorithm> alg1 =
- SignatureAlgorithm::CreateRsaPkcs1(DigestAlgorithm::Sha512);
-
- scoped_ptr<SignatureAlgorithm> alg2 =
- SignatureAlgorithm::CreateRsaPkcs1(DigestAlgorithm::Sha512);
-
- ASSERT_TRUE(alg1->Equals(*alg2));
-}
-
-// Tests that two RSASSA-PSS algorithms are equal.
-TEST(SignatureAlgorithmTest, EqualsRsaPssMatch) {
- scoped_ptr<SignatureAlgorithm> alg1 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha256, DigestAlgorithm::Sha1, 21);
-
- scoped_ptr<SignatureAlgorithm> alg2 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha256, DigestAlgorithm::Sha1, 21);
-
- ASSERT_TRUE(alg1->Equals(*alg2));
-}
-
-// Tests that two RSASSA-PSS algorithms with different hashes are not equal.
-TEST(SignatureAlgorithmTest, EqualsRsaPssWithDifferentDigest) {
- scoped_ptr<SignatureAlgorithm> alg1 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha1, DigestAlgorithm::Sha1, 20);
-
- scoped_ptr<SignatureAlgorithm> alg2 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha256, DigestAlgorithm::Sha1, 20);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
-// Tests that two RSASSA-PSS algorithms with different mask gens are not equal.
-TEST(SignatureAlgorithmTest, EqualsRsaPssWithDifferentMaskGen) {
- scoped_ptr<SignatureAlgorithm> alg1 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha256, DigestAlgorithm::Sha1, 20);
-
- scoped_ptr<SignatureAlgorithm> alg2 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha256, DigestAlgorithm::Sha256, 20);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
-// Tests that two RSASSA-PSS algorithms with different salts
-TEST(SignatureAlgorithmTest, EqualsRsaPssWithDifferentSalt) {
- scoped_ptr<SignatureAlgorithm> alg1 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha1, DigestAlgorithm::Sha1, 20);
-
- scoped_ptr<SignatureAlgorithm> alg2 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha1, DigestAlgorithm::Sha1, 16);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
// Tests that the parmeters returned for an ECDSA algorithm are null for
// non-ECDSA algorithms.
TEST(SignatureAlgorithmTest, ParamsAreNullForWrongTypeEcdsa) {
diff --git a/chromium/net/cert/internal/signature_policy.h b/chromium/net/cert/internal/signature_policy.h
index 72ff945ed2c..3acf17b9ea6 100644
--- a/chromium/net/cert/internal/signature_policy.h
+++ b/chromium/net/cert/internal/signature_policy.h
@@ -5,6 +5,8 @@
#ifndef NET_CERT_INTERNAL_SIGNATURE_POLICY_H_
#define NET_CERT_INTERNAL_SIGNATURE_POLICY_H_
+#include <stddef.h>
+
#include "base/compiler_specific.h"
#include "net/base/net_export.h"
#include "net/cert/internal/signature_algorithm.h"
diff --git a/chromium/net/cert/internal/test_helpers.cc b/chromium/net/cert/internal/test_helpers.cc
index 0b5363d8acc..4194ae3e6a4 100644
--- a/chromium/net/cert/internal/test_helpers.cc
+++ b/chromium/net/cert/internal/test_helpers.cc
@@ -9,6 +9,8 @@
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "net/cert/pem_tokenizer.h"
+#include "net/der/parser.h"
+#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -30,8 +32,18 @@ bool operator==(const Input& a, const Input& b) {
} // namespace der
-der::Input InputFromString(const std::string* s) {
- return der::Input(reinterpret_cast<const uint8_t*>(s->data()), s->size());
+der::Input SequenceValueFromString(const std::string* s) {
+ der::Parser parser((der::Input(s)));
+ der::Input data;
+ if (!parser.ReadTag(der::kSequence, &data)) {
+ ADD_FAILURE();
+ return der::Input();
+ }
+ if (parser.HasMore()) {
+ ADD_FAILURE();
+ return der::Input();
+ }
+ return data;
}
::testing::AssertionResult ReadTestDataFromPemFile(
diff --git a/chromium/net/cert/internal/test_helpers.h b/chromium/net/cert/internal/test_helpers.h
index d10148191a4..a1b3d8045ee 100644
--- a/chromium/net/cert/internal/test_helpers.h
+++ b/chromium/net/cert/internal/test_helpers.h
@@ -5,6 +5,8 @@
#ifndef NET_CERT_INTERNAL_TEST_HELPERS_H_
#define NET_CERT_INTERNAL_TEST_HELPERS_H_
+#include <stddef.h>
+
#include <ostream>
#include <string>
#include <vector>
@@ -23,15 +25,13 @@ bool operator==(const Input& a, const Input& b);
} // namespace der
-// Creates a der::Input from an std::string. The lifetimes are a bit subtle
-// when using this function:
+// Parses |s| as a DER SEQUENCE TLV and returns a der::Input corresponding to
+// the value portion. On error returns an empty der::Input and adds a gtest
+// failure.
//
// The returned der::Input() is only valid so long as the input string is alive
// and is not mutated.
-//
-// Note that the input parameter has been made a pointer to prevent callers
-// from accidentally passing an r-value.
-der::Input InputFromString(const std::string* s);
+der::Input SequenceValueFromString(const std::string* s);
// Helper structure that maps a PEM block header (for instance "CERTIFICATE") to
// the destination where the value for that block should be written.
diff --git a/chromium/net/cert/internal/verify_certificate_chain.cc b/chromium/net/cert/internal/verify_certificate_chain.cc
new file mode 100644
index 00000000000..524de925d3e
--- /dev/null
+++ b/chromium/net/cert/internal/verify_certificate_chain.cc
@@ -0,0 +1,549 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/internal/verify_certificate_chain.h"
+
+#include "base/logging.h"
+#include "net/cert/internal/parse_certificate.h"
+#include "net/cert/internal/signature_algorithm.h"
+#include "net/cert/internal/signature_policy.h"
+#include "net/cert/internal/verify_name_match.h"
+#include "net/cert/internal/verify_signed_data.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
+
+namespace net {
+
+namespace {
+
+// Map from OID to ParsedExtension.
+using ExtensionsMap = std::map<der::Input, ParsedExtension>;
+
+// Describes all parsed properties of a certificate that are relevant for
+// certificate verification.
+struct FullyParsedCert {
+ ParsedCertificate cert;
+ ParsedTbsCertificate tbs;
+
+ scoped_ptr<SignatureAlgorithm> signature_algorithm;
+
+ // Standard extensions that were parsed.
+ bool has_basic_constraints = false;
+ ParsedBasicConstraints basic_constraints;
+
+ bool has_key_usage = false;
+ der::BitString key_usage;
+
+ // The remaining extensions (excludes the standard ones above).
+ ExtensionsMap unconsumed_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|.
+WARN_UNUSED_RESULT bool ConsumeExtension(const der::Input& oid,
+ ExtensionsMap* unconsumed_extensions,
+ ParsedExtension* extension) {
+ auto it = unconsumed_extensions->find(oid);
+ if (it == unconsumed_extensions->end())
+ return false;
+
+ *extension = it->second;
+ unconsumed_extensions->erase(it);
+ return true;
+}
+
+// Returns true if the certificate does not contain any unconsumed _critical_
+// extensions.
+WARN_UNUSED_RESULT bool VerifyNoUnconsumedCriticalExtensions(
+ const FullyParsedCert& cert) {
+ for (const auto& entry : cert.unconsumed_extensions) {
+ if (entry.second.critical)
+ return false;
+ }
+ return true;
+}
+
+// Parses an X.509 Certificate fully (including the TBSCertificate and
+// standard extensions), saving all the properties to |out_|.
+WARN_UNUSED_RESULT bool FullyParseCertificate(const der::Input& cert_tlv,
+ FullyParsedCert* out) {
+ // Parse the outer Certificate.
+ if (!ParseCertificate(cert_tlv, &out->cert))
+ return false;
+
+ // Parse the signature algorithm contained in the Certificate (there is
+ // another one in the TBSCertificate, which is checked later by
+ // VerifySignatureAlgorithmsMatch)
+ out->signature_algorithm =
+ SignatureAlgorithm::CreateFromDer(out->cert.signature_algorithm_tlv);
+ if (!out->signature_algorithm)
+ return false;
+
+ // Parse the TBSCertificate.
+ if (!ParseTbsCertificate(out->cert.tbs_certificate_tlv, &out->tbs))
+ return false;
+
+ // Reset state relating to extensions (which may not get overwritten). This is
+ // just a precaution, since in practice |out| will already be default
+ // initialize.
+ out->has_basic_constraints = false;
+ out->has_key_usage = false;
+ out->unconsumed_extensions.clear();
+
+ // Parse the standard X.509 extensions and remove them from
+ // |unconsumed_extensions|.
+ if (out->tbs.has_extensions) {
+ // ParseExtensions() ensures there are no duplicates, and maps the (unique)
+ // OID to the extension value.
+ if (!ParseExtensions(out->tbs.extensions_tlv, &out->unconsumed_extensions))
+ return false;
+
+ ParsedExtension extension;
+
+ // Basic constraints.
+ if (ConsumeExtension(BasicConstraintsOid(), &out->unconsumed_extensions,
+ &extension)) {
+ out->has_basic_constraints = true;
+ if (!ParseBasicConstraints(extension.value, &out->basic_constraints))
+ return false;
+ }
+
+ // KeyUsage.
+ if (ConsumeExtension(KeyUsageOid(), &out->unconsumed_extensions,
+ &extension)) {
+ out->has_key_usage = true;
+ if (!ParseKeyUsage(extension.value, &out->key_usage))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv,
+ der::Input* value) {
+ der::Parser parser(tlv);
+ return parser.ReadTag(der::kSequence, value) && !parser.HasMore();
+}
+
+// Returns true if |name1_tlv| matches |name2_tlv|. The two inputs must be
+// tag-length-value for RFC 5280's Name.
+WARN_UNUSED_RESULT bool NameMatches(const der::Input& name1_tlv,
+ const der::Input& name2_tlv) {
+ der::Input name1_value;
+ der::Input name2_value;
+
+ // Assume that the Name is an RDNSequence. VerifyNameMatch() expects the
+ // value from a SEQUENCE, so strip off the tag.
+ if (!GetSequenceValue(name1_tlv, &name1_value) ||
+ !GetSequenceValue(name2_tlv, &name2_value)) {
+ return false;
+ }
+
+ return VerifyNameMatch(name1_value, name2_value);
+}
+
+// Returns true if |cert| was self-issued. The definition of self-issuance
+// comes from RFC 5280 section 6.1:
+//
+// A certificate is self-issued if the same DN appears in the subject
+// and issuer fields (the two DNs are the same if they match according
+// to the rules specified in Section 7.1). In general, the issuer and
+// subject of the certificates that make up a path are different for
+// each certificate. However, a CA may issue a certificate to itself to
+// support key rollover or changes in certificate policies. These
+// self-issued certificates are not counted when evaluating path length
+// or name constraints.
+WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) {
+ return NameMatches(cert.tbs.subject_tlv, cert.tbs.issuer_tlv);
+}
+
+// Finds a trust anchor that matches |name| in |trust_store| or returns
+// nullptr. The returned pointer references data in |trust_store|.
+//
+// TODO(eroman): This implementation is linear in the size of the trust store,
+// and also presumes that all names are unique. In practice it is possible to
+// have multiple SPKIs with the same name. Also this mechanism of
+// searching is fairly primitive, and does not take advantage of other
+// properties like the authority key id.
+WARN_UNUSED_RESULT const TrustAnchor* FindTrustAnchorByName(
+ const TrustStore& trust_store,
+ const der::Input& name) {
+ for (const auto& anchor : trust_store.anchors) {
+ if (NameMatches(name, der::Input(&anchor.name)))
+ return &anchor;
+ }
+ return nullptr;
+}
+
+// Returns true if |cert| is valid at time |time|.
+//
+// The certificate's validity requirements are described by RFC 5280 section
+// 4.1.2.5:
+//
+// The validity period for a certificate is the period of time from
+// notBefore through notAfter, inclusive.
+WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert,
+ const der::GeneralizedTime time) {
+ return !(time < cert.tbs.validity_not_before) &&
+ !(cert.tbs.validity_not_after < time);
+}
+
+// Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for
+// RSA with SHA1.
+WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm(
+ const der::Input& signature_algorithm_tlv) {
+ scoped_ptr<SignatureAlgorithm> algorithm =
+ SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv);
+
+ return algorithm &&
+ algorithm->algorithm() == SignatureAlgorithmId::RsaPkcs1 &&
+ algorithm->digest() == DigestAlgorithm::Sha1;
+}
+
+// Returns true if |cert| has internally consistent signature algorithms.
+//
+// X.509 certificates contain two different signature algorithms:
+// (1) The signatureAlgorithm field of Certificate
+// (2) The signature field of TBSCertificate
+//
+// According to RFC 5280 section 4.1.1.2 and 4.1.2.3 these two fields must be
+// equal:
+//
+// This field MUST contain the same algorithm identifier as the
+// signature field in the sequence tbsCertificate (Section 4.1.2.3).
+//
+// The spec is not explicit about what "the same algorithm identifier" means.
+// Our interpretation is that the two DER-encoded fields must be byte-for-byte
+// identical.
+//
+// In practice however there are certificates which use different encodings for
+// specifying RSA with SHA1 (different OIDs). This is special-cased for
+// compatibility sake.
+WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch(
+ const FullyParsedCert& cert) {
+ const der::Input& alg1_tlv = cert.cert.signature_algorithm_tlv;
+ const der::Input& alg2_tlv = cert.tbs.signature_algorithm_tlv;
+
+ // Ensure that the two DER-encoded signature algorithms are byte-for-byte
+ // equal, but make a compatibility concession for RSA with SHA1.
+ return alg1_tlv.Equals(alg2_tlv) ||
+ (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) &&
+ IsRsaWithSha1SignatureAlgorithm(alg2_tlv));
+}
+
+// This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate
+// Processing" procedure.
+WARN_UNUSED_RESULT bool BasicCertificateProcessing(
+ const FullyParsedCert& cert,
+ const SignaturePolicy* signature_policy,
+ const der::GeneralizedTime& time,
+ const der::Input& working_spki,
+ const der::Input& working_issuer_name) {
+ // Check that the signature algorithms in Certificate vs TBSCertificate
+ // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by
+ // sections 4.1.1.2 and 4.1.2.3.
+ if (!VerifySignatureAlgorithmsMatch(cert))
+ return false;
+
+ // Verify the digital signature using the previous certificate's (or trust
+ // anchor's) key (RFC 5280 section 6.1.3 step a.1).
+ if (!VerifySignedData(
+ *cert.signature_algorithm, cert.cert.tbs_certificate_tlv,
+ cert.cert.signature_value, working_spki, signature_policy)) {
+ return false;
+ }
+
+ // Check the time range for the certificate's validity, ensuring it is valid
+ // at |time|.
+ // (RFC 5280 section 6.1.3 step a.2)
+ if (!VerifyTimeValidity(cert, time))
+ return false;
+
+ // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3)
+
+ // Verify the certificate's issuer name matches the issuing certificate's (or
+ // trust anchor's) subject name. (RFC 5280 section 6.1.3 step a.4)
+ if (!NameMatches(cert.tbs.issuer_tlv, working_issuer_name))
+ return false;
+
+ // TODO(eroman): Steps b-f are omitted, as policy/name constraints are not yet
+ // implemented.
+
+ return true;
+}
+
+// This function corresponds to RFC 5280 section 6.1.4's "Preparation for
+// Certificate i+1" procedure. |cert| is expected to be an intermediary.
+WARN_UNUSED_RESULT bool PrepareForNextCertificate(
+ const FullyParsedCert& cert,
+ size_t* max_path_length_ptr,
+ der::Input* working_spki,
+ der::Input* working_issuer_name) {
+ // TODO(eroman): Steps a-b are omitted, as policy/name constraints are not yet
+ // implemented.
+
+ // From RFC 5280 section 6.1.4 step c:
+ //
+ // Assign the certificate subject name to working_issuer_name.
+ *working_issuer_name = cert.tbs.subject_tlv;
+
+ // From RFC 5280 section 6.1.4 step d:
+ //
+ // Assign the certificate subjectPublicKey to working_public_key.
+ *working_spki = cert.tbs.spki_tlv;
+
+ // Note that steps e and f are omitted as they are handled by
+ // the assignment to |working_spki| above. See the definition
+ // of |working_spki|.
+
+ // TODO(eroman): Steps g-j are omitted as policy/name constraints are not yet
+ // implemented.
+
+ // From RFC 5280 section 6.1.4 step k:
+ //
+ // If certificate i is a version 3 certificate, verify that the
+ // basicConstraints extension is present and that cA is set to
+ // TRUE. (If certificate i is a version 1 or version 2
+ // certificate, then the application MUST either verify that
+ // certificate i is a CA certificate through out-of-band means
+ // or reject the certificate. Conforming implementations may
+ // choose to reject all version 1 and version 2 intermediate
+ // certificates.)
+ //
+ // This code implicitly rejects non version 3 intermediaries, since they
+ // can't contain a BasicConstraints extension.
+ if (!cert.has_basic_constraints || !cert.basic_constraints.is_ca)
+ return false;
+
+ // From RFC 5280 section 6.1.4 step l:
+ //
+ // If the certificate was not self-issued, verify that
+ // max_path_length is greater than zero and decrement
+ // max_path_length by 1.
+ if (!IsSelfIssued(cert)) {
+ if (*max_path_length_ptr == 0)
+ return false;
+ --(*max_path_length_ptr);
+ }
+
+ // From RFC 5280 section 6.1.4 step m:
+ //
+ // If pathLenConstraint is present in the certificate and is
+ // less than max_path_length, set max_path_length to the value
+ // of pathLenConstraint.
+ if (cert.basic_constraints.has_path_len &&
+ cert.basic_constraints.path_len < *max_path_length_ptr) {
+ *max_path_length_ptr = cert.basic_constraints.path_len;
+ }
+
+ // From RFC 5280 section 6.1.4 step n:
+ //
+ // If a key usage extension is present, verify that the
+ // keyCertSign bit is set.
+ if (cert.has_key_usage &&
+ !cert.key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) {
+ return false;
+ }
+
+ // From RFC 5280 section 6.1.4 step o:
+ //
+ // Recognize and process any other critical extension present in
+ // the certificate. Process any other recognized non-critical
+ // extension present in the certificate that is relevant to path
+ // processing.
+ if (!VerifyNoUnconsumedCriticalExtensions(cert))
+ return false;
+
+ return true;
+}
+
+// Checks that if the target certificate has properties that only a CA should
+// have (keyCertSign, CA=true, pathLenConstraint), then its other properties
+// are consistent with being a CA.
+//
+// This follows from some requirements in RFC 5280 section 4.2.1.9. In
+// particular:
+//
+// CAs MUST NOT include the pathLenConstraint field unless the cA
+// boolean is asserted and the key usage extension asserts the
+// keyCertSign bit.
+//
+// And:
+//
+// If the cA boolean is not asserted, then the keyCertSign bit in the key
+// usage extension MUST NOT be asserted.
+//
+// TODO(eroman): Strictly speaking the first requirement is on CAs and not the
+// certificate client, so could be skipped.
+//
+// TODO(eroman): I don't believe Firefox enforces the keyCertSign restriction
+// for compatibility reasons. Investigate if we need to similarly relax this
+// constraint.
+WARN_UNUSED_RESULT bool VerifyTargetCertHasConsistentCaBits(
+ const FullyParsedCert& cert) {
+ // Check if the certificate contains any property specific to CAs.
+ bool has_ca_property =
+ (cert.has_basic_constraints &&
+ (cert.basic_constraints.is_ca || cert.basic_constraints.has_path_len)) ||
+ (cert.has_key_usage &&
+ cert.key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
+
+ // If it "looks" like a CA because it has a CA-only property, then check that
+ // it sets ALL the properties expected of a CA.
+ if (has_ca_property) {
+ return cert.has_basic_constraints && cert.basic_constraints.is_ca &&
+ (!cert.has_key_usage ||
+ cert.key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
+ }
+
+ return true;
+}
+
+// This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up Procedure".
+// It does processing for the final certificate (the target cert).
+WARN_UNUSED_RESULT bool WrapUp(const FullyParsedCert& cert) {
+ // TODO(eroman): Steps a-c are omitted as policy/name constraints are not yet
+ // implemented.
+
+ // Note step c-e are omitted the verification function does
+ // not output the working public key.
+
+ // From RFC 5280 section 6.1.5 step f:
+ //
+ // Recognize and process any other critical extension present in
+ // the certificate n. Process any other recognized non-critical
+ // extension present in certificate n that is relevant to path
+ // processing.
+ //
+ // Note that this is duplicated by PrepareForNextCertificate() so as to
+ // directly match the procedures in RFC 5280's section 6.1.
+ if (!VerifyNoUnconsumedCriticalExtensions(cert))
+ return false;
+
+ // TODO(eroman): Step g is omitted, as policy constraints are not yet
+ // implemented.
+
+ // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure",
+ // however is implied by RFC 5280 section 4.2.1.9.
+ if (!VerifyTargetCertHasConsistentCaBits(cert))
+ return false;
+
+ return true;
+}
+
+} // namespace
+
+TrustAnchor::~TrustAnchor() {}
+
+TrustStore::TrustStore() {}
+TrustStore::~TrustStore() {}
+
+// This implementation is structured to mimic the description of certificate
+// path verification given by RFC 5280 section 6.1.
+bool VerifyCertificateChain(const std::vector<der::Input>& certs_der,
+ const TrustStore& trust_store,
+ const SignaturePolicy* signature_policy,
+ const der::GeneralizedTime& time) {
+ // An empty chain is necessarily invalid.
+ if (certs_der.empty())
+ return false;
+
+ // |working_spki| is an amalgamation of 3 separate variables from RFC 5280:
+ // * working_public_key
+ // * working_public_key_algorithm
+ // * working_public_key_parameters
+ //
+ // They are combined for simplicity since the signature verification takes an
+ // SPKI, and the parameter inheritence is not applicable for the supported
+ // key types.
+ //
+ // An approximate explanation of |working_spki| is this description from RFC
+ // 5280 section 6.1.2:
+ //
+ // working_public_key: the public key used to verify the
+ // signature of a certificate. The working_public_key is
+ // initialized from the trusted public key provided in the trust
+ // anchor information.
+ der::Input working_spki;
+
+ // |working_issuer_name| corresponds with the same named variable in RFC 5280
+ // section 6.1.2:
+ //
+ // working_issuer_name: the issuer distinguished name expected
+ // in the next certificate in the chain. The
+ // working_issuer_name is initialized to the trusted issuer name
+ // provided in the trust anchor information.
+ der::Input working_issuer_name;
+
+ // |max_path_length| corresponds with the same named variable in RFC 5280
+ // section 6.1.2:
+ //
+ // max_path_length: this integer is initialized to n, is
+ // decremented for each non-self-issued certificate in the path,
+ // and may be reduced to the value in the path length constraint
+ // field within the basic constraints extension of a CA
+ // certificate.
+ size_t max_path_length = certs_der.size();
+
+ // Iterate over all the certificates in the reverse direction: starting from
+ // the trust anchor and progressing towards the target certificate.
+ //
+ // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based.
+ //
+ // * i=0 : Certificate signed by a trust anchor.
+ // * i=N-1 : Target certificate.
+ for (size_t i = 0; i < certs_der.size(); ++i) {
+ const size_t index_into_certs_der = certs_der.size() - i - 1;
+ const bool is_target_cert = index_into_certs_der == 0;
+
+ // Parse the current certificate into |cert|.
+ FullyParsedCert cert;
+ const der::Input& cert_der = certs_der[index_into_certs_der];
+ if (!FullyParseCertificate(cert_der, &cert))
+ return false;
+
+ // When processing the first certificate, initialize |working_spki|
+ // and |working_issuer_name| to the trust anchor per RFC 5280 section 6.1.2.
+ // This is done inside the loop in order to have access to the parsed
+ // certificate.
+ if (i == 0) {
+ const TrustAnchor* trust_anchor =
+ FindTrustAnchorByName(trust_store, cert.tbs.issuer_tlv);
+ if (!trust_anchor)
+ return false;
+ working_spki = der::Input(&trust_anchor->spki);
+ working_issuer_name = der::Input(&trust_anchor->name);
+ }
+
+ // Per RFC 5280 section 6.1:
+ // * Do basic processing for each certificate
+ // * If it is the last certificate in the path (target certificate)
+ // - Then run "Wrap up"
+ // - Otherwise run "Prepare for Next cert"
+ if (!BasicCertificateProcessing(cert, signature_policy, time, working_spki,
+ working_issuer_name)) {
+ return false;
+ }
+ if (!is_target_cert) {
+ if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki,
+ &working_issuer_name)) {
+ return false;
+ }
+ } else {
+ if (!WrapUp(cert))
+ return false;
+ }
+ }
+
+ // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1:
+ //
+ // A certificate MUST NOT appear more than once in a prospective
+ // certification path.
+
+ return true;
+}
+
+} // namespace net
diff --git a/chromium/net/cert/internal/verify_certificate_chain.h b/chromium/net/cert/internal/verify_certificate_chain.h
new file mode 100644
index 00000000000..8f7e21f8ad6
--- /dev/null
+++ b/chromium/net/cert/internal/verify_certificate_chain.h
@@ -0,0 +1,86 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_CERT_INTERNAL_VERIFY_CERTIFICATE_CHAIN_H_
+#define NET_CERT_INTERNAL_VERIFY_CERTIFICATE_CHAIN_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace der {
+class Input;
+struct GeneralizedTime;
+}
+
+class SignaturePolicy;
+
+struct NET_EXPORT TrustAnchor {
+ ~TrustAnchor();
+
+ // DER-encoded SubjectPublicKeyInfo for the trusted key.
+ std::string spki;
+
+ // DER-encoded "Name" corresponding to the key.
+ std::string name;
+};
+
+// A very simple implementation of a TrustStore, which contains mappings from
+// names to trusted public keys.
+struct NET_EXPORT TrustStore {
+ TrustStore();
+ ~TrustStore();
+
+ std::vector<TrustAnchor> anchors;
+};
+
+// VerifyCertificateChain() verifies a certificate path (chain) based on the
+// rules in RFC 5280.
+//
+// WARNING: This implementation is in progress, and is currently
+// incomplete. DO NOT USE IT unless its limitations are acceptable for your use.
+//
+// ---------
+// Inputs
+// ---------
+//
+// cert_chain:
+// A non-empty chain of N DER-encoded certificates, listed in the
+// "forward" direction.
+//
+// * cert_chain[0] is the target certificate to verify.
+// * cert_chain[i+1] holds the certificate that issued cert_chain[i].
+// * cert_chain[N-1] must have been issued by a trust anchor
+//
+// trust_store:
+// Contains the set of trusted public keys (and their names).
+//
+// signature_policy:
+// The policy to use when verifying signatures (what hash algorithms are
+// allowed, what length keys, what named curves, etc).
+//
+// time:
+// The UTC time to use for expiration checks.
+//
+// ---------
+// Outputs
+// ---------
+//
+// Returns true if the target certificate can be verified.
+NET_EXPORT bool VerifyCertificateChain(const std::vector<der::Input>& certs_der,
+ const TrustStore& trust_store,
+ const SignaturePolicy* signature_policy,
+ const der::GeneralizedTime& time)
+ WARN_UNUSED_RESULT;
+
+} // namespace net
+
+#endif // NET_CERT_INTERNAL_VERIFY_CERTIFICATE_CHAIN_H_
diff --git a/chromium/net/cert/internal/verify_certificate_chain_unittest.cc b/chromium/net/cert/internal/verify_certificate_chain_unittest.cc
new file mode 100644
index 00000000000..c997f5386ef
--- /dev/null
+++ b/chromium/net/cert/internal/verify_certificate_chain_unittest.cc
@@ -0,0 +1,246 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/internal/verify_certificate_chain.h"
+
+#include "base/base_paths.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "net/cert/internal/parse_certificate.h"
+#include "net/cert/internal/signature_policy.h"
+#include "net/cert/internal/test_helpers.h"
+#include "net/cert/pem_tokenizer.h"
+#include "net/der/input.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// TODO(eroman): Because VerifySignedData() is only implemented for BoringSSL
+// these tests also depend on BoringSSL.
+#if defined(USE_OPENSSL)
+
+namespace net {
+
+namespace {
+
+// Reads a data file from the unit-test data.
+std::string ReadTestFileToString(const std::string& file_name) {
+ // Compute the full path, relative to the src/ directory.
+ base::FilePath src_root;
+ PathService::Get(base::DIR_SOURCE_ROOT, &src_root);
+ base::FilePath filepath = src_root.AppendASCII(
+ std::string("net/data/verify_certificate_chain_unittest/") + file_name);
+
+ // Read the full contents of the file.
+ std::string file_data;
+ if (!base::ReadFileToString(filepath, &file_data)) {
+ ADD_FAILURE() << "Couldn't read file: " << filepath.value();
+ return std::string();
+ }
+
+ return file_data;
+}
+
+// Adds the certificate |cert_der| as a trust anchor to |trust_store|.
+void AddCertificateToTrustStore(const std::string& cert_der,
+ TrustStore* trust_store) {
+ ParsedCertificate cert;
+ ASSERT_TRUE(ParseCertificate(der::Input(&cert_der), &cert));
+
+ ParsedTbsCertificate tbs;
+ ASSERT_TRUE(ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs));
+ TrustAnchor anchor = {tbs.spki_tlv.AsString(), tbs.subject_tlv.AsString()};
+ trust_store->anchors.push_back(anchor);
+}
+
+// Reads a test case from |file_name|. Test cases are comprised of a
+// certificate chain, trust store, a timestamp to validate at, and the
+// expected result of verification.
+void ReadTestFromFile(const std::string& file_name,
+ std::vector<std::string>* chain,
+ TrustStore* trust_store,
+ der::GeneralizedTime* time,
+ bool* verify_result) {
+ chain->clear();
+ *trust_store = TrustStore();
+
+ std::string file_data = ReadTestFileToString(file_name);
+
+ std::vector<std::string> pem_headers;
+
+ const char kCertificateHeader[] = "CERTIFICATE";
+ const char kTrustedCertificateHeader[] = "TRUSTED_CERTIFICATE";
+ const char kTimeHeader[] = "TIME";
+ const char kResultHeader[] = "VERIFY_RESULT";
+
+ pem_headers.push_back(kCertificateHeader);
+ pem_headers.push_back(kTrustedCertificateHeader);
+ pem_headers.push_back(kTimeHeader);
+ pem_headers.push_back(kResultHeader);
+
+ bool has_time = false;
+ bool has_result = false;
+
+ PEMTokenizer pem_tokenizer(file_data, pem_headers);
+ while (pem_tokenizer.GetNext()) {
+ const std::string& block_type = pem_tokenizer.block_type();
+ const std::string& block_data = pem_tokenizer.data();
+
+ if (block_type == kCertificateHeader) {
+ chain->push_back(block_data);
+ } else if (block_type == kTrustedCertificateHeader) {
+ AddCertificateToTrustStore(block_data, trust_store);
+ } else if (block_type == kTimeHeader) {
+ ASSERT_FALSE(has_time) << "Duplicate " << kTimeHeader;
+ has_time = true;
+ ASSERT_TRUE(der::ParseUTCTime(der::Input(&block_data), time));
+ } else if (block_type == kResultHeader) {
+ ASSERT_FALSE(has_result) << "Duplicate " << kResultHeader;
+ ASSERT_TRUE(block_data == "SUCCESS" || block_data == "FAIL")
+ << "Unrecognized result: " << block_data;
+ has_result = true;
+ *verify_result = block_data == "SUCCESS";
+ }
+ }
+
+ ASSERT_TRUE(has_time);
+ ASSERT_TRUE(has_result);
+}
+
+void RunTest(const char* file_name) {
+ std::vector<std::string> chain;
+ TrustStore trust_store;
+ der::GeneralizedTime time;
+ bool expected_result;
+
+ ReadTestFromFile(file_name, &chain, &trust_store, &time, &expected_result);
+
+ std::vector<der::Input> input_chain;
+ for (const auto& cert_str : chain)
+ input_chain.push_back(der::Input(&cert_str));
+
+ SimpleSignaturePolicy signature_policy(1024);
+
+ bool result =
+ VerifyCertificateChain(input_chain, trust_store, &signature_policy, time);
+
+ ASSERT_EQ(expected_result, result);
+}
+
+TEST(VerifyCertificateChainTest, TargetAndIntermediary) {
+ RunTest("target-and-intermediary.pem");
+}
+
+TEST(VerifyCertificateChainTest, UnknownRoot) {
+ RunTest("unknown-root.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryLacksBasicConstraints) {
+ RunTest("intermediary-lacks-basic-constraints.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryBasicConstraintsCaFalse) {
+ RunTest("intermediary-basic-constraints-ca-false.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryBasicConstraintsNotCritical) {
+ RunTest("intermediary-basic-constraints-not-critical.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryLacksSigningKeyUsage) {
+ RunTest("intermediary-lacks-signing-key-usage.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryUnknownCriticalExtension) {
+ RunTest("intermediary-unknown-critical-extension.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryUnknownNonCriticalExtension) {
+ RunTest("intermediary-unknown-non-critical-extension.pem");
+}
+
+TEST(VerifyCertificateChainTest, ViolatesBasicConstraintsPathlen0) {
+ RunTest("violates-basic-constraints-pathlen-0.pem");
+}
+
+TEST(VerifyCertificateChainTest, BasicConstraintsPathlen0SelfIssued) {
+ RunTest("basic-constraints-pathlen-0-self-issued.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetSignedWithMd5) {
+ RunTest("target-signed-with-md5.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediarySignedWithMd5) {
+ RunTest("intermediary-signed-with-md5.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetWrongSignature) {
+ RunTest("target-wrong-signature.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetSignedBy512bitRsa) {
+ RunTest("target-signed-by-512bit-rsa.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetSignedUsingEcdsa) {
+ RunTest("target-signed-using-ecdsa.pem");
+}
+
+TEST(VerifyCertificateChainTest, ExpiredIntermediary) {
+ RunTest("expired-intermediary.pem");
+}
+
+TEST(VerifyCertificateChainTest, ExpiredTarget) {
+ RunTest("expired-target.pem");
+}
+
+TEST(VerifyCertificateChainTest, ExpiredTargetNotBefore) {
+ RunTest("expired-target-notBefore.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetNotEndEntity) {
+ RunTest("target-not-end-entity.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetHasKeyCertSignButNotCa) {
+ RunTest("target-has-keycertsign-but-not-ca.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetHasPathlenButNotCa) {
+ RunTest("target-has-pathlen-but-not-ca.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetUnknownCriticalExtension) {
+ RunTest("target-unknown-critical-extension.pem");
+}
+
+TEST(VerifyCertificateChainTest, IssuerAndSubjectNotByteForByteEqual) {
+ RunTest("issuer-and-subject-not-byte-for-byte-equal.pem");
+}
+
+TEST(VerifyCertificateChainTest, IssuerAndSubjectNotByteForByteEqualAnchor) {
+ RunTest("issuer-and-subject-not-byte-for-byte-equal-anchor.pem");
+}
+
+// Tests that verifying a chain with no certificates fails.
+TEST(VerifyCertificateChainTest, EmptyChainIsInvalid) {
+ TrustStore trust_store;
+ der::GeneralizedTime time;
+ std::vector<der::Input> chain;
+ SimpleSignaturePolicy signature_policy(2048);
+
+ ASSERT_FALSE(
+ VerifyCertificateChain(chain, trust_store, &signature_policy, time));
+}
+
+// TODO(eroman): Add test that invalidate validity dates where the day or month
+// ordinal not in range, like "March 39, 2016" are rejected.
+
+} // namespace
+
+} // namespace net
+
+#endif
diff --git a/chromium/net/cert/internal/verify_name_match.cc b/chromium/net/cert/internal/verify_name_match.cc
index 5b6cf4cbf2a..00d1fb5c113 100644
--- a/chromium/net/cert/internal/verify_name_match.cc
+++ b/chromium/net/cert/internal/verify_name_match.cc
@@ -6,7 +6,6 @@
#include <string.h>
-#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversion_utils.h"
@@ -22,6 +21,17 @@ namespace net {
namespace {
+// RFC 5280 section A.1:
+//
+// pkcs-9 OBJECT IDENTIFIER ::=
+// { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
+//
+// id-emailAddress AttributeType ::= { pkcs-9 1 }
+//
+// In dotted form: 1.2.840.113549.1.9.1
+const uint8_t kOidEmailAddress[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
+ 0x0D, 0x01, 0x09, 0x01};
+
// Types of character set checking that NormalizeDirectoryString can perform.
enum CharsetEnforcement {
NO_ENFORCEMENT,
@@ -202,7 +212,7 @@ WARN_UNUSED_RESULT bool NormalizeUniversalStringValue(const der::Input& in,
std::vector<uint32_t> in_32bit(in.Length() / 4);
if (in.Length())
- memcpy(vector_as_array(&in_32bit), in.UnsafeData(), in.Length());
+ memcpy(in_32bit.data(), in.UnsafeData(), in.Length());
for (const uint32_t c : in_32bit) {
// UniversalString is UCS-4 in big-endian order.
uint32_t codepoint = base::NetToHost32(c);
@@ -389,8 +399,16 @@ bool VerifyRdnMatch(der::Parser* a_parser, der::Parser* b_parser) {
return true;
}
-} // namespace
+enum NameMatchType {
+ EXACT_MATCH,
+ SUBTREE_MATCH,
+};
+// Verify that |a| matches |b|. If |match_type| is EXACT_MATCH, returns true if
+// they are an exact match as defined by RFC 5280 7.1. If |match_type| is
+// SUBTREE_MATCH, returns true if |a| is within the subtree defined by |b| as
+// defined by RFC 5280 7.1.
+//
// |a| and |b| are ASN.1 RDNSequence values (not including the Sequence tag),
// defined in RFC 5280 section 4.1.2.4:
//
@@ -401,7 +419,9 @@ bool VerifyRdnMatch(der::Parser* a_parser, der::Parser* b_parser) {
//
// RelativeDistinguishedName ::=
// SET SIZE (1..MAX) OF AttributeTypeAndValue
-bool VerifyNameMatch(const der::Input& a, const der::Input& b) {
+bool VerifyNameMatchInternal(const der::Input& a,
+ const der::Input& b,
+ NameMatchType match_type) {
// Empty Names are allowed. RFC 5280 section 4.1.2.4 requires "The issuer
// field MUST contain a non-empty distinguished name (DN)", while section
// 4.1.2.6 allows for the Subject to be empty in certain cases. The caller is
@@ -421,7 +441,12 @@ bool VerifyNameMatch(const der::Input& a, const der::Input& b) {
return false;
}
}
- if (a_rdn_sequence_counter.HasMore() || b_rdn_sequence_counter.HasMore())
+ // If doing exact match and either of the sequences has more elements than the
+ // other, not a match. If doing a subtree match, the first Name may have more
+ // RDNs than the second.
+ if (b_rdn_sequence_counter.HasMore())
+ return false;
+ if (match_type == EXACT_MATCH && a_rdn_sequence_counter.HasMore())
return false;
// Same number of RDNs, now check if they match.
@@ -440,4 +465,42 @@ bool VerifyNameMatch(const der::Input& a, const der::Input& b) {
return true;
}
+} // namespace
+
+bool VerifyNameMatch(const der::Input& a_rdn_sequence,
+ const der::Input& b_rdn_sequence) {
+ return VerifyNameMatchInternal(a_rdn_sequence, b_rdn_sequence, EXACT_MATCH);
+}
+
+bool VerifyNameInSubtree(const der::Input& name_rdn_sequence,
+ const der::Input& parent_rdn_sequence) {
+ return VerifyNameMatchInternal(name_rdn_sequence, parent_rdn_sequence,
+ SUBTREE_MATCH);
+}
+
+bool NameContainsEmailAddress(const der::Input& name_rdn_sequence,
+ bool* contained_email_address) {
+ der::Parser rdn_sequence_parser(name_rdn_sequence);
+
+ while (rdn_sequence_parser.HasMore()) {
+ der::Parser rdn_parser;
+ if (!rdn_sequence_parser.ReadConstructed(der::kSet, &rdn_parser))
+ return false;
+
+ std::vector<AttributeTypeAndValue> type_and_values;
+ if (!ReadRdn(&rdn_parser, &type_and_values))
+ return false;
+
+ for (const auto& type_and_value : type_and_values) {
+ if (type_and_value.type.Equals(der::Input(kOidEmailAddress))) {
+ *contained_email_address = true;
+ return true;
+ }
+ }
+ }
+
+ *contained_email_address = false;
+ return true;
+}
+
} // namespace net
diff --git a/chromium/net/cert/internal/verify_name_match.h b/chromium/net/cert/internal/verify_name_match.h
index 99d09f0e107..5cca36ad2db 100644
--- a/chromium/net/cert/internal/verify_name_match.h
+++ b/chromium/net/cert/internal/verify_name_match.h
@@ -5,6 +5,7 @@
#ifndef NET_CERT_INTERNAL_VERIFY_NAME_MATCH_H_
#define NET_CERT_INTERNAL_VERIFY_NAME_MATCH_H_
+#include "base/compiler_specific.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -14,13 +15,30 @@ namespace der {
class Input;
} // namespace der
-// Compare DER-encoded X.501 Name values according to RFC 5280 rules.
+// Compares DER-encoded X.501 Name values according to RFC 5280 rules.
// |a_rdn_sequence| and |b_rdn_sequence| should be the DER-encoded RDNSequence
// values (not including the Sequence tag).
// Returns true if |a_rdn_sequence| and |b_rdn_sequence| match.
NET_EXPORT bool VerifyNameMatch(const der::Input& a_rdn_sequence,
const der::Input& b_rdn_sequence);
+// Compares |name_rdn_sequence| and |parent_rdn_sequence| and return true if
+// |name_rdn_sequence| is within the subtree defined by |parent_rdn_sequence| as
+// defined by RFC 5280 section 7.1. |name_rdn_sequence| and
+// |parent_rdn_sequence| should be the DER-encoded sequence values (not
+// including the Sequence tag).
+NET_EXPORT bool VerifyNameInSubtree(const der::Input& name_rdn_sequence,
+ const der::Input& parent_rdn_sequence);
+
+// Helper functions:
+
+// Checks if |name_rdn_sequence| contains an emailAddress attribute type.
+// If the return value is true, |*contained_email_address| will be set to
+// indicate whether an emailAddress attribute was present.
+// Returns false if there was a parsing error.
+bool NameContainsEmailAddress(const der::Input& name_rdn_sequence,
+ bool* contained_email_address) WARN_UNUSED_RESULT;
+
} // namespace net
#endif // NET_CERT_INTERNAL_VERIFY_NAME_MATCH_H_
diff --git a/chromium/net/cert/internal/verify_name_match_unittest.cc b/chromium/net/cert/internal/verify_name_match_unittest.cc
index d6dc3884dcb..2bdf82efb68 100644
--- a/chromium/net/cert/internal/verify_name_match_unittest.cc
+++ b/chromium/net/cert/internal/verify_name_match_unittest.cc
@@ -7,27 +7,11 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "net/cert/internal/test_helpers.h"
-#include "net/der/input.h"
-#include "net/der/parser.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
-der::Input SequenceValueFromString(const std::string* s) {
- der::Parser parser(InputFromString(s));
- der::Input data;
- if (!parser.ReadTag(der::kSequence, &data)) {
- ADD_FAILURE();
- return der::Input();
- }
- if (parser.HasMore()) {
- ADD_FAILURE();
- return der::Input();
- }
- return data;
-}
-
// Loads test data from file. The filename is constructed from the parameters:
// |prefix| describes the type of data being tested, e.g. "ascii",
// "unicode_bmp", "unicode_supplementary", and "invalid".
@@ -232,6 +216,58 @@ TEST_P(VerifyNameMatchDifferingTypesTest, NormalizableTypesAreEqual) {
}
}
+TEST_P(VerifyNameMatchDifferingTypesTest, NormalizableTypesInSubtrees) {
+ std::string der_1;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_1(), "unmangled", &der_1));
+ std::string der_1_extra_rdn;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_1(), "unmangled-extra_rdn",
+ &der_1_extra_rdn));
+ std::string der_1_extra_attr;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_1(), "unmangled-extra_attr",
+ &der_1_extra_attr));
+ std::string der_2;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_2(), "unmangled", &der_2));
+ std::string der_2_extra_rdn;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_2(), "unmangled-extra_rdn",
+ &der_2_extra_rdn));
+ std::string der_2_extra_attr;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_2(), "unmangled-extra_attr",
+ &der_2_extra_attr));
+
+ if (TypesAreComparable(value_type_1(), value_type_2())) {
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&der_1),
+ SequenceValueFromString(&der_2)));
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&der_2),
+ SequenceValueFromString(&der_1)));
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&der_1_extra_rdn),
+ SequenceValueFromString(&der_2)));
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&der_2_extra_rdn),
+ SequenceValueFromString(&der_1)));
+ } else {
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_1),
+ SequenceValueFromString(&der_2)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_2),
+ SequenceValueFromString(&der_1)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_1_extra_rdn),
+ SequenceValueFromString(&der_2)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_2_extra_rdn),
+ SequenceValueFromString(&der_1)));
+ }
+
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_1),
+ SequenceValueFromString(&der_2_extra_rdn)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_2),
+ SequenceValueFromString(&der_1_extra_rdn)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_1_extra_attr),
+ SequenceValueFromString(&der_2)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_2_extra_attr),
+ SequenceValueFromString(&der_1)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_1),
+ SequenceValueFromString(&der_2_extra_attr)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_2),
+ SequenceValueFromString(&der_1_extra_attr)));
+}
+
// Runs VerifyNameMatchDifferingTypesTest for all combinations of value types in
// value_type1 and value_type_2.
INSTANTIATE_TEST_CASE_P(InstantiationName,
@@ -459,4 +495,36 @@ TEST(VerifyNameMatchRDNSorting, DuplicateTypes) {
SequenceValueFromString(&a)));
}
+TEST(VerifyNameInSubtreeInvalidDataTest, FailOnEmptyRdn) {
+ std::string valid;
+ ASSERT_TRUE(LoadTestData("ascii", "PRINTABLESTRING", "unmangled", &valid));
+ std::string invalid;
+ ASSERT_TRUE(LoadTestData("invalid", "RDN", "empty", &invalid));
+ // For both |name| and |parent|, a RelativeDistinguishedName must have at
+ // least one AttributeTypeAndValue.
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&valid),
+ SequenceValueFromString(&invalid)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&invalid),
+ SequenceValueFromString(&valid)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&invalid),
+ SequenceValueFromString(&invalid)));
+}
+
+TEST(VerifyNameInSubtreeTest, EmptyNameMatching) {
+ std::string empty;
+ ASSERT_TRUE(LoadTestData("valid", "Name", "empty", &empty));
+ std::string non_empty;
+ ASSERT_TRUE(
+ LoadTestData("ascii", "PRINTABLESTRING", "unmangled", &non_empty));
+ // Empty name is in the subtree defined by empty name.
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&empty),
+ SequenceValueFromString(&empty)));
+ // Any non-empty name is in the subtree defined by empty name.
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&non_empty),
+ SequenceValueFromString(&empty)));
+ // Empty name is not in the subtree defined by non-empty name.
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&empty),
+ SequenceValueFromString(&non_empty)));
+}
+
} // namespace net
diff --git a/chromium/net/cert/internal/verify_signed_data_unittest.cc b/chromium/net/cert/internal/verify_signed_data_unittest.cc
index a718c779a51..d7e822869cd 100644
--- a/chromium/net/cert/internal/verify_signed_data_unittest.cc
+++ b/chromium/net/cert/internal/verify_signed_data_unittest.cc
@@ -61,21 +61,20 @@ void RunTestCaseUsingPolicy(VerifyResult expected_result,
ASSERT_TRUE(ReadTestDataFromPemFile(path, mappings));
scoped_ptr<SignatureAlgorithm> signature_algorithm =
- SignatureAlgorithm::CreateFromDer(InputFromString(&algorithm));
+ SignatureAlgorithm::CreateFromDer(der::Input(&algorithm));
ASSERT_TRUE(signature_algorithm);
der::BitString signature_value_bit_string;
- der::Parser signature_value_parser(InputFromString(&signature_value));
+ der::Parser signature_value_parser((der::Input(&signature_value)));
ASSERT_TRUE(signature_value_parser.ReadBitString(&signature_value_bit_string))
<< "The signature value is not a valid BIT STRING";
bool expected_result_bool = expected_result == SUCCESS;
- EXPECT_EQ(
- expected_result_bool,
- VerifySignedData(*signature_algorithm, InputFromString(&signed_data),
- signature_value_bit_string, InputFromString(&public_key),
- policy));
+ EXPECT_EQ(expected_result_bool,
+ VerifySignedData(*signature_algorithm, der::Input(&signed_data),
+ signature_value_bit_string,
+ der::Input(&public_key), policy));
}
// RunTestCase() is the same as RunTestCaseUsingPolicy(), only it uses a
diff --git a/chromium/net/cert/jwk_serializer_nss.cc b/chromium/net/cert/jwk_serializer_nss.cc
index 1db65f705ba..441a98ff4f9 100644
--- a/chromium/net/cert/jwk_serializer_nss.cc
+++ b/chromium/net/cert/jwk_serializer_nss.cc
@@ -8,7 +8,7 @@
#include <keyhi.h>
#include <nss.h>
-#include "base/base64.h"
+#include "base/base64url.h"
#include "base/values.h"
#include "crypto/nss_util.h"
#include "crypto/scoped_nss_types.h"
@@ -37,7 +37,7 @@ bool ConvertEcPrime256v1PublicKeyInfoToJwk(
reinterpret_cast<char*>(spki->subjectPublicKey.data + 1),
kPrime256v1PublicKeyLength / 2);
std::string x_b64;
- base::Base64Encode(x, &x_b64);
+ base::Base64UrlEncode(x, base::Base64UrlEncodePolicy::OMIT_PADDING, &x_b64);
public_key_jwk->SetString("x", x_b64);
base::StringPiece y(
@@ -45,7 +45,7 @@ bool ConvertEcPrime256v1PublicKeyInfoToJwk(
kPrime256v1PublicKeyLength / 2),
kPrime256v1PublicKeyLength / 2);
std::string y_b64;
- base::Base64Encode(y, &y_b64);
+ base::Base64UrlEncode(y, base::Base64UrlEncodePolicy::OMIT_PADDING, &y_b64);
public_key_jwk->SetString("y", y_b64);
return true;
}
diff --git a/chromium/net/cert/jwk_serializer_openssl.cc b/chromium/net/cert/jwk_serializer_openssl.cc
index 67683fbc56d..f5afd4fb734 100644
--- a/chromium/net/cert/jwk_serializer_openssl.cc
+++ b/chromium/net/cert/jwk_serializer_openssl.cc
@@ -10,7 +10,7 @@
#include <openssl/evp.h>
#include <openssl/x509.h>
-#include "base/base64.h"
+#include "base/base64url.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/values.h"
@@ -74,11 +74,13 @@ bool ConvertEcKeyToJwk(EVP_PKEY* pkey,
public_key_jwk->SetString("crv", curve_name);
std::string x_b64;
- base::Base64Encode(x_bytes, &x_b64);
+ base::Base64UrlEncode(x_bytes, base::Base64UrlEncodePolicy::OMIT_PADDING,
+ &x_b64);
public_key_jwk->SetString("x", x_b64);
std::string y_b64;
- base::Base64Encode(y_bytes, &y_b64);
+ base::Base64UrlEncode(y_bytes, base::Base64UrlEncodePolicy::OMIT_PADDING,
+ &y_b64);
public_key_jwk->SetString("y", y_b64);
return true;
diff --git a/chromium/net/cert/jwk_serializer_unittest.cc b/chromium/net/cert/jwk_serializer_unittest.cc
index 6fa318f3637..ec974175c1c 100644
--- a/chromium/net/cert/jwk_serializer_unittest.cc
+++ b/chromium/net/cert/jwk_serializer_unittest.cc
@@ -4,12 +4,14 @@
#include "net/cert/jwk_serializer.h"
-#include "base/base64.h"
+#include "base/base64url.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
+namespace {
+
// This is the ASN.1 prefix for a P-256 public key. Specifically it's:
// SEQUENCE
// SEQUENCE
@@ -60,6 +62,15 @@ static const unsigned char kSpkiEcWithLeadingZero[] = {
0xc9, 0x1e, 0x31, 0x89, 0xe2, 0x62, 0xcb, 0x3f
};
+// Section 2 of RFC 7515 defines that an URL-safe base64 encoding must be used
+// with all trailing '=' characters omitted. Returns whether the |input|
+// contains any of the forbidden base64 characters (+, -, =).
+bool ContainsNonUrlSafeBase64Characters(base::StringPiece input) {
+ return input.find_first_of("+-=") != std::string::npos;
+}
+
+} // namespace
+
TEST(JwkSerializerTest, ConvertSpkiFromDerToJwkEc) {
base::StringPiece spki;
base::DictionaryValue public_key_jwk;
@@ -78,8 +89,11 @@ TEST(JwkSerializerTest, ConvertSpkiFromDerToJwkEc) {
EXPECT_STREQ("P-256", string_value.c_str());
EXPECT_TRUE(public_key_jwk.GetString("x", &string_value));
+ EXPECT_FALSE(ContainsNonUrlSafeBase64Characters(string_value));
std::string decoded_coordinate;
- EXPECT_TRUE(base::Base64Decode(string_value, &decoded_coordinate));
+ EXPECT_TRUE(base::Base64UrlDecode(
+ string_value, base::Base64UrlDecodePolicy::DISALLOW_PADDING,
+ &decoded_coordinate));
EXPECT_EQ(kEcCoordinateSize, decoded_coordinate.size());
EXPECT_EQ(0,
memcmp(decoded_coordinate.data(),
@@ -87,7 +101,10 @@ TEST(JwkSerializerTest, ConvertSpkiFromDerToJwkEc) {
kEcCoordinateSize));
EXPECT_TRUE(public_key_jwk.GetString("y", &string_value));
- EXPECT_TRUE(base::Base64Decode(string_value, &decoded_coordinate));
+ EXPECT_FALSE(ContainsNonUrlSafeBase64Characters(string_value));
+ EXPECT_TRUE(base::Base64UrlDecode(
+ string_value, base::Base64UrlDecodePolicy::DISALLOW_PADDING,
+ &decoded_coordinate));
EXPECT_EQ(kEcCoordinateSize, decoded_coordinate.size());
EXPECT_EQ(0,
memcmp(decoded_coordinate.data(),
@@ -106,7 +123,10 @@ TEST(JwkSerializerTest, ConvertSpkiFromDerToJwkEc) {
EXPECT_STREQ("P-256", string_value.c_str());
EXPECT_TRUE(public_key_jwk.GetString("x", &string_value));
- EXPECT_TRUE(base::Base64Decode(string_value, &decoded_coordinate));
+ EXPECT_FALSE(ContainsNonUrlSafeBase64Characters(string_value));
+ EXPECT_TRUE(base::Base64UrlDecode(
+ string_value, base::Base64UrlDecodePolicy::DISALLOW_PADDING,
+ &decoded_coordinate));
EXPECT_EQ(kEcCoordinateSize, decoded_coordinate.size());
EXPECT_EQ(0,
memcmp(decoded_coordinate.data(),
@@ -114,7 +134,10 @@ TEST(JwkSerializerTest, ConvertSpkiFromDerToJwkEc) {
kEcCoordinateSize));
EXPECT_TRUE(public_key_jwk.GetString("y", &string_value));
- EXPECT_TRUE(base::Base64Decode(string_value, &decoded_coordinate));
+ EXPECT_FALSE(ContainsNonUrlSafeBase64Characters(string_value));
+ EXPECT_TRUE(base::Base64UrlDecode(
+ string_value, base::Base64UrlDecodePolicy::DISALLOW_PADDING,
+ &decoded_coordinate));
EXPECT_EQ(kEcCoordinateSize, decoded_coordinate.size());
EXPECT_EQ(0, memcmp(
decoded_coordinate.data(),
diff --git a/chromium/net/cert/merkle_consistency_proof.cc b/chromium/net/cert/merkle_consistency_proof.cc
new file mode 100644
index 00000000000..02f2b181a3d
--- /dev/null
+++ b/chromium/net/cert/merkle_consistency_proof.cc
@@ -0,0 +1,27 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/merkle_consistency_proof.h"
+
+namespace net {
+
+namespace ct {
+
+MerkleConsistencyProof::MerkleConsistencyProof() {}
+
+MerkleConsistencyProof::MerkleConsistencyProof(
+ const std::string& log_id,
+ const std::vector<std::string>& proof_nodes,
+ uint64_t old_size,
+ uint64_t new_size)
+ : log_id(log_id),
+ nodes(proof_nodes),
+ first_tree_size(old_size),
+ second_tree_size(new_size) {}
+
+MerkleConsistencyProof::~MerkleConsistencyProof() {}
+
+} // namespace ct
+
+} // namespace net
diff --git a/chromium/net/cert/merkle_consistency_proof.h b/chromium/net/cert/merkle_consistency_proof.h
new file mode 100644
index 00000000000..48a70dc5eaa
--- /dev/null
+++ b/chromium/net/cert/merkle_consistency_proof.h
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_CERT_MERKLE_CONSISTENCY_PROOF_H_
+#define NET_CERT_MERKLE_CONSISTENCY_PROOF_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace ct {
+
+// Consistency proof between two STHs as defined in section 2.1.2. of RFC6962.
+struct NET_EXPORT MerkleConsistencyProof {
+ MerkleConsistencyProof();
+ MerkleConsistencyProof(const std::string& log_id,
+ const std::vector<std::string>& proof_nodes,
+ uint64_t old_size,
+ uint64_t new_size);
+ ~MerkleConsistencyProof();
+
+ // The origin of this proof.
+ std::string log_id;
+
+ // Consistency proof nodes.
+ std::vector<std::string> nodes;
+
+ // Size of the older tree.
+ uint64_t first_tree_size = 0;
+
+ // Size of the newer tree.
+ uint64_t second_tree_size = 0;
+};
+
+} // namespace ct
+
+} // namespace net
+
+#endif // NET_CERT_MERKLE_CONSISTENCY_PROOF_H_
diff --git a/chromium/net/cert/multi_log_ct_verifier.cc b/chromium/net/cert/multi_log_ct_verifier.cc
index 7e421b2980b..d3ff7375a9c 100644
--- a/chromium/net/cert/multi_log_ct_verifier.cc
+++ b/chromium/net/cert/multi_log_ct_verifier.cc
@@ -62,7 +62,7 @@ MultiLogCTVerifier::MultiLogCTVerifier() : observer_(nullptr) {
MultiLogCTVerifier::~MultiLogCTVerifier() { }
void MultiLogCTVerifier::AddLogs(
- const std::vector<scoped_refptr<CTLogVerifier>>& log_verifiers) {
+ const std::vector<scoped_refptr<const CTLogVerifier>>& log_verifiers) {
for (const auto& log_verifier : log_verifiers) {
VLOG(1) << "Adding CT log: " << log_verifier->description();
logs_[log_verifier->key_id()] = log_verifier;
diff --git a/chromium/net/cert/multi_log_ct_verifier.h b/chromium/net/cert/multi_log_ct_verifier.h
index 4546606112d..0d8667e6e7e 100644
--- a/chromium/net/cert/multi_log_ct_verifier.h
+++ b/chromium/net/cert/multi_log_ct_verifier.h
@@ -8,6 +8,7 @@
#include <map>
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/cert/ct_verifier.h"
@@ -23,15 +24,14 @@ class CTLogVerifier;
// A Certificate Transparency verifier that can verify Signed Certificate
// Timestamps from multiple logs.
-// There should be a global instance of this class and for all known logs,
-// AddLog should be called with a CTLogVerifier (which is created from the
-// log's public key).
+// It must be initialized with a list of logs by calling AddLogs.
class NET_EXPORT MultiLogCTVerifier : public CTVerifier {
public:
MultiLogCTVerifier();
~MultiLogCTVerifier() override;
- void AddLogs(const std::vector<scoped_refptr<CTLogVerifier>>& log_verifiers);
+ void AddLogs(
+ const std::vector<scoped_refptr<const CTLogVerifier>>& log_verifiers);
// CTVerifier implementation:
int Verify(X509Certificate* cert,
@@ -61,7 +61,7 @@ class NET_EXPORT MultiLogCTVerifier : public CTVerifier {
// Mapping from a log's ID to the verifier for this log.
// A log's ID is the SHA-256 of the log's key, as defined in section 3.2.
// of RFC6962.
- std::map<std::string, scoped_refptr<CTLogVerifier>> logs_;
+ std::map<std::string, scoped_refptr<const CTLogVerifier>> logs_;
Observer* observer_;
diff --git a/chromium/net/cert/multi_log_ct_verifier_unittest.cc b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
index 492c21a06d4..d5d609a8ec4 100644
--- a/chromium/net/cert/multi_log_ct_verifier_unittest.cc
+++ b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
@@ -50,7 +50,7 @@ class MockSCTObserver : public CTVerifier::Observer {
class MultiLogCTVerifierTest : public ::testing::Test {
public:
void SetUp() override {
- scoped_refptr<CTLogVerifier> log(CTLogVerifier::Create(
+ scoped_refptr<const CTLogVerifier> log(CTLogVerifier::Create(
ct::GetTestPublicKey(), kLogDescription, "https://ct.example.com"));
ASSERT_TRUE(log);
log_verifiers_.push_back(log);
@@ -206,7 +206,7 @@ class MultiLogCTVerifierTest : public ::testing::Test {
scoped_ptr<MultiLogCTVerifier> verifier_;
scoped_refptr<X509Certificate> chain_;
scoped_refptr<X509Certificate> embedded_sct_chain_;
- std::vector<scoped_refptr<CTLogVerifier>> log_verifiers_;
+ std::vector<scoped_refptr<const CTLogVerifier>> log_verifiers_;
};
TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCT) {
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.cc b/chromium/net/cert/multi_threaded_cert_verifier.cc
index aef8a75288d..23f1d874ec8 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.cc
+++ b/chromium/net/cert/multi_threaded_cert_verifier.cc
@@ -5,6 +5,7 @@
#include "net/cert/multi_threaded_cert_verifier.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -106,9 +107,9 @@ scoped_ptr<base::Value> CertVerifyResultCallback(
++it) {
hashes->AppendString(it->ToString());
}
- results->Set("public_key_hashes", hashes.Pass());
+ results->Set("public_key_hashes", std::move(hashes));
- return results.Pass();
+ return std::move(results);
}
} // namespace
@@ -329,7 +330,7 @@ class CertVerifierJob {
net_log_.source().ToEventParametersCallback());
requests_.Append(request.get());
- return request.Pass();
+ return request;
}
private:
@@ -468,7 +469,7 @@ int MultiThreadedCertVerifier::Verify(X509Certificate* cert,
scoped_ptr<CertVerifierRequest> request =
job->CreateRequest(callback, verify_result, net_log);
- *out_req = request.Pass();
+ *out_req = std::move(request);
return ERR_IO_PENDING;
}
@@ -483,7 +484,7 @@ MultiThreadedCertVerifier::RequestParams::RequestParams(
const std::string& ocsp_response_arg,
int flags_arg,
const CertificateList& additional_trust_anchors)
- : hostname(hostname_arg), flags(flags_arg) {
+ : hostname(hostname_arg), flags(flags_arg), start_time(base::Time::Now()) {
hash_values.reserve(3 + additional_trust_anchors.size());
SHA1HashValue ocsp_hash;
base::SHA1HashBytes(
@@ -522,10 +523,34 @@ void MultiThreadedCertVerifier::SaveResultToCache(const RequestParams& key,
const CachedResult& result) {
DCHECK(CalledOnValidThread());
- base::Time now = base::Time::Now();
+ // When caching, this uses the time that validation started as the
+ // beginning of the validity, rather than the time that it ended (aka
+ // base::Time::Now()), to account for the fact that during validation,
+ // the clock may have changed.
+ //
+ // If the clock has changed significantly, then this result will ideally
+ // be evicted and the next time the certificate is encountered, it will
+ // be revalidated.
+ //
+ // Because of this, it's possible for situations to arise where the
+ // clock was correct at the start of validation, changed to an
+ // incorrect time during validation (such as too far in the past or
+ // future), and then was reset to the correct time. If this happens,
+ // it's likely that the result will not be a valid/correct result,
+ // but will still be used from the cache because the clock was reset
+ // to the correct time after the (bad) validation result completed.
+ //
+ // However, this solution optimizes for the case where the clock is
+ // bad at the start of validation, and subsequently is corrected. In
+ // that situation, the result is also incorrect, but because the clock
+ // was corrected after validation, if the cache validity period was
+ // computed at the end of validation, it would continue to serve an
+ // invalid result for kTTLSecs.
+ const base::Time start_time = key.start_time;
cache_.Put(
- key, result, CacheValidityPeriod(now),
- CacheValidityPeriod(now, now + base::TimeDelta::FromSeconds(kTTLSecs)));
+ key, result, CacheValidityPeriod(start_time),
+ CacheValidityPeriod(start_time,
+ start_time + base::TimeDelta::FromSeconds(kTTLSecs)));
}
scoped_ptr<CertVerifierJob> MultiThreadedCertVerifier::RemoveJob(
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.h b/chromium/net/cert/multi_threaded_cert_verifier.h
index 96329702415..30234ff9bc2 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.h
+++ b/chromium/net/cert/multi_threaded_cert_verifier.h
@@ -5,7 +5,9 @@
#ifndef NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_
#define NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_
+#include <stddef.h>
#include <stdint.h>
+
#include <set>
#include <string>
#include <vector>
@@ -97,6 +99,10 @@ class NET_EXPORT_PRIVATE MultiThreadedCertVerifier
std::string hostname;
int flags;
std::vector<SHA1HashValue> hash_values;
+ // The time when verification started.
+ // Note: This uses base::Time, rather than base::TimeTicks, to
+ // account for system clock changes.
+ base::Time start_time;
};
// CachedResult contains the result of a certificate verification.
diff --git a/chromium/net/cert/nss_cert_database.cc b/chromium/net/cert/nss_cert_database.cc
index c9f013324a8..53ea7c79fc5 100644
--- a/chromium/net/cert/nss_cert_database.cc
+++ b/chromium/net/cert/nss_cert_database.cc
@@ -9,10 +9,12 @@
#include <keyhi.h>
#include <pk11pub.h>
#include <secmod.h>
+#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list_threadsafe.h"
#include "base/task_runner.h"
@@ -80,8 +82,8 @@ NSSCertDatabase::ImportCertFailure::~ImportCertFailure() {}
NSSCertDatabase::NSSCertDatabase(crypto::ScopedPK11Slot public_slot,
crypto::ScopedPK11Slot private_slot)
- : public_slot_(public_slot.Pass()),
- private_slot_(private_slot.Pass()),
+ : public_slot_(std::move(public_slot)),
+ private_slot_(std::move(private_slot)),
observer_list_(new base::ObserverListThreadSafe<Observer>),
weak_factory_(this) {
CHECK(public_slot_);
@@ -227,6 +229,18 @@ X509Certificate* NSSCertDatabase::FindRootInList(
return cert0;
}
+int NSSCertDatabase::ImportUserCert(const std::string& data) {
+ CertificateList certificates =
+ X509Certificate::CreateCertificateListFromBytes(
+ data.c_str(), data.size(), net::X509Certificate::FORMAT_AUTO);
+ int result = psm::ImportUserCert(certificates);
+
+ if (result == OK)
+ NotifyObserversOfCertAdded(NULL);
+
+ return result;
+}
+
bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates,
TrustBits trust_bits,
ImportCertFailureList* not_imported) {
diff --git a/chromium/net/cert/nss_cert_database.h b/chromium/net/cert/nss_cert_database.h
index 42447f95a73..ff96af029d4 100644
--- a/chromium/net/cert/nss_cert_database.h
+++ b/chromium/net/cert/nss_cert_database.h
@@ -6,6 +6,7 @@
#define NET_CERT_NSS_CERT_DATABASE_H_
#include <stdint.h>
+
#include <string>
#include <vector>
@@ -192,6 +193,11 @@ class NET_EXPORT NSSCertDatabase {
// TODO(mattm): improve this to handle any order.
X509Certificate* FindRootInList(const CertificateList& certificates) const;
+ // Import a user certificate. The private key for the user certificate must
+ // already be installed, otherwise we return ERR_NO_PRIVATE_KEY_FOR_CERT.
+ // Returns OK or a network error code.
+ int ImportUserCert(const std::string& data);
+
// Import CA certificates.
// Tries to import all the certificates given. The root will be trusted
// according to |trust_bits|. Any certificates that could not be imported
diff --git a/chromium/net/cert/nss_cert_database_chromeos.cc b/chromium/net/cert/nss_cert_database_chromeos.cc
index 63d969cd7ea..fda5307f4e3 100644
--- a/chromium/net/cert/nss_cert_database_chromeos.cc
+++ b/chromium/net/cert/nss_cert_database_chromeos.cc
@@ -6,8 +6,8 @@
#include <cert.h>
#include <pk11pub.h>
-
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/callback.h"
@@ -21,7 +21,7 @@ namespace net {
NSSCertDatabaseChromeOS::NSSCertDatabaseChromeOS(
crypto::ScopedPK11Slot public_slot,
crypto::ScopedPK11Slot private_slot)
- : NSSCertDatabase(public_slot.Pass(), private_slot.Pass()) {
+ : NSSCertDatabase(std::move(public_slot), std::move(private_slot)) {
// By default, don't use a system slot. Only if explicitly set by
// SetSystemSlot, the system slot will be used.
profile_filter_.Init(GetPublicSlot(),
@@ -33,7 +33,7 @@ NSSCertDatabaseChromeOS::~NSSCertDatabaseChromeOS() {}
void NSSCertDatabaseChromeOS::SetSystemSlot(
crypto::ScopedPK11Slot system_slot) {
- system_slot_ = system_slot.Pass();
+ system_slot_ = std::move(system_slot);
profile_filter_.Init(GetPublicSlot(), GetPrivateSlot(), GetSystemSlot());
}
@@ -42,7 +42,7 @@ void NSSCertDatabaseChromeOS::ListCertsSync(CertificateList* certs) {
}
void NSSCertDatabaseChromeOS::ListCerts(
- const base::Callback<void(scoped_ptr<CertificateList> certs)>& callback) {
+ const NSSCertDatabase::ListCertsCallback& callback) {
scoped_ptr<CertificateList> certs(new CertificateList());
// base::Pased will NULL out |certs|, so cache the underlying pointer here.
diff --git a/chromium/net/cert/nss_cert_database_chromeos.h b/chromium/net/cert/nss_cert_database_chromeos.h
index 930f9f23e28..4eb27a7fd48 100644
--- a/chromium/net/cert/nss_cert_database_chromeos.h
+++ b/chromium/net/cert/nss_cert_database_chromeos.h
@@ -6,6 +6,7 @@
#define NET_CERT_NSS_CERT_DATABASE_CHROMEOS_
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "crypto/scoped_nss_types.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/cert/nss_profile_filter_chromeos.cc b/chromium/net/cert/nss_profile_filter_chromeos.cc
index 8e4167a6e9b..40502e350f2 100644
--- a/chromium/net/cert/nss_profile_filter_chromeos.cc
+++ b/chromium/net/cert/nss_profile_filter_chromeos.cc
@@ -4,6 +4,8 @@
#include "net/cert/nss_profile_filter_chromeos.h"
+#include <utility>
+
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "net/cert/x509_certificate.h"
@@ -71,11 +73,11 @@ void NSSProfileFilterChromeOS::Init(crypto::ScopedPK11Slot public_slot,
// not release its reference, and the receiving object won't free
// its copy.
if (public_slot_.get() != public_slot.get())
- public_slot_ = public_slot.Pass();
+ public_slot_ = std::move(public_slot);
if (private_slot_.get() != private_slot.get())
- private_slot_ = private_slot.Pass();
+ private_slot_ = std::move(private_slot);
if (system_slot_.get() != system_slot.get())
- system_slot_ = system_slot.Pass();
+ system_slot_ = std::move(system_slot);
}
bool NSSProfileFilterChromeOS::IsModuleAllowed(PK11SlotInfo* slot) const {
diff --git a/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc b/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc
index d4051af1197..f0243d843da 100644
--- a/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc
+++ b/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc
@@ -7,6 +7,7 @@
#include <cert.h>
#include <pk11pub.h>
#include <secmod.h>
+#include <utility>
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_nss_types.h"
@@ -75,8 +76,7 @@ class NSSProfileFilterChromeOSTest : public testing::Test {
ASSERT_TRUE(private_slot_1.get());
profile_filter_1_.Init(
crypto::GetPublicSlotForChromeOSUser(user_1_.username_hash()),
- private_slot_1.Pass(),
- get_system_slot());
+ std::move(private_slot_1), get_system_slot());
profile_filter_1_copy_ = profile_filter_1_;
@@ -86,7 +86,7 @@ class NSSProfileFilterChromeOSTest : public testing::Test {
ASSERT_TRUE(private_slot_2.get());
profile_filter_2_.Init(
crypto::GetPublicSlotForChromeOSUser(user_2_.username_hash()),
- private_slot_2.Pass(),
+ std::move(private_slot_2),
crypto::ScopedPK11Slot() /* no system slot */);
certs_ = CreateCertificateListFromFile(GetTestCertsDirectory(),
diff --git a/chromium/net/cert/pem_tokenizer.h b/chromium/net/cert/pem_tokenizer.h
index bb41c446db7..808acbd34e8 100644
--- a/chromium/net/cert/pem_tokenizer.h
+++ b/chromium/net/cert/pem_tokenizer.h
@@ -5,9 +5,12 @@
#ifndef NET_CERT_PEM_TOKENIZER_H_
#define NET_CERT_PEM_TOKENIZER_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/cert/signed_certificate_timestamp.h b/chromium/net/cert/signed_certificate_timestamp.h
index 671c250fdc8..02697dc7a1f 100644
--- a/chromium/net/cert/signed_certificate_timestamp.h
+++ b/chromium/net/cert/signed_certificate_timestamp.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "net/base/hash_value.h"
diff --git a/chromium/net/cert/signed_tree_head.h b/chromium/net/cert/signed_tree_head.h
index fdbcdc48499..161373607b2 100644
--- a/chromium/net/cert/signed_tree_head.h
+++ b/chromium/net/cert/signed_tree_head.h
@@ -5,6 +5,8 @@
#ifndef NET_CERT_SIGNED_TREE_HEAD_H_
#define NET_CERT_SIGNED_TREE_HEAD_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
diff --git a/chromium/net/cert/test_root_certs.h b/chromium/net/cert/test_root_certs.h
index 32eb999ec81..a7d0fd212de 100644
--- a/chromium/net/cert/test_root_certs.h
+++ b/chromium/net/cert/test_root_certs.h
@@ -6,6 +6,7 @@
#define NET_CERT_TEST_ROOT_CERTS_H_
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "build/build_config.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/cert/test_root_certs_nss.cc b/chromium/net/cert/test_root_certs_nss.cc
index f7d855c54b1..bcd4add1e86 100644
--- a/chromium/net/cert/test_root_certs_nss.cc
+++ b/chromium/net/cert/test_root_certs_nss.cc
@@ -7,6 +7,7 @@
#include <cert.h>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/stl_util.h"
#include "crypto/nss_util.h"
#include "net/cert/x509_certificate.h"
diff --git a/chromium/net/cert/test_root_certs_win.cc b/chromium/net/cert/test_root_certs_win.cc
index a83ac047905..67bf1b09f75 100644
--- a/chromium/net/cert/test_root_certs_win.cc
+++ b/chromium/net/cert/test_root_certs_win.cc
@@ -100,8 +100,8 @@ BOOL WINAPI InterceptedOpenStoreW(LPCSTR store_provider,
// If the high word is all zeroes, then |store_provider| is a numeric ID.
// Otherwise, it's a pointer to a null-terminated ASCII string. See the
// documentation for CryptGetOIDFunctionAddress for more information.
- uint32_t store_as_uint = reinterpret_cast<uint32_t>(store_provider);
- if (store_as_uint > 0xFFFF || store_provider != CERT_STORE_PROV_SYSTEM_W ||
+ uintptr_t store_as_uintptr = reinterpret_cast<uintptr_t>(store_provider);
+ if (store_as_uintptr > 0xFFFF || store_provider != CERT_STORE_PROV_SYSTEM_W ||
!g_capi_injector.Get().original_function)
return FALSE;
@@ -148,7 +148,7 @@ bool TestRootCerts::Add(X509Certificate* certificate) {
CERT_STORE_ADD_NEW, NULL);
if (!ok) {
// If the certificate is already added, return successfully.
- return GetLastError() == CRYPT_E_EXISTS;
+ return GetLastError() == static_cast<DWORD>(CRYPT_E_EXISTS);
}
empty_ = false;
diff --git a/chromium/net/cert/x509_cert_types.h b/chromium/net/cert/x509_cert_types.h
index 4e9340a4c0d..d2a55fe4b54 100644
--- a/chromium/net/cert/x509_cert_types.h
+++ b/chromium/net/cert/x509_cert_types.h
@@ -5,6 +5,7 @@
#ifndef NET_CERT_X509_CERT_TYPES_H_
#define NET_CERT_X509_CERT_TYPES_H_
+#include <stddef.h>
#include <string.h>
#include <map>
diff --git a/chromium/net/cert/x509_certificate.cc b/chromium/net/cert/x509_certificate.cc
index dc3cd80c7fd..d925ce6b490 100644
--- a/chromium/net/cert/x509_certificate.cc
+++ b/chromium/net/cert/x509_certificate.cc
@@ -4,6 +4,7 @@
#include "net/cert/x509_certificate.h"
+#include <limits.h>
#include <stdlib.h>
#include <algorithm>
@@ -14,6 +15,7 @@
#include "base/base64.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram_macros.h"
@@ -301,7 +303,7 @@ X509Certificate* X509Certificate::CreateFromDERCertChain(
// static
X509Certificate* X509Certificate::CreateFromBytes(const char* data,
- int length) {
+ size_t length) {
OSCertHandle cert_handle = CreateOSCertHandleFromBytes(data, length);
if (!cert_handle)
return NULL;
@@ -399,7 +401,9 @@ X509Certificate* X509Certificate::CreateFromPickle(
// static
CertificateList X509Certificate::CreateCertificateListFromBytes(
- const char* data, int length, int format) {
+ const char* data,
+ size_t length,
+ int format) {
OSCertHandles certificates;
// Check to see if it is in a PEM-encoded form. This check is performed
diff --git a/chromium/net/cert/x509_certificate.h b/chromium/net/cert/x509_certificate.h
index 3cd1ad77a4d..c22a0d50d24 100644
--- a/chromium/net/cert/x509_certificate.h
+++ b/chromium/net/cert/x509_certificate.h
@@ -5,12 +5,14 @@
#ifndef NET_CERT_X509_CERTIFICATE_H_
#define NET_CERT_X509_CERTIFICATE_H_
+#include <stddef.h>
#include <string.h>
#include <string>
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
@@ -155,7 +157,7 @@ class NET_EXPORT X509Certificate
// Returns NULL on failure.
//
// The returned pointer must be stored in a scoped_refptr<X509Certificate>.
- static X509Certificate* CreateFromBytes(const char* data, int length);
+ static X509Certificate* CreateFromBytes(const char* data, size_t length);
#if defined(USE_NSS_CERTS)
// Create an X509Certificate from the DER-encoded representation.
@@ -166,7 +168,7 @@ class NET_EXPORT X509Certificate
// This function differs from CreateFromBytes in that it takes a
// nickname that will be used when the certificate is imported into PKCS#11.
static X509Certificate* CreateFromBytesWithNickname(const char* data,
- int length,
+ size_t length,
const char* nickname);
// The default nickname of the certificate, based on the certificate type
@@ -189,7 +191,7 @@ class NET_EXPORT X509Certificate
// certificates may have been serialized as. If an error occurs, an empty
// collection will be returned.
static CertificateList CreateCertificateListFromBytes(const char* data,
- int length,
+ size_t length,
int format);
// Appends a representation of this object to the given pickle.
@@ -362,7 +364,7 @@ class NET_EXPORT X509Certificate
// Creates an OS certificate handle from the DER-encoded representation.
// Returns NULL on failure.
static OSCertHandle CreateOSCertHandleFromBytes(const char* data,
- int length);
+ size_t length);
#if defined(USE_NSS_CERTS)
// Creates an OS certificate handle from the DER-encoded representation.
@@ -370,16 +372,15 @@ class NET_EXPORT X509Certificate
// non-NULL.
static OSCertHandle CreateOSCertHandleFromBytesWithNickname(
const char* data,
- int length,
+ size_t length,
const char* nickname);
#endif
// Creates all possible OS certificate handles from |data| encoded in a
// specific |format|. Returns an empty collection on failure.
- static OSCertHandles CreateOSCertHandlesFromBytes(
- const char* data,
- int length,
- Format format);
+ static OSCertHandles CreateOSCertHandlesFromBytes(const char* data,
+ size_t length,
+ Format format);
// Duplicates (or adds a reference to) an OS certificate handle.
static OSCertHandle DupOSCertHandle(OSCertHandle cert_handle);
diff --git a/chromium/net/cert/x509_certificate_ios.cc b/chromium/net/cert/x509_certificate_ios.cc
index 9c3b333724e..d458589872d 100644
--- a/chromium/net/cert/x509_certificate_ios.cc
+++ b/chromium/net/cert/x509_certificate_ios.cc
@@ -24,6 +24,7 @@
#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_ptr.h"
+#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/time/time.h"
#include "crypto/nss_util.h"
@@ -131,18 +132,19 @@ bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
- const char* data, int length) {
+ const char* data,
+ size_t length) {
ScopedCFTypeRef<CFDataRef> cert_data(CFDataCreateWithBytesNoCopy(
- kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data), length,
- kCFAllocatorNull));
+ kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data),
+ base::checked_cast<CFIndex>(length), kCFAllocatorNull));
if (!cert_data)
- return NULL;
+ return nullptr;
OSCertHandle cert_handle = SecCertificateCreateWithData(NULL, cert_data);
if (!cert_handle)
- return NULL;
+ return nullptr;
if (!IsValidOSCertHandle(cert_handle)) {
CFRelease(cert_handle);
- return NULL;
+ return nullptr;
}
return cert_handle;
}
@@ -150,7 +152,7 @@ X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
// static
X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
const char* data,
- int length,
+ size_t length,
Format format) {
return x509_util::CreateOSCertHandlesFromBytes(data, length, format);
}
diff --git a/chromium/net/cert/x509_certificate_known_roots_mac.h b/chromium/net/cert/x509_certificate_known_roots_mac.h
deleted file mode 100644
index fb5d0f5b9b6..00000000000
--- a/chromium/net/cert/x509_certificate_known_roots_mac.h
+++ /dev/null
@@ -1,560 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_CERT_X509_CERTIFICATE_KNOWN_ROOTS_MAC_H_
-#define NET_CERT_X509_CERTIFICATE_KNOWN_ROOTS_MAC_H_
-
-// This is the set of Apple trusted roots from OS X 10.6.0 to
-// OS X 10.10.1, available at http://opensource.apple.com
-//
-// Note that these *are not* trust anchors for Chromium. They are only used to
-// distinguish `real' root CAs from roots that were user-installed.
-static uint8_t kKnownRootCertSHA1Hashes[][20] = {
- {0x01, 0x68, 0x97, 0xe1, 0xa0, 0xb8, 0xf2, 0xc3, 0xb1, 0x34,
- 0x66, 0x5c, 0x20, 0xa7, 0x27, 0xb7, 0xa1, 0x58, 0xe2, 0x8f},
- {0x02, 0x72, 0x68, 0x29, 0x3e, 0x5f, 0x5d, 0x17, 0xaa, 0xa4,
- 0xb3, 0xc3, 0xe6, 0x36, 0x1e, 0x1f, 0x92, 0x57, 0x5e, 0xaa},
- {0x02, 0xfa, 0xf3, 0xe2, 0x91, 0x43, 0x54, 0x68, 0x60, 0x78,
- 0x57, 0x69, 0x4d, 0xf5, 0xe4, 0x5b, 0x68, 0x85, 0x18, 0x68},
- {0x03, 0x9e, 0xed, 0xb8, 0x0b, 0xe7, 0xa0, 0x3c, 0x69, 0x53,
- 0x89, 0x3b, 0x20, 0xd2, 0xd9, 0x32, 0x3a, 0x4c, 0x2a, 0xfd},
- {0x04, 0x83, 0xed, 0x33, 0x99, 0xac, 0x36, 0x08, 0x05, 0x87,
- 0x22, 0xed, 0xbc, 0x5e, 0x46, 0x00, 0xe3, 0xbe, 0xf9, 0xd7},
- {0x05, 0x63, 0xb8, 0x63, 0x0d, 0x62, 0xd7, 0x5a, 0xbb, 0xc8,
- 0xab, 0x1e, 0x4b, 0xdf, 0xb5, 0xa8, 0x99, 0xb2, 0x4d, 0x43},
- {0x06, 0x08, 0x3f, 0x59, 0x3f, 0x15, 0xa1, 0x04, 0xa0, 0x69,
- 0xa4, 0x6b, 0xa9, 0x03, 0xd0, 0x06, 0xb7, 0x97, 0x09, 0x91},
- {0x07, 0x47, 0x22, 0x01, 0x99, 0xce, 0x74, 0xb9, 0x7c, 0xb0,
- 0x3d, 0x79, 0xb2, 0x64, 0xa2, 0xc8, 0x55, 0xe9, 0x33, 0xff},
- {0x07, 0xe0, 0x32, 0xe0, 0x20, 0xb7, 0x2c, 0x3f, 0x19, 0x2f,
- 0x06, 0x28, 0xa2, 0x59, 0x3a, 0x19, 0xa7, 0x0f, 0x06, 0x9e},
- {0x08, 0x64, 0x18, 0xe9, 0x06, 0xce, 0xe8, 0x9c, 0x23, 0x53,
- 0xb6, 0xe2, 0x7f, 0xbd, 0x9e, 0x74, 0x39, 0xf7, 0x63, 0x16},
- {0x09, 0x3c, 0x61, 0xf3, 0x8b, 0x8b, 0xdc, 0x7d, 0x55, 0xdf,
- 0x75, 0x38, 0x02, 0x05, 0x00, 0xe1, 0x25, 0xf5, 0xc8, 0x36},
- {0x0b, 0x77, 0xbe, 0xbb, 0xcb, 0x7a, 0xa2, 0x47, 0x05, 0xde,
- 0xcc, 0x0f, 0xbd, 0x6a, 0x02, 0xfc, 0x7a, 0xbd, 0x9b, 0x52},
- {0x0b, 0x97, 0x2c, 0x9e, 0xa6, 0xe7, 0xcc, 0x58, 0xd9, 0x3b,
- 0x20, 0xbf, 0x71, 0xec, 0x41, 0x2e, 0x72, 0x09, 0xfa, 0xbf},
- {0x0c, 0x08, 0xb8, 0x4a, 0x1f, 0x26, 0xf5, 0x05, 0x49, 0xda,
- 0xab, 0x36, 0x33, 0x08, 0xd3, 0x56, 0x52, 0x68, 0xf1, 0x60},
- {0x10, 0x1d, 0xfa, 0x3f, 0xd5, 0x0b, 0xcb, 0xbb, 0x9b, 0xb5,
- 0x60, 0x0c, 0x19, 0x55, 0xa4, 0x1a, 0xf4, 0x73, 0x3a, 0x04},
- {0x10, 0xf1, 0x93, 0xf3, 0x40, 0xac, 0x91, 0xd6, 0xde, 0x5f,
- 0x1e, 0xdc, 0x00, 0x62, 0x47, 0xc4, 0xf2, 0x5d, 0x96, 0x71},
- {0x12, 0x1f, 0x9f, 0xac, 0x62, 0x9f, 0xf1, 0x33, 0x88, 0x7c,
- 0x1b, 0x45, 0x64, 0x0c, 0x1a, 0x03, 0x4f, 0x03, 0xf2, 0x8f},
- {0x13, 0x2d, 0x0d, 0x45, 0x53, 0x4b, 0x69, 0x97, 0xcd, 0xb2,
- 0xd5, 0xc3, 0x39, 0xe2, 0x55, 0x76, 0x60, 0x9b, 0x5c, 0xc6},
- {0x14, 0x69, 0x89, 0x89, 0xbf, 0xb2, 0x95, 0x09, 0x21, 0xa4,
- 0x24, 0x52, 0x64, 0x6d, 0x37, 0xb5, 0x0a, 0xf0, 0x17, 0xe2},
- {0x17, 0xc0, 0xc5, 0x9a, 0xb5, 0xd8, 0xd5, 0x85, 0x20, 0x43,
- 0xe8, 0xec, 0x69, 0x2c, 0x40, 0x9d, 0x80, 0x62, 0xaa, 0x53},
- {0x1b, 0x4b, 0x39, 0x61, 0x26, 0x27, 0x6b, 0x64, 0x91, 0xa2,
- 0x68, 0x6d, 0xd7, 0x02, 0x43, 0x21, 0x2d, 0x1f, 0x1d, 0x96},
- {0x1b, 0x8e, 0xea, 0x57, 0x96, 0x29, 0x1a, 0xc9, 0x39, 0xea,
- 0xb8, 0x0a, 0x81, 0x1a, 0x73, 0x73, 0xc0, 0x93, 0x79, 0x67},
- {0x1f, 0x24, 0xc6, 0x30, 0xcd, 0xa4, 0x18, 0xef, 0x20, 0x69,
- 0xff, 0xad, 0x4f, 0xdd, 0x5f, 0x46, 0x3a, 0x1b, 0x69, 0xaa},
- {0x1f, 0x49, 0x14, 0xf7, 0xd8, 0x74, 0x95, 0x1d, 0xdd, 0xae,
- 0x02, 0xc0, 0xbe, 0xfd, 0x3a, 0x2d, 0x82, 0x75, 0x51, 0x85},
- {0x20, 0x42, 0x85, 0xdc, 0xf7, 0xeb, 0x76, 0x41, 0x95, 0x57,
- 0x8e, 0x13, 0x6b, 0xd4, 0xb7, 0xd1, 0xe9, 0x8e, 0x46, 0xa5},
- {0x20, 0x99, 0x00, 0xb6, 0x3d, 0x95, 0x57, 0x28, 0x14, 0x0c,
- 0xd1, 0x36, 0x22, 0xd8, 0xc6, 0x87, 0xa4, 0xeb, 0x00, 0x85},
- {0x20, 0xce, 0xb1, 0xf0, 0xf5, 0x1c, 0x0e, 0x19, 0xa9, 0xf3,
- 0x8d, 0xb1, 0xaa, 0x8e, 0x03, 0x8c, 0xaa, 0x7a, 0xc7, 0x01},
- {0x20, 0xd8, 0x06, 0x40, 0xdf, 0x9b, 0x25, 0xf5, 0x12, 0x25,
- 0x3a, 0x11, 0xea, 0xf7, 0x59, 0x8a, 0xeb, 0x14, 0xb5, 0x47},
- {0x21, 0xfc, 0xbd, 0x8e, 0x7f, 0x6c, 0xaf, 0x05, 0x1b, 0xd1,
- 0xb3, 0x43, 0xec, 0xa8, 0xe7, 0x61, 0x47, 0xf2, 0x0f, 0x8a},
- {0x22, 0xd5, 0xd8, 0xdf, 0x8f, 0x02, 0x31, 0xd1, 0x8d, 0xf7,
- 0x9d, 0xb7, 0xcf, 0x8a, 0x2d, 0x64, 0xc9, 0x3f, 0x6c, 0x3a},
- {0x23, 0xe5, 0x94, 0x94, 0x51, 0x95, 0xf2, 0x41, 0x48, 0x03,
- 0xb4, 0xd5, 0x64, 0xd2, 0xa3, 0xa3, 0xf5, 0xd8, 0x8b, 0x8c},
- {0x25, 0x01, 0x90, 0x19, 0xcf, 0xfb, 0xd9, 0x99, 0x1c, 0xb7,
- 0x68, 0x25, 0x74, 0x8d, 0x94, 0x5f, 0x30, 0x93, 0x95, 0x42},
- {0x25, 0x3f, 0x77, 0x5b, 0x0e, 0x77, 0x97, 0xab, 0x64, 0x5f,
- 0x15, 0x91, 0x55, 0x97, 0xc3, 0x9e, 0x26, 0x36, 0x31, 0xd1},
- {0x26, 0xa1, 0x6c, 0x23, 0x5a, 0x24, 0x72, 0x22, 0x9b, 0x23,
- 0x62, 0x80, 0x25, 0xbc, 0x80, 0x97, 0xc8, 0x85, 0x24, 0xa1},
- {0x26, 0xca, 0xff, 0x09, 0xa7, 0xaf, 0xba, 0xe9, 0x68, 0x10,
- 0xcf, 0xff, 0x82, 0x1a, 0x94, 0x32, 0x6d, 0x28, 0x45, 0xaa},
- {0x27, 0x0c, 0x50, 0x0c, 0xc6, 0xc8, 0x6e, 0xcb, 0x19, 0x80,
- 0xbc, 0x13, 0x05, 0x43, 0x9e, 0xd2, 0x82, 0x48, 0x0b, 0xe3},
- {0x27, 0x3e, 0xe1, 0x24, 0x57, 0xfd, 0xc4, 0xf9, 0x0c, 0x55,
- 0xe8, 0x2b, 0x56, 0x16, 0x7f, 0x62, 0xf5, 0x32, 0xe5, 0x47},
- {0x27, 0x96, 0xba, 0xe6, 0x3f, 0x18, 0x01, 0xe2, 0x77, 0x26,
- 0x1b, 0xa0, 0xd7, 0x77, 0x70, 0x02, 0x8f, 0x20, 0xee, 0xe4},
- {0x29, 0x36, 0x21, 0x02, 0x8b, 0x20, 0xed, 0x02, 0xf5, 0x66,
- 0xc5, 0x32, 0xd1, 0xd6, 0xed, 0x90, 0x9f, 0x45, 0x00, 0x2f},
- {0x29, 0x64, 0xb6, 0x86, 0x13, 0x5b, 0x5d, 0xfd, 0xdd, 0x32,
- 0x53, 0xa8, 0x9b, 0xbc, 0x24, 0xd7, 0x4b, 0x08, 0xc6, 0x4d},
- {0x2a, 0xb6, 0x28, 0x48, 0x5e, 0x78, 0xfb, 0xf3, 0xad, 0x9e,
- 0x79, 0x10, 0xdd, 0x6b, 0xdf, 0x99, 0x72, 0x2c, 0x96, 0xe5},
- {0x2a, 0xc8, 0xd5, 0x8b, 0x57, 0xce, 0xbf, 0x2f, 0x49, 0xaf,
- 0xf2, 0xfc, 0x76, 0x8f, 0x51, 0x14, 0x62, 0x90, 0x7a, 0x41},
- {0x2b, 0x84, 0xbf, 0xbb, 0x34, 0xee, 0x2e, 0xf9, 0x49, 0xfe,
- 0x1c, 0xbe, 0x30, 0xaa, 0x02, 0x64, 0x16, 0xeb, 0x22, 0x16},
- {0x2c, 0xeb, 0x05, 0x34, 0xad, 0x59, 0x27, 0x18, 0x0d, 0x34,
- 0x8c, 0x5f, 0x0e, 0x05, 0x6d, 0x38, 0x2b, 0x50, 0x82, 0x87},
- {0x2d, 0xc7, 0xab, 0xf6, 0x7e, 0x9e, 0x63, 0x9a, 0x22, 0xdb,
- 0xdf, 0x4e, 0xee, 0x9b, 0xc5, 0x2a, 0x48, 0xa2, 0xcc, 0x2d},
- {0x2d, 0xff, 0x63, 0x36, 0xe3, 0x3a, 0x48, 0x29, 0xaa, 0x00,
- 0x9f, 0x01, 0xa1, 0x80, 0x1e, 0xe7, 0xeb, 0xa5, 0x82, 0xbb},
- {0x2e, 0x14, 0xda, 0xec, 0x28, 0xf0, 0xfa, 0x1e, 0x8e, 0x38,
- 0x9a, 0x4e, 0xab, 0xeb, 0x26, 0xc0, 0x0a, 0xd3, 0x83, 0xc3},
- {0x2e, 0xf6, 0x4b, 0xba, 0x77, 0xdd, 0x37, 0x79, 0xe9, 0x1f,
- 0xbd, 0x5a, 0x4e, 0xee, 0x63, 0x3c, 0x8a, 0x36, 0xa5, 0xb1},
- {0x2f, 0x17, 0x3f, 0x7d, 0xe9, 0x96, 0x67, 0xaf, 0xa5, 0x7a,
- 0xf8, 0x0a, 0xa2, 0xd1, 0xb1, 0x2f, 0xac, 0x83, 0x03, 0x38},
- {0x2f, 0x78, 0x3d, 0x25, 0x52, 0x18, 0xa7, 0x4a, 0x65, 0x39,
- 0x71, 0xb5, 0x2c, 0xa2, 0x9c, 0x45, 0x15, 0x6f, 0xe9, 0x19},
- {0x30, 0x77, 0x9e, 0x93, 0x15, 0x02, 0x2e, 0x94, 0x85, 0x6a,
- 0x3f, 0xf8, 0xbc, 0xf8, 0x15, 0xb0, 0x82, 0xf9, 0xae, 0xfd},
- {0x31, 0x7a, 0x2a, 0xd0, 0x7f, 0x2b, 0x33, 0x5e, 0xf5, 0xa1,
- 0xc3, 0x4e, 0x4b, 0x57, 0xe8, 0xb7, 0xd8, 0xf1, 0xfc, 0xa6},
- {0x31, 0xf1, 0xfd, 0x68, 0x22, 0x63, 0x20, 0xee, 0xc6, 0x3b,
- 0x3f, 0x9d, 0xea, 0x4a, 0x3e, 0x53, 0x7c, 0x7c, 0x39, 0x17},
- {0x32, 0x3c, 0x11, 0x8e, 0x1b, 0xf7, 0xb8, 0xb6, 0x52, 0x54,
- 0xe2, 0xe2, 0x10, 0x0d, 0xd6, 0x02, 0x90, 0x37, 0xf0, 0x96},
- {0x33, 0x9b, 0x6b, 0x14, 0x50, 0x24, 0x9b, 0x55, 0x7a, 0x01,
- 0x87, 0x72, 0x84, 0xd9, 0xe0, 0x2f, 0xc3, 0xd2, 0xd8, 0xe9},
- {0x36, 0x79, 0xca, 0x35, 0x66, 0x87, 0x72, 0x30, 0x4d, 0x30,
- 0xa5, 0xfb, 0x87, 0x3b, 0x0f, 0xa7, 0x7b, 0xb7, 0x0d, 0x54},
- {0x36, 0x7d, 0x4b, 0x3b, 0x4f, 0xcb, 0xbc, 0x0b, 0x76, 0x7b,
- 0x2e, 0xc0, 0xcd, 0xb2, 0xa3, 0x6e, 0xab, 0x71, 0xa4, 0xeb},
- {0x36, 0x86, 0x35, 0x63, 0xfd, 0x51, 0x28, 0xc7, 0xbe, 0xa6,
- 0xf0, 0x05, 0xcf, 0xe9, 0xb4, 0x36, 0x68, 0x08, 0x6c, 0xce},
- {0x36, 0xb1, 0x2b, 0x49, 0xf9, 0x81, 0x9e, 0xd7, 0x4c, 0x9e,
- 0xbc, 0x38, 0x0f, 0xc6, 0x56, 0x8f, 0x5d, 0xac, 0xb2, 0xf7},
- {0x37, 0xf7, 0x6d, 0xe6, 0x07, 0x7c, 0x90, 0xc5, 0xb1, 0x3e,
- 0x93, 0x1a, 0xb7, 0x41, 0x10, 0xb4, 0xf2, 0xe4, 0x9a, 0x27},
- {0x39, 0x21, 0xc1, 0x15, 0xc1, 0x5d, 0x0e, 0xca, 0x5c, 0xcb,
- 0x5b, 0xc4, 0xf0, 0x7d, 0x21, 0xd8, 0x05, 0x0b, 0x56, 0x6a},
- {0x39, 0x4f, 0xf6, 0x85, 0x0b, 0x06, 0xbe, 0x52, 0xe5, 0x18,
- 0x56, 0xcc, 0x10, 0xe1, 0x80, 0xe8, 0x82, 0xb3, 0x85, 0xcc},
- {0x3a, 0x32, 0xef, 0x7b, 0x9a, 0xb8, 0x36, 0xf8, 0x37, 0x18,
- 0x1a, 0x4c, 0xef, 0xa3, 0x55, 0xc6, 0x46, 0x67, 0xac, 0xbf},
- {0x3a, 0x44, 0x73, 0x5a, 0xe5, 0x81, 0x90, 0x1f, 0x24, 0x86,
- 0x61, 0x46, 0x1e, 0x3b, 0x9c, 0xc4, 0x5f, 0xf5, 0x3a, 0x1b},
- {0x3b, 0x16, 0x6c, 0x3b, 0x7d, 0xc4, 0xb7, 0x51, 0xc9, 0xfe,
- 0x2a, 0xfa, 0xb9, 0x13, 0x56, 0x41, 0xe3, 0x88, 0xe1, 0x86},
- {0x3b, 0xc0, 0x38, 0x0b, 0x33, 0xc3, 0xf6, 0xa6, 0x0c, 0x86,
- 0x15, 0x22, 0x93, 0xd9, 0xdf, 0xf5, 0x4b, 0x81, 0xc0, 0x04},
- {0x3b, 0xc4, 0x9f, 0x48, 0xf8, 0xf3, 0x73, 0xa0, 0x9c, 0x1e,
- 0xbd, 0xf8, 0x5b, 0xb1, 0xc3, 0x65, 0xc7, 0xd8, 0x11, 0xb3},
- {0x3e, 0x2b, 0xf7, 0xf2, 0x03, 0x1b, 0x96, 0xf3, 0x8c, 0xe6,
- 0xc4, 0xd8, 0xa8, 0x5d, 0x3e, 0x2d, 0x58, 0x47, 0x6a, 0x0f},
- {0x3e, 0x5d, 0x35, 0x8f, 0x28, 0x3a, 0x0f, 0x64, 0x7c, 0x1c,
- 0x92, 0x7f, 0xfb, 0xaa, 0xd4, 0x85, 0x2d, 0x99, 0x72, 0x56},
- {0x3f, 0x01, 0x8e, 0x6f, 0xe3, 0x36, 0x09, 0x6a, 0x79, 0x1b,
- 0x81, 0xe7, 0x69, 0xbe, 0x70, 0x1a, 0xaf, 0x21, 0xe3, 0x07},
- {0x40, 0x54, 0xda, 0x6f, 0x1c, 0x3f, 0x40, 0x74, 0xac, 0xed,
- 0x0f, 0xec, 0xcd, 0xdb, 0x79, 0xd1, 0x53, 0xfb, 0x90, 0x1d},
- {0x40, 0x9d, 0x4b, 0xd9, 0x17, 0xb5, 0x5c, 0x27, 0xb6, 0x9b,
- 0x64, 0xcb, 0x98, 0x22, 0x44, 0x0d, 0xcd, 0x09, 0xb8, 0x89},
- {0x40, 0xaa, 0x38, 0x73, 0x1b, 0xd1, 0x89, 0xf9, 0xcd, 0xb5,
- 0xb9, 0xdc, 0x35, 0xe2, 0x13, 0x6f, 0x38, 0x77, 0x7a, 0xf4},
- {0x40, 0xb3, 0x31, 0xa0, 0xe9, 0xbf, 0xe8, 0x55, 0xbc, 0x39,
- 0x93, 0xca, 0x70, 0x4f, 0x4e, 0xc2, 0x51, 0xd4, 0x1d, 0x8f},
- {0x40, 0xe7, 0x8c, 0x1d, 0x52, 0x3d, 0x1c, 0xd9, 0x95, 0x4f,
- 0xac, 0x1a, 0x1a, 0xb3, 0xbd, 0x3c, 0xba, 0xa1, 0x5b, 0xfc},
- {0x42, 0xf8, 0x18, 0xe8, 0x33, 0x06, 0x3b, 0xf5, 0x16, 0xc6,
- 0x61, 0x8c, 0x1e, 0x60, 0xfd, 0x0f, 0x35, 0xc4, 0x76, 0x21},
- {0x43, 0x13, 0xbb, 0x96, 0xf1, 0xd5, 0x86, 0x9b, 0xc1, 0x4e,
- 0x6a, 0x92, 0xf6, 0xcf, 0xf6, 0x34, 0x69, 0x87, 0x82, 0x37},
- {0x43, 0xd9, 0xbc, 0xb5, 0x68, 0xe0, 0x39, 0xd0, 0x73, 0xa7,
- 0x4a, 0x71, 0xd8, 0x51, 0x1f, 0x74, 0x76, 0x08, 0x9c, 0xc3},
- {0x43, 0xf9, 0xb1, 0x10, 0xd5, 0xba, 0xfd, 0x48, 0x22, 0x52,
- 0x31, 0xb0, 0xd0, 0x08, 0x2b, 0x37, 0x2f, 0xef, 0x9a, 0x54},
- {0x47, 0xbe, 0xab, 0xc9, 0x22, 0xea, 0xe8, 0x0e, 0x78, 0x78,
- 0x34, 0x62, 0xa7, 0x9f, 0x45, 0xc2, 0x54, 0xfd, 0xe6, 0x8b},
- {0x48, 0x12, 0xbd, 0x92, 0x3c, 0xa8, 0xc4, 0x39, 0x06, 0xe7,
- 0x30, 0x6d, 0x27, 0x96, 0xe6, 0xa4, 0xcf, 0x22, 0x2e, 0x7d},
- {0x49, 0x0a, 0x75, 0x74, 0xde, 0x87, 0x0a, 0x47, 0xfe, 0x58,
- 0xee, 0xf6, 0xc7, 0x6b, 0xeb, 0xc6, 0x0b, 0x12, 0x40, 0x99},
- {0x4a, 0x3f, 0x8d, 0x6b, 0xdc, 0x0e, 0x1e, 0xcf, 0xcd, 0x72,
- 0xe3, 0x77, 0xde, 0xf2, 0xd7, 0xff, 0x92, 0xc1, 0x9b, 0xc7},
- {0x4a, 0x65, 0xd5, 0xf4, 0x1d, 0xef, 0x39, 0xb8, 0xb8, 0x90,
- 0x4a, 0x4a, 0xd3, 0x64, 0x81, 0x33, 0xcf, 0xc7, 0xa1, 0xd1},
- {0x4a, 0xbd, 0xee, 0xec, 0x95, 0x0d, 0x35, 0x9c, 0x89, 0xae,
- 0xc7, 0x52, 0xa1, 0x2c, 0x5b, 0x29, 0xf6, 0xd6, 0xaa, 0x0c},
- {0x4a, 0xd4, 0x4d, 0x4d, 0x81, 0x2e, 0x42, 0x23, 0x2f, 0xe0,
- 0x38, 0x76, 0x4c, 0x7b, 0x0c, 0xeb, 0x46, 0x6e, 0xef, 0x96},
- {0x4c, 0xab, 0x31, 0xa1, 0x28, 0x34, 0x02, 0x52, 0xbc, 0xb4,
- 0x67, 0xd6, 0x2a, 0x99, 0x63, 0x1b, 0x21, 0x77, 0x20, 0x50},
- {0x4d, 0x23, 0x78, 0xec, 0x91, 0x95, 0x39, 0xb5, 0x00, 0x7f,
- 0x75, 0x8f, 0x03, 0x3b, 0x21, 0x1e, 0xc5, 0x4d, 0x8b, 0xcf},
- {0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58,
- 0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5},
- {0x4f, 0x99, 0xaa, 0x93, 0xfb, 0x2b, 0xd1, 0x37, 0x26, 0xa1,
- 0x99, 0x4a, 0xce, 0x7f, 0xf0, 0x05, 0xf2, 0x93, 0x5d, 0x1e},
- {0x50, 0x30, 0x06, 0x09, 0x1d, 0x97, 0xd4, 0xf5, 0xae, 0x39,
- 0xf7, 0xcb, 0xe7, 0x92, 0x7d, 0x7d, 0x65, 0x2d, 0x34, 0x31},
- {0x51, 0x7f, 0x61, 0x1e, 0x29, 0x91, 0x6b, 0x53, 0x82, 0xfb,
- 0x72, 0xe7, 0x44, 0xd9, 0x8d, 0xc3, 0xcc, 0x53, 0x6d, 0x64},
- {0x51, 0xa4, 0x4c, 0x28, 0xf3, 0x13, 0xe3, 0xf9, 0xcb, 0x5e,
- 0x7c, 0x0a, 0x1e, 0x0e, 0x0d, 0xd2, 0x84, 0x37, 0x58, 0xae},
- {0x51, 0xc3, 0x24, 0x7d, 0x60, 0xf3, 0x56, 0xc7, 0xca, 0x3b,
- 0xaf, 0x4c, 0x3f, 0x42, 0x9d, 0xac, 0x93, 0xee, 0x7b, 0x74},
- {0x51, 0xc6, 0xe7, 0x08, 0x49, 0x06, 0x6e, 0xf3, 0x92, 0xd4,
- 0x5c, 0xa0, 0x0d, 0x6d, 0xa3, 0x62, 0x8f, 0xc3, 0x52, 0x39},
- {0x51, 0xcc, 0xa0, 0x71, 0x0a, 0xf7, 0x73, 0x3d, 0x34, 0xac,
- 0xdc, 0x19, 0x45, 0x09, 0x9f, 0x43, 0x5c, 0x7f, 0xc5, 0x9f},
- {0x55, 0xa6, 0x72, 0x3e, 0xcb, 0xf2, 0xec, 0xcd, 0xc3, 0x23,
- 0x74, 0x70, 0x19, 0x9d, 0x2a, 0xbe, 0x11, 0xe3, 0x81, 0xd1},
- {0x56, 0x4b, 0x6f, 0x8c, 0x56, 0x38, 0xdc, 0x05, 0x5b, 0xba,
- 0x2b, 0xa1, 0x39, 0x0f, 0x7e, 0x31, 0x95, 0x4a, 0x55, 0x50},
- {0x56, 0xe0, 0xfa, 0xc0, 0x3b, 0x8f, 0x18, 0x23, 0x55, 0x18,
- 0xe5, 0xd3, 0x11, 0xca, 0xe8, 0xc2, 0x43, 0x31, 0xab, 0x66},
- {0x57, 0xf0, 0x3d, 0xce, 0xfb, 0x45, 0x69, 0x4c, 0x1c, 0x25,
- 0xe6, 0xee, 0xa0, 0x2c, 0x43, 0xd7, 0x52, 0x38, 0xd3, 0xc4},
- {0x58, 0x0f, 0x80, 0x47, 0x92, 0xab, 0xc6, 0x3b, 0xbb, 0x80,
- 0x15, 0x4d, 0x4d, 0xfd, 0xdd, 0x8b, 0x2e, 0xf2, 0x67, 0x4e},
- {0x58, 0x11, 0x9f, 0x0e, 0x12, 0x82, 0x87, 0xea, 0x50, 0xfd,
- 0xd9, 0x87, 0x45, 0x6f, 0x4f, 0x78, 0xdc, 0xfa, 0xd6, 0xd4},
- {0x58, 0xd5, 0x2d, 0xb9, 0x33, 0x01, 0xa4, 0xfd, 0x29, 0x1a,
- 0x8c, 0x96, 0x45, 0xa0, 0x8f, 0xee, 0x7f, 0x52, 0x92, 0x82},
- {0x58, 0xe8, 0xab, 0xb0, 0x36, 0x15, 0x33, 0xfb, 0x80, 0xf7,
- 0x9b, 0x1b, 0x6d, 0x29, 0xd3, 0xff, 0x8d, 0x5f, 0x00, 0xf0},
- {0x59, 0x0d, 0x2d, 0x7d, 0x88, 0x4f, 0x40, 0x2e, 0x61, 0x7e,
- 0xa5, 0x62, 0x32, 0x17, 0x65, 0xcf, 0x17, 0xd8, 0x94, 0xe9},
- {0x59, 0x22, 0xa1, 0xe1, 0x5a, 0xea, 0x16, 0x35, 0x21, 0xf8,
- 0x98, 0x39, 0x6a, 0x46, 0x46, 0xb0, 0x44, 0x1b, 0x0f, 0xa9},
- {0x59, 0xaf, 0x82, 0x79, 0x91, 0x86, 0xc7, 0xb4, 0x75, 0x07,
- 0xcb, 0xcf, 0x03, 0x57, 0x46, 0xeb, 0x04, 0xdd, 0xb7, 0x16},
- {0x5a, 0x4d, 0x0e, 0x8b, 0x5f, 0xdc, 0xfd, 0xf6, 0x4e, 0x72,
- 0x99, 0xa3, 0x6c, 0x06, 0x0d, 0xb2, 0x22, 0xca, 0x78, 0xe4},
- {0x5c, 0xfb, 0x1f, 0x5d, 0xb7, 0x32, 0xe4, 0x08, 0x4c, 0x0d,
- 0xd4, 0x97, 0x85, 0x74, 0xe0, 0xcb, 0xc0, 0x93, 0xbe, 0xb3},
- {0x5d, 0x98, 0x9c, 0xdb, 0x15, 0x96, 0x11, 0x36, 0x51, 0x65,
- 0x64, 0x1b, 0x56, 0x0f, 0xdb, 0xea, 0x2a, 0xc2, 0x3e, 0xf1},
- {0x5d, 0xe8, 0x3e, 0xe8, 0x2a, 0xc5, 0x09, 0x0a, 0xea, 0x9d,
- 0x6a, 0xc4, 0xe7, 0xa6, 0xe2, 0x13, 0xf9, 0x46, 0xe1, 0x79},
- {0x5f, 0x3a, 0xfc, 0x0a, 0x8b, 0x64, 0xf6, 0x86, 0x67, 0x34,
- 0x74, 0xdf, 0x7e, 0xa9, 0xa2, 0xfe, 0xf9, 0xfa, 0x7a, 0x51},
- {0x5f, 0x3b, 0x8c, 0xf2, 0xf8, 0x10, 0xb3, 0x7d, 0x78, 0xb4,
- 0xce, 0xec, 0x19, 0x19, 0xc3, 0x73, 0x34, 0xb9, 0xc7, 0x74},
- {0x5f, 0x4e, 0x1f, 0xcf, 0x31, 0xb7, 0x91, 0x3b, 0x85, 0x0b,
- 0x54, 0xf6, 0xe5, 0xff, 0x50, 0x1a, 0x2b, 0x6f, 0xc6, 0xcf},
- {0x5f, 0xb7, 0xee, 0x06, 0x33, 0xe2, 0x59, 0xdb, 0xad, 0x0c,
- 0x4c, 0x9a, 0xe6, 0xd3, 0x8f, 0x1a, 0x61, 0xc7, 0xdc, 0x25},
- {0x61, 0x1e, 0x5b, 0x66, 0x2c, 0x59, 0x3a, 0x08, 0xff, 0x58,
- 0xd1, 0x4a, 0xe2, 0x24, 0x52, 0xd1, 0x98, 0xdf, 0x6c, 0x60},
- {0x61, 0x57, 0x3a, 0x11, 0xdf, 0x0e, 0xd8, 0x7e, 0xd5, 0x92,
- 0x65, 0x22, 0xea, 0xd0, 0x56, 0xd7, 0x44, 0xb3, 0x23, 0x71},
- {0x61, 0xef, 0x43, 0xd7, 0x7f, 0xca, 0xd4, 0x61, 0x51, 0xbc,
- 0x98, 0xe0, 0xc3, 0x59, 0x12, 0xaf, 0x9f, 0xeb, 0x63, 0x11},
- {0x62, 0x52, 0xdc, 0x40, 0xf7, 0x11, 0x43, 0xa2, 0x2f, 0xde,
- 0x9e, 0xf7, 0x34, 0x8e, 0x06, 0x42, 0x51, 0xb1, 0x81, 0x18},
- {0x62, 0x7f, 0x8d, 0x78, 0x27, 0x65, 0x63, 0x99, 0xd2, 0x7d,
- 0x7f, 0x90, 0x44, 0xc9, 0xfe, 0xb3, 0xf3, 0x3e, 0xfa, 0x9a},
- {0x66, 0x31, 0xbf, 0x9e, 0xf7, 0x4f, 0x9e, 0xb6, 0xc9, 0xd5,
- 0xa6, 0x0c, 0xba, 0x6a, 0xbe, 0xd1, 0xf7, 0xbd, 0xef, 0x7b},
- {0x67, 0x24, 0x90, 0x2e, 0x48, 0x01, 0xb0, 0x22, 0x96, 0x40,
- 0x10, 0x46, 0xb4, 0xb1, 0x67, 0x2c, 0xa9, 0x75, 0xfd, 0x2b},
- {0x67, 0x65, 0x0d, 0xf1, 0x7e, 0x8e, 0x7e, 0x5b, 0x82, 0x40,
- 0xa4, 0xf4, 0x56, 0x4b, 0xcf, 0xe2, 0x3d, 0x69, 0xc6, 0xf0},
- {0x67, 0x82, 0xaa, 0xe0, 0xed, 0xee, 0xe2, 0x1a, 0x58, 0x39,
- 0xd3, 0xc0, 0xcd, 0x14, 0x68, 0x0a, 0x4f, 0x60, 0x14, 0x2a},
- {0x67, 0x9a, 0x4f, 0x81, 0xfc, 0x70, 0x5d, 0xde, 0xc4, 0x19,
- 0x77, 0x8d, 0xd2, 0xeb, 0xd8, 0x75, 0xf4, 0xc2, 0x42, 0xc6},
- {0x69, 0x69, 0x56, 0x2e, 0x40, 0x80, 0xf4, 0x24, 0xa1, 0xe7,
- 0x19, 0x9f, 0x14, 0xba, 0xf3, 0xee, 0x58, 0xab, 0x6a, 0xbb},
- {0x69, 0xbd, 0x8c, 0xf4, 0x9c, 0xd3, 0x00, 0xfb, 0x59, 0x2e,
- 0x17, 0x93, 0xca, 0x55, 0x6a, 0xf3, 0xec, 0xaa, 0x35, 0xfb},
- {0x6a, 0x84, 0xfe, 0x62, 0x7e, 0xcc, 0x49, 0xa1, 0xbe, 0x02,
- 0xe9, 0x18, 0xfa, 0xc9, 0xe1, 0xf7, 0x32, 0x80, 0x3a, 0x62},
- {0x6b, 0x2f, 0x34, 0xad, 0x89, 0x58, 0xbe, 0x62, 0xfd, 0xb0,
- 0x6b, 0x5c, 0xce, 0xbb, 0x9d, 0xd9, 0x4f, 0x4e, 0x39, 0xf3},
- {0x6b, 0x81, 0x44, 0x6a, 0x5c, 0xdd, 0xf4, 0x74, 0xa0, 0xf8,
- 0x00, 0xff, 0xbe, 0x69, 0xfd, 0x0d, 0xb6, 0x28, 0x75, 0x16},
- {0x6e, 0x3a, 0x55, 0xa4, 0x19, 0x0c, 0x19, 0x5c, 0x93, 0x84,
- 0x3c, 0xc0, 0xdb, 0x72, 0x2e, 0x31, 0x30, 0x61, 0xf0, 0xb1},
- {0x70, 0x17, 0x9b, 0x86, 0x8c, 0x00, 0xa4, 0xfa, 0x60, 0x91,
- 0x52, 0x22, 0x3f, 0x9f, 0x3e, 0x32, 0xbd, 0xe0, 0x05, 0x62},
- {0x70, 0x43, 0x2d, 0xe4, 0x3c, 0x9d, 0x1e, 0x79, 0xc1, 0x13,
- 0x25, 0x20, 0xbc, 0x58, 0x43, 0xf7, 0xbb, 0x7d, 0x92, 0x95},
- {0x74, 0x20, 0x74, 0x41, 0x72, 0x9c, 0xdd, 0x92, 0xec, 0x79,
- 0x31, 0xd8, 0x23, 0x10, 0x8d, 0xc2, 0x81, 0x92, 0xe2, 0xbb},
- {0x74, 0x2c, 0x31, 0x92, 0xe6, 0x07, 0xe4, 0x24, 0xeb, 0x45,
- 0x49, 0x54, 0x2b, 0xe1, 0xbb, 0xc5, 0x3e, 0x61, 0x74, 0xe2},
- {0x74, 0x54, 0x53, 0x5c, 0x24, 0xa3, 0xa7, 0x58, 0x20, 0x7e,
- 0x3e, 0x3e, 0xd3, 0x24, 0xf8, 0x16, 0xfb, 0x21, 0x16, 0x49},
- {0x74, 0xa2, 0x66, 0xf0, 0x95, 0xa9, 0xa4, 0xeb, 0x95, 0x22,
- 0x19, 0xd6, 0x05, 0xda, 0x93, 0x63, 0xf5, 0x14, 0xfa, 0xf9},
- {0x74, 0xf8, 0xa3, 0xc3, 0xef, 0xe7, 0xb3, 0x90, 0x06, 0x4b,
- 0x83, 0x90, 0x3c, 0x21, 0x64, 0x60, 0x20, 0xe5, 0xdf, 0xce},
- {0x75, 0xe0, 0xab, 0xb6, 0x13, 0x85, 0x12, 0x27, 0x1c, 0x04,
- 0xf8, 0x5f, 0xdd, 0xde, 0x38, 0xe4, 0xb7, 0x24, 0x2e, 0xfe},
- {0x76, 0xe2, 0x7e, 0xc1, 0x4f, 0xdb, 0x82, 0xc1, 0xc0, 0xa6,
- 0x75, 0xb5, 0x05, 0xbe, 0x3d, 0x29, 0xb4, 0xed, 0xdb, 0xbb},
- {0x77, 0x47, 0x4f, 0xc6, 0x30, 0xe4, 0x0f, 0x4c, 0x47, 0x64,
- 0x3f, 0x84, 0xba, 0xb8, 0xc6, 0x95, 0x4a, 0x8a, 0x41, 0xec},
- {0x78, 0x6a, 0x74, 0xac, 0x76, 0xab, 0x14, 0x7f, 0x9c, 0x6a,
- 0x30, 0x50, 0xba, 0x9e, 0xa8, 0x7e, 0xfe, 0x9a, 0xce, 0x3c},
- {0x79, 0x98, 0xa3, 0x08, 0xe1, 0x4d, 0x65, 0x85, 0xe6, 0xc2,
- 0x1e, 0x15, 0x3a, 0x71, 0x9f, 0xba, 0x5a, 0xd3, 0x4a, 0xd9},
- {0x7e, 0x04, 0xde, 0x89, 0x6a, 0x3e, 0x66, 0x6d, 0x00, 0xe6,
- 0x87, 0xd3, 0x3f, 0xfa, 0xd9, 0x3b, 0xe8, 0x3d, 0x34, 0x9e},
- {0x7e, 0x78, 0x4a, 0x10, 0x1c, 0x82, 0x65, 0xcc, 0x2d, 0xe1,
- 0xf1, 0x6d, 0x47, 0xb4, 0x40, 0xca, 0xd9, 0x0a, 0x19, 0x45},
- {0x7f, 0x8a, 0xb0, 0xcf, 0xd0, 0x51, 0x87, 0x6a, 0x66, 0xf3,
- 0x36, 0x0f, 0x47, 0xc8, 0x8d, 0x8c, 0xd3, 0x35, 0xfc, 0x74},
- {0x80, 0x1d, 0x62, 0xd0, 0x7b, 0x44, 0x9d, 0x5c, 0x5c, 0x03,
- 0x5c, 0x98, 0xea, 0x61, 0xfa, 0x44, 0x3c, 0x2a, 0x58, 0xfe},
- {0x80, 0x25, 0xef, 0xf4, 0x6e, 0x70, 0xc8, 0xd4, 0x72, 0x24,
- 0x65, 0x84, 0xfe, 0x40, 0x3b, 0x8a, 0x8d, 0x6a, 0xdb, 0xf5},
- {0x82, 0x50, 0xbe, 0xd5, 0xa2, 0x14, 0x43, 0x3a, 0x66, 0x37,
- 0x7c, 0xbc, 0x10, 0xef, 0x83, 0xf6, 0x69, 0xda, 0x3a, 0x67},
- {0x82, 0x68, 0x99, 0x3e, 0xda, 0xeb, 0xb1, 0xe4, 0xfb, 0x77,
- 0x91, 0x0f, 0x12, 0xcb, 0xd6, 0xc6, 0x70, 0xf0, 0x7c, 0xea},
- {0x84, 0xf2, 0xe3, 0xdd, 0x83, 0x13, 0x3e, 0xa9, 0x1d, 0x19,
- 0x52, 0x7f, 0x02, 0xd7, 0x29, 0xbf, 0xc1, 0x5f, 0xe6, 0x67},
- {0x85, 0x37, 0x1c, 0xa6, 0xe5, 0x50, 0x14, 0x3d, 0xce, 0x28,
- 0x03, 0x47, 0x1b, 0xde, 0x3a, 0x09, 0xe8, 0xf8, 0x77, 0x0f},
- {0x85, 0xa4, 0x08, 0xc0, 0x9c, 0x19, 0x3e, 0x5d, 0x51, 0x58,
- 0x7d, 0xcd, 0xd6, 0x13, 0x30, 0xfd, 0x8c, 0xde, 0x37, 0xbf},
- {0x85, 0xb5, 0xff, 0x67, 0x9b, 0x0c, 0x79, 0x96, 0x1f, 0xc8,
- 0x6e, 0x44, 0x22, 0x00, 0x46, 0x13, 0xdb, 0x17, 0x92, 0x84},
- {0x86, 0xe8, 0x17, 0xc8, 0x1a, 0x5c, 0xa6, 0x72, 0xfe, 0x00,
- 0x0f, 0x36, 0xf8, 0x78, 0xc1, 0x95, 0x18, 0xd6, 0xf8, 0x44},
- {0x87, 0x81, 0xc2, 0x5a, 0x96, 0xbd, 0xc2, 0xfb, 0x4c, 0x65,
- 0x06, 0x4f, 0xf9, 0x39, 0x0b, 0x26, 0x04, 0x8a, 0x0e, 0x01},
- {0x87, 0x82, 0xc6, 0xc3, 0x04, 0x35, 0x3b, 0xcf, 0xd2, 0x96,
- 0x92, 0xd2, 0x59, 0x3e, 0x7d, 0x44, 0xd9, 0x34, 0xff, 0x11},
- {0x87, 0x9f, 0x4b, 0xee, 0x05, 0xdf, 0x98, 0x58, 0x3b, 0xe3,
- 0x60, 0xd6, 0x33, 0xe7, 0x0d, 0x3f, 0xfe, 0x98, 0x71, 0xaf},
- {0x89, 0xdf, 0x74, 0xfe, 0x5c, 0xf4, 0x0f, 0x4a, 0x80, 0xf9,
- 0xe3, 0x37, 0x7d, 0x54, 0xda, 0x91, 0xe1, 0x01, 0x31, 0x8e},
- {0x8b, 0xaf, 0x4c, 0x9b, 0x1d, 0xf0, 0x2a, 0x92, 0xf7, 0xda,
- 0x12, 0x8e, 0xb9, 0x1b, 0xac, 0xf4, 0x98, 0x60, 0x4b, 0x6f},
- {0x8c, 0x94, 0x1b, 0x34, 0xea, 0x1e, 0xa6, 0xed, 0x9a, 0xe2,
- 0xbc, 0x54, 0xcf, 0x68, 0x72, 0x52, 0xb4, 0xc9, 0xb5, 0x61},
- {0x8c, 0x96, 0xba, 0xeb, 0xdd, 0x2b, 0x07, 0x07, 0x48, 0xee,
- 0x30, 0x32, 0x66, 0xa0, 0xf3, 0x98, 0x6e, 0x7c, 0xae, 0x58},
- {0x8c, 0xc4, 0x30, 0x7b, 0xc6, 0x07, 0x55, 0xe7, 0xb2, 0x2d,
- 0xd9, 0xf7, 0xfe, 0xa2, 0x45, 0x93, 0x6c, 0x7c, 0xf2, 0x88},
- {0x8c, 0xf4, 0x27, 0xfd, 0x79, 0x0c, 0x3a, 0xd1, 0x66, 0x06,
- 0x8d, 0xe8, 0x1e, 0x57, 0xef, 0xbb, 0x93, 0x22, 0x72, 0xd4},
- {0x8d, 0x17, 0x84, 0xd5, 0x37, 0xf3, 0x03, 0x7d, 0xec, 0x70,
- 0xfe, 0x57, 0x8b, 0x51, 0x9a, 0x99, 0xe6, 0x10, 0xd7, 0xb0},
- {0x8e, 0x1c, 0x74, 0xf8, 0xa6, 0x20, 0xb9, 0xe5, 0x8a, 0xf4,
- 0x61, 0xfa, 0xec, 0x2b, 0x47, 0x56, 0x51, 0x1a, 0x52, 0xc6},
- {0x8e, 0x5b, 0xd5, 0x0d, 0x6a, 0xe6, 0x86, 0xd6, 0x52, 0x52,
- 0xf8, 0x43, 0xa9, 0xd4, 0xb9, 0x6d, 0x19, 0x77, 0x30, 0xab},
- {0x90, 0x5f, 0x94, 0x2f, 0xd9, 0xf2, 0x8f, 0x67, 0x9b, 0x37,
- 0x81, 0x80, 0xfd, 0x4f, 0x84, 0x63, 0x47, 0xf6, 0x45, 0xc1},
- {0x90, 0xae, 0xa2, 0x69, 0x85, 0xff, 0x14, 0x80, 0x4c, 0x43,
- 0x49, 0x52, 0xec, 0xe9, 0x60, 0x84, 0x77, 0xaf, 0x55, 0x6f},
- {0x91, 0xc6, 0xd6, 0xee, 0x3e, 0x8a, 0xc8, 0x63, 0x84, 0xe5,
- 0x48, 0xc2, 0x99, 0x29, 0x5c, 0x75, 0x6c, 0x81, 0x7b, 0x81},
- {0x92, 0x5a, 0x8f, 0x8d, 0x2c, 0x6d, 0x04, 0xe0, 0x66, 0x5f,
- 0x59, 0x6a, 0xff, 0x22, 0xd8, 0x63, 0xe8, 0x25, 0x6f, 0x3f},
- {0x93, 0xe6, 0xab, 0x22, 0x03, 0x03, 0xb5, 0x23, 0x28, 0xdc,
- 0xda, 0x56, 0x9e, 0xba, 0xe4, 0xd1, 0xd1, 0xcc, 0xfb, 0x65},
- {0x94, 0x32, 0xbd, 0x9a, 0xec, 0x1d, 0x75, 0xd1, 0x70, 0x5c,
- 0x54, 0x3a, 0xa3, 0x4c, 0x4a, 0xf6, 0xa5, 0x26, 0xc1, 0x3d},
- {0x96, 0x56, 0xcd, 0x7b, 0x57, 0x96, 0x98, 0x95, 0xd0, 0xe1,
- 0x41, 0x46, 0x68, 0x06, 0xfb, 0xb8, 0xc6, 0x11, 0x06, 0x87},
- {0x96, 0x83, 0x38, 0xf1, 0x13, 0xe3, 0x6a, 0x7b, 0xab, 0xdd,
- 0x08, 0xf7, 0x77, 0x63, 0x91, 0xa6, 0x87, 0x36, 0x58, 0x2e},
- {0x96, 0xc9, 0x1b, 0x0b, 0x95, 0xb4, 0x10, 0x98, 0x42, 0xfa,
- 0xd0, 0xd8, 0x22, 0x79, 0xfe, 0x60, 0xfa, 0xb9, 0x16, 0x83},
- {0x97, 0x81, 0x79, 0x50, 0xd8, 0x1c, 0x96, 0x70, 0xcc, 0x34,
- 0xd8, 0x09, 0xcf, 0x79, 0x44, 0x31, 0x36, 0x7e, 0xf4, 0x74},
- {0x98, 0x45, 0xa4, 0x31, 0xd5, 0x19, 0x59, 0xca, 0xf2, 0x25,
- 0x32, 0x2b, 0x4a, 0x4f, 0xe9, 0xf2, 0x23, 0xce, 0x6d, 0x15},
- {0x99, 0xa6, 0x9b, 0xe6, 0x1a, 0xfe, 0x88, 0x6b, 0x4d, 0x2b,
- 0x82, 0x00, 0x7c, 0xb8, 0x54, 0xfc, 0x31, 0x7e, 0x15, 0x39},
- {0x9b, 0xaa, 0xe5, 0x9f, 0x56, 0xee, 0x21, 0xcb, 0x43, 0x5a,
- 0xbe, 0x25, 0x93, 0xdf, 0xa7, 0xf0, 0x40, 0xd1, 0x1d, 0xcb},
- {0x9c, 0xbb, 0x48, 0x53, 0xf6, 0xa4, 0xf6, 0xd3, 0x52, 0xa4,
- 0xe8, 0x32, 0x52, 0x55, 0x60, 0x13, 0xf5, 0xad, 0xaf, 0x65},
- {0x9d, 0x70, 0xbb, 0x01, 0xa5, 0xa4, 0xa0, 0x18, 0x11, 0x2e,
- 0xf7, 0x1c, 0x01, 0xb9, 0x32, 0xc5, 0x34, 0xe7, 0x88, 0xa8},
- {0x9f, 0xad, 0x91, 0xa6, 0xce, 0x6a, 0xc6, 0xc5, 0x00, 0x47,
- 0xc4, 0x4e, 0xc9, 0xd4, 0xa5, 0x0d, 0x92, 0xd8, 0x49, 0x79},
- {0xa0, 0xa1, 0xab, 0x90, 0xc9, 0xfc, 0x84, 0x7b, 0x3b, 0x12,
- 0x61, 0xe8, 0x97, 0x7d, 0x5f, 0xd3, 0x22, 0x61, 0xd3, 0xcc},
- {0xa1, 0x4b, 0x48, 0xd9, 0x43, 0xee, 0x0a, 0x0e, 0x40, 0x90,
- 0x4f, 0x3c, 0xe0, 0xa4, 0xc0, 0x91, 0x93, 0x51, 0x5d, 0x3f},
- {0xa1, 0xdb, 0x63, 0x93, 0x91, 0x6f, 0x17, 0xe4, 0x18, 0x55,
- 0x09, 0x40, 0x04, 0x15, 0xc7, 0x02, 0x40, 0xb0, 0xae, 0x6b},
- {0xa2, 0x48, 0x41, 0xab, 0xd6, 0xa0, 0xca, 0x5c, 0xcd, 0x2a,
- 0xa3, 0xb1, 0x90, 0x70, 0x1e, 0xd6, 0x4b, 0x39, 0xfe, 0x53},
- {0xa3, 0xf1, 0x33, 0x3f, 0xe2, 0x42, 0xbf, 0xcf, 0xc5, 0xd1,
- 0x4e, 0x8f, 0x39, 0x42, 0x98, 0x40, 0x68, 0x10, 0xd1, 0xa0},
- {0xa6, 0x76, 0xdb, 0xf1, 0x92, 0x48, 0xf5, 0x2c, 0x57, 0x53,
- 0xd0, 0xda, 0xc1, 0x4c, 0x53, 0xc4, 0x74, 0xa4, 0x83, 0x5e},
- {0xa6, 0x9a, 0x91, 0xfd, 0x05, 0x7f, 0x13, 0x6a, 0x42, 0x63,
- 0x0b, 0xb1, 0x76, 0x0d, 0x2d, 0x51, 0x12, 0x0c, 0x16, 0x50},
- {0xa8, 0x98, 0x5d, 0x3a, 0x65, 0xe5, 0xe5, 0xc4, 0xb2, 0xd7,
- 0xd6, 0x6d, 0x40, 0xc6, 0xdd, 0x2f, 0xb1, 0x9c, 0x54, 0x36},
- {0xaa, 0xdb, 0xbc, 0x22, 0x23, 0x8f, 0xc4, 0x01, 0xa1, 0x27,
- 0xbb, 0x38, 0xdd, 0xf4, 0x1d, 0xdb, 0x08, 0x9e, 0xf0, 0x12},
- {0xac, 0xed, 0x5f, 0x65, 0x53, 0xfd, 0x25, 0xce, 0x01, 0x5f,
- 0x1f, 0x7a, 0x48, 0x3b, 0x6a, 0x74, 0x9f, 0x61, 0x78, 0xc6},
- {0xad, 0x7e, 0x1c, 0x28, 0xb0, 0x64, 0xef, 0x8f, 0x60, 0x03,
- 0x40, 0x20, 0x14, 0xc3, 0xd0, 0xe3, 0x37, 0x0e, 0xb5, 0x8a},
- {0xae, 0x3b, 0x31, 0xbf, 0x8f, 0xd8, 0x91, 0x07, 0x9c, 0xf1,
- 0xdf, 0x34, 0xcb, 0xce, 0x6e, 0x70, 0xd3, 0x7f, 0xb5, 0xb0},
- {0xae, 0x50, 0x83, 0xed, 0x7c, 0xf4, 0x5c, 0xbc, 0x8f, 0x61,
- 0xc6, 0x21, 0xfe, 0x68, 0x5d, 0x79, 0x42, 0x21, 0x15, 0x6e},
- {0xae, 0xc5, 0xfb, 0x3f, 0xc8, 0xe1, 0xbf, 0xc4, 0xe5, 0x4f,
- 0x03, 0x07, 0x5a, 0x9a, 0xe8, 0x00, 0xb7, 0xf7, 0xb6, 0xfa},
- {0xb0, 0x91, 0xaa, 0x91, 0x38, 0x47, 0xf3, 0x13, 0xd7, 0x27,
- 0xbc, 0xef, 0xc8, 0x17, 0x9f, 0x08, 0x6f, 0x3a, 0x8c, 0x0f},
- {0xb1, 0x2e, 0x13, 0x63, 0x45, 0x86, 0xa4, 0x6f, 0x1a, 0xb2,
- 0x60, 0x68, 0x37, 0x58, 0x2d, 0xc4, 0xac, 0xfd, 0x94, 0x97},
- {0xb1, 0x72, 0xb1, 0xa5, 0x6d, 0x95, 0xf9, 0x1f, 0xe5, 0x02,
- 0x87, 0xe1, 0x4d, 0x37, 0xea, 0x6a, 0x44, 0x63, 0x76, 0x8a},
- {0xb1, 0xbc, 0x96, 0x8b, 0xd4, 0xf4, 0x9d, 0x62, 0x2a, 0xa8,
- 0x9a, 0x81, 0xf2, 0x15, 0x01, 0x52, 0xa4, 0x1d, 0x82, 0x9c},
- {0xb3, 0x1e, 0xb1, 0xb7, 0x40, 0xe3, 0x6c, 0x84, 0x02, 0xda,
- 0xdc, 0x37, 0xd4, 0x4d, 0xf5, 0xd4, 0x67, 0x49, 0x52, 0xf9},
- {0xb3, 0xea, 0xc4, 0x47, 0x76, 0xc9, 0xc8, 0x1c, 0xea, 0xf2,
- 0x9d, 0x95, 0xb6, 0xcc, 0xa0, 0x08, 0x1b, 0x67, 0xec, 0x9d},
- {0xb4, 0x35, 0xd4, 0xe1, 0x11, 0x9d, 0x1c, 0x66, 0x90, 0xa7,
- 0x49, 0xeb, 0xb3, 0x94, 0xbd, 0x63, 0x7b, 0xa7, 0x82, 0xb7},
- {0xb4, 0x57, 0x12, 0x1e, 0x63, 0x45, 0xff, 0x93, 0x5d, 0x6b,
- 0x1c, 0xa2, 0xdd, 0xf4, 0x52, 0x3c, 0xc6, 0xd0, 0xef, 0x6b},
- {0xb5, 0x1c, 0x06, 0x7c, 0xee, 0x2b, 0x0c, 0x3d, 0xf8, 0x55,
- 0xab, 0x2d, 0x92, 0xf4, 0xfe, 0x39, 0xd4, 0xe7, 0x0f, 0x0e},
- {0xb5, 0x2c, 0xb0, 0x2f, 0xd5, 0x67, 0xe0, 0x35, 0x9f, 0xe8,
- 0xfa, 0x4d, 0x4c, 0x41, 0x03, 0x79, 0x70, 0xfe, 0x01, 0xb0},
- {0xb5, 0x61, 0xeb, 0xea, 0xa4, 0xde, 0xe4, 0x25, 0x4b, 0x69,
- 0x1a, 0x98, 0xa5, 0x57, 0x47, 0xc2, 0x34, 0xc7, 0xd9, 0x71},
- {0xb6, 0xca, 0x21, 0x5b, 0x83, 0x6c, 0x35, 0x10, 0x1d, 0xaf,
- 0x74, 0x63, 0x90, 0x0a, 0x93, 0x68, 0x80, 0x76, 0x7a, 0xa6},
- {0xb8, 0x01, 0x86, 0xd1, 0xeb, 0x9c, 0x86, 0xa5, 0x41, 0x04,
- 0xcf, 0x30, 0x54, 0xf3, 0x4c, 0x52, 0xb7, 0xe5, 0x58, 0xc6},
- {0xb8, 0x23, 0x6b, 0x00, 0x2f, 0x1d, 0x16, 0x86, 0x53, 0x01,
- 0x55, 0x6c, 0x11, 0xa4, 0x37, 0xca, 0xeb, 0xff, 0xc3, 0xbb},
- {0xb8, 0x6e, 0x79, 0x16, 0x20, 0xf7, 0x59, 0xf1, 0x7b, 0x8d,
- 0x25, 0xe3, 0x8c, 0xa8, 0xbe, 0x32, 0xe7, 0xd5, 0xea, 0xc2},
- {0xba, 0x29, 0x41, 0x60, 0x77, 0x98, 0x3f, 0xf4, 0xf3, 0xef,
- 0xf2, 0x31, 0x05, 0x3b, 0x2e, 0xea, 0x6d, 0x4d, 0x45, 0xfd},
- {0xc0, 0x60, 0xed, 0x44, 0xcb, 0xd8, 0x81, 0xbd, 0x0e, 0xf8,
- 0x6c, 0x0b, 0xa2, 0x87, 0xdd, 0xcf, 0x81, 0x67, 0x47, 0x8c},
- {0xc8, 0xec, 0x8c, 0x87, 0x92, 0x69, 0xcb, 0x4b, 0xab, 0x39,
- 0xe9, 0x8d, 0x7e, 0x57, 0x67, 0xf3, 0x14, 0x95, 0x73, 0x9d},
- {0xc9, 0xa8, 0xb9, 0xe7, 0x55, 0x80, 0x5e, 0x58, 0xe3, 0x53,
- 0x77, 0xa7, 0x25, 0xeb, 0xaf, 0xc3, 0x7b, 0x27, 0xcc, 0xd7},
- {0xca, 0x39, 0xd8, 0xea, 0x48, 0x22, 0x13, 0x7f, 0x33, 0x8d,
- 0xca, 0x79, 0x56, 0x6e, 0xdd, 0xf0, 0x54, 0x7e, 0xce, 0xa7},
- {0xca, 0x3a, 0xfb, 0xcf, 0x12, 0x40, 0x36, 0x4b, 0x44, 0xb2,
- 0x16, 0x20, 0x88, 0x80, 0x48, 0x39, 0x19, 0x93, 0x7c, 0xf7},
- {0xcb, 0x44, 0xa0, 0x97, 0x85, 0x7c, 0x45, 0xfa, 0x18, 0x7e,
- 0xd9, 0x52, 0x08, 0x6c, 0xb9, 0x84, 0x1f, 0x2d, 0x51, 0xb5},
- {0xcb, 0x65, 0x82, 0x64, 0xea, 0x8c, 0xda, 0x18, 0x6e, 0x17,
- 0x52, 0xfb, 0x52, 0xc3, 0x97, 0x36, 0x7e, 0xa3, 0x87, 0xbe},
- {0xcb, 0xa1, 0xc5, 0xf8, 0xb0, 0xe3, 0x5e, 0xb8, 0xb9, 0x45,
- 0x12, 0xd3, 0xf9, 0x34, 0xa2, 0xe9, 0x06, 0x10, 0xd3, 0x36},
- {0xcc, 0xab, 0x0e, 0xa0, 0x4c, 0x23, 0x01, 0xd6, 0x69, 0x7b,
- 0xdd, 0x37, 0x9f, 0xcd, 0x12, 0xeb, 0x24, 0xe3, 0x94, 0x9d},
- {0xce, 0x6a, 0x64, 0xa3, 0x09, 0xe4, 0x2f, 0xbb, 0xd9, 0x85,
- 0x1c, 0x45, 0x3e, 0x64, 0x09, 0xea, 0xe8, 0x7d, 0x60, 0xf1},
- {0xcf, 0x9e, 0x87, 0x6d, 0xd3, 0xeb, 0xfc, 0x42, 0x26, 0x97,
- 0xa3, 0xb5, 0xa3, 0x7a, 0xa0, 0x76, 0xa9, 0x06, 0x23, 0x48},
- {0xd1, 0xeb, 0x23, 0xa4, 0x6d, 0x17, 0xd6, 0x8f, 0xd9, 0x25,
- 0x64, 0xc2, 0xf1, 0xf1, 0x60, 0x17, 0x64, 0xd8, 0xe3, 0x49},
- {0xd2, 0x32, 0x09, 0xad, 0x23, 0xd3, 0x14, 0x23, 0x21, 0x74,
- 0xe4, 0x0d, 0x7f, 0x9d, 0x62, 0x13, 0x97, 0x86, 0x63, 0x3a},
- {0xd2, 0x44, 0x1a, 0xa8, 0xc2, 0x03, 0xae, 0xca, 0xa9, 0x6e,
- 0x50, 0x1f, 0x12, 0x4d, 0x52, 0xb6, 0x8f, 0xe4, 0xc3, 0x75},
- {0xd3, 0xc0, 0x63, 0xf2, 0x19, 0xed, 0x07, 0x3e, 0x34, 0xad,
- 0x5d, 0x75, 0x0b, 0x32, 0x76, 0x29, 0xff, 0xd5, 0x9a, 0xf2},
- {0xd3, 0xee, 0xfb, 0xcb, 0xbc, 0xf4, 0x98, 0x67, 0x83, 0x86,
- 0x26, 0xe2, 0x3b, 0xb5, 0x9c, 0xa0, 0x1e, 0x30, 0x5d, 0xb7},
- {0xd4, 0x37, 0x19, 0xb5, 0x1b, 0x57, 0xca, 0x4b, 0xb8, 0x74,
- 0x16, 0x7d, 0x47, 0x95, 0x23, 0x1d, 0x34, 0x34, 0xfd, 0xa8},
- {0xd4, 0xde, 0x20, 0xd0, 0x5e, 0x66, 0xfc, 0x53, 0xfe, 0x1a,
- 0x50, 0x88, 0x2c, 0x78, 0xdb, 0x28, 0x52, 0xca, 0xe4, 0x74},
- {0xd6, 0x9b, 0x56, 0x11, 0x48, 0xf0, 0x1c, 0x77, 0xc5, 0x45,
- 0x78, 0xc1, 0x09, 0x26, 0xdf, 0x5b, 0x85, 0x69, 0x76, 0xad},
- {0xd6, 0xda, 0xa8, 0x20, 0x8d, 0x09, 0xd2, 0x15, 0x4d, 0x24,
- 0xb5, 0x2f, 0xcb, 0x34, 0x6e, 0xb2, 0x58, 0xb2, 0x8a, 0x58},
- {0xd8, 0xa6, 0x33, 0x2c, 0xe0, 0x03, 0x6f, 0xb1, 0x85, 0xf6,
- 0x63, 0x4f, 0x7d, 0x6a, 0x06, 0x65, 0x26, 0x32, 0x28, 0x27},
- {0xd8, 0xc5, 0x38, 0x8a, 0xb7, 0x30, 0x1b, 0x1b, 0x6e, 0xd4,
- 0x7a, 0xe6, 0x45, 0x25, 0x3a, 0x6f, 0x9f, 0x1a, 0x27, 0x61},
- {0xda, 0x40, 0x18, 0x8b, 0x91, 0x89, 0xa3, 0xed, 0xee, 0xae,
- 0xda, 0x97, 0xfe, 0x2f, 0x9d, 0xf5, 0xb7, 0xd1, 0x8a, 0x41},
- {0xda, 0xc9, 0x02, 0x4f, 0x54, 0xd8, 0xf6, 0xdf, 0x94, 0x93,
- 0x5f, 0xb1, 0x73, 0x26, 0x38, 0xca, 0x6a, 0xd7, 0x7c, 0x13},
- {0xda, 0xfa, 0xf7, 0xfa, 0x66, 0x84, 0xec, 0x06, 0x8f, 0x14,
- 0x50, 0xbd, 0xc7, 0xc2, 0x81, 0xa5, 0xbc, 0xa9, 0x64, 0x57},
- {0xdd, 0xfb, 0x16, 0xcd, 0x49, 0x31, 0xc9, 0x73, 0xa2, 0x03,
- 0x7d, 0x3f, 0xc8, 0x3a, 0x4d, 0x7d, 0x77, 0x5d, 0x05, 0xe4},
- {0xde, 0x28, 0xf4, 0xa4, 0xff, 0xe5, 0xb9, 0x2f, 0xa3, 0xc5,
- 0x03, 0xd1, 0xa3, 0x49, 0xa7, 0xf9, 0x96, 0x2a, 0x82, 0x12},
- {0xde, 0x3f, 0x40, 0xbd, 0x50, 0x93, 0xd3, 0x9b, 0x6c, 0x60,
- 0xf6, 0xda, 0xbc, 0x07, 0x62, 0x01, 0x00, 0x89, 0x76, 0xc9},
- {0xde, 0x99, 0x0c, 0xed, 0x99, 0xe0, 0x43, 0x1f, 0x60, 0xed,
- 0xc3, 0x93, 0x7e, 0x7c, 0xd5, 0xbf, 0x0e, 0xd9, 0xe5, 0xfa},
- {0xdf, 0x3c, 0x24, 0xf9, 0xbf, 0xd6, 0x66, 0x76, 0x1b, 0x26,
- 0x80, 0x73, 0xfe, 0x06, 0xd1, 0xcc, 0x8d, 0x4f, 0x82, 0xa4},
- {0xdf, 0x71, 0x7e, 0xaa, 0x4a, 0xd9, 0x4e, 0xc9, 0x55, 0x84,
- 0x99, 0x60, 0x2d, 0x48, 0xde, 0x5f, 0xbc, 0xf0, 0x3a, 0x25},
- {0xdf, 0xdf, 0xac, 0x89, 0x47, 0xbd, 0xf7, 0x52, 0x64, 0xa9,
- 0x23, 0x3a, 0xc1, 0x0e, 0xe3, 0xd1, 0x28, 0x33, 0xda, 0xcc},
- {0xe0, 0x5f, 0x7c, 0x22, 0x59, 0x8c, 0x12, 0x56, 0xa7, 0xb9,
- 0x4d, 0x92, 0xd3, 0xd1, 0x94, 0x50, 0x8c, 0x8c, 0xba, 0x71},
- {0xe0, 0xab, 0x05, 0x94, 0x20, 0x72, 0x54, 0x93, 0x05, 0x60,
- 0x62, 0x02, 0x36, 0x70, 0xf7, 0xcd, 0x2e, 0xfc, 0x66, 0x66},
- {0xe1, 0x2d, 0xfb, 0x4b, 0x41, 0xd7, 0xd9, 0xc3, 0x2b, 0x30,
- 0x51, 0x4b, 0xac, 0x1d, 0x81, 0xd8, 0x38, 0x5e, 0x2d, 0x46},
- {0xe1, 0x9f, 0xe3, 0x0e, 0x8b, 0x84, 0x60, 0x9e, 0x80, 0x9b,
- 0x17, 0x0d, 0x72, 0xa8, 0xc5, 0xba, 0x6e, 0x14, 0x09, 0xbd},
- {0xe1, 0xa4, 0x5b, 0x14, 0x1a, 0x21, 0xda, 0x1a, 0x79, 0xf4,
- 0x1a, 0x42, 0xa9, 0x61, 0xd6, 0x69, 0xcd, 0x06, 0x34, 0xc1},
- {0xe3, 0x92, 0x51, 0x2f, 0x0a, 0xcf, 0xf5, 0x05, 0xdf, 0xf6,
- 0xde, 0x06, 0x7f, 0x75, 0x37, 0xe1, 0x65, 0xea, 0x57, 0x4b},
- {0xe5, 0xdf, 0x74, 0x3c, 0xb6, 0x01, 0xc4, 0x9b, 0x98, 0x43,
- 0xdc, 0xab, 0x8c, 0xe8, 0x6a, 0x81, 0x10, 0x9f, 0xe4, 0x8e},
- {0xe6, 0x18, 0x83, 0xae, 0x84, 0xca, 0xc1, 0xc1, 0xcd, 0x52,
- 0xad, 0xe8, 0xe9, 0x25, 0x2b, 0x45, 0xa6, 0x4f, 0xb7, 0xe2},
- {0xe6, 0x19, 0xd2, 0x5b, 0x38, 0x0b, 0x7b, 0x13, 0xfd, 0xa3,
- 0x3e, 0x8a, 0x58, 0xcd, 0x82, 0xd8, 0xa8, 0x8e, 0x05, 0x15},
- {0xe7, 0xa1, 0x90, 0x29, 0xd3, 0xd5, 0x52, 0xdc, 0x0d, 0x0f,
- 0xc6, 0x92, 0xd3, 0xea, 0x88, 0x0d, 0x15, 0x2e, 0x1a, 0x6b},
- {0xe7, 0xb4, 0xf6, 0x9d, 0x61, 0xec, 0x90, 0x69, 0xdb, 0x7e,
- 0x90, 0xa7, 0x40, 0x1a, 0x3c, 0xf4, 0x7d, 0x4f, 0xe8, 0xee},
- {0xee, 0xef, 0xaa, 0x0b, 0xcd, 0x11, 0xaf, 0x5c, 0x02, 0xfa,
- 0x96, 0x20, 0x6a, 0xc5, 0xc6, 0x2b, 0xa7, 0x24, 0xd6, 0x0a},
- {0xf0, 0x0f, 0xc3, 0x7d, 0x6a, 0x1c, 0x92, 0x61, 0xfb, 0x6b,
- 0xc1, 0xc2, 0x18, 0x49, 0x8c, 0x5a, 0xa4, 0xdc, 0x51, 0xfb},
- {0xf1, 0x7f, 0x6f, 0xb6, 0x31, 0xdc, 0x99, 0xe3, 0xa3, 0xc8,
- 0x7f, 0xfe, 0x1c, 0xf1, 0x81, 0x10, 0x88, 0xd9, 0x60, 0x33},
- {0xf1, 0x8b, 0x53, 0x8d, 0x1b, 0xe9, 0x03, 0xb6, 0xa6, 0xf0,
- 0x56, 0x43, 0x5b, 0x17, 0x15, 0x89, 0xca, 0xf3, 0x6b, 0xf2},
- {0xf3, 0x73, 0xb3, 0x87, 0x06, 0x5a, 0x28, 0x84, 0x8a, 0xf2,
- 0xf3, 0x4a, 0xce, 0x19, 0x2b, 0xdd, 0xc7, 0x8e, 0x9c, 0xac},
- {0xf5, 0x17, 0xa2, 0x4f, 0x9a, 0x48, 0xc6, 0xc9, 0xf8, 0xa2,
- 0x00, 0x26, 0x9f, 0xdc, 0x0f, 0x48, 0x2c, 0xab, 0x30, 0x89},
- {0xf7, 0x4d, 0xac, 0xb2, 0x14, 0x14, 0xdc, 0xba, 0xab, 0x0b,
- 0x94, 0x7c, 0x8a, 0x25, 0x7c, 0x32, 0x5c, 0xa8, 0x85, 0x50},
- {0xf8, 0xa5, 0x4e, 0x03, 0xaa, 0xdc, 0x56, 0x92, 0xb8, 0x50,
- 0x49, 0x6a, 0x4c, 0x46, 0x30, 0xff, 0xea, 0xa2, 0x9d, 0x83},
- {0xf9, 0xb5, 0xb6, 0x32, 0x45, 0x5f, 0x9c, 0xbe, 0xec, 0x57,
- 0x5f, 0x80, 0xdc, 0xe9, 0x6e, 0x2c, 0xc7, 0xb2, 0x78, 0xb7},
- {0xf9, 0xcd, 0x0e, 0x2c, 0xda, 0x76, 0x24, 0xc1, 0x8f, 0xbd,
- 0xf0, 0xf0, 0xab, 0xb6, 0x45, 0xb8, 0xf7, 0xfe, 0xd5, 0x7a},
- {0xfa, 0xa7, 0xd9, 0xfb, 0x31, 0xb7, 0x46, 0xf2, 0x00, 0xa8,
- 0x5e, 0x65, 0x79, 0x76, 0x13, 0xd8, 0x16, 0xe0, 0x63, 0xb5},
- {0xfa, 0xb7, 0xee, 0x36, 0x97, 0x26, 0x62, 0xfb, 0x2d, 0xb0,
- 0x2a, 0xf6, 0xbf, 0x03, 0xfd, 0xe8, 0x7c, 0x4b, 0x2f, 0x9b},
- {0xfc, 0x21, 0x9a, 0x76, 0x11, 0x2f, 0x76, 0xc1, 0xc5, 0x08,
- 0x83, 0x3c, 0x9a, 0x2f, 0xa2, 0xba, 0x84, 0xac, 0x08, 0x7a},
- {0xfe, 0x45, 0x65, 0x9b, 0x79, 0x03, 0x5b, 0x98, 0xa1, 0x61,
- 0xb5, 0x51, 0x2e, 0xac, 0xda, 0x58, 0x09, 0x48, 0x22, 0x4d},
- {0xfe, 0xb8, 0xc4, 0x32, 0xdc, 0xf9, 0x76, 0x9a, 0xce, 0xae,
- 0x3d, 0xd8, 0x90, 0x8f, 0xfd, 0x28, 0x86, 0x65, 0x64, 0x7d},
- {0xff, 0xad, 0x0e, 0x26, 0xf0, 0x5b, 0xbc, 0xd8, 0x06, 0x3c,
- 0xce, 0x1d, 0xfa, 0x60, 0x24, 0x5e, 0x14, 0x3d, 0x53, 0x80},
-};
-
-#endif // NET_CERT_X509_CERTIFICATE_KNOWN_ROOTS_MAC_H_
diff --git a/chromium/net/cert/x509_certificate_known_roots_win.h b/chromium/net/cert/x509_certificate_known_roots_win.h
index ce7dce86e86..f914ec865d7 100644
--- a/chromium/net/cert/x509_certificate_known_roots_win.h
+++ b/chromium/net/cert/x509_certificate_known_roots_win.h
@@ -5,8 +5,10 @@
#ifndef NET_CERT_X509_CERTIFICATE_KNOWN_ROOTS_WIN_H_
#define NET_CERT_X509_CERTIFICATE_KNOWN_ROOTS_WIN_H_
-// This is a union of Microsoft trust roots over time, from 29 April
-// 2013 through 15 May 2015.
+#include <stdint.h>
+
+// This is a union of Microsoft trust roots over time, from 01 January
+// 2007 through 24 November 2015.
//
// Extracted from
// http://www.download.windowsupdate.com/msdownload/update/v3/
@@ -14,829 +16,1878 @@
//
// Note that these *are not* trust anchors for Chromium. They are only used to
// distinguish `real' root CAs from roots that were user-installed.
-static uint8_t kKnownRootCertSHA1Hashes[][20] = {
- {0x00, 0x48, 0xf8, 0xd3, 0x7b, 0x15, 0x3f, 0x6e, 0xa2, 0x79,
- 0x8c, 0x32, 0x3e, 0xf4, 0xf3, 0x18, 0xa5, 0x62, 0x4a, 0x9e},
- {0x00, 0xea, 0x52, 0x2c, 0x8a, 0x9c, 0x06, 0xaa, 0x3e, 0xcc,
- 0xe0, 0xb4, 0xfa, 0x6c, 0xdc, 0x21, 0xd9, 0x2e, 0x80, 0x99},
- {0x01, 0x68, 0x97, 0xe1, 0xa0, 0xb8, 0xf2, 0xc3, 0xb1, 0x34,
- 0x66, 0x5c, 0x20, 0xa7, 0x27, 0xb7, 0xa1, 0x58, 0xe2, 0x8f},
- {0x02, 0x72, 0x68, 0x29, 0x3e, 0x5f, 0x5d, 0x17, 0xaa, 0xa4,
- 0xb3, 0xc3, 0xe6, 0x36, 0x1e, 0x1f, 0x92, 0x57, 0x5e, 0xaa},
- {0x02, 0xfa, 0xf3, 0xe2, 0x91, 0x43, 0x54, 0x68, 0x60, 0x78,
- 0x57, 0x69, 0x4d, 0xf5, 0xe4, 0x5b, 0x68, 0x85, 0x18, 0x68},
- {0x03, 0x9e, 0xed, 0xb8, 0x0b, 0xe7, 0xa0, 0x3c, 0x69, 0x53,
- 0x89, 0x3b, 0x20, 0xd2, 0xd9, 0x32, 0x3a, 0x4c, 0x2a, 0xfd},
- {0x04, 0x09, 0x56, 0x5b, 0x77, 0xda, 0x58, 0x2e, 0x64, 0x95,
- 0xac, 0x00, 0x60, 0xa7, 0x23, 0x54, 0xe6, 0x4b, 0x01, 0x92},
- {0x04, 0x46, 0xc8, 0xbb, 0x9a, 0x69, 0x83, 0xc9, 0x5c, 0x8a,
- 0x2e, 0x54, 0x64, 0x68, 0x7c, 0x11, 0x15, 0xaa, 0xb7, 0x4a},
- {0x04, 0x56, 0xf2, 0x3d, 0x1e, 0x9c, 0x43, 0xae, 0xcb, 0x0d,
- 0x80, 0x7f, 0x1c, 0x06, 0x47, 0x55, 0x1a, 0x05, 0xf4, 0x56},
- {0x04, 0x83, 0xed, 0x33, 0x99, 0xac, 0x36, 0x08, 0x05, 0x87,
- 0x22, 0xed, 0xbc, 0x5e, 0x46, 0x00, 0xe3, 0xbe, 0xf9, 0xd7},
- {0x04, 0x98, 0x11, 0x05, 0x6a, 0xfe, 0x9f, 0xd0, 0xf5, 0xbe,
- 0x01, 0x68, 0x5a, 0xac, 0xe6, 0xa5, 0xd1, 0xc4, 0x45, 0x4c},
- {0x05, 0x60, 0xa2, 0xc7, 0x38, 0xff, 0x98, 0xd1, 0x17, 0x2a,
- 0x94, 0xfe, 0x45, 0xfb, 0x8a, 0x47, 0xd6, 0x65, 0x37, 0x1e},
- {0x05, 0x63, 0xb8, 0x63, 0x0d, 0x62, 0xd7, 0x5a, 0xbb, 0xc8,
- 0xab, 0x1e, 0x4b, 0xdf, 0xb5, 0xa8, 0x99, 0xb2, 0x4d, 0x43},
- {0x06, 0x08, 0x3f, 0x59, 0x3f, 0x15, 0xa1, 0x04, 0xa0, 0x69,
- 0xa4, 0x6b, 0xa9, 0x03, 0xd0, 0x06, 0xb7, 0x97, 0x09, 0x91},
- {0x06, 0x14, 0x31, 0x51, 0xe0, 0x2b, 0x45, 0xdd, 0xba, 0xdd,
- 0x5d, 0x8e, 0x56, 0x53, 0x0d, 0xaa, 0xe3, 0x28, 0xcf, 0x90},
- {0x07, 0x47, 0x22, 0x01, 0x99, 0xce, 0x74, 0xb9, 0x7c, 0xb0,
- 0x3d, 0x79, 0xb2, 0x64, 0xa2, 0xc8, 0x55, 0xe9, 0x33, 0xff},
- {0x07, 0xe0, 0x32, 0xe0, 0x20, 0xb7, 0x2c, 0x3f, 0x19, 0x2f,
- 0x06, 0x28, 0xa2, 0x59, 0x3a, 0x19, 0xa7, 0x0f, 0x06, 0x9e},
- {0x08, 0x64, 0x18, 0xe9, 0x06, 0xce, 0xe8, 0x9c, 0x23, 0x53,
- 0xb6, 0xe2, 0x7f, 0xbd, 0x9e, 0x74, 0x39, 0xf7, 0x63, 0x16},
- {0x09, 0x3c, 0x61, 0xf3, 0x8b, 0x8b, 0xdc, 0x7d, 0x55, 0xdf,
- 0x75, 0x38, 0x02, 0x05, 0x00, 0xe1, 0x25, 0xf5, 0xc8, 0x36},
- {0x0b, 0x71, 0x99, 0xa1, 0xc7, 0xf3, 0xad, 0xdf, 0x7b, 0xa7,
- 0xea, 0xb8, 0xeb, 0x57, 0x4a, 0xe8, 0x0d, 0x60, 0xdd, 0xde},
- {0x0b, 0x77, 0xbe, 0xbb, 0xcb, 0x7a, 0xa2, 0x47, 0x05, 0xde,
- 0xcc, 0x0f, 0xbd, 0x6a, 0x02, 0xfc, 0x7a, 0xbd, 0x9b, 0x52},
- {0x0b, 0x97, 0x2c, 0x9e, 0xa6, 0xe7, 0xcc, 0x58, 0xd9, 0x3b,
- 0x20, 0xbf, 0x71, 0xec, 0x41, 0x2e, 0x72, 0x09, 0xfa, 0xbf},
- {0x0c, 0x62, 0x8f, 0x5c, 0x55, 0x70, 0xb1, 0xc9, 0x57, 0xfa,
- 0xfd, 0x38, 0x3f, 0xb0, 0x3d, 0x7b, 0x7d, 0xd7, 0xb9, 0xc6},
- {0x0c, 0xfd, 0x83, 0xdb, 0xae, 0x44, 0xb9, 0xa0, 0xc8, 0xf6,
- 0x76, 0xf3, 0xb5, 0x70, 0x65, 0x0b, 0x94, 0xb6, 0x9d, 0xbf},
- {0x10, 0x1d, 0xfa, 0x3f, 0xd5, 0x0b, 0xcb, 0xbb, 0x9b, 0xb5,
- 0x60, 0x0c, 0x19, 0x55, 0xa4, 0x1a, 0xf4, 0x73, 0x3a, 0x04},
- {0x11, 0xc5, 0xb5, 0xf7, 0x55, 0x52, 0xb0, 0x11, 0x66, 0x9c,
- 0x2e, 0x97, 0x17, 0xde, 0x6d, 0x9b, 0xff, 0x5f, 0xa8, 0x10},
- {0x11, 0xe1, 0x9b, 0xbc, 0x74, 0x7b, 0x1a, 0xed, 0x0d, 0xb8,
- 0x33, 0xc9, 0x4c, 0xac, 0x6c, 0x3f, 0x85, 0xbd, 0xeb, 0xdb},
- {0x13, 0x2d, 0x0d, 0x45, 0x53, 0x4b, 0x69, 0x97, 0xcd, 0xb2,
- 0xd5, 0xc3, 0x39, 0xe2, 0x55, 0x76, 0x60, 0x9b, 0x5c, 0xc6},
- {0x15, 0x03, 0x32, 0xa5, 0x8d, 0xc5, 0x91, 0xfc, 0x42, 0xd4,
- 0xc8, 0x73, 0xff, 0x9f, 0x1f, 0x0f, 0x81, 0xd5, 0x97, 0xc9},
- {0x16, 0x32, 0x47, 0x8d, 0x89, 0xf9, 0x21, 0x3a, 0x92, 0x00,
- 0x85, 0x63, 0xf5, 0xa4, 0xa7, 0xd3, 0x12, 0x40, 0x8a, 0xd6},
- {0x16, 0xd8, 0x66, 0x35, 0xaf, 0x13, 0x41, 0xcd, 0x34, 0x79,
- 0x94, 0x45, 0xeb, 0x60, 0x3e, 0x27, 0x37, 0x02, 0x96, 0x5d},
- {0x18, 0xf7, 0xc1, 0xfc, 0xc3, 0x09, 0x02, 0x03, 0xfd, 0x5b,
- 0xaa, 0x2f, 0x86, 0x1a, 0x75, 0x49, 0x76, 0xc8, 0xdd, 0x25},
- {0x1a, 0xc9, 0x2f, 0x09, 0xea, 0x89, 0xe2, 0x8b, 0x12, 0x6d,
- 0xfa, 0xc5, 0x1e, 0x3a, 0xf7, 0xea, 0x90, 0x95, 0xa3, 0xee},
- {0x1b, 0x4b, 0x39, 0x61, 0x26, 0x27, 0x6b, 0x64, 0x91, 0xa2,
- 0x68, 0x6d, 0xd7, 0x02, 0x43, 0x21, 0x2d, 0x1f, 0x1d, 0x96},
- {0x1b, 0x8e, 0xea, 0x57, 0x96, 0x29, 0x1a, 0xc9, 0x39, 0xea,
- 0xb8, 0x0a, 0x81, 0x1a, 0x73, 0x73, 0xc0, 0x93, 0x79, 0x67},
- {0x1f, 0x24, 0xc6, 0x30, 0xcd, 0xa4, 0x18, 0xef, 0x20, 0x69,
- 0xff, 0xad, 0x4f, 0xdd, 0x5f, 0x46, 0x3a, 0x1b, 0x69, 0xaa},
- {0x1f, 0x49, 0x14, 0xf7, 0xd8, 0x74, 0x95, 0x1d, 0xdd, 0xae,
- 0x02, 0xc0, 0xbe, 0xfd, 0x3a, 0x2d, 0x82, 0x75, 0x51, 0x85},
- {0x20, 0x42, 0x85, 0xdc, 0xf7, 0xeb, 0x76, 0x41, 0x95, 0x57,
- 0x8e, 0x13, 0x6b, 0xd4, 0xb7, 0xd1, 0xe9, 0x8e, 0x46, 0xa5},
- {0x20, 0x99, 0x00, 0xb6, 0x3d, 0x95, 0x57, 0x28, 0x14, 0x0c,
- 0xd1, 0x36, 0x22, 0xd8, 0xc6, 0x87, 0xa4, 0xeb, 0x00, 0x85},
- {0x20, 0xcb, 0x59, 0x4f, 0xb4, 0xed, 0xd8, 0x95, 0x76, 0x3f,
- 0xd5, 0x25, 0x4e, 0x95, 0x9a, 0x66, 0x74, 0xc6, 0xee, 0xb2},
- {0x20, 0xd8, 0x06, 0x40, 0xdf, 0x9b, 0x25, 0xf5, 0x12, 0x25,
- 0x3a, 0x11, 0xea, 0xf7, 0x59, 0x8a, 0xeb, 0x14, 0xb5, 0x47},
- {0x21, 0x11, 0x65, 0xca, 0x37, 0x9f, 0xbb, 0x5e, 0xd8, 0x01,
- 0xe3, 0x1c, 0x43, 0x0a, 0x62, 0xaa, 0xc1, 0x09, 0xbc, 0xb4},
- {0x21, 0x6b, 0x2a, 0x29, 0xe6, 0x2a, 0x00, 0xce, 0x82, 0x01,
- 0x46, 0xd8, 0x24, 0x41, 0x41, 0xb9, 0x25, 0x11, 0xb2, 0x79},
- {0x21, 0xfc, 0xbd, 0x8e, 0x7f, 0x6c, 0xaf, 0x05, 0x1b, 0xd1,
- 0xb3, 0x43, 0xec, 0xa8, 0xe7, 0x61, 0x47, 0xf2, 0x0f, 0x8a},
- {0x22, 0xd5, 0xd8, 0xdf, 0x8f, 0x02, 0x31, 0xd1, 0x8d, 0xf7,
- 0x9d, 0xb7, 0xcf, 0x8a, 0x2d, 0x64, 0xc9, 0x3f, 0x6c, 0x3a},
- {0x23, 0x88, 0xc9, 0xd3, 0x71, 0xcc, 0x9e, 0x96, 0x3d, 0xff,
- 0x7d, 0x3c, 0xa7, 0xce, 0xfc, 0xd6, 0x25, 0xec, 0x19, 0x0d},
- {0x23, 0xe5, 0x94, 0x94, 0x51, 0x95, 0xf2, 0x41, 0x48, 0x03,
- 0xb4, 0xd5, 0x64, 0xd2, 0xa3, 0xa3, 0xf5, 0xd8, 0x8b, 0x8c},
- {0x23, 0xe8, 0x33, 0x23, 0x3e, 0x7d, 0x0c, 0xc9, 0x2b, 0x7c,
- 0x42, 0x79, 0xac, 0x19, 0xc2, 0xf4, 0x74, 0xd6, 0x04, 0xca},
- {0x24, 0x5c, 0x97, 0xdf, 0x75, 0x14, 0xe7, 0xcf, 0x2d, 0xf8,
- 0xbe, 0x72, 0xae, 0x95, 0x7b, 0x9e, 0x04, 0x74, 0x1e, 0x85},
- {0x24, 0xa4, 0x0a, 0x1f, 0x57, 0x36, 0x43, 0xa6, 0x7f, 0x0a,
- 0x4b, 0x07, 0x49, 0xf6, 0xa2, 0x2b, 0xf2, 0x8a, 0xbb, 0x6b},
- {0x24, 0xba, 0x6d, 0x6c, 0x8a, 0x5b, 0x58, 0x37, 0xa4, 0x8d,
- 0xb5, 0xfa, 0xe9, 0x19, 0xea, 0x67, 0x5c, 0x94, 0xd2, 0x17},
- {0x25, 0x01, 0x90, 0x19, 0xcf, 0xfb, 0xd9, 0x99, 0x1c, 0xb7,
- 0x68, 0x25, 0x74, 0x8d, 0x94, 0x5f, 0x30, 0x93, 0x95, 0x42},
- {0x25, 0x3f, 0x77, 0x5b, 0x0e, 0x77, 0x97, 0xab, 0x64, 0x5f,
- 0x15, 0x91, 0x55, 0x97, 0xc3, 0x9e, 0x26, 0x36, 0x31, 0xd1},
- {0x26, 0xa1, 0x6c, 0x23, 0x5a, 0x24, 0x72, 0x22, 0x9b, 0x23,
- 0x62, 0x80, 0x25, 0xbc, 0x80, 0x97, 0xc8, 0x85, 0x24, 0xa1},
- {0x27, 0x3e, 0xe1, 0x24, 0x57, 0xfd, 0xc4, 0xf9, 0x0c, 0x55,
- 0xe8, 0x2b, 0x56, 0x16, 0x7f, 0x62, 0xf5, 0x32, 0xe5, 0x47},
- {0x27, 0x96, 0xba, 0xe6, 0x3f, 0x18, 0x01, 0xe2, 0x77, 0x26,
- 0x1b, 0xa0, 0xd7, 0x77, 0x70, 0x02, 0x8f, 0x20, 0xee, 0xe4},
- {0x28, 0x90, 0x3a, 0x63, 0x5b, 0x52, 0x80, 0xfa, 0xe6, 0x77,
- 0x4c, 0x0b, 0x6d, 0xa7, 0xd6, 0xba, 0xa6, 0x4a, 0xf2, 0xe8},
- {0x29, 0x36, 0x21, 0x02, 0x8b, 0x20, 0xed, 0x02, 0xf5, 0x66,
- 0xc5, 0x32, 0xd1, 0xd6, 0xed, 0x90, 0x9f, 0x45, 0x00, 0x2f},
- {0x29, 0x64, 0xb6, 0x86, 0x13, 0x5b, 0x5d, 0xfd, 0xdd, 0x32,
- 0x53, 0xa8, 0x9b, 0xbc, 0x24, 0xd7, 0x4b, 0x08, 0xc6, 0x4d},
- {0x2a, 0xc8, 0xd5, 0x8b, 0x57, 0xce, 0xbf, 0x2f, 0x49, 0xaf,
- 0xf2, 0xfc, 0x76, 0x8f, 0x51, 0x14, 0x62, 0x90, 0x7a, 0x41},
- {0x2b, 0x8f, 0x1b, 0x57, 0x33, 0x0d, 0xbb, 0xa2, 0xd0, 0x7a,
- 0x6c, 0x51, 0xf7, 0x0e, 0xe9, 0x0d, 0xda, 0xb9, 0xad, 0x8e},
- {0x2b, 0xb1, 0xf5, 0x3e, 0x55, 0x0c, 0x1d, 0xc5, 0xf1, 0xd4,
- 0xe6, 0xb7, 0x6a, 0x46, 0x4b, 0x55, 0x06, 0x02, 0xac, 0x21},
- {0x2e, 0x14, 0xda, 0xec, 0x28, 0xf0, 0xfa, 0x1e, 0x8e, 0x38,
- 0x9a, 0x4e, 0xab, 0xeb, 0x26, 0xc0, 0x0a, 0xd3, 0x83, 0xc3},
- {0x2e, 0x66, 0xc9, 0x84, 0x11, 0x81, 0xc0, 0x8f, 0xb1, 0xdf,
- 0xab, 0xd4, 0xff, 0x8d, 0x5c, 0xc7, 0x2b, 0xe0, 0x8f, 0x02},
- {0x30, 0x70, 0xf8, 0x83, 0x3e, 0x4a, 0xa6, 0x80, 0x3e, 0x09,
- 0xa6, 0x46, 0xae, 0x3f, 0x7d, 0x8a, 0xe1, 0xfd, 0x16, 0x54},
- {0x30, 0x77, 0x9e, 0x93, 0x15, 0x02, 0x2e, 0x94, 0x85, 0x6a,
- 0x3f, 0xf8, 0xbc, 0xf8, 0x15, 0xb0, 0x82, 0xf9, 0xae, 0xfd},
- {0x31, 0x7a, 0x2a, 0xd0, 0x7f, 0x2b, 0x33, 0x5e, 0xf5, 0xa1,
- 0xc3, 0x4e, 0x4b, 0x57, 0xe8, 0xb7, 0xd8, 0xf1, 0xfc, 0xa6},
- {0x31, 0xe2, 0xc5, 0x2c, 0xe1, 0x08, 0x9b, 0xef, 0xfd, 0xda,
- 0xdb, 0x26, 0xdd, 0x7c, 0x78, 0x2e, 0xbc, 0x40, 0x37, 0xbd},
- {0x31, 0xf1, 0xfd, 0x68, 0x22, 0x63, 0x20, 0xee, 0xc6, 0x3b,
- 0x3f, 0x9d, 0xea, 0x4a, 0x3e, 0x53, 0x7c, 0x7c, 0x39, 0x17},
- {0x32, 0x3c, 0x11, 0x8e, 0x1b, 0xf7, 0xb8, 0xb6, 0x52, 0x54,
- 0xe2, 0xe2, 0x10, 0x0d, 0xd6, 0x02, 0x90, 0x37, 0xf0, 0x96},
- {0x33, 0x5a, 0x7f, 0xf0, 0x09, 0x27, 0xcf, 0x2d, 0xf2, 0x78,
- 0xe2, 0xc9, 0x19, 0x2f, 0x7a, 0x4d, 0x55, 0x34, 0xf8, 0x0c},
- {0x33, 0x9b, 0x6b, 0x14, 0x50, 0x24, 0x9b, 0x55, 0x7a, 0x01,
- 0x87, 0x72, 0x84, 0xd9, 0xe0, 0x2f, 0xc3, 0xd2, 0xd8, 0xe9},
- {0x34, 0x2c, 0xd9, 0xd3, 0x06, 0x2d, 0xa4, 0x8c, 0x34, 0x69,
- 0x65, 0x29, 0x7f, 0x08, 0x1e, 0xbc, 0x2e, 0xf6, 0x8f, 0xdc},
- {0x34, 0xd4, 0x99, 0x42, 0x6f, 0x9f, 0xc2, 0xbb, 0x27, 0xb0,
- 0x75, 0xba, 0xb6, 0x82, 0xaa, 0xe5, 0xef, 0xfc, 0xba, 0x74},
- {0x36, 0x79, 0xca, 0x35, 0x66, 0x87, 0x72, 0x30, 0x4d, 0x30,
- 0xa5, 0xfb, 0x87, 0x3b, 0x0f, 0xa7, 0x7b, 0xb7, 0x0d, 0x54},
- {0x36, 0x86, 0x35, 0x63, 0xfd, 0x51, 0x28, 0xc7, 0xbe, 0xa6,
- 0xf0, 0x05, 0xcf, 0xe9, 0xb4, 0x36, 0x68, 0x08, 0x6c, 0xce},
- {0x36, 0xb1, 0x2b, 0x49, 0xf9, 0x81, 0x9e, 0xd7, 0x4c, 0x9e,
- 0xbc, 0x38, 0x0f, 0xc6, 0x56, 0x8f, 0x5d, 0xac, 0xb2, 0xf7},
- {0x37, 0x9a, 0x19, 0x7b, 0x41, 0x85, 0x45, 0x35, 0x0c, 0xa6,
- 0x03, 0x69, 0xf3, 0x3c, 0x2e, 0xaf, 0x47, 0x4f, 0x20, 0x79},
- {0x37, 0xf7, 0x6d, 0xe6, 0x07, 0x7c, 0x90, 0xc5, 0xb1, 0x3e,
- 0x93, 0x1a, 0xb7, 0x41, 0x10, 0xb4, 0xf2, 0xe4, 0x9a, 0x27},
- {0x38, 0xdd, 0x76, 0x59, 0xc7, 0x35, 0x10, 0x0b, 0x00, 0xa2,
- 0x37, 0xe4, 0x91, 0xb7, 0xbc, 0x0f, 0xfc, 0xd2, 0x31, 0x6c},
- {0x39, 0x13, 0x85, 0x3e, 0x45, 0xc4, 0x39, 0xa2, 0xda, 0x71,
- 0x8c, 0xdf, 0xb6, 0xf3, 0xe0, 0x33, 0xe0, 0x4f, 0xee, 0x71},
- {0x39, 0x21, 0xc1, 0x15, 0xc1, 0x5d, 0x0e, 0xca, 0x5c, 0xcb,
- 0x5b, 0xc4, 0xf0, 0x7d, 0x21, 0xd8, 0x05, 0x0b, 0x56, 0x6a},
- {0x39, 0x41, 0x0b, 0xc2, 0x30, 0x37, 0x48, 0x06, 0x60, 0x69,
- 0xa7, 0x2a, 0x66, 0x4d, 0xe4, 0xc7, 0x43, 0x48, 0x12, 0x96},
- {0x39, 0x4f, 0xf6, 0x85, 0x0b, 0x06, 0xbe, 0x52, 0xe5, 0x18,
- 0x56, 0xcc, 0x10, 0xe1, 0x80, 0xe8, 0x82, 0xb3, 0x85, 0xcc},
- {0x39, 0x8e, 0xbe, 0x9c, 0x0f, 0x46, 0xc0, 0x79, 0xc3, 0xc7,
- 0xaf, 0xe0, 0x7a, 0x2f, 0xdd, 0x9f, 0xae, 0x5f, 0x8a, 0x5c},
- {0x3a, 0x44, 0x73, 0x5a, 0xe5, 0x81, 0x90, 0x1f, 0x24, 0x86,
- 0x61, 0x46, 0x1e, 0x3b, 0x9c, 0xc4, 0x5f, 0xf5, 0x3a, 0x1b},
- {0x3b, 0x1e, 0xfd, 0x3a, 0x66, 0xea, 0x28, 0xb1, 0x66, 0x97,
- 0x39, 0x47, 0x03, 0xa7, 0x2c, 0xa3, 0x40, 0xa0, 0x5b, 0xd5},
- {0x3b, 0xc0, 0x38, 0x0b, 0x33, 0xc3, 0xf6, 0xa6, 0x0c, 0x86,
- 0x15, 0x22, 0x93, 0xd9, 0xdf, 0xf5, 0x4b, 0x81, 0xc0, 0x04},
- {0x3b, 0xc4, 0x9f, 0x48, 0xf8, 0xf3, 0x73, 0xa0, 0x9c, 0x1e,
- 0xbd, 0xf8, 0x5b, 0xb1, 0xc3, 0x65, 0xc7, 0xd8, 0x11, 0xb3},
- {0x3c, 0x71, 0xd7, 0x0e, 0x35, 0xa5, 0xda, 0xa8, 0xb2, 0xe3,
- 0x81, 0x2d, 0xc3, 0x67, 0x74, 0x17, 0xf5, 0x99, 0x0d, 0xf3},
- {0x3e, 0x2b, 0xf7, 0xf2, 0x03, 0x1b, 0x96, 0xf3, 0x8c, 0xe6,
- 0xc4, 0xd8, 0xa8, 0x5d, 0x3e, 0x2d, 0x58, 0x47, 0x6a, 0x0f},
- {0x3e, 0x42, 0xa1, 0x87, 0x06, 0xbd, 0x0c, 0x9c, 0xcf, 0x59,
- 0x47, 0x50, 0xd2, 0xe4, 0xd6, 0xab, 0x00, 0x48, 0xfd, 0xc4},
- {0x3e, 0x5d, 0x35, 0x8f, 0x28, 0x3a, 0x0f, 0x64, 0x7c, 0x1c,
- 0x92, 0x7f, 0xfb, 0xaa, 0xd4, 0x85, 0x2d, 0x99, 0x72, 0x56},
- {0x3e, 0x84, 0xd3, 0xbc, 0xc5, 0x44, 0xc0, 0xf6, 0xfa, 0x19,
- 0x43, 0x5c, 0x85, 0x1f, 0x3f, 0x2f, 0xcb, 0xa8, 0xe8, 0x14},
- {0x3e, 0xe2, 0x2a, 0xdc, 0x26, 0x7d, 0xde, 0x0e, 0xb0, 0x23,
- 0x17, 0x45, 0xf6, 0xcf, 0x9d, 0x6e, 0xab, 0xd3, 0x3c, 0x19},
- {0x3f, 0x85, 0xf2, 0xbb, 0x4a, 0x62, 0xb0, 0xb5, 0x8b, 0xe1,
- 0x61, 0x4a, 0xbb, 0x0d, 0x46, 0x31, 0xb4, 0xbe, 0xf8, 0xba},
- {0x40, 0x54, 0xda, 0x6f, 0x1c, 0x3f, 0x40, 0x74, 0xac, 0xed,
- 0x0f, 0xec, 0xcd, 0xdb, 0x79, 0xd1, 0x53, 0xfb, 0x90, 0x1d},
- {0x40, 0x9d, 0x4b, 0xd9, 0x17, 0xb5, 0x5c, 0x27, 0xb6, 0x9b,
- 0x64, 0xcb, 0x98, 0x22, 0x44, 0x0d, 0xcd, 0x09, 0xb8, 0x89},
- {0x40, 0xe7, 0x8c, 0x1d, 0x52, 0x3d, 0x1c, 0xd9, 0x95, 0x4f,
- 0xac, 0x1a, 0x1a, 0xb3, 0xbd, 0x3c, 0xba, 0xa1, 0x5b, 0xfc},
- {0x42, 0xef, 0xdd, 0xe6, 0xbf, 0xf3, 0x5e, 0xd0, 0xba, 0xe6,
- 0xac, 0xdd, 0x20, 0x4c, 0x50, 0xae, 0x86, 0xc4, 0xf4, 0xfa},
- {0x43, 0x13, 0xbb, 0x96, 0xf1, 0xd5, 0x86, 0x9b, 0xc1, 0x4e,
- 0x6a, 0x92, 0xf6, 0xcf, 0xf6, 0x34, 0x69, 0x87, 0x82, 0x37},
- {0x43, 0x94, 0xce, 0x31, 0x26, 0xff, 0x1a, 0x22, 0x4c, 0xdd,
- 0x4d, 0xee, 0xb4, 0xf4, 0xec, 0x1d, 0xa3, 0x68, 0xef, 0x6a},
- {0x43, 0xf9, 0xb1, 0x10, 0xd5, 0xba, 0xfd, 0x48, 0x22, 0x52,
- 0x31, 0xb0, 0xd0, 0x08, 0x2b, 0x37, 0x2f, 0xef, 0x9a, 0x54},
- {0x44, 0x63, 0xc5, 0x31, 0xd7, 0xcc, 0xc1, 0x00, 0x67, 0x94,
- 0x61, 0x2b, 0xb6, 0x56, 0xd3, 0xbf, 0x82, 0x57, 0x84, 0x6f},
- {0x47, 0xbe, 0xab, 0xc9, 0x22, 0xea, 0xe8, 0x0e, 0x78, 0x78,
- 0x34, 0x62, 0xa7, 0x9f, 0x45, 0xc2, 0x54, 0xfd, 0xe6, 0x8b},
- {0x48, 0x12, 0xbd, 0x92, 0x3c, 0xa8, 0xc4, 0x39, 0x06, 0xe7,
- 0x30, 0x6d, 0x27, 0x96, 0xe6, 0xa4, 0xcf, 0x22, 0x2e, 0x7d},
- {0x49, 0x0a, 0x75, 0x74, 0xde, 0x87, 0x0a, 0x47, 0xfe, 0x58,
- 0xee, 0xf6, 0xc7, 0x6b, 0xeb, 0xc6, 0x0b, 0x12, 0x40, 0x99},
- {0x4a, 0x05, 0x8f, 0xdf, 0xd7, 0x61, 0xdb, 0x21, 0xb0, 0xc2,
- 0xee, 0x48, 0x57, 0x9b, 0xe2, 0x7f, 0x42, 0xa4, 0xda, 0x1c},
- {0x4a, 0x3f, 0x8d, 0x6b, 0xdc, 0x0e, 0x1e, 0xcf, 0xcd, 0x72,
- 0xe3, 0x77, 0xde, 0xf2, 0xd7, 0xff, 0x92, 0xc1, 0x9b, 0xc7},
- {0x4a, 0xbd, 0xee, 0xec, 0x95, 0x0d, 0x35, 0x9c, 0x89, 0xae,
- 0xc7, 0x52, 0xa1, 0x2c, 0x5b, 0x29, 0xf6, 0xd6, 0xaa, 0x0c},
- {0x4b, 0x6b, 0xd2, 0xd3, 0x88, 0x4e, 0x46, 0xc8, 0x0c, 0xe2,
- 0xb9, 0x62, 0xbc, 0x59, 0x8c, 0xd9, 0xd5, 0xd8, 0x40, 0x13},
- {0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58,
- 0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5},
- {0x4e, 0xfc, 0xed, 0x9c, 0x6b, 0xdd, 0x0c, 0x98, 0x5c, 0xa3,
- 0xc7, 0xd2, 0x53, 0x06, 0x3c, 0x5b, 0xe6, 0xfc, 0x62, 0x0c},
- {0x4f, 0x55, 0x5c, 0xe2, 0x0d, 0xcd, 0x33, 0x64, 0xe0, 0xdc,
- 0x7c, 0x41, 0xef, 0xdd, 0x40, 0xf5, 0x03, 0x56, 0xc1, 0x22},
- {0x4f, 0x65, 0x56, 0x63, 0x36, 0xdb, 0x65, 0x98, 0x58, 0x1d,
- 0x58, 0x4a, 0x59, 0x6c, 0x87, 0x93, 0x4d, 0x5f, 0x2a, 0xb4},
- {0x4f, 0x99, 0xaa, 0x93, 0xfb, 0x2b, 0xd1, 0x37, 0x26, 0xa1,
- 0x99, 0x4a, 0xce, 0x7f, 0xf0, 0x05, 0xf2, 0x93, 0x5d, 0x1e},
- {0x50, 0x30, 0x06, 0x09, 0x1d, 0x97, 0xd4, 0xf5, 0xae, 0x39,
- 0xf7, 0xcb, 0xe7, 0x92, 0x7d, 0x7d, 0x65, 0x2d, 0x34, 0x31},
- {0x51, 0xa4, 0x4c, 0x28, 0xf3, 0x13, 0xe3, 0xf9, 0xcb, 0x5e,
- 0x7c, 0x0a, 0x1e, 0x0e, 0x0d, 0xd2, 0x84, 0x37, 0x58, 0xae},
- {0x51, 0xc6, 0xe7, 0x08, 0x49, 0x06, 0x6e, 0xf3, 0x92, 0xd4,
- 0x5c, 0xa0, 0x0d, 0x6d, 0xa3, 0x62, 0x8f, 0xc3, 0x52, 0x39},
- {0x52, 0x41, 0x2b, 0xd6, 0x7b, 0x5a, 0x6c, 0x69, 0x52, 0x82,
- 0x38, 0x60, 0x26, 0xf0, 0xb0, 0x53, 0xdd, 0x40, 0x0e, 0xfc},
- {0x53, 0x5b, 0x00, 0x16, 0x72, 0xab, 0xbf, 0x7b, 0x6c, 0xc2,
- 0x54, 0x05, 0xae, 0x4d, 0x24, 0xfe, 0x03, 0x3f, 0xd1, 0xcc},
- {0x54, 0xf9, 0xc1, 0x63, 0x75, 0x9f, 0x19, 0x04, 0x51, 0x21,
- 0xa3, 0x19, 0xf6, 0x4c, 0x2d, 0x05, 0x55, 0xb7, 0xe0, 0x73},
- {0x55, 0xa6, 0x72, 0x3e, 0xcb, 0xf2, 0xec, 0xcd, 0xc3, 0x23,
- 0x74, 0x70, 0x19, 0x9d, 0x2a, 0xbe, 0x11, 0xe3, 0x81, 0xd1},
- {0x55, 0xc8, 0x6f, 0x74, 0x14, 0xac, 0x8b, 0xdd, 0x68, 0x14,
- 0xf4, 0xd8, 0x6a, 0xf1, 0x5f, 0x37, 0x10, 0xe1, 0x04, 0xd0},
- {0x56, 0xe0, 0xfa, 0xc0, 0x3b, 0x8f, 0x18, 0x23, 0x55, 0x18,
- 0xe5, 0xd3, 0x11, 0xca, 0xe8, 0xc2, 0x43, 0x31, 0xab, 0x66},
- {0x58, 0x11, 0x9f, 0x0e, 0x12, 0x82, 0x87, 0xea, 0x50, 0xfd,
- 0xd9, 0x87, 0x45, 0x6f, 0x4f, 0x78, 0xdc, 0xfa, 0xd6, 0xd4},
- {0x58, 0x5f, 0x78, 0x75, 0xbe, 0xe7, 0x43, 0x3e, 0xb0, 0x79,
- 0xea, 0xab, 0x7d, 0x05, 0xbb, 0x0f, 0x7a, 0xf2, 0xbc, 0xcc},
- {0x58, 0xd5, 0x2d, 0xb9, 0x33, 0x01, 0xa4, 0xfd, 0x29, 0x1a,
- 0x8c, 0x96, 0x45, 0xa0, 0x8f, 0xee, 0x7f, 0x52, 0x92, 0x82},
- {0x58, 0xe8, 0xab, 0xb0, 0x36, 0x15, 0x33, 0xfb, 0x80, 0xf7,
- 0x9b, 0x1b, 0x6d, 0x29, 0xd3, 0xff, 0x8d, 0x5f, 0x00, 0xf0},
- {0x59, 0x0d, 0x2d, 0x7d, 0x88, 0x4f, 0x40, 0x2e, 0x61, 0x7e,
- 0xa5, 0x62, 0x32, 0x17, 0x65, 0xcf, 0x17, 0xd8, 0x94, 0xe9},
- {0x59, 0x22, 0xa1, 0xe1, 0x5a, 0xea, 0x16, 0x35, 0x21, 0xf8,
- 0x98, 0x39, 0x6a, 0x46, 0x46, 0xb0, 0x44, 0x1b, 0x0f, 0xa9},
- {0x59, 0xaf, 0x82, 0x79, 0x91, 0x86, 0xc7, 0xb4, 0x75, 0x07,
- 0xcb, 0xcf, 0x03, 0x57, 0x46, 0xeb, 0x04, 0xdd, 0xb7, 0x16},
- {0x5a, 0x4d, 0x0e, 0x8b, 0x5f, 0xdc, 0xfd, 0xf6, 0x4e, 0x72,
- 0x99, 0xa3, 0x6c, 0x06, 0x0d, 0xb2, 0x22, 0xca, 0x78, 0xe4},
- {0x5a, 0x5a, 0x4d, 0xaf, 0x78, 0x61, 0x26, 0x7c, 0x4b, 0x1f,
- 0x1e, 0x67, 0x58, 0x6b, 0xae, 0x6e, 0xd4, 0xfe, 0xb9, 0x3f},
- {0x5b, 0xb5, 0x99, 0x20, 0xd1, 0x1b, 0x39, 0x14, 0x79, 0x46,
- 0x3a, 0xdd, 0x51, 0x00, 0xdb, 0x1d, 0x52, 0xf4, 0x3a, 0xd4},
- {0x5d, 0x00, 0x38, 0x60, 0xf0, 0x02, 0xed, 0x82, 0x9d, 0xea,
- 0xa4, 0x18, 0x68, 0xf7, 0x88, 0x18, 0x6d, 0x62, 0x12, 0x7f},
- {0x5d, 0x98, 0x9c, 0xdb, 0x15, 0x96, 0x11, 0x36, 0x51, 0x65,
- 0x64, 0x1b, 0x56, 0x0f, 0xdb, 0xea, 0x2a, 0xc2, 0x3e, 0xf1},
- {0x5f, 0x3a, 0xfc, 0x0a, 0x8b, 0x64, 0xf6, 0x86, 0x67, 0x34,
- 0x74, 0xdf, 0x7e, 0xa9, 0xa2, 0xfe, 0xf9, 0xfa, 0x7a, 0x51},
- {0x5f, 0x3b, 0x8c, 0xf2, 0xf8, 0x10, 0xb3, 0x7d, 0x78, 0xb4,
- 0xce, 0xec, 0x19, 0x19, 0xc3, 0x73, 0x34, 0xb9, 0xc7, 0x74},
- {0x5f, 0x43, 0xe5, 0xb1, 0xbf, 0xf8, 0x78, 0x8c, 0xac, 0x1c,
- 0xc7, 0xca, 0x4a, 0x9a, 0xc6, 0x22, 0x2b, 0xcc, 0x34, 0xc6},
- {0x5f, 0x4e, 0x1f, 0xcf, 0x31, 0xb7, 0x91, 0x3b, 0x85, 0x0b,
- 0x54, 0xf6, 0xe5, 0xff, 0x50, 0x1a, 0x2b, 0x6f, 0xc6, 0xcf},
- {0x5f, 0xb7, 0xee, 0x06, 0x33, 0xe2, 0x59, 0xdb, 0xad, 0x0c,
- 0x4c, 0x9a, 0xe6, 0xd3, 0x8f, 0x1a, 0x61, 0xc7, 0xdc, 0x25},
- {0x60, 0xd6, 0x89, 0x74, 0xb5, 0xc2, 0x65, 0x9e, 0x8a, 0x0f,
- 0xc1, 0x88, 0x7c, 0x88, 0xd2, 0x46, 0x69, 0x1b, 0x18, 0x2c},
- {0x61, 0x57, 0x3a, 0x11, 0xdf, 0x0e, 0xd8, 0x7e, 0xd5, 0x92,
- 0x65, 0x22, 0xea, 0xd0, 0x56, 0xd7, 0x44, 0xb3, 0x23, 0x71},
- {0x61, 0xef, 0x43, 0xd7, 0x7f, 0xca, 0xd4, 0x61, 0x51, 0xbc,
- 0x98, 0xe0, 0xc3, 0x59, 0x12, 0xaf, 0x9f, 0xeb, 0x63, 0x11},
- {0x62, 0x52, 0xdc, 0x40, 0xf7, 0x11, 0x43, 0xa2, 0x2f, 0xde,
- 0x9e, 0xf7, 0x34, 0x8e, 0x06, 0x42, 0x51, 0xb1, 0x81, 0x18},
- {0x62, 0x7f, 0x8d, 0x78, 0x27, 0x65, 0x63, 0x99, 0xd2, 0x7d,
- 0x7f, 0x90, 0x44, 0xc9, 0xfe, 0xb3, 0xf3, 0x3e, 0xfa, 0x9a},
- {0x64, 0x90, 0x2a, 0xd7, 0x27, 0x7a, 0xf3, 0xe3, 0x2c, 0xd8,
- 0xcc, 0x1d, 0xc7, 0x9d, 0xe1, 0xfd, 0x7f, 0x80, 0x69, 0xea},
- {0x67, 0x24, 0x89, 0x80, 0xde, 0x77, 0x5d, 0x2c, 0x9b, 0x04,
- 0xe4, 0x03, 0x07, 0x94, 0x0b, 0xad, 0xb3, 0x51, 0xf3, 0x95},
- {0x67, 0x65, 0x0d, 0xf1, 0x7e, 0x8e, 0x7e, 0x5b, 0x82, 0x40,
- 0xa4, 0xf4, 0x56, 0x4b, 0xcf, 0xe2, 0x3d, 0x69, 0xc6, 0xf0},
- {0x67, 0x82, 0xaa, 0xe0, 0xed, 0xee, 0xe2, 0x1a, 0x58, 0x39,
- 0xd3, 0xc0, 0xcd, 0x14, 0x68, 0x0a, 0x4f, 0x60, 0x14, 0x2a},
- {0x67, 0x9a, 0x4f, 0x81, 0xfc, 0x70, 0x5d, 0xde, 0xc4, 0x19,
- 0x77, 0x8d, 0xd2, 0xeb, 0xd8, 0x75, 0xf4, 0xc2, 0x42, 0xc6},
- {0x67, 0xeb, 0x33, 0x7b, 0x68, 0x4c, 0xeb, 0x0e, 0xc2, 0xb0,
- 0x76, 0x0a, 0xb4, 0x88, 0x27, 0x8c, 0xdd, 0x95, 0x97, 0xdd},
- {0x68, 0x8b, 0x6e, 0xb8, 0x07, 0xe8, 0xed, 0xa5, 0xc7, 0xb1,
- 0x7c, 0x43, 0x93, 0xd0, 0x79, 0x5f, 0x0f, 0xae, 0x15, 0x5f},
- {0x68, 0xed, 0x18, 0xb3, 0x09, 0xcd, 0x52, 0x91, 0xc0, 0xd3,
- 0x35, 0x7c, 0x1d, 0x11, 0x41, 0xbf, 0x88, 0x38, 0x66, 0xb1},
- {0x69, 0x69, 0x56, 0x2e, 0x40, 0x80, 0xf4, 0x24, 0xa1, 0xe7,
- 0x19, 0x9f, 0x14, 0xba, 0xf3, 0xee, 0x58, 0xab, 0x6a, 0xbb},
- {0x69, 0xbd, 0x8c, 0xf4, 0x9c, 0xd3, 0x00, 0xfb, 0x59, 0x2e,
- 0x17, 0x93, 0xca, 0x55, 0x6a, 0xf3, 0xec, 0xaa, 0x35, 0xfb},
- {0x6a, 0x17, 0x45, 0x70, 0xa9, 0x16, 0xfb, 0xe8, 0x44, 0x53,
- 0xee, 0xd3, 0xd0, 0x70, 0xa1, 0xd8, 0xda, 0x44, 0x28, 0x29},
- {0x6a, 0x6f, 0x2a, 0x8b, 0x6e, 0x26, 0x15, 0x08, 0x8d, 0xf5,
- 0x9c, 0xd2, 0x4c, 0x40, 0x24, 0x18, 0xae, 0x42, 0xa3, 0xf1},
- {0x6a, 0xd2, 0x3b, 0x9d, 0xc4, 0x8e, 0x37, 0x5f, 0x85, 0x9a,
- 0xd9, 0xca, 0xb5, 0x85, 0x32, 0x5c, 0x23, 0x89, 0x40, 0x71},
- {0x6b, 0x2f, 0x34, 0xad, 0x89, 0x58, 0xbe, 0x62, 0xfd, 0xb0,
- 0x6b, 0x5c, 0xce, 0xbb, 0x9d, 0xd9, 0x4f, 0x4e, 0x39, 0xf3},
- {0x6b, 0x81, 0x44, 0x6a, 0x5c, 0xdd, 0xf4, 0x74, 0xa0, 0xf8,
- 0x00, 0xff, 0xbe, 0x69, 0xfd, 0x0d, 0xb6, 0x28, 0x75, 0x16},
- {0x6d, 0xc5, 0xe5, 0x62, 0xa9, 0xfd, 0x64, 0xd4, 0xbb, 0x2f,
- 0x63, 0x1c, 0xcd, 0x04, 0x1e, 0x9a, 0xa6, 0xff, 0x60, 0xf1},
- {0x6e, 0x3a, 0x55, 0xa4, 0x19, 0x0c, 0x19, 0x5c, 0x93, 0x84,
- 0x3c, 0xc0, 0xdb, 0x72, 0x2e, 0x31, 0x30, 0x61, 0xf0, 0xb1},
- {0x6f, 0x38, 0x84, 0x56, 0x8e, 0x99, 0xc8, 0xc6, 0xac, 0x0e,
- 0x5d, 0xde, 0x2d, 0xb2, 0x02, 0xdd, 0x00, 0x2e, 0x36, 0x63},
- {0x6f, 0x62, 0xde, 0xb8, 0x6c, 0x85, 0x58, 0x5a, 0xe4, 0x2e,
- 0x47, 0x8d, 0xb4, 0xd7, 0x6d, 0xb3, 0x67, 0x58, 0x5a, 0xe6},
- {0x70, 0x17, 0x9b, 0x86, 0x8c, 0x00, 0xa4, 0xfa, 0x60, 0x91,
- 0x52, 0x22, 0x3f, 0x9f, 0x3e, 0x32, 0xbd, 0xe0, 0x05, 0x62},
- {0x70, 0x30, 0xaa, 0xbf, 0x84, 0x32, 0xa8, 0x00, 0x66, 0x6c,
- 0xcc, 0xc4, 0x2a, 0x88, 0x7e, 0x42, 0xb7, 0x55, 0x3e, 0x2b},
- {0x70, 0x5d, 0x2b, 0x45, 0x65, 0xc7, 0x04, 0x7a, 0x54, 0x06,
- 0x94, 0xa7, 0x9a, 0xf7, 0xab, 0xb8, 0x42, 0xbd, 0xc1, 0x61},
- {0x71, 0x89, 0x9a, 0x67, 0xbf, 0x33, 0xaf, 0x31, 0xbe, 0xfd,
- 0xc0, 0x71, 0xf8, 0xf7, 0x33, 0xb1, 0x83, 0x85, 0x63, 0x32},
- {0x72, 0x0f, 0xc1, 0x5d, 0xdc, 0x27, 0xd4, 0x56, 0xd0, 0x98,
- 0xfa, 0xbf, 0x3c, 0xdd, 0x78, 0xd3, 0x1e, 0xf5, 0xa8, 0xda},
- {0x74, 0x20, 0x74, 0x41, 0x72, 0x9c, 0xdd, 0x92, 0xec, 0x79,
- 0x31, 0xd8, 0x23, 0x10, 0x8d, 0xc2, 0x81, 0x92, 0xe2, 0xbb},
- {0x74, 0x2c, 0x31, 0x92, 0xe6, 0x07, 0xe4, 0x24, 0xeb, 0x45,
- 0x49, 0x54, 0x2b, 0xe1, 0xbb, 0xc5, 0x3e, 0x61, 0x74, 0xe2},
- {0x74, 0x2c, 0xdf, 0x15, 0x94, 0x04, 0x9c, 0xbf, 0x17, 0xa2,
- 0x04, 0x6c, 0xc6, 0x39, 0xbb, 0x38, 0x88, 0xe0, 0x2e, 0x33},
- {0x75, 0x02, 0x51, 0xb2, 0xc6, 0x32, 0x53, 0x6f, 0x9d, 0x91,
- 0x72, 0x79, 0x54, 0x3c, 0x13, 0x7c, 0xd7, 0x21, 0xc6, 0xe0},
- {0x75, 0xe0, 0xab, 0xb6, 0x13, 0x85, 0x12, 0x27, 0x1c, 0x04,
- 0xf8, 0x5f, 0xdd, 0xde, 0x38, 0xe4, 0xb7, 0x24, 0x2e, 0xfe},
- {0x76, 0x12, 0xed, 0x9e, 0x49, 0xb3, 0x65, 0xb4, 0xda, 0xd3,
- 0x12, 0x0c, 0x01, 0xe6, 0x03, 0x74, 0x8d, 0xae, 0x8c, 0xf0},
- {0x76, 0x39, 0xc7, 0x18, 0x47, 0xe1, 0x51, 0xb5, 0xc7, 0xea,
- 0x01, 0xc7, 0x58, 0xfb, 0xf1, 0x2a, 0xba, 0x29, 0x8f, 0x7a},
- {0x76, 0xb7, 0x60, 0x96, 0xdd, 0x14, 0x56, 0x29, 0xac, 0x75,
- 0x85, 0xd3, 0x70, 0x63, 0xc1, 0xbc, 0x47, 0x86, 0x1c, 0x8b},
- {0x76, 0xe2, 0x7e, 0xc1, 0x4f, 0xdb, 0x82, 0xc1, 0xc0, 0xa6,
- 0x75, 0xb5, 0x05, 0xbe, 0x3d, 0x29, 0xb4, 0xed, 0xdb, 0xbb},
- {0x77, 0x47, 0x4f, 0xc6, 0x30, 0xe4, 0x0f, 0x4c, 0x47, 0x64,
- 0x3f, 0x84, 0xba, 0xb8, 0xc6, 0x95, 0x4a, 0x8a, 0x41, 0xec},
- {0x78, 0x6a, 0x74, 0xac, 0x76, 0xab, 0x14, 0x7f, 0x9c, 0x6a,
- 0x30, 0x50, 0xba, 0x9e, 0xa8, 0x7e, 0xfe, 0x9a, 0xce, 0x3c},
- {0x78, 0xe9, 0xdd, 0x06, 0x50, 0x62, 0x4d, 0xb9, 0xcb, 0x36,
- 0xb5, 0x07, 0x67, 0xf2, 0x09, 0xb8, 0x43, 0xbe, 0x15, 0xb3},
- {0x79, 0x98, 0xa3, 0x08, 0xe1, 0x4d, 0x65, 0x85, 0xe6, 0xc2,
- 0x1e, 0x15, 0x3a, 0x71, 0x9f, 0xba, 0x5a, 0xd3, 0x4a, 0xd9},
- {0x7a, 0x1c, 0xdd, 0xe3, 0xd2, 0x19, 0x7e, 0x71, 0x37, 0x43,
- 0x3d, 0x3f, 0x99, 0xc0, 0xb3, 0x69, 0xf7, 0x06, 0xc7, 0x49},
- {0x7a, 0x74, 0x41, 0x0f, 0xb0, 0xcd, 0x5c, 0x97, 0x2a, 0x36,
- 0x4b, 0x71, 0xbf, 0x03, 0x1d, 0x88, 0xa6, 0x51, 0x0e, 0x9e},
- {0x7a, 0xc5, 0xff, 0xf8, 0xdc, 0xbc, 0x55, 0x83, 0x17, 0x68,
- 0x77, 0x07, 0x3b, 0xf7, 0x51, 0x73, 0x5e, 0x9b, 0xd3, 0x58},
- {0x7e, 0x04, 0xde, 0x89, 0x6a, 0x3e, 0x66, 0x6d, 0x00, 0xe6,
- 0x87, 0xd3, 0x3f, 0xfa, 0xd9, 0x3b, 0xe8, 0x3d, 0x34, 0x9e},
- {0x7e, 0x20, 0x69, 0x39, 0xcc, 0x5f, 0xa8, 0x83, 0x63, 0x5f,
- 0x64, 0xc7, 0x50, 0xeb, 0xf5, 0xfd, 0xa9, 0xae, 0xe6, 0x53},
- {0x7e, 0x78, 0x4a, 0x10, 0x1c, 0x82, 0x65, 0xcc, 0x2d, 0xe1,
- 0xf1, 0x6d, 0x47, 0xb4, 0x40, 0xca, 0xd9, 0x0a, 0x19, 0x45},
- {0x7e, 0xb1, 0xa0, 0x42, 0x9b, 0xe5, 0xf4, 0x28, 0xac, 0x2b,
- 0x93, 0x97, 0x1d, 0x7c, 0x84, 0x48, 0xa5, 0x36, 0x07, 0x0c},
- {0x7f, 0x88, 0xcd, 0x72, 0x23, 0xf3, 0xc8, 0x13, 0x81, 0x8c,
- 0x99, 0x46, 0x14, 0xa8, 0x9c, 0x99, 0xfa, 0x3b, 0x52, 0x47},
- {0x7f, 0x8a, 0x77, 0x83, 0x6b, 0xdc, 0x6d, 0x06, 0x8f, 0x8b,
- 0x07, 0x37, 0xfc, 0xc5, 0x72, 0x54, 0x13, 0x06, 0x8c, 0xa4},
- {0x7f, 0x8a, 0xb0, 0xcf, 0xd0, 0x51, 0x87, 0x6a, 0x66, 0xf3,
- 0x36, 0x0f, 0x47, 0xc8, 0x8d, 0x8c, 0xd3, 0x35, 0xfc, 0x74},
- {0x7f, 0xb9, 0xe2, 0xc9, 0x95, 0xc9, 0x7a, 0x93, 0x9f, 0x9e,
- 0x81, 0xa0, 0x7a, 0xea, 0x9b, 0x4d, 0x70, 0x46, 0x34, 0x96},
- {0x7f, 0xbb, 0x6a, 0xcd, 0x7e, 0x0a, 0xb4, 0x38, 0xda, 0xaf,
- 0x6f, 0xd5, 0x02, 0x10, 0xd0, 0x07, 0xc6, 0xc0, 0x82, 0x9c},
- {0x80, 0x25, 0xef, 0xf4, 0x6e, 0x70, 0xc8, 0xd4, 0x72, 0x24,
- 0x65, 0x84, 0xfe, 0x40, 0x3b, 0x8a, 0x8d, 0x6a, 0xdb, 0xf5},
- {0x80, 0xbf, 0x3d, 0xe9, 0xa4, 0x1d, 0x76, 0x8d, 0x19, 0x4b,
- 0x29, 0x3c, 0x85, 0x63, 0x2c, 0xdb, 0xc8, 0xea, 0x8c, 0xf7},
- {0x81, 0x96, 0x8b, 0x3a, 0xef, 0x1c, 0xdc, 0x70, 0xf5, 0xfa,
- 0x32, 0x69, 0xc2, 0x92, 0xa3, 0x63, 0x5b, 0xd1, 0x23, 0xd3},
- {0x82, 0x50, 0xbe, 0xd5, 0xa2, 0x14, 0x43, 0x3a, 0x66, 0x37,
- 0x7c, 0xbc, 0x10, 0xef, 0x83, 0xf6, 0x69, 0xda, 0x3a, 0x67},
- {0x83, 0x51, 0x50, 0x9b, 0x7d, 0xf8, 0xcf, 0xe8, 0x7b, 0xae,
- 0x62, 0xae, 0xb9, 0xb0, 0x3a, 0x52, 0xf4, 0xe6, 0x2c, 0x79},
- {0x83, 0x8e, 0x30, 0xf7, 0x7f, 0xdd, 0x14, 0xaa, 0x38, 0x5e,
- 0xd1, 0x45, 0x00, 0x9c, 0x0e, 0x22, 0x36, 0x49, 0x4f, 0xaa},
- {0x84, 0x42, 0x9d, 0x9f, 0xe2, 0xe7, 0x3a, 0x0d, 0xc8, 0xaa,
- 0x0a, 0xe0, 0xa9, 0x02, 0xf2, 0x74, 0x99, 0x33, 0xfe, 0x02},
- {0x85, 0x37, 0x1c, 0xa6, 0xe5, 0x50, 0x14, 0x3d, 0xce, 0x28,
- 0x03, 0x47, 0x1b, 0xde, 0x3a, 0x09, 0xe8, 0xf8, 0x77, 0x0f},
- {0x85, 0xa4, 0x08, 0xc0, 0x9c, 0x19, 0x3e, 0x5d, 0x51, 0x58,
- 0x7d, 0xcd, 0xd6, 0x13, 0x30, 0xfd, 0x8c, 0xde, 0x37, 0xbf},
- {0x85, 0xb5, 0xff, 0x67, 0x9b, 0x0c, 0x79, 0x96, 0x1f, 0xc8,
- 0x6e, 0x44, 0x22, 0x00, 0x46, 0x13, 0xdb, 0x17, 0x92, 0x84},
- {0x87, 0x81, 0xc2, 0x5a, 0x96, 0xbd, 0xc2, 0xfb, 0x4c, 0x65,
- 0x06, 0x4f, 0xf9, 0x39, 0x0b, 0x26, 0x04, 0x8a, 0x0e, 0x01},
- {0x87, 0x82, 0xc6, 0xc3, 0x04, 0x35, 0x3b, 0xcf, 0xd2, 0x96,
- 0x92, 0xd2, 0x59, 0x3e, 0x7d, 0x44, 0xd9, 0x34, 0xff, 0x11},
- {0x87, 0x9f, 0x4b, 0xee, 0x05, 0xdf, 0x98, 0x58, 0x3b, 0xe3,
- 0x60, 0xd6, 0x33, 0xe7, 0x0d, 0x3f, 0xfe, 0x98, 0x71, 0xaf},
- {0x89, 0xc3, 0x2e, 0x6b, 0x52, 0x4e, 0x4d, 0x65, 0x38, 0x8b,
- 0x9e, 0xce, 0xdc, 0x63, 0x71, 0x34, 0xed, 0x41, 0x93, 0xa3},
- {0x89, 0xdf, 0x74, 0xfe, 0x5c, 0xf4, 0x0f, 0x4a, 0x80, 0xf9,
- 0xe3, 0x37, 0x7d, 0x54, 0xda, 0x91, 0xe1, 0x01, 0x31, 0x8e},
- {0x8a, 0x5c, 0x8c, 0xee, 0xa5, 0x03, 0xe6, 0x05, 0x56, 0xba,
- 0xd8, 0x1b, 0xd4, 0xf6, 0xc9, 0xb0, 0xed, 0xe5, 0x2f, 0xe0},
- {0x8b, 0x1a, 0x11, 0x06, 0xb8, 0xe2, 0x6b, 0x23, 0x29, 0x80,
- 0xfd, 0x65, 0x2e, 0x61, 0x81, 0x37, 0x64, 0x41, 0xfd, 0x11},
- {0x8b, 0xaf, 0x4c, 0x9b, 0x1d, 0xf0, 0x2a, 0x92, 0xf7, 0xda,
- 0x12, 0x8e, 0xb9, 0x1b, 0xac, 0xf4, 0x98, 0x60, 0x4b, 0x6f},
- {0x8c, 0x96, 0xba, 0xeb, 0xdd, 0x2b, 0x07, 0x07, 0x48, 0xee,
- 0x30, 0x32, 0x66, 0xa0, 0xf3, 0x98, 0x6e, 0x7c, 0xae, 0x58},
- {0x8c, 0xc4, 0x30, 0x7b, 0xc6, 0x07, 0x55, 0xe7, 0xb2, 0x2d,
- 0xd9, 0xf7, 0xfe, 0xa2, 0x45, 0x93, 0x6c, 0x7c, 0xf2, 0x88},
- {0x8c, 0xf4, 0x27, 0xfd, 0x79, 0x0c, 0x3a, 0xd1, 0x66, 0x06,
- 0x8d, 0xe8, 0x1e, 0x57, 0xef, 0xbb, 0x93, 0x22, 0x72, 0xd4},
- {0x8d, 0x08, 0xfc, 0x43, 0xc0, 0x77, 0x0c, 0xa8, 0x4f, 0x4d,
- 0xcc, 0xb2, 0xd4, 0x1a, 0x5d, 0x95, 0x6d, 0x78, 0x6d, 0xc4},
- {0x8d, 0x17, 0x84, 0xd5, 0x37, 0xf3, 0x03, 0x7d, 0xec, 0x70,
- 0xfe, 0x57, 0x8b, 0x51, 0x9a, 0x99, 0xe6, 0x10, 0xd7, 0xb0},
- {0x8e, 0x10, 0x32, 0xe9, 0x24, 0x59, 0x44, 0xf8, 0x47, 0x91,
- 0x98, 0x3e, 0xc9, 0xe8, 0x29, 0xcb, 0x10, 0x59, 0xb4, 0xd3},
- {0x8e, 0x1c, 0x74, 0xf8, 0xa6, 0x20, 0xb9, 0xe5, 0x8a, 0xf4,
- 0x61, 0xfa, 0xec, 0x2b, 0x47, 0x56, 0x51, 0x1a, 0x52, 0xc6},
- {0x8e, 0xb0, 0x3f, 0xc3, 0xcf, 0x7b, 0xb2, 0x92, 0x86, 0x62,
- 0x68, 0xb7, 0x51, 0x22, 0x3d, 0xb5, 0x10, 0x34, 0x05, 0xcb},
- {0x8e, 0xfd, 0xca, 0xbc, 0x93, 0xe6, 0x1e, 0x92, 0x5d, 0x4d,
- 0x1d, 0xed, 0x18, 0x1a, 0x43, 0x20, 0xa4, 0x67, 0xa1, 0x39},
- {0x8f, 0x43, 0x28, 0x8a, 0xd2, 0x72, 0xf3, 0x10, 0x3b, 0x6f,
- 0xb1, 0x42, 0x84, 0x85, 0xea, 0x30, 0x14, 0xc0, 0xbc, 0xfe},
- {0x90, 0x5f, 0x94, 0x2f, 0xd9, 0xf2, 0x8f, 0x67, 0x9b, 0x37,
- 0x81, 0x80, 0xfd, 0x4f, 0x84, 0x63, 0x47, 0xf6, 0x45, 0xc1},
- {0x90, 0x78, 0xc5, 0xa2, 0x8f, 0x9a, 0x43, 0x25, 0xc2, 0xa7,
- 0xc7, 0x38, 0x13, 0xcd, 0xfe, 0x13, 0xc2, 0x0f, 0x93, 0x4e},
- {0x90, 0xae, 0xa2, 0x69, 0x85, 0xff, 0x14, 0x80, 0x4c, 0x43,
- 0x49, 0x52, 0xec, 0xe9, 0x60, 0x84, 0x77, 0xaf, 0x55, 0x6f},
- {0x90, 0xde, 0xce, 0x77, 0xf8, 0xc8, 0x25, 0x34, 0x0e, 0x62,
- 0xeb, 0xd6, 0x35, 0xe1, 0xbe, 0x20, 0xcf, 0x73, 0x27, 0xdd},
- {0x90, 0xde, 0xde, 0x9e, 0x4c, 0x4e, 0x9f, 0x6f, 0xd8, 0x86,
- 0x17, 0x57, 0x9d, 0xd3, 0x91, 0xbc, 0x65, 0xa6, 0x89, 0x64},
- {0x91, 0x21, 0x98, 0xee, 0xf2, 0x3d, 0xca, 0xc4, 0x09, 0x39,
- 0x31, 0x2f, 0xee, 0x97, 0xdd, 0x56, 0x0b, 0xae, 0x49, 0xb1},
- {0x91, 0x58, 0xc5, 0xef, 0x98, 0x73, 0x01, 0xa8, 0x90, 0x3c,
- 0xfd, 0xab, 0x03, 0xd7, 0x2d, 0xa1, 0xd8, 0x89, 0x09, 0xc9},
- {0x91, 0xc6, 0xd6, 0xee, 0x3e, 0x8a, 0xc8, 0x63, 0x84, 0xe5,
- 0x48, 0xc2, 0x99, 0x29, 0x5c, 0x75, 0x6c, 0x81, 0x7b, 0x81},
- {0x92, 0x5a, 0x8f, 0x8d, 0x2c, 0x6d, 0x04, 0xe0, 0x66, 0x5f,
- 0x59, 0x6a, 0xff, 0x22, 0xd8, 0x63, 0xe8, 0x25, 0x6f, 0x3f},
- {0x93, 0x05, 0x7a, 0x88, 0x15, 0xc6, 0x4f, 0xce, 0x88, 0x2f,
- 0xfa, 0x91, 0x16, 0x52, 0x28, 0x78, 0xbc, 0x53, 0x64, 0x17},
- {0x93, 0xe6, 0xab, 0x22, 0x03, 0x03, 0xb5, 0x23, 0x28, 0xdc,
- 0xda, 0x56, 0x9e, 0xba, 0xe4, 0xd1, 0xd1, 0xcc, 0xfb, 0x65},
- {0x93, 0xf7, 0xf4, 0x8b, 0x12, 0x61, 0x94, 0x3f, 0x6a, 0x78,
- 0x21, 0x0c, 0x52, 0xe6, 0x26, 0xdf, 0xbf, 0xbb, 0xe2, 0x60},
- {0x96, 0x56, 0xcd, 0x7b, 0x57, 0x96, 0x98, 0x95, 0xd0, 0xe1,
- 0x41, 0x46, 0x68, 0x06, 0xfb, 0xb8, 0xc6, 0x11, 0x06, 0x87},
- {0x96, 0x83, 0x38, 0xf1, 0x13, 0xe3, 0x6a, 0x7b, 0xab, 0xdd,
- 0x08, 0xf7, 0x77, 0x63, 0x91, 0xa6, 0x87, 0x36, 0x58, 0x2e},
- {0x96, 0x97, 0x4c, 0xd6, 0xb6, 0x63, 0xa7, 0x18, 0x45, 0x26,
- 0xb1, 0xd6, 0x48, 0xad, 0x81, 0x5c, 0xf5, 0x1e, 0x80, 0x1a},
- {0x96, 0xc9, 0x1b, 0x0b, 0x95, 0xb4, 0x10, 0x98, 0x42, 0xfa,
- 0xd0, 0xd8, 0x22, 0x79, 0xfe, 0x60, 0xfa, 0xb9, 0x16, 0x83},
- {0x97, 0x1d, 0x34, 0x86, 0xfc, 0x1e, 0x8e, 0x63, 0x15, 0xf7,
- 0xc6, 0xf2, 0xe1, 0x29, 0x67, 0xc7, 0x24, 0x34, 0x22, 0x14},
- {0x97, 0x22, 0x6a, 0xae, 0x4a, 0x7a, 0x64, 0xa5, 0x9b, 0xd1,
- 0x67, 0x87, 0xf2, 0x7f, 0x84, 0x1c, 0x0a, 0x00, 0x1f, 0xd0},
- {0x97, 0x81, 0x79, 0x50, 0xd8, 0x1c, 0x96, 0x70, 0xcc, 0x34,
- 0xd8, 0x09, 0xcf, 0x79, 0x44, 0x31, 0x36, 0x7e, 0xf4, 0x74},
- {0x97, 0xe2, 0xe9, 0x96, 0x36, 0xa5, 0x47, 0x55, 0x4f, 0x83,
- 0x8f, 0xba, 0x38, 0xb8, 0x2e, 0x74, 0xf8, 0x9a, 0x83, 0x0a},
- {0x99, 0x57, 0xc5, 0x3f, 0xc5, 0x9f, 0xb8, 0xe7, 0x39, 0xf7,
- 0xa4, 0xb7, 0xa7, 0x0e, 0x9b, 0x8e, 0x65, 0x9f, 0x20, 0x8c},
- {0x99, 0xa6, 0x9b, 0xe6, 0x1a, 0xfe, 0x88, 0x6b, 0x4d, 0x2b,
- 0x82, 0x00, 0x7c, 0xb8, 0x54, 0xfc, 0x31, 0x7e, 0x15, 0x39},
- {0x9b, 0xaa, 0xe5, 0x9f, 0x56, 0xee, 0x21, 0xcb, 0x43, 0x5a,
- 0xbe, 0x25, 0x93, 0xdf, 0xa7, 0xf0, 0x40, 0xd1, 0x1d, 0xcb},
- {0x9c, 0x61, 0x5c, 0x4d, 0x4d, 0x85, 0x10, 0x3a, 0x53, 0x26,
- 0xc2, 0x4d, 0xba, 0xea, 0xe4, 0xa2, 0xd2, 0xd5, 0xcc, 0x97},
- {0x9c, 0xbb, 0x48, 0x53, 0xf6, 0xa4, 0xf6, 0xd3, 0x52, 0xa4,
- 0xe8, 0x32, 0x52, 0x55, 0x60, 0x13, 0xf5, 0xad, 0xaf, 0x65},
- {0x9c, 0xde, 0x26, 0xd0, 0x7b, 0xb6, 0x8d, 0xe3, 0x50, 0xc8,
- 0x35, 0xe7, 0x95, 0x0e, 0xe8, 0x1c, 0xde, 0x97, 0x87, 0xf5},
- {0x9d, 0x70, 0xbb, 0x01, 0xa5, 0xa4, 0xa0, 0x18, 0x11, 0x2e,
- 0xf7, 0x1c, 0x01, 0xb9, 0x32, 0xc5, 0x34, 0xe7, 0x88, 0xa8},
- {0x9e, 0xd1, 0x80, 0x28, 0xfb, 0x1e, 0x8a, 0x97, 0x01, 0x48,
- 0x0a, 0x78, 0x90, 0xa5, 0x9a, 0xcd, 0x73, 0xdf, 0xf8, 0x71},
- {0x9f, 0x74, 0x4e, 0x9f, 0x2b, 0x4d, 0xba, 0xec, 0x0f, 0x31,
- 0x2c, 0x50, 0xb6, 0x56, 0x3b, 0x8e, 0x2d, 0x93, 0xc3, 0x11},
- {0x9f, 0xad, 0x91, 0xa6, 0xce, 0x6a, 0xc6, 0xc5, 0x00, 0x47,
- 0xc4, 0x4e, 0xc9, 0xd4, 0xa5, 0x0d, 0x92, 0xd8, 0x49, 0x79},
- {0x9f, 0xc7, 0x96, 0xe8, 0xf8, 0x52, 0x4f, 0x86, 0x3a, 0xe1,
- 0x49, 0x6d, 0x38, 0x12, 0x42, 0x10, 0x5f, 0x1b, 0x78, 0xf5},
- {0xa0, 0x73, 0xe5, 0xc5, 0xbd, 0x43, 0x61, 0x0d, 0x86, 0x4c,
- 0x21, 0x13, 0x0a, 0x85, 0x58, 0x57, 0xcc, 0x9c, 0xea, 0x46},
- {0xa0, 0xa1, 0xab, 0x90, 0xc9, 0xfc, 0x84, 0x7b, 0x3b, 0x12,
- 0x61, 0xe8, 0x97, 0x7d, 0x5f, 0xd3, 0x22, 0x61, 0xd3, 0xcc},
- {0xa0, 0xf8, 0xdb, 0x3f, 0x0b, 0xf4, 0x17, 0x69, 0x3b, 0x28,
- 0x2e, 0xb7, 0x4a, 0x6a, 0xd8, 0x6d, 0xf9, 0xd4, 0x48, 0xa3},
- {0xa1, 0x4b, 0x48, 0xd9, 0x43, 0xee, 0x0a, 0x0e, 0x40, 0x90,
- 0x4f, 0x3c, 0xe0, 0xa4, 0xc0, 0x91, 0x93, 0x51, 0x5d, 0x3f},
- {0xa1, 0x58, 0x51, 0x87, 0x15, 0x65, 0x86, 0xce, 0xf9, 0xc4,
- 0x54, 0xe2, 0x2a, 0xb1, 0x5c, 0x58, 0x74, 0x56, 0x07, 0xb4},
- {0xa1, 0xdb, 0x63, 0x93, 0x91, 0x6f, 0x17, 0xe4, 0x18, 0x55,
- 0x09, 0x40, 0x04, 0x15, 0xc7, 0x02, 0x40, 0xb0, 0xae, 0x6b},
- {0xa1, 0xe7, 0xc6, 0x00, 0xaa, 0x41, 0x70, 0xe5, 0xb7, 0x4b,
- 0xc9, 0x4f, 0x9b, 0x97, 0x03, 0xed, 0xc2, 0x61, 0xb4, 0xb9},
- {0xa3, 0x99, 0xf7, 0x6f, 0x0c, 0xbf, 0x4c, 0x9d, 0xa5, 0x5e,
- 0x4a, 0xc2, 0x4e, 0x89, 0x60, 0x98, 0x4b, 0x29, 0x05, 0xb6},
- {0xa3, 0xe3, 0x1e, 0x20, 0xb2, 0xe4, 0x6a, 0x32, 0x85, 0x20,
- 0x47, 0x2d, 0x0c, 0xde, 0x95, 0x23, 0xe7, 0x26, 0x0c, 0x6d},
- {0xa4, 0x34, 0x89, 0x15, 0x9a, 0x52, 0x0f, 0x0d, 0x93, 0xd0,
- 0x32, 0xcc, 0xaf, 0x37, 0xe7, 0xfe, 0x20, 0xa8, 0xb4, 0x19},
- {0xa5, 0x9c, 0x9b, 0x10, 0xec, 0x73, 0x57, 0x51, 0x5a, 0xbb,
- 0x66, 0x0c, 0x4d, 0x94, 0xf7, 0x3b, 0x9e, 0x6e, 0x92, 0x72},
- {0xa5, 0xec, 0x73, 0xd4, 0x8c, 0x34, 0xfc, 0xbe, 0xf1, 0x00,
- 0x5a, 0xeb, 0x85, 0x84, 0x35, 0x24, 0xbb, 0xfa, 0xb7, 0x27},
- {0xa6, 0x9a, 0x91, 0xfd, 0x05, 0x7f, 0x13, 0x6a, 0x42, 0x63,
- 0x0b, 0xb1, 0x76, 0x0d, 0x2d, 0x51, 0x12, 0x0c, 0x16, 0x50},
- {0xa7, 0xf8, 0x39, 0x0b, 0xa5, 0x77, 0x05, 0x09, 0x6f, 0xd3,
- 0x69, 0x41, 0xd4, 0x2e, 0x71, 0x98, 0xc6, 0xd4, 0xd9, 0xd5},
- {0xa8, 0x98, 0x5d, 0x3a, 0x65, 0xe5, 0xe5, 0xc4, 0xb2, 0xd7,
- 0xd6, 0x6d, 0x40, 0xc6, 0xdd, 0x2f, 0xb1, 0x9c, 0x54, 0x36},
- {0xa9, 0x62, 0x8f, 0x4b, 0x98, 0xa9, 0x1b, 0x48, 0x35, 0xba,
- 0xd2, 0xc1, 0x46, 0x32, 0x86, 0xbb, 0x66, 0x64, 0x6a, 0x8c},
- {0xa9, 0x82, 0x2e, 0x6c, 0x69, 0x33, 0xc6, 0x3c, 0x14, 0x8c,
- 0x2d, 0xca, 0xa4, 0x4a, 0x5c, 0xf1, 0xaa, 0xd2, 0xc4, 0x2e},
- {0xa9, 0xe9, 0x78, 0x08, 0x14, 0x37, 0x58, 0x88, 0xf2, 0x05,
- 0x19, 0xb0, 0x6d, 0x2b, 0x0d, 0x2b, 0x60, 0x16, 0x90, 0x7d},
- {0xaa, 0xdb, 0xbc, 0x22, 0x23, 0x8f, 0xc4, 0x01, 0xa1, 0x27,
- 0xbb, 0x38, 0xdd, 0xf4, 0x1d, 0xdb, 0x08, 0x9e, 0xf0, 0x12},
- {0xab, 0x16, 0xdd, 0x14, 0x4e, 0xcd, 0xc0, 0xfc, 0x4b, 0xaa,
- 0xb6, 0x2e, 0xcf, 0x04, 0x08, 0x89, 0x6f, 0xde, 0x52, 0xb7},
- {0xab, 0x48, 0xf3, 0x33, 0xdb, 0x04, 0xab, 0xb9, 0xc0, 0x72,
- 0xda, 0x5b, 0x0c, 0xc1, 0xd0, 0x57, 0xf0, 0x36, 0x9b, 0x46},
- {0xab, 0x9d, 0x58, 0xc0, 0x3f, 0x54, 0xb1, 0xda, 0xe3, 0xf7,
- 0xc2, 0xd4, 0xc6, 0xc1, 0xec, 0x36, 0x94, 0x55, 0x9c, 0x37},
- {0xac, 0xed, 0x5f, 0x65, 0x53, 0xfd, 0x25, 0xce, 0x01, 0x5f,
- 0x1f, 0x7a, 0x48, 0x3b, 0x6a, 0x74, 0x9f, 0x61, 0x78, 0xc6},
- {0xad, 0x7e, 0x1c, 0x28, 0xb0, 0x64, 0xef, 0x8f, 0x60, 0x03,
- 0x40, 0x20, 0x14, 0xc3, 0xd0, 0xe3, 0x37, 0x0e, 0xb5, 0x8a},
- {0xae, 0x3b, 0x31, 0xbf, 0x8f, 0xd8, 0x91, 0x07, 0x9c, 0xf1,
- 0xdf, 0x34, 0xcb, 0xce, 0x6e, 0x70, 0xd3, 0x7f, 0xb5, 0xb0},
- {0xae, 0x50, 0x83, 0xed, 0x7c, 0xf4, 0x5c, 0xbc, 0x8f, 0x61,
- 0xc6, 0x21, 0xfe, 0x68, 0x5d, 0x79, 0x42, 0x21, 0x15, 0x6e},
- {0xae, 0xc5, 0xfb, 0x3f, 0xc8, 0xe1, 0xbf, 0xc4, 0xe5, 0x4f,
- 0x03, 0x07, 0x5a, 0x9a, 0xe8, 0x00, 0xb7, 0xf7, 0xb6, 0xfa},
- {0xaf, 0xe5, 0xd2, 0x44, 0xa8, 0xd1, 0x19, 0x42, 0x30, 0xff,
- 0x47, 0x9f, 0xe2, 0xf8, 0x97, 0xbb, 0xcd, 0x7a, 0x8c, 0xb4},
- {0xb0, 0x91, 0xaa, 0x91, 0x38, 0x47, 0xf3, 0x13, 0xd7, 0x27,
- 0xbc, 0xef, 0xc8, 0x17, 0x9f, 0x08, 0x6f, 0x3a, 0x8c, 0x0f},
- {0xb1, 0x2e, 0x13, 0x63, 0x45, 0x86, 0xa4, 0x6f, 0x1a, 0xb2,
- 0x60, 0x68, 0x37, 0x58, 0x2d, 0xc4, 0xac, 0xfd, 0x94, 0x97},
- {0xb1, 0x72, 0xb1, 0xa5, 0x6d, 0x95, 0xf9, 0x1f, 0xe5, 0x02,
- 0x87, 0xe1, 0x4d, 0x37, 0xea, 0x6a, 0x44, 0x63, 0x76, 0x8a},
- {0xb1, 0x9d, 0xd0, 0x96, 0xdc, 0xd4, 0xe3, 0xe0, 0xfd, 0x67,
- 0x68, 0x85, 0x50, 0x5a, 0x67, 0x2c, 0x43, 0x8d, 0x4e, 0x9c},
- {0xb1, 0xb2, 0x36, 0x4f, 0xd4, 0xd4, 0xf5, 0x2e, 0x89, 0xb2,
- 0xd0, 0xfa, 0xf3, 0x3e, 0x4d, 0x62, 0xbd, 0x96, 0x99, 0x21},
- {0xb1, 0xbc, 0x96, 0x8b, 0xd4, 0xf4, 0x9d, 0x62, 0x2a, 0xa8,
- 0x9a, 0x81, 0xf2, 0x15, 0x01, 0x52, 0xa4, 0x1d, 0x82, 0x9c},
- {0xb1, 0xea, 0xc3, 0xe5, 0xb8, 0x24, 0x76, 0xe9, 0xd5, 0x0b,
- 0x1e, 0xc6, 0x7d, 0x2c, 0xc1, 0x1e, 0x12, 0xe0, 0xb4, 0x91},
- {0xb2, 0xbd, 0x90, 0x31, 0xaa, 0x6d, 0x0e, 0x14, 0xf4, 0xc5,
- 0x7f, 0xd5, 0x48, 0x25, 0x8f, 0x37, 0xb1, 0xfb, 0x39, 0xe4},
- {0xb3, 0x1e, 0xb1, 0xb7, 0x40, 0xe3, 0x6c, 0x84, 0x02, 0xda,
- 0xdc, 0x37, 0xd4, 0x4d, 0xf5, 0xd4, 0x67, 0x49, 0x52, 0xf9},
- {0xb3, 0x8f, 0xec, 0xec, 0x0b, 0x14, 0x8a, 0xa6, 0x86, 0xc3,
- 0xd0, 0x0f, 0x01, 0xec, 0xc8, 0x84, 0x8e, 0x80, 0x85, 0xeb},
- {0xb3, 0xea, 0xc4, 0x47, 0x76, 0xc9, 0xc8, 0x1c, 0xea, 0xf2,
- 0x9d, 0x95, 0xb6, 0xcc, 0xa0, 0x08, 0x1b, 0x67, 0xec, 0x9d},
- {0xb4, 0x2c, 0x86, 0xc9, 0x57, 0xfd, 0x39, 0x20, 0x0c, 0x45,
- 0xbb, 0xe3, 0x76, 0xc0, 0x8c, 0xd0, 0xf4, 0xd5, 0x86, 0xdb},
- {0xb4, 0x35, 0xd4, 0xe1, 0x11, 0x9d, 0x1c, 0x66, 0x90, 0xa7,
- 0x49, 0xeb, 0xb3, 0x94, 0xbd, 0x63, 0x7b, 0xa7, 0x82, 0xb7},
- {0xb5, 0x1c, 0x06, 0x7c, 0xee, 0x2b, 0x0c, 0x3d, 0xf8, 0x55,
- 0xab, 0x2d, 0x92, 0xf4, 0xfe, 0x39, 0xd4, 0xe7, 0x0f, 0x0e},
- {0xb5, 0x61, 0xeb, 0xea, 0xa4, 0xde, 0xe4, 0x25, 0x4b, 0x69,
- 0x1a, 0x98, 0xa5, 0x57, 0x47, 0xc2, 0x34, 0xc7, 0xd9, 0x71},
- {0xb7, 0x2f, 0xff, 0x92, 0xd2, 0xce, 0x43, 0xde, 0x0a, 0x8d,
- 0x4c, 0x54, 0x8c, 0x50, 0x37, 0x26, 0xa8, 0x1e, 0x2b, 0x93},
- {0xb8, 0x01, 0x86, 0xd1, 0xeb, 0x9c, 0x86, 0xa5, 0x41, 0x04,
- 0xcf, 0x30, 0x54, 0xf3, 0x4c, 0x52, 0xb7, 0xe5, 0x58, 0xc6},
- {0xb8, 0x23, 0x6b, 0x00, 0x2f, 0x1d, 0x16, 0x86, 0x53, 0x01,
- 0x55, 0x6c, 0x11, 0xa4, 0x37, 0xca, 0xeb, 0xff, 0xc3, 0xbb},
- {0xb8, 0x65, 0x13, 0x0b, 0xed, 0xca, 0x38, 0xd2, 0x7f, 0x69,
- 0x92, 0x94, 0x20, 0x77, 0x0b, 0xed, 0x86, 0xef, 0xbc, 0x10},
- {0xb9, 0x42, 0x94, 0xbf, 0x91, 0xea, 0x8f, 0xb6, 0x4b, 0xe6,
- 0x10, 0x97, 0xc7, 0xfb, 0x00, 0x13, 0x59, 0xb6, 0x76, 0xcb},
- {0xb9, 0xcd, 0x0c, 0xf6, 0x98, 0x35, 0xea, 0xbf, 0x3f, 0x13,
- 0x7f, 0x20, 0x49, 0xe4, 0xc9, 0x24, 0x87, 0x84, 0x77, 0xdb},
- {0xba, 0x29, 0x41, 0x60, 0x77, 0x98, 0x3f, 0xf4, 0xf3, 0xef,
- 0xf2, 0x31, 0x05, 0x3b, 0x2e, 0xea, 0x6d, 0x4d, 0x45, 0xfd},
- {0xbc, 0x7b, 0x3c, 0x6f, 0xef, 0x26, 0xb9, 0xf7, 0xab, 0x10,
- 0xd7, 0xa1, 0xf6, 0xb6, 0x7c, 0x5e, 0xd2, 0xa1, 0x2d, 0x3d},
- {0xbc, 0x92, 0x19, 0xdd, 0xc9, 0x8e, 0x14, 0xbf, 0x1a, 0x78,
- 0x1f, 0x6e, 0x28, 0x0b, 0x04, 0xc2, 0x7f, 0x90, 0x27, 0x12},
- {0xbe, 0x1a, 0xf2, 0x85, 0xf7, 0x86, 0xcd, 0xdb, 0xc4, 0x30,
- 0x38, 0x2e, 0xef, 0xf2, 0xa6, 0x6d, 0xfb, 0xcd, 0x5d, 0xd0},
- {0xbe, 0x36, 0xa4, 0x56, 0x2f, 0xb2, 0xee, 0x05, 0xdb, 0xb3,
- 0xd3, 0x23, 0x23, 0xad, 0xf4, 0x45, 0x08, 0x4e, 0xd6, 0x56},
- {0xbe, 0xb5, 0xa9, 0x95, 0x74, 0x6b, 0x9e, 0xdf, 0x73, 0x8b,
- 0x56, 0xe6, 0xdf, 0x43, 0x7a, 0x77, 0xbe, 0x10, 0x6b, 0x81},
- {0xbe, 0xd5, 0x25, 0xd1, 0xac, 0x63, 0xa7, 0xfc, 0x6a, 0x66,
- 0x0b, 0xa7, 0xa8, 0x95, 0x81, 0x8d, 0x5e, 0x8d, 0xd5, 0x64},
- {0xc0, 0x9a, 0xb0, 0xc8, 0xad, 0x71, 0x14, 0x71, 0x4e, 0xd5,
- 0xe2, 0x1a, 0x5a, 0x27, 0x6a, 0xdc, 0xd5, 0xe7, 0xef, 0xcb},
- {0xc0, 0xdb, 0x57, 0x81, 0x57, 0xe9, 0xee, 0x82, 0xb5, 0x91,
- 0x7d, 0xf0, 0xdd, 0x6d, 0x82, 0xee, 0x90, 0x39, 0xc4, 0xe2},
- {0xc1, 0x82, 0x11, 0x32, 0x8a, 0x92, 0xb3, 0xb2, 0x38, 0x09,
- 0xb9, 0xb5, 0xe2, 0x74, 0x0a, 0x07, 0xfb, 0x12, 0xeb, 0x5e},
- {0xc4, 0x18, 0xf6, 0x4d, 0x46, 0xd1, 0xdf, 0x00, 0x3d, 0x27,
- 0x30, 0x13, 0x72, 0x43, 0xa9, 0x12, 0x11, 0xc6, 0x75, 0xfb},
- {0xc4, 0x67, 0x4d, 0xdc, 0x6c, 0xe2, 0x96, 0x7f, 0xf9, 0xc9,
- 0x2e, 0x07, 0x2e, 0xf8, 0xe8, 0xa7, 0xfb, 0xd6, 0xa1, 0x31},
- {0xc7, 0x30, 0x26, 0xe3, 0x25, 0xfe, 0x21, 0x91, 0x6b, 0x55,
- 0xc4, 0xb5, 0x3a, 0x56, 0xb1, 0x3d, 0xca, 0xf3, 0xd6, 0x25},
- {0xc7, 0xf7, 0xcb, 0xe2, 0x02, 0x36, 0x66, 0xf9, 0x86, 0x02,
- 0x5d, 0x4a, 0x3e, 0x31, 0x3f, 0x29, 0xeb, 0x0c, 0x5b, 0x38},
- {0xc8, 0x60, 0xa3, 0x18, 0xfc, 0xf5, 0xb7, 0x13, 0x0b, 0x10,
- 0x07, 0xad, 0x7f, 0x61, 0x4a, 0x40, 0xff, 0xff, 0x18, 0x5f},
- {0xc8, 0xec, 0x8c, 0x87, 0x92, 0x69, 0xcb, 0x4b, 0xab, 0x39,
- 0xe9, 0x8d, 0x7e, 0x57, 0x67, 0xf3, 0x14, 0x95, 0x73, 0x9d},
- {0xc9, 0x32, 0x1d, 0xe6, 0xb5, 0xa8, 0x26, 0x66, 0xcf, 0x69,
- 0x71, 0xa1, 0x8a, 0x56, 0xf2, 0xd3, 0xa8, 0x67, 0x56, 0x02},
- {0xc9, 0x3c, 0x34, 0xea, 0x90, 0xd9, 0x13, 0x0c, 0x0f, 0x03,
- 0x00, 0x4b, 0x98, 0xbd, 0x8b, 0x35, 0x70, 0x91, 0x56, 0x11},
- {0xc9, 0xa8, 0xb9, 0xe7, 0x55, 0x80, 0x5e, 0x58, 0xe3, 0x53,
- 0x77, 0xa7, 0x25, 0xeb, 0xaf, 0xc3, 0x7b, 0x27, 0xcc, 0xd7},
- {0xca, 0x3a, 0xfb, 0xcf, 0x12, 0x40, 0x36, 0x4b, 0x44, 0xb2,
- 0x16, 0x20, 0x88, 0x80, 0x48, 0x39, 0x19, 0x93, 0x7c, 0xf7},
- {0xca, 0xbb, 0x51, 0x67, 0x24, 0x00, 0x58, 0x8e, 0x64, 0x19,
- 0xf1, 0xd4, 0x08, 0x78, 0xd0, 0x40, 0x3a, 0xa2, 0x02, 0x64},
- {0xcb, 0x44, 0xa0, 0x97, 0x85, 0x7c, 0x45, 0xfa, 0x18, 0x7e,
- 0xd9, 0x52, 0x08, 0x6c, 0xb9, 0x84, 0x1f, 0x2d, 0x51, 0xb5},
- {0xcb, 0x65, 0x82, 0x64, 0xea, 0x8c, 0xda, 0x18, 0x6e, 0x17,
- 0x52, 0xfb, 0x52, 0xc3, 0x97, 0x36, 0x7e, 0xa3, 0x87, 0xbe},
- {0xcb, 0xa1, 0xc5, 0xf8, 0xb0, 0xe3, 0x5e, 0xb8, 0xb9, 0x45,
- 0x12, 0xd3, 0xf9, 0x34, 0xa2, 0xe9, 0x06, 0x10, 0xd3, 0x36},
- {0xcc, 0x7e, 0xa2, 0x92, 0xaf, 0x87, 0x15, 0xd7, 0x4c, 0xa4,
- 0xb4, 0x15, 0xf3, 0x20, 0x15, 0x4b, 0x24, 0xf5, 0x65, 0xfd},
- {0xcd, 0x78, 0x7a, 0x3d, 0x5c, 0xba, 0x82, 0x07, 0x08, 0x28,
- 0x48, 0x36, 0x5e, 0x9a, 0xcd, 0xe9, 0x68, 0x33, 0x64, 0xd8},
- {0xcd, 0xd4, 0xee, 0xae, 0x60, 0x00, 0xac, 0x7f, 0x40, 0xc3,
- 0x80, 0x2c, 0x17, 0x1e, 0x30, 0x14, 0x80, 0x30, 0xc0, 0x72},
- {0xce, 0x6a, 0x64, 0xa3, 0x09, 0xe4, 0x2f, 0xbb, 0xd9, 0x85,
- 0x1c, 0x45, 0x3e, 0x64, 0x09, 0xea, 0xe8, 0x7d, 0x60, 0xf1},
- {0xce, 0xa9, 0x89, 0x0d, 0x85, 0xd8, 0x07, 0x53, 0xa6, 0x26,
- 0x28, 0x6c, 0xda, 0xd7, 0x8c, 0xb5, 0x66, 0xd7, 0x0c, 0xf2},
- {0xcf, 0x9e, 0x87, 0x6d, 0xd3, 0xeb, 0xfc, 0x42, 0x26, 0x97,
- 0xa3, 0xb5, 0xa3, 0x7a, 0xa0, 0x76, 0xa9, 0x06, 0x23, 0x48},
- {0xcf, 0xde, 0xfe, 0x10, 0x2f, 0xda, 0x05, 0xbb, 0xe4, 0xc7,
- 0x8d, 0x2e, 0x44, 0x23, 0x58, 0x90, 0x05, 0xb2, 0x57, 0x1d},
- {0xcf, 0xe4, 0x31, 0x3d, 0xba, 0x05, 0xb8, 0xa7, 0xc3, 0x00,
- 0x63, 0x99, 0x5a, 0x9e, 0xb7, 0xc2, 0x47, 0xad, 0x8f, 0xd5},
- {0xcf, 0xf3, 0x60, 0xf5, 0x24, 0xcb, 0x20, 0xf1, 0xfe, 0xad,
- 0x89, 0x00, 0x6f, 0x7f, 0x58, 0x6a, 0x28, 0x5b, 0x2d, 0x5b},
- {0xcf, 0xf8, 0x10, 0xfb, 0x2c, 0x4f, 0xfc, 0x01, 0x56, 0xbf,
- 0xe1, 0xe1, 0xfa, 0xbc, 0xb4, 0x18, 0xc6, 0x8d, 0x31, 0xc5},
- {0xd1, 0xcb, 0xca, 0x5d, 0xb2, 0xd5, 0x2a, 0x7f, 0x69, 0x3b,
- 0x67, 0x4d, 0xe5, 0xf0, 0x5a, 0x1d, 0x0c, 0x95, 0x7d, 0xf0},
- {0xd1, 0xeb, 0x23, 0xa4, 0x6d, 0x17, 0xd6, 0x8f, 0xd9, 0x25,
- 0x64, 0xc2, 0xf1, 0xf1, 0x60, 0x17, 0x64, 0xd8, 0xe3, 0x49},
- {0xd2, 0x32, 0x09, 0xad, 0x23, 0xd3, 0x14, 0x23, 0x21, 0x74,
- 0xe4, 0x0d, 0x7f, 0x9d, 0x62, 0x13, 0x97, 0x86, 0x63, 0x3a},
- {0xd2, 0x44, 0x1a, 0xa8, 0xc2, 0x03, 0xae, 0xca, 0xa9, 0x6e,
- 0x50, 0x1f, 0x12, 0x4d, 0x52, 0xb6, 0x8f, 0xe4, 0xc3, 0x75},
- {0xd2, 0x9f, 0x6c, 0x98, 0xbe, 0xfc, 0x6d, 0x98, 0x65, 0x21,
- 0x54, 0x3e, 0xe8, 0xbe, 0x56, 0xce, 0xbc, 0x28, 0x8c, 0xf3},
- {0xd2, 0xed, 0xf8, 0x8b, 0x41, 0xb6, 0xfe, 0x01, 0x46, 0x1d,
- 0x6e, 0x28, 0x34, 0xec, 0x7c, 0x8f, 0x6c, 0x77, 0x72, 0x1e},
- {0xd3, 0xc0, 0x63, 0xf2, 0x19, 0xed, 0x07, 0x3e, 0x34, 0xad,
- 0x5d, 0x75, 0x0b, 0x32, 0x76, 0x29, 0xff, 0xd5, 0x9a, 0xf2},
- {0xd3, 0xee, 0xfb, 0xcb, 0xbc, 0xf4, 0x98, 0x67, 0x83, 0x86,
- 0x26, 0xe2, 0x3b, 0xb5, 0x9c, 0xa0, 0x1e, 0x30, 0x5d, 0xb7},
- {0xd4, 0xde, 0x20, 0xd0, 0x5e, 0x66, 0xfc, 0x53, 0xfe, 0x1a,
- 0x50, 0x88, 0x2c, 0x78, 0xdb, 0x28, 0x52, 0xca, 0xe4, 0x74},
- {0xd6, 0x9b, 0x56, 0x11, 0x48, 0xf0, 0x1c, 0x77, 0xc5, 0x45,
- 0x78, 0xc1, 0x09, 0x26, 0xdf, 0x5b, 0x85, 0x69, 0x76, 0xad},
- {0xd6, 0xbf, 0x79, 0x94, 0xf4, 0x2b, 0xe5, 0xfa, 0x29, 0xda,
- 0x0b, 0xd7, 0x58, 0x7b, 0x59, 0x1f, 0x47, 0xa4, 0x4f, 0x22},
- {0xd6, 0xda, 0xa8, 0x20, 0x8d, 0x09, 0xd2, 0x15, 0x4d, 0x24,
- 0xb5, 0x2f, 0xcb, 0x34, 0x6e, 0xb2, 0x58, 0xb2, 0x8a, 0x58},
- {0xd8, 0xa6, 0x33, 0x2c, 0xe0, 0x03, 0x6f, 0xb1, 0x85, 0xf6,
- 0x63, 0x4f, 0x7d, 0x6a, 0x06, 0x65, 0x26, 0x32, 0x28, 0x27},
- {0xd8, 0xc5, 0x38, 0x8a, 0xb7, 0x30, 0x1b, 0x1b, 0x6e, 0xd4,
- 0x7a, 0xe6, 0x45, 0x25, 0x3a, 0x6f, 0x9f, 0x1a, 0x27, 0x61},
- {0xd8, 0xeb, 0x6b, 0x41, 0x51, 0x92, 0x59, 0xe0, 0xf3, 0xe7,
- 0x85, 0x00, 0xc0, 0x3d, 0xb6, 0x88, 0x97, 0xc9, 0xee, 0xfc},
- {0xd9, 0x04, 0x08, 0x0a, 0x49, 0x29, 0xc8, 0x38, 0xe9, 0xf1,
- 0x85, 0xec, 0xf7, 0xa2, 0x2d, 0xef, 0x99, 0x34, 0x24, 0x07},
- {0xda, 0x40, 0x18, 0x8b, 0x91, 0x89, 0xa3, 0xed, 0xee, 0xae,
- 0xda, 0x97, 0xfe, 0x2f, 0x9d, 0xf5, 0xb7, 0xd1, 0x8a, 0x41},
- {0xda, 0x8b, 0x65, 0x67, 0xef, 0x3f, 0x6e, 0x1e, 0xa2, 0x6a,
- 0xb1, 0x46, 0xe3, 0x6c, 0xcb, 0x57, 0x28, 0x04, 0x18, 0x46},
- {0xda, 0xc9, 0x02, 0x4f, 0x54, 0xd8, 0xf6, 0xdf, 0x94, 0x93,
- 0x5f, 0xb1, 0x73, 0x26, 0x38, 0xca, 0x6a, 0xd7, 0x7c, 0x13},
- {0xda, 0xfa, 0xf7, 0xfa, 0x66, 0x84, 0xec, 0x06, 0x8f, 0x14,
- 0x50, 0xbd, 0xc7, 0xc2, 0x81, 0xa5, 0xbc, 0xa9, 0x64, 0x57},
- {0xdb, 0x2b, 0x7b, 0x43, 0x4d, 0xfb, 0x7f, 0xc1, 0xcb, 0x59,
- 0x26, 0xec, 0x5d, 0x95, 0x21, 0xfe, 0x35, 0x0f, 0xf2, 0x79},
- {0xdb, 0xac, 0x3c, 0x7a, 0xa4, 0x25, 0x4d, 0xa1, 0xaa, 0x5c,
- 0xaa, 0xd6, 0x84, 0x68, 0xcb, 0x88, 0xee, 0xdd, 0xee, 0xa8},
- {0xdd, 0x83, 0xc5, 0x19, 0xd4, 0x34, 0x81, 0xfa, 0xd4, 0xc2,
- 0x2c, 0x03, 0xd7, 0x02, 0xfe, 0x9f, 0x3b, 0x22, 0xf5, 0x17},
- {0xdd, 0xe1, 0xd2, 0xa9, 0x01, 0x80, 0x2e, 0x1d, 0x87, 0x5e,
- 0x84, 0xb3, 0x80, 0x7e, 0x4b, 0xb1, 0xfd, 0x99, 0x41, 0x34},
- {0xdd, 0xfb, 0x16, 0xcd, 0x49, 0x31, 0xc9, 0x73, 0xa2, 0x03,
- 0x7d, 0x3f, 0xc8, 0x3a, 0x4d, 0x7d, 0x77, 0x5d, 0x05, 0xe4},
- {0xde, 0x28, 0xf4, 0xa4, 0xff, 0xe5, 0xb9, 0x2f, 0xa3, 0xc5,
- 0x03, 0xd1, 0xa3, 0x49, 0xa7, 0xf9, 0x96, 0x2a, 0x82, 0x12},
- {0xde, 0x3f, 0x40, 0xbd, 0x50, 0x93, 0xd3, 0x9b, 0x6c, 0x60,
- 0xf6, 0xda, 0xbc, 0x07, 0x62, 0x01, 0x00, 0x89, 0x76, 0xc9},
- {0xde, 0x99, 0x0c, 0xed, 0x99, 0xe0, 0x43, 0x1f, 0x60, 0xed,
- 0xc3, 0x93, 0x7e, 0x7c, 0xd5, 0xbf, 0x0e, 0xd9, 0xe5, 0xfa},
- {0xdf, 0x3c, 0x24, 0xf9, 0xbf, 0xd6, 0x66, 0x76, 0x1b, 0x26,
- 0x80, 0x73, 0xfe, 0x06, 0xd1, 0xcc, 0x8d, 0x4f, 0x82, 0xa4},
- {0xdf, 0x64, 0x6d, 0xcb, 0x7b, 0x0f, 0xd3, 0xa9, 0x6a, 0xee,
- 0x88, 0xc6, 0x4e, 0x2d, 0x67, 0x67, 0x11, 0xff, 0x9d, 0x5f},
- {0xdf, 0x71, 0x7e, 0xaa, 0x4a, 0xd9, 0x4e, 0xc9, 0x55, 0x84,
- 0x99, 0x60, 0x2d, 0x48, 0xde, 0x5f, 0xbc, 0xf0, 0x3a, 0x25},
- {0xe0, 0x92, 0x5e, 0x18, 0xc7, 0x76, 0x5e, 0x22, 0xda, 0xbd,
- 0x94, 0x27, 0x52, 0x9d, 0xa6, 0xaf, 0x4e, 0x06, 0x64, 0x28},
- {0xe0, 0x98, 0xec, 0xf3, 0x55, 0xc1, 0x99, 0x53, 0x27, 0x4d,
- 0x84, 0x77, 0x2a, 0x1c, 0xec, 0x96, 0xdc, 0x33, 0x56, 0xca},
- {0xe0, 0xab, 0x05, 0x94, 0x20, 0x72, 0x54, 0x93, 0x05, 0x60,
- 0x62, 0x02, 0x36, 0x70, 0xf7, 0xcd, 0x2e, 0xfc, 0x66, 0x66},
- {0xe0, 0xb4, 0x32, 0x2e, 0xb2, 0xf6, 0xa5, 0x68, 0xb6, 0x54,
- 0x53, 0x84, 0x48, 0x18, 0x4a, 0x50, 0x36, 0x87, 0x43, 0x84},
- {0xe1, 0x2d, 0xfb, 0x4b, 0x41, 0xd7, 0xd9, 0xc3, 0x2b, 0x30,
- 0x51, 0x4b, 0xac, 0x1d, 0x81, 0xd8, 0x38, 0x5e, 0x2d, 0x46},
- {0xe1, 0xa4, 0x5b, 0x14, 0x1a, 0x21, 0xda, 0x1a, 0x79, 0xf4,
- 0x1a, 0x42, 0xa9, 0x61, 0xd6, 0x69, 0xcd, 0x06, 0x34, 0xc1},
- {0xe2, 0xb8, 0x29, 0x4b, 0x55, 0x84, 0xab, 0x6b, 0x58, 0xc2,
- 0x90, 0x46, 0x6c, 0xac, 0x3f, 0xb8, 0x39, 0x8f, 0x84, 0x83},
- {0xe3, 0x92, 0x51, 0x2f, 0x0a, 0xcf, 0xf5, 0x05, 0xdf, 0xf6,
- 0xde, 0x06, 0x7f, 0x75, 0x37, 0xe1, 0x65, 0xea, 0x57, 0x4b},
- {0xe3, 0xd7, 0x36, 0x06, 0x99, 0x6c, 0xdf, 0xef, 0x61, 0xfa,
- 0x04, 0xc3, 0x35, 0xe9, 0x8e, 0xa9, 0x61, 0x04, 0x26, 0x4a},
- {0xe5, 0xdf, 0x74, 0x3c, 0xb6, 0x01, 0xc4, 0x9b, 0x98, 0x43,
- 0xdc, 0xab, 0x8c, 0xe8, 0x6a, 0x81, 0x10, 0x9f, 0xe4, 0x8e},
- {0xe6, 0x19, 0xd2, 0x5b, 0x38, 0x0b, 0x7b, 0x13, 0xfd, 0xa3,
- 0x3e, 0x8a, 0x58, 0xcd, 0x82, 0xd8, 0xa8, 0x8e, 0x05, 0x15},
- {0xe6, 0x21, 0xf3, 0x35, 0x43, 0x79, 0x05, 0x9a, 0x4b, 0x68,
- 0x30, 0x9d, 0x8a, 0x2f, 0x74, 0x22, 0x15, 0x87, 0xec, 0x79},
- {0xe7, 0x07, 0x15, 0xf6, 0xf7, 0x28, 0x36, 0x5b, 0x51, 0x90,
- 0xe2, 0x71, 0xde, 0xe4, 0xc6, 0x5e, 0xbe, 0xea, 0xca, 0xf3},
- {0xe7, 0xa1, 0x90, 0x29, 0xd3, 0xd5, 0x52, 0xdc, 0x0d, 0x0f,
- 0xc6, 0x92, 0xd3, 0xea, 0x88, 0x0d, 0x15, 0x2e, 0x1a, 0x6b},
- {0xe7, 0xb4, 0xf6, 0x9d, 0x61, 0xec, 0x90, 0x69, 0xdb, 0x7e,
- 0x90, 0xa7, 0x40, 0x1a, 0x3c, 0xf4, 0x7d, 0x4f, 0xe8, 0xee},
- {0xea, 0xbd, 0xa2, 0x40, 0x44, 0x0a, 0xbb, 0xd6, 0x94, 0x93,
- 0x0a, 0x01, 0xd0, 0x97, 0x64, 0xc6, 0xc2, 0xd7, 0x79, 0x66},
- {0xec, 0x0c, 0x37, 0x16, 0xea, 0x9e, 0xdf, 0xad, 0xd3, 0x5d,
- 0xfb, 0xd5, 0x56, 0x08, 0xe6, 0x0a, 0x05, 0xd3, 0xcb, 0xf3},
- {0xec, 0x93, 0xde, 0x08, 0x3c, 0x93, 0xd9, 0x33, 0xa9, 0x86,
- 0xb3, 0xd5, 0xcd, 0xe2, 0x5a, 0xcb, 0x2f, 0xee, 0xcf, 0x8e},
- {0xed, 0x8d, 0xc8, 0x38, 0x6c, 0x48, 0x86, 0xae, 0xee, 0x07,
- 0x91, 0x58, 0xaa, 0xc3, 0xbf, 0xe6, 0x58, 0xe3, 0x94, 0xb4},
- {0xed, 0xb3, 0xcb, 0x5f, 0xb4, 0x19, 0xa1, 0x85, 0x06, 0x62,
- 0x67, 0xe5, 0x79, 0x15, 0x54, 0xe1, 0xe2, 0x8b, 0x63, 0x99},
- {0xee, 0x29, 0xd6, 0xea, 0x98, 0xe6, 0x32, 0xc6, 0xe5, 0x27,
- 0xe0, 0x90, 0x6f, 0x02, 0x80, 0x68, 0x8b, 0xdf, 0x44, 0xdc},
- {0xee, 0x86, 0x93, 0x87, 0xff, 0xfd, 0x83, 0x49, 0xab, 0x5a,
- 0xd1, 0x43, 0x22, 0x58, 0x87, 0x89, 0xa4, 0x57, 0xb0, 0x12},
- {0xf0, 0x0f, 0xc3, 0x7d, 0x6a, 0x1c, 0x92, 0x61, 0xfb, 0x6b,
- 0xc1, 0xc2, 0x18, 0x49, 0x8c, 0x5a, 0xa4, 0xdc, 0x51, 0xfb},
- {0xf1, 0x38, 0xa3, 0x30, 0xa4, 0xea, 0x98, 0x6b, 0xeb, 0x52,
- 0x0b, 0xb1, 0x10, 0x35, 0x87, 0x6e, 0xfb, 0x9d, 0x7f, 0x1c},
- {0xf1, 0x7f, 0x6f, 0xb6, 0x31, 0xdc, 0x99, 0xe3, 0xa3, 0xc8,
- 0x7f, 0xfe, 0x1c, 0xf1, 0x81, 0x10, 0x88, 0xd9, 0x60, 0x33},
- {0xf1, 0x8b, 0x53, 0x8d, 0x1b, 0xe9, 0x03, 0xb6, 0xa6, 0xf0,
- 0x56, 0x43, 0x5b, 0x17, 0x15, 0x89, 0xca, 0xf3, 0x6b, 0xf2},
- {0xf3, 0x73, 0xb3, 0x87, 0x06, 0x5a, 0x28, 0x84, 0x8a, 0xf2,
- 0xf3, 0x4a, 0xce, 0x19, 0x2b, 0xdd, 0xc7, 0x8e, 0x9c, 0xac},
- {0xf4, 0x40, 0x95, 0xc2, 0x38, 0xac, 0x73, 0xfc, 0x4f, 0x77,
- 0xbf, 0x8f, 0x98, 0xdf, 0x70, 0xf8, 0xf0, 0x91, 0xbc, 0x52},
- {0xf4, 0x8b, 0x11, 0xbf, 0xde, 0xab, 0xbe, 0x94, 0x54, 0x20,
- 0x71, 0xe6, 0x41, 0xde, 0x6b, 0xbe, 0x88, 0x2b, 0x40, 0xb9},
- {0xf5, 0x17, 0xa2, 0x4f, 0x9a, 0x48, 0xc6, 0xc9, 0xf8, 0xa2,
- 0x00, 0x26, 0x9f, 0xdc, 0x0f, 0x48, 0x2c, 0xab, 0x30, 0x89},
- {0xf5, 0xc2, 0x7c, 0xf5, 0xff, 0xf3, 0x02, 0x9a, 0xcf, 0x1a,
- 0x1a, 0x4b, 0xec, 0x7e, 0xe1, 0x96, 0x4c, 0x77, 0xd7, 0x84},
- {0xf9, 0xb5, 0xb6, 0x32, 0x45, 0x5f, 0x9c, 0xbe, 0xec, 0x57,
- 0x5f, 0x80, 0xdc, 0xe9, 0x6e, 0x2c, 0xc7, 0xb2, 0x78, 0xb7},
- {0xf9, 0xcd, 0x0e, 0x2c, 0xda, 0x76, 0x24, 0xc1, 0x8f, 0xbd,
- 0xf0, 0xf0, 0xab, 0xb6, 0x45, 0xb8, 0xf7, 0xfe, 0xd5, 0x7a},
- {0xf9, 0xdd, 0x19, 0x26, 0x6b, 0x20, 0x43, 0xf1, 0xfe, 0x4b,
- 0x3d, 0xcb, 0x01, 0x90, 0xaf, 0xf1, 0x1f, 0x31, 0xa6, 0x9d},
- {0xfa, 0x08, 0x82, 0x59, 0x5f, 0x9c, 0xa6, 0xa1, 0x1e, 0xcc,
- 0xbe, 0xaf, 0x65, 0xc7, 0x64, 0xc0, 0xcc, 0xc3, 0x11, 0xd0},
- {0xfa, 0xa7, 0xd9, 0xfb, 0x31, 0xb7, 0x46, 0xf2, 0x00, 0xa8,
- 0x5e, 0x65, 0x79, 0x76, 0x13, 0xd8, 0x16, 0xe0, 0x63, 0xb5},
- {0xfa, 0xaa, 0x27, 0xb8, 0xca, 0xf5, 0xfd, 0xf5, 0xcd, 0xa9,
- 0x8a, 0xc3, 0x37, 0x85, 0x72, 0xe0, 0x4c, 0xe8, 0xf2, 0xe0},
- {0xfa, 0xb7, 0xee, 0x36, 0x97, 0x26, 0x62, 0xfb, 0x2d, 0xb0,
- 0x2a, 0xf6, 0xbf, 0x03, 0xfd, 0xe8, 0x7c, 0x4b, 0x2f, 0x9b},
- {0xfd, 0x1e, 0xd1, 0xe2, 0x02, 0x1b, 0x0b, 0x9f, 0x73, 0xe8,
- 0xeb, 0x75, 0xce, 0x23, 0x43, 0x6b, 0xbc, 0xc7, 0x46, 0xeb},
- {0xfe, 0x45, 0x65, 0x9b, 0x79, 0x03, 0x5b, 0x98, 0xa1, 0x61,
- 0xb5, 0x51, 0x2e, 0xac, 0xda, 0x58, 0x09, 0x48, 0x22, 0x4d},
- {0xfe, 0xb8, 0xc4, 0x32, 0xdc, 0xf9, 0x76, 0x9a, 0xce, 0xae,
- 0x3d, 0xd8, 0x90, 0x8f, 0xfd, 0x28, 0x86, 0x65, 0x64, 0x7d},
- {0xff, 0xb7, 0xe0, 0x8f, 0x66, 0xe1, 0xd0, 0xc2, 0x58, 0x2f,
- 0x02, 0x45, 0xc4, 0x97, 0x02, 0x92, 0xa4, 0x6e, 0x88, 0x03},
+static uint8_t kKnownRootCertSHA256Hashes[][32] = {
+ // C=US, O=Network Solutions L.L.C., CN=Network Solutions Certificate
+ // Authority
+ {0x00, 0x16, 0x86, 0xCD, 0x18, 0x1F, 0x83, 0xA1, 0xB1, 0x21, 0x7D, 0x30,
+ 0x5B, 0x36, 0x5C, 0x41, 0xE3, 0x47, 0x0A, 0x78, 0xA1, 0xD3, 0x7B, 0x13,
+ 0x4A, 0x98, 0xCD, 0x54, 0x7B, 0x92, 0xDA, 0xB3},
+ // C=SI, O=POSTA, OU=POSTArCA
+ {0x00, 0x7E, 0x45, 0x2F, 0xD5, 0xCF, 0x83, 0x89, 0x46, 0x69, 0x6D, 0xFE,
+ 0x37, 0xA2, 0xDB, 0x2E, 0xF3, 0x99, 0x14, 0x36, 0xD2, 0x7B, 0xCB, 0xAB,
+ 0x45, 0x92, 0x20, 0x53, 0xC1, 0x5A, 0x87, 0xA8},
+ // C=ES, O=Agencia Notarial de Certificacion S.L. Unipersonal - CIF
+ // B83395988, CN=ANCERT Certificados Notariales
+ {0x00, 0xAB, 0x44, 0x4A, 0xBD, 0x6B, 0xDB, 0xA3, 0x3D, 0xA8, 0xDE, 0x56,
+ 0x9A, 0xC4, 0xEC, 0xDE, 0x32, 0x6D, 0x1B, 0xE1, 0xA6, 0x14, 0x42, 0xD5,
+ 0xEE, 0xC3, 0x97, 0x5A, 0x0C, 0x24, 0x3F, 0x04},
+ // C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012
+ // Entrust, Inc. - for authorized use only, CN=Entrust Root Certification
+ // Authority - EC1
+ {0x02, 0xED, 0x0E, 0xB2, 0x8C, 0x14, 0xDA, 0x45, 0x16, 0x5C, 0x56, 0x67,
+ 0x91, 0x70, 0x0D, 0x64, 0x51, 0xD7, 0xFB, 0x56, 0xF0, 0xB2, 0xAB, 0x1D,
+ 0x3B, 0x8E, 0xB0, 0x70, 0xE5, 0x6E, 0xDF, 0xF5},
+ // C=US, O=Wells Fargo, OU=Wells Fargo Certification Authority, CN=Wells
+ // Fargo Root Certificate Authority
+ {0x03, 0x45, 0x8B, 0x6A, 0xBE, 0xEC, 0xC2, 0x14, 0x95, 0x3D, 0x97, 0x14,
+ 0x9A, 0xF4, 0x53, 0x91, 0x69, 0x1D, 0xE9, 0xF9, 0xCD, 0xCC, 0x26, 0x47,
+ 0x86, 0x3A, 0x3D, 0x67, 0xC9, 0x5C, 0x24, 0x3B},
+ // C=US, O=AffirmTrust, CN=AffirmTrust Commercial
+ {0x03, 0x76, 0xAB, 0x1D, 0x54, 0xC5, 0xF9, 0x80, 0x3C, 0xE4, 0xB2, 0xE2,
+ 0x01, 0xA0, 0xEE, 0x7E, 0xEF, 0x7B, 0x57, 0xB6, 0x36, 0xE8, 0xA9, 0x3C,
+ 0x9B, 0x8D, 0x48, 0x60, 0xC9, 0x6F, 0x5F, 0xA7},
+ // C=KR, O=Government of Korea, OU=GPKI, CN=Root CA
+ {0x03, 0x78, 0xB2, 0x02, 0xCC, 0xAB, 0xBA, 0x99, 0xA1, 0x2E, 0x56, 0x9A,
+ 0x11, 0xA0, 0x77, 0xDB, 0x1E, 0xDB, 0x39, 0x48, 0x20, 0x61, 0xC7, 0x5D,
+ 0x00, 0x73, 0x05, 0x9D, 0x9A, 0xB5, 0xB5, 0x13},
+ // CN=ACEDICOM Root, OU=PKI, O=EDICOM, C=ES
+ {0x03, 0x95, 0x0F, 0xB4, 0x9A, 0x53, 0x1F, 0x3E, 0x19, 0x91, 0x94, 0x23,
+ 0x98, 0xDF, 0xA9, 0xE0, 0xEA, 0x32, 0xD7, 0xBA, 0x1C, 0xDD, 0x9B, 0xC8,
+ 0x5D, 0xB5, 0x7E, 0xD9, 0x40, 0x0B, 0x43, 0x4A},
+ // C=ES, CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
+ {0x04, 0x04, 0x80, 0x28, 0xBF, 0x1F, 0x28, 0x64, 0xD4, 0x8F, 0x9A, 0xD4,
+ 0xD8, 0x32, 0x94, 0x36, 0x6A, 0x82, 0x88, 0x56, 0x55, 0x3F, 0x3B, 0x14,
+ 0x30, 0x3F, 0x90, 0x14, 0x7F, 0x5D, 0x40, 0xEF},
+ // C=us, O=U.S. Government, OU=FBCA, CN=Common Policy
+ {0x04, 0xAC, 0xFB, 0x3B, 0x24, 0x79, 0x3F, 0x30, 0x0F, 0x67, 0xEF, 0x87,
+ 0xE4, 0x4D, 0xD7, 0x2C, 0xB9, 0xB2, 0x8B, 0x20, 0x4F, 0x38, 0x9A, 0x7C,
+ 0xD5, 0xAE, 0x28, 0x78, 0x5C, 0x7D, 0x42, 0xCD},
+ // C=LT, O=VI Registru Centras - I.k. 124110246, OU=Registru Centro
+ // Sertifikavimo Centras, CN=VI Registru Centras RCSC (RootCA)
+ {0x05, 0x36, 0x80, 0x1F, 0xBB, 0x44, 0x3B, 0x3E, 0x90, 0x5F, 0xD6, 0xD7,
+ 0x0D, 0x8C, 0x81, 0xEB, 0x88, 0x55, 0x1B, 0xE8, 0x06, 0x12, 0x99, 0x11,
+ 0x0D, 0x2B, 0x4F, 0x82, 0xE6, 0x4C, 0xAD, 0xE1},
+ // C=BE, O=Certipost s.a./n.v., CN=Certipost E-Trust Primary Qualified CA
+ {0x05, 0x8A, 0x40, 0x32, 0x3E, 0xC8, 0xC4, 0x62, 0x62, 0xC3, 0x05, 0x2A,
+ 0x5D, 0x35, 0x7B, 0x91, 0xAC, 0x24, 0xD3, 0xDA, 0x26, 0x35, 0x1B, 0x3F,
+ 0xF4, 0x40, 0x7E, 0x99, 0xF7, 0xA4, 0xE9, 0xB4},
+ // C=EU, L=Madrid (see current address at
+ // www.camerfirma.com/address)/serialNumber=A82743287, O=AC Camerfirma S.A.,
+ // CN=Chambers of Commerce Root - 2008
+ {0x06, 0x3E, 0x4A, 0xFA, 0xC4, 0x91, 0xDF, 0xD3, 0x32, 0xF3, 0x08, 0x9B,
+ 0x85, 0x42, 0xE9, 0x46, 0x17, 0xD8, 0x93, 0xD7, 0xFE, 0x94, 0x4E, 0x10,
+ 0xA7, 0x93, 0x7E, 0xE2, 0x9D, 0x96, 0x93, 0xC0},
+ // O=Digital Signature Trust Co., CN=DST Root CA X3
+ {0x06, 0x87, 0x26, 0x03, 0x31, 0xA7, 0x24, 0x03, 0xD9, 0x09, 0xF1, 0x05,
+ 0xE6, 0x9B, 0xCF, 0x0D, 0x32, 0xE1, 0xBD, 0x24, 0x93, 0xFF, 0xC6, 0xD9,
+ 0x20, 0x6D, 0x11, 0xBC, 0xD6, 0x77, 0x07, 0x39},
+ // C=JP, O=LGPKI, OU=Application CA G2
+ {0x06, 0xDB, 0x3A, 0xF2, 0xDB, 0x7B, 0xAE, 0xE0, 0x0C, 0x03, 0xB9, 0x57,
+ 0x82, 0x88, 0xBB, 0xDE, 0x54, 0x1D, 0x90, 0x6E, 0xB0, 0x06, 0x93, 0x27,
+ 0x41, 0x32, 0x95, 0xFF, 0xB4, 0x86, 0x00, 0x8E},
+ // C=IE, O=An Post, OU=Post.Trust Ltd., CN=Post.Trust Root CA
+ {0x07, 0x45, 0x3D, 0x53, 0x79, 0x3B, 0xF4, 0x18, 0x19, 0xA5, 0x25, 0x1C,
+ 0x69, 0xF8, 0x8E, 0x2B, 0xB3, 0x44, 0xB5, 0x9C, 0xA8, 0x28, 0xB5, 0xA5,
+ 0x43, 0x78, 0x15, 0x99, 0xEA, 0xF3, 0xD6, 0x02},
+ // C=IL, O=PersonalID Ltd., OU=Certificate Services, CN=PersonalID
+ // Trustworthy RootCA 2011
+ {0x07, 0x5B, 0xFC, 0xCA, 0x2D, 0x55, 0xAE, 0x6E, 0x35, 0x74, 0x2C, 0x32,
+ 0xAF, 0xD0, 0xCA, 0x8E, 0xA4, 0xC9, 0x58, 0xFE, 0xEF, 0xC2, 0x32, 0x24,
+ 0x99, 0x95, 0x41, 0xC0, 0x33, 0xD6, 0x9C, 0x8D},
+ // C=CN, O=CFCA GT CA
+ {0x07, 0x71, 0x92, 0x0C, 0x8C, 0xB8, 0x74, 0xD5, 0xC5, 0xA4, 0xDC, 0x0D,
+ 0x6A, 0x51, 0xA2, 0xD4, 0x95, 0xD3, 0x8C, 0x4D, 0xE2, 0xCD, 0x5B, 0x83,
+ 0xD2, 0xA0, 0x6F, 0xAA, 0x05, 0x19, 0x35, 0xF6},
+ // C=US, O=Equifax, OU=Equifax Secure Certificate Authority
+ {0x08, 0x29, 0x7A, 0x40, 0x47, 0xDB, 0xA2, 0x36, 0x80, 0xC7, 0x31, 0xDB,
+ 0x6E, 0x31, 0x76, 0x53, 0xCA, 0x78, 0x48, 0xE1, 0xBE, 0xBD, 0x3A, 0x0B,
+ 0x01, 0x79, 0xA7, 0x07, 0xF9, 0x2C, 0xF1, 0x78},
+ // C=US, O=AffirmTrust, CN=AffirmTrust Networking
+ {0x0A, 0x81, 0xEC, 0x5A, 0x92, 0x97, 0x77, 0xF1, 0x45, 0x90, 0x4A, 0xF3,
+ 0x8D, 0x5D, 0x50, 0x9F, 0x66, 0xB5, 0xE2, 0xC5, 0x8F, 0xCD, 0xB5, 0x31,
+ 0x05, 0x8B, 0x0E, 0x17, 0xF3, 0xF0, 0xB4, 0x1B},
+ // C=HU, L=Budapest, O=NetLock Halozatbiztonsagi Kft., OU=Tanusitvanykiadok,
+ // CN=NetLock Expressz (Class C) Tanusitvanykiado
+ {0x0B, 0x5E, 0xED, 0x4E, 0x84, 0x64, 0x03, 0xCF, 0x55, 0xE0, 0x65, 0x84,
+ 0x84, 0x40, 0xED, 0x2A, 0x82, 0x75, 0x8B, 0xF5, 0xB9, 0xAA, 0x1F, 0x25,
+ 0x3D, 0x46, 0x13, 0xCF, 0xA0, 0x80, 0xFF, 0x3F},
+ // C=LT, O=Skaitmeninio sertifikavimo centras, OU=Certification Authority,
+ // CN=SSC Root CA B
+ {0x0B, 0x9F, 0x26, 0xDF, 0xCA, 0x68, 0x4C, 0x2C, 0xFC, 0xE2, 0x3E, 0x4E,
+ 0x4D, 0xD5, 0x67, 0xC8, 0x86, 0xBA, 0x25, 0x9E, 0x1D, 0xB2, 0x67, 0xF9,
+ 0x80, 0x6F, 0x0C, 0x5A, 0x09, 0x97, 0x11, 0xF2},
+ // C=EU, O=AC Camerfirma SA CIF A82743287, OU=http://www.chambersign.org,
+ // CN=Chambers of Commerce Root
+ {0x0C, 0x25, 0x8A, 0x12, 0xA5, 0x67, 0x4A, 0xEF, 0x25, 0xF2, 0x8B, 0xA7,
+ 0xDC, 0xFA, 0xEC, 0xEE, 0xA3, 0x48, 0xE5, 0x41, 0xE6, 0xF5, 0xCC, 0x4E,
+ 0xE6, 0x3B, 0x71, 0xB3, 0x61, 0x60, 0x6A, 0xC3},
+ // C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO
+ // Certification Authority
+ {0x0C, 0x2C, 0xD6, 0x3D, 0xF7, 0x80, 0x6F, 0xA3, 0x99, 0xED, 0xE8, 0x09,
+ 0x11, 0x6B, 0x57, 0x5B, 0xF8, 0x79, 0x89, 0xF0, 0x65, 0x18, 0xF9, 0x80,
+ 0x8C, 0x86, 0x05, 0x03, 0x17, 0x8B, 0xAF, 0x66},
+ // C=NL, O=DigiNotar, CN=DigiNotar Root CA/emailAddress=info@diginotar.nl
+ {0x0D, 0x13, 0x6E, 0x43, 0x9F, 0x0A, 0xB6, 0xE9, 0x7F, 0x3A, 0x02, 0xA5,
+ 0x40, 0xDA, 0x9F, 0x06, 0x41, 0xAA, 0x55, 0x4E, 0x1D, 0x66, 0xEA, 0x51,
+ 0xAE, 0x29, 0x20, 0xD5, 0x1B, 0x2F, 0x72, 0x17},
+ // CN=Autoridad de Certificacion Raiz del Estado Venezolano, C=VE,
+ // L=Caracas, ST=Distrito Capital, O=Sistema Nacional de Certificacion
+ // Electronica, OU=Superintendencia de Servicios de Certificacion
+ // Electronica/emailAddress=acraiz@suscerte.gob.ve
+ {0x0E, 0x88, 0xEB, 0x6E, 0xA2, 0x56, 0xE1, 0x9E, 0xF8, 0xD3, 0xAB, 0xD6,
+ 0x1A, 0x24, 0xD3, 0x8D, 0xBA, 0xD6, 0x32, 0x81, 0x6D, 0xD9, 0x57, 0x29,
+ 0x44, 0x27, 0xE4, 0x72, 0x4D, 0x81, 0xA3, 0x86},
+ // C=NO, O=Buypass AS-983163327, CN=Buypass Class 2 CA 1
+ {0x0F, 0x4E, 0x9C, 0xDD, 0x26, 0x4B, 0x02, 0x55, 0x50, 0xD1, 0x70, 0x80,
+ 0x63, 0x40, 0x21, 0x4F, 0xE9, 0x44, 0x34, 0xC9, 0xB0, 0x2F, 0x69, 0x7E,
+ 0xC7, 0x10, 0xFC, 0x5F, 0xEA, 0xFB, 0x5E, 0x38},
+ // C=FR, O=Certplus, CN=Class 2 Primary CA
+ {0x0F, 0x99, 0x3C, 0x8A, 0xEF, 0x97, 0xBA, 0xAF, 0x56, 0x87, 0x14, 0x0E,
+ 0xD5, 0x9A, 0xD1, 0x82, 0x1B, 0xB4, 0xAF, 0xAC, 0xF0, 0xAA, 0x9A, 0x58,
+ 0xB5, 0xD5, 0x7A, 0x33, 0x8A, 0x3A, 0xFB, 0xCB},
+ // C=JP, O=Japanese Government, OU=GPKI, CN=ApplicationCA2 Root
+ {0x12, 0x6B, 0xF0, 0x1C, 0x10, 0x94, 0xD2, 0xF0, 0xCA, 0x2E, 0x35, 0x23,
+ 0x80, 0xB3, 0xC7, 0x24, 0x29, 0x45, 0x46, 0xCC, 0xC6, 0x55, 0x97, 0xBE,
+ 0xF7, 0xF1, 0x2D, 0x8A, 0x17, 0x1F, 0x19, 0x84},
+ // C=si, O=state-institutions, OU=sigen-ca
+ {0x12, 0xD4, 0x80, 0xC1, 0xA3, 0xC6, 0x64, 0x78, 0x1B, 0x99, 0xD9, 0xDF,
+ 0x0E, 0x9F, 0xAF, 0x3F, 0x1C, 0xAC, 0xEE, 0x1B, 0x3C, 0x30, 0xC3, 0x12,
+ 0x3A, 0x33, 0x7A, 0x4A, 0x45, 0x4F, 0xFE, 0xD2},
+ // C=EU, L=Madrid (see current address at
+ // www.camerfirma.com/address)/serialNumber=A82743287, O=AC Camerfirma S.A.,
+ // CN=Global Chambersign Root - 2008
+ {0x13, 0x63, 0x35, 0x43, 0x93, 0x34, 0xA7, 0x69, 0x80, 0x16, 0xA0, 0xD3,
+ 0x24, 0xDE, 0x72, 0x28, 0x4E, 0x07, 0x9D, 0x7B, 0x52, 0x20, 0xBB, 0x8F,
+ 0xBD, 0x74, 0x78, 0x16, 0xEE, 0xBE, 0xBA, 0xCA},
+ // C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification
+ // Authority
+ {0x14, 0x65, 0xFA, 0x20, 0x53, 0x97, 0xB8, 0x76, 0xFA, 0xA6, 0xF0, 0xA9,
+ 0x95, 0x8E, 0x55, 0x90, 0xE4, 0x0F, 0xCC, 0x7F, 0xAA, 0x4F, 0xB7, 0xC2,
+ 0xC8, 0x67, 0x75, 0x21, 0xFB, 0x5F, 0xB6, 0x58},
+ // C=FR, O=Certplus, CN=Certplus Root CA G1
+ {0x15, 0x2A, 0x40, 0x2B, 0xFC, 0xDF, 0x2C, 0xD5, 0x48, 0x05, 0x4D, 0x22,
+ 0x75, 0xB3, 0x9C, 0x7F, 0xCA, 0x3E, 0xC0, 0x97, 0x80, 0x78, 0xB0, 0xF0,
+ 0xEA, 0x76, 0xE5, 0x61, 0xA6, 0xC7, 0x43, 0x3E},
+ // C=es, O=Servicio de Certificacion del Colegio de Registradores (SCR),
+ // OU=Certificado Propio, OU=Certificado Raiz, CN=Certificado de la Clave
+ // Principal/street=Principe de Vergara 72 28006
+ // Madrid/emailAddress=scr@registradores.org
+ {0x15, 0x94, 0xCB, 0x5B, 0x82, 0x6C, 0x31, 0x5D, 0xE3, 0xBC, 0x93, 0x2C,
+ 0x56, 0x89, 0x5F, 0xF2, 0x3A, 0x3A, 0x98, 0x8B, 0x5D, 0xC1, 0xF0, 0x34,
+ 0xD2, 0x14, 0xDF, 0xD8, 0x58, 0xD8, 0x9E, 0xE8},
+ // C=US, O=Network Solutions L.L.C., CN=Network Solutions Certificate
+ // Authority
+ {0x15, 0xF0, 0xBA, 0x00, 0xA3, 0xAC, 0x7A, 0xF3, 0xAC, 0x88, 0x4C, 0x07,
+ 0x2B, 0x10, 0x11, 0xA0, 0x77, 0xBD, 0x77, 0xC0, 0x97, 0xF4, 0x01, 0x64,
+ 0xB2, 0xF8, 0x59, 0x8A, 0xBD, 0x83, 0x86, 0x0C},
+ // C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
+ {0x16, 0xAF, 0x57, 0xA9, 0xF6, 0x76, 0xB0, 0xAB, 0x12, 0x60, 0x95, 0xAA,
+ 0x5E, 0xBA, 0xDE, 0xF2, 0x2A, 0xB3, 0x11, 0x19, 0xD6, 0x44, 0xAC, 0x95,
+ 0xCD, 0x4B, 0x93, 0xDB, 0xF3, 0xF2, 0x6A, 0xEB},
+ // C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO
+ // ECC Certification Authority
+ {0x17, 0x93, 0x92, 0x7A, 0x06, 0x14, 0x54, 0x97, 0x89, 0xAD, 0xCE, 0x2F,
+ 0x8F, 0x34, 0xF7, 0xF0, 0xB6, 0x6D, 0x0F, 0x3A, 0xE3, 0xA3, 0xB8, 0x4D,
+ 0x21, 0xEC, 0x15, 0xDB, 0xBA, 0x4F, 0xAD, 0xC7},
+ // OU=GlobalSign ECC Root CA - R5, O=GlobalSign, CN=GlobalSign
+ {0x17, 0x9F, 0xBC, 0x14, 0x8A, 0x3D, 0xD0, 0x0F, 0xD2, 0x4E, 0xA1, 0x34,
+ 0x58, 0xCC, 0x43, 0xBF, 0xA7, 0xF5, 0x9C, 0x81, 0x82, 0xD7, 0x83, 0xA5,
+ 0x13, 0xF6, 0xEB, 0xEC, 0x10, 0x0C, 0x89, 0x24},
+ // C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3
+ {0x18, 0xF1, 0xFC, 0x7F, 0x20, 0x5D, 0xF8, 0xAD, 0xDD, 0xEB, 0x7F, 0xE0,
+ 0x07, 0xDD, 0x57, 0xE3, 0xAF, 0x37, 0x5A, 0x9C, 0x4D, 0x8D, 0x73, 0x54,
+ 0x6B, 0xF4, 0xF1, 0xFE, 0xD1, 0xE1, 0x8D, 0x35},
+ // C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO
+ // Certification Authority
+ {0x1A, 0x0D, 0x20, 0x44, 0x5D, 0xE5, 0xBA, 0x18, 0x62, 0xD1, 0x9E, 0xF8,
+ 0x80, 0x85, 0x8C, 0xBC, 0xE5, 0x01, 0x02, 0xB3, 0x6E, 0x8F, 0x0A, 0x04,
+ 0x0C, 0x3C, 0x69, 0xE7, 0x45, 0x22, 0xFE, 0x6E},
+ // C=ZA, ST=Western Cape, L=Somerset West, O=South African Post Office
+ // Limited, OU=SAPO Trust Centre, CN=SAPO Class 3 Root
+ // CA/emailAddress=pkiadmin@trustcentre.co.za
+ {0x1A, 0x25, 0x12, 0xCD, 0xA6, 0x74, 0x4A, 0xBE, 0xA1, 0x14, 0x32, 0xA2,
+ 0xFD, 0xC9, 0xF8, 0xC0, 0x88, 0xDB, 0x5A, 0x98, 0xC8, 0x9E, 0x13, 0x35,
+ 0x25, 0x74, 0xCD, 0xE4, 0xD9, 0xE8, 0x0C, 0xDD},
+ // C=CN, O=China Internet Network Information Center, CN=China Internet
+ // Network Information Center EV Certificates Root
+ {0x1C, 0x01, 0xC6, 0xF4, 0xDB, 0xB2, 0xFE, 0xFC, 0x22, 0x55, 0x8B, 0x2B,
+ 0xCA, 0x32, 0x56, 0x3F, 0x49, 0x84, 0x4A, 0xCF, 0xC3, 0x2B, 0x7B, 0xE4,
+ 0xB0, 0xFF, 0x59, 0x9F, 0x9E, 0x8C, 0x7A, 0xF7},
+ // C=TN, O=ANCE, OU=Certification & PKI, CN=Agence Nationale de
+ // Certification Electronique/emailAddress=ance@certification.tn
+ {0x1D, 0x4F, 0x05, 0x96, 0xFC, 0xA2, 0x61, 0x1D, 0x09, 0xF8, 0x4C, 0x78,
+ 0xF2, 0xEA, 0x56, 0x5E, 0xF2, 0xEA, 0xB9, 0xCF, 0xC2, 0x72, 0xA1, 0x71,
+ 0x8B, 0xD3, 0x36, 0xE6, 0xE0, 0xAE, 0x02, 0x1A},
+ // C=FR, O=ANSSI, OU=0002 130007669, CN=IGC/A AC racine Etat francais
+ {0x1E, 0x1A, 0x69, 0x84, 0xB4, 0xE7, 0x6B, 0xD7, 0x09, 0xAE, 0xE3, 0xE9,
+ 0xC9, 0xCF, 0x31, 0x18, 0xEA, 0xC0, 0x96, 0xDA, 0xB9, 0xCC, 0x20, 0xDC,
+ 0x25, 0xFA, 0xAB, 0x67, 0x29, 0x7E, 0x96, 0x5A},
+ // C=CH, O=SwissSign AG, CN=SwissSign Silver Root CA - G3
+ {0x1E, 0x49, 0xAC, 0x5D, 0xC6, 0x9E, 0x86, 0xD0, 0x56, 0x5D, 0xA2, 0xC1,
+ 0x30, 0x5C, 0x41, 0x93, 0x30, 0xB0, 0xB7, 0x81, 0xBF, 0xEC, 0x50, 0xE5,
+ 0x4A, 0x1B, 0x35, 0xAF, 0x7F, 0xDD, 0xD5, 0x01},
+ // C=ch, O=Swisscom, OU=Digital Certificate Services, CN=Swisscom Root CA 1
+ {0x21, 0xDB, 0x20, 0x12, 0x36, 0x60, 0xBB, 0x2E, 0xD4, 0x18, 0x20, 0x5D,
+ 0xA1, 0x1E, 0xE7, 0xA8, 0x5A, 0x65, 0xE2, 0xBC, 0x6E, 0x55, 0xB5, 0xAF,
+ 0x7E, 0x78, 0x99, 0xC8, 0xA2, 0x66, 0xD9, 0x2E},
+ // C=US, O=Cisco Systems, CN=Cisco RXC-R2
+ {0x22, 0x9C, 0xCC, 0x19, 0x6D, 0x32, 0xC9, 0x84, 0x21, 0xCC, 0x11, 0x9E,
+ 0x78, 0x48, 0x6E, 0xEB, 0xEF, 0x60, 0x3A, 0xEC, 0xD5, 0x25, 0xC6, 0xB8,
+ 0x8B, 0x47, 0xAB, 0xB7, 0x40, 0x69, 0x2B, 0x96},
+ // C=US, O=Digital Signature Trust Co., OU=DST-Entrust GTI CA
+ {0x22, 0xE0, 0xD1, 0x1D, 0xC9, 0x20, 0x7E, 0x16, 0xC9, 0x2B, 0x2E, 0xE1,
+ 0x8C, 0xFD, 0xB2, 0xC2, 0xE9, 0x40, 0x62, 0x68, 0x47, 0x92, 0x1F, 0xC5,
+ 0x28, 0xCE, 0xDD, 0x2F, 0x79, 0x32, 0xF7, 0x14},
+ // C=ES, O=IZENPE S.A., CN=Izenpe.com
+ {0x23, 0x80, 0x42, 0x03, 0xCA, 0x45, 0xD8, 0xCD, 0xE7, 0x16, 0xB8, 0xC1,
+ 0x3B, 0xF3, 0xB4, 0x48, 0x45, 0x7F, 0xA0, 0x6C, 0xC1, 0x02, 0x50, 0x99,
+ 0x7F, 0xA0, 0x14, 0x58, 0x31, 0x7C, 0x41, 0xE5},
+ // C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2008 VeriSign,
+ // Inc. - For authorized use only, CN=VeriSign Universal Root Certification
+ // Authority
+ {0x23, 0x99, 0x56, 0x11, 0x27, 0xA5, 0x71, 0x25, 0xDE, 0x8C, 0xEF, 0xEA,
+ 0x61, 0x0D, 0xDF, 0x2F, 0xA0, 0x78, 0xB5, 0xC8, 0x06, 0x7F, 0x4E, 0x82,
+ 0x82, 0x90, 0xBF, 0xB8, 0x60, 0xE8, 0x4B, 0x3C},
+ // C=US, ST=Utah, L=Salt Lake City, O=Xcert EZ by DST, CN=Xcert EZ by
+ // DST/emailAddress=ca@digsigtrust.com
+ {0x26, 0x02, 0xD2, 0x1E, 0x81, 0x27, 0x7A, 0x83, 0xF6, 0x04, 0x81, 0x28,
+ 0xF6, 0x1D, 0x79, 0x4A, 0x06, 0xF4, 0x74, 0xE1, 0xF7, 0x5E, 0x49, 0x74,
+ 0x0A, 0x81, 0x7C, 0x26, 0x66, 0xF6, 0x22, 0x11},
+ // CN=ComSign Global Root CA, O=ComSign Ltd., C=IL
+ {0x26, 0x05, 0x87, 0x5A, 0xFC, 0xC1, 0x76, 0xB2, 0xD6, 0x6D, 0xD6, 0x6A,
+ 0x99, 0x5D, 0x7F, 0x8D, 0x5E, 0xBB, 0x86, 0xCE, 0x12, 0x0D, 0x0E, 0x7E,
+ 0x9E, 0x7C, 0x6E, 0xF2, 0x94, 0xA2, 0x7D, 0x4C},
+ // C=FR, O=OpenTrust, CN=OpenTrust Root CA G2
+ {0x27, 0x99, 0x58, 0x29, 0xFE, 0x6A, 0x75, 0x15, 0xC1, 0xBF, 0xE8, 0x48,
+ 0xF9, 0xC4, 0x76, 0x1D, 0xB1, 0x6C, 0x22, 0x59, 0x29, 0x25, 0x7B, 0xF4,
+ 0x0D, 0x08, 0x94, 0xF2, 0x9E, 0xA8, 0xBA, 0xF2},
+ // C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Universal CA, CN=TC
+ // TrustCenter Universal CA II
+ {0x28, 0x34, 0x99, 0x1C, 0xF6, 0x77, 0x46, 0x6D, 0x22, 0xBA, 0xAC, 0x3B,
+ 0x00, 0x55, 0xE5, 0xB9, 0x11, 0xD9, 0xA9, 0xE5, 0x5F, 0x5B, 0x85, 0xBA,
+ 0x02, 0xDC, 0x56, 0x67, 0x82, 0xC3, 0x0E, 0x8A},
+ // C=US, O=RSA Data Security, Inc., OU=Secure Server Certification Authority
+ {0x29, 0x30, 0xBD, 0x09, 0xA0, 0x71, 0x26, 0xBD, 0xC1, 0x72, 0x88, 0xD4,
+ 0xF2, 0xAD, 0x84, 0x64, 0x5E, 0xC9, 0x48, 0x60, 0x79, 0x07, 0xA9, 0x7B,
+ 0x5E, 0xD0, 0xB0, 0xB0, 0x58, 0x79, 0xEF, 0x69},
+ // C=NL, O=DigiNotar, CN=DigiNotar Root CA G2/emailAddress=info@diginotar.nl
+ {0x29, 0x4F, 0x55, 0xEF, 0x3B, 0xD7, 0x24, 0x4C, 0x6F, 0xF8, 0xA6, 0x8A,
+ 0xB7, 0x97, 0xE9, 0x18, 0x6E, 0xC2, 0x75, 0x82, 0x75, 0x1A, 0x79, 0x15,
+ 0x15, 0xE3, 0x29, 0x2E, 0x48, 0x37, 0x2D, 0x61},
+ // C=FR, O=Certinomis, OU=0002 433998903, CN=Certinomis - Root CA
+ {0x2A, 0x99, 0xF5, 0xBC, 0x11, 0x74, 0xB7, 0x3C, 0xBB, 0x1D, 0x62, 0x08,
+ 0x84, 0xE0, 0x1C, 0x34, 0xE5, 0x1C, 0xCB, 0x39, 0x78, 0xDA, 0x12, 0x5F,
+ 0x0E, 0x33, 0x26, 0x88, 0x83, 0xBF, 0x41, 0x58},
+ // C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc.,
+ // CN=Starfield Root Certificate Authority - G2
+ {0x2C, 0xE1, 0xCB, 0x0B, 0xF9, 0xD2, 0xF9, 0xE1, 0x02, 0x99, 0x3F, 0xBE,
+ 0x21, 0x51, 0x52, 0xC3, 0xB2, 0xDD, 0x0C, 0xAB, 0xDE, 0x1C, 0x68, 0xE5,
+ 0x31, 0x9B, 0x83, 0x91, 0x54, 0xDB, 0xB7, 0xF5},
+ // C=JP, O=Japanese Government, OU=ApplicationCA
+ {0x2D, 0x47, 0x43, 0x7D, 0xE1, 0x79, 0x51, 0x21, 0x5A, 0x12, 0xF3, 0xC5,
+ 0x8E, 0x51, 0xC7, 0x29, 0xA5, 0x80, 0x26, 0xEF, 0x1F, 0xCC, 0x0A, 0x5F,
+ 0xB3, 0xD9, 0xDC, 0x01, 0x2F, 0x60, 0x0D, 0x19},
+ // C=IN, O=India PKI, CN=CCA India 2011
+ {0x2D, 0x66, 0xA7, 0x02, 0xAE, 0x81, 0xBA, 0x03, 0xAF, 0x8C, 0xFF, 0x55,
+ 0xAB, 0x31, 0x8A, 0xFA, 0x91, 0x90, 0x39, 0xD9, 0xF3, 0x1B, 0x4D, 0x64,
+ 0x38, 0x86, 0x80, 0xF8, 0x13, 0x11, 0xB6, 0x5A},
+ // C=AT, ST=Austria, L=Vienna, O=ARGE DATEN - Austrian Society for Data
+ // Protection, OU=A-CERT Certification Service, CN=A-CERT
+ // ADVANCED/emailAddress=info@a-cert.at
+ {0x2D, 0xC6, 0x2C, 0x3F, 0x6C, 0x0C, 0xC9, 0x02, 0x0B, 0xBA, 0x77, 0xE1,
+ 0xC5, 0x11, 0x51, 0x10, 0x24, 0xB9, 0x43, 0xEE, 0x59, 0x88, 0x56, 0xDA,
+ 0x5A, 0x22, 0xE2, 0x22, 0xB7, 0x27, 0x7A, 0x20},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-Root-05, CN=A-Trust-Root-05
+ {0x2D, 0xDE, 0x9D, 0x0C, 0x0A, 0x90, 0xE7, 0xB3, 0x2B, 0x5A, 0xBC, 0x01,
+ 0xF4, 0x17, 0x99, 0xD4, 0x2E, 0x95, 0xA1, 0xE3, 0xC3, 0x1C, 0x3B, 0x39,
+ 0x37, 0x3B, 0xB8, 0x14, 0x1E, 0xA5, 0x44, 0x71},
+ // C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE
+ // CyberTrust Root
+ {0x2D, 0xFC, 0xBA, 0xCA, 0xDF, 0x22, 0xA6, 0xFF, 0x10, 0x7A, 0x51, 0xFD,
+ 0x3E, 0x8B, 0x9E, 0x17, 0x85, 0x80, 0x28, 0x87, 0x9B, 0x13, 0xF7, 0xC3,
+ 0xB5, 0x7B, 0x3E, 0x1B, 0xD2, 0x31, 0x58, 0x09},
+ // C=US, O=Equifax Secure, OU=Equifax Secure eBusiness CA-2
+ {0x2F, 0x27, 0x4E, 0x48, 0xAB, 0xA4, 0xAC, 0x7B, 0x76, 0x59, 0x33, 0x10,
+ 0x17, 0x75, 0x50, 0x6D, 0xC3, 0x0E, 0xE3, 0x8E, 0xF6, 0xAC, 0xD5, 0xC0,
+ 0x49, 0x32, 0xCF, 0xE0, 0x41, 0x23, 0x42, 0x20},
+ // C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Universal CA, CN=TC
+ // TrustCenter Universal CA III
+ {0x30, 0x9B, 0x4A, 0x87, 0xF6, 0xCA, 0x56, 0xC9, 0x31, 0x69, 0xAA, 0xA9,
+ 0x9C, 0x6D, 0x98, 0x88, 0x54, 0xD7, 0x89, 0x2B, 0xD5, 0x43, 0x7E, 0x2D,
+ 0x07, 0xB2, 0x9C, 0xBE, 0xDA, 0x55, 0xD3, 0x5D},
+ // C=US, O=IdenTrust, CN=IdenTrust Public Sector Root CA 1
+ {0x30, 0xD0, 0x89, 0x5A, 0x9A, 0x44, 0x8A, 0x26, 0x20, 0x91, 0x63, 0x55,
+ 0x22, 0xD1, 0xF5, 0x20, 0x10, 0xB5, 0x86, 0x7A, 0xCA, 0xE1, 0x2C, 0x78,
+ 0xEF, 0x95, 0x8F, 0xD4, 0xF4, 0x38, 0x9F, 0x2F},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G3
+ {0x31, 0xAD, 0x66, 0x48, 0xF8, 0x10, 0x41, 0x38, 0xC7, 0x38, 0xF3, 0x9E,
+ 0xA4, 0x32, 0x01, 0x33, 0x39, 0x3E, 0x3A, 0x18, 0xCC, 0x02, 0x29, 0x6E,
+ 0xF9, 0x7C, 0x2A, 0xC9, 0xEF, 0x67, 0x31, 0xD0},
+ // C=BR, ST=Rio de Janeiro, L=Rio de Janeiro, O=Certisign Certificadora
+ // Digital Ltda., OU=Certisign Autoridade Certificadora AC3S
+ {0x31, 0xEA, 0xCE, 0x9B, 0x4C, 0x9C, 0x71, 0x73, 0x4A, 0x18, 0x56, 0x80,
+ 0xBC, 0x24, 0x86, 0x6C, 0xA6, 0xCB, 0xD8, 0x2B, 0x3C, 0xB6, 0x1B, 0xCC,
+ 0x87, 0x06, 0x26, 0x1B, 0x59, 0xCE, 0x10, 0x73},
+ // C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Class 4 CA, CN=TC
+ // TrustCenter Class 4 CA II
+ {0x32, 0x66, 0x96, 0x7E, 0x59, 0xCD, 0x68, 0x00, 0x8D, 0x9D, 0xD3, 0x20,
+ 0x81, 0x11, 0x85, 0xC7, 0x04, 0x20, 0x5E, 0x8D, 0x95, 0xFD, 0xD8, 0x4F,
+ 0x1C, 0x7B, 0x31, 0x1E, 0x67, 0x04, 0xFC, 0x32},
+ // C=HU, L=Budapest, O=Microsec Ltd., OU=e-Szigno CA, CN=Microsec e-Szigno
+ // Root CA
+ {0x32, 0x7A, 0x3D, 0x76, 0x1A, 0xBA, 0xDE, 0xA0, 0x34, 0xEB, 0x99, 0x84,
+ 0x06, 0x27, 0x5C, 0xB1, 0xA4, 0x77, 0x6E, 0xFD, 0xAE, 0x2F, 0xDF, 0x6D,
+ 0x01, 0x68, 0xEA, 0x1C, 0x4F, 0x55, 0x67, 0xD0},
+ // C=SA, O=National Center for Digital Certification, OU=Saudi National Root
+ // CA
+ {0x34, 0xBB, 0x34, 0xE1, 0x4F, 0xAE, 0xD0, 0xD3, 0x39, 0x2F, 0x2F, 0xC4,
+ 0x41, 0xC0, 0xEC, 0xD5, 0xFD, 0x88, 0xAD, 0x88, 0x11, 0x8D, 0xF2, 0xD1,
+ 0xBA, 0x76, 0xCD, 0xEC, 0x1E, 0xEA, 0x10, 0xB8},
+ // CN=EBG Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1, O=EBG Bili\xC5\x9Fim
+ // Teknolojileri ve Hizmetleri A.\xC5\x9E., C=TR
+ {0x35, 0xAE, 0x5B, 0xDD, 0xD8, 0xF7, 0xAE, 0x63, 0x5C, 0xFF, 0xBA, 0x56,
+ 0x82, 0xA8, 0xF0, 0x0B, 0x95, 0xF4, 0x84, 0x62, 0xC7, 0x10, 0x8E, 0xE9,
+ 0xA0, 0xE5, 0x29, 0x2B, 0x07, 0x4A, 0xAF, 0xB2},
+ // C=ES, O=Agencia Notarial de Certificacion S.L. Unipersonal - CIF
+ // B83395988, CN=ANCERT Corporaciones de Derecho Publico
+ {0x36, 0x54, 0x4D, 0x2F, 0xCE, 0x03, 0xC6, 0xC7, 0x2B, 0x70, 0xEB, 0x1A,
+ 0x80, 0x64, 0x26, 0x4D, 0xC1, 0x51, 0x17, 0x68, 0xC2, 0xD8, 0xF7, 0x6A,
+ 0x8B, 0x9F, 0x1F, 0x2B, 0xBD, 0x15, 0x3B, 0x7D},
+ // C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
+ {0x37, 0xD5, 0x10, 0x06, 0xC5, 0x12, 0xEA, 0xAB, 0x62, 0x64, 0x21, 0xF1,
+ 0xEC, 0x8C, 0x92, 0x01, 0x3F, 0xC5, 0xF8, 0x2A, 0xE9, 0x8E, 0xE5, 0x33,
+ 0xEB, 0x46, 0x19, 0xB8, 0xDE, 0xB4, 0xD0, 0x6C},
+ // C=HU, L=Budapest, O=NetLock Halozatbiztonsagi Kft., OU=Tanusitvanykiadok,
+ // CN=NetLock Uzleti (Class B) Tanusitvanykiado
+ {0x39, 0xDF, 0x7B, 0x68, 0x2B, 0x7B, 0x93, 0x8F, 0x84, 0x71, 0x54, 0x81,
+ 0xCC, 0xDE, 0x8D, 0x60, 0xD8, 0xF2, 0x2E, 0xC5, 0x98, 0x87, 0x7D, 0x0A,
+ 0xAA, 0xC1, 0x2B, 0x59, 0x18, 0x2B, 0x03, 0x12},
+ // C=IE, O=An Post, OU=Post.Trust Ltd., CN=Post.Trust Root CA
+ {0x39, 0xF6, 0x03, 0x3C, 0xA6, 0x64, 0xCE, 0xDB, 0x21, 0x67, 0x44, 0xD3,
+ 0xC6, 0xF2, 0xB2, 0xE8, 0xE3, 0xCE, 0xBD, 0x68, 0x69, 0xF7, 0xDF, 0xF4,
+ 0x7E, 0x0D, 0xB9, 0x1A, 0x79, 0xC4, 0x16, 0xF8},
+ // C=CH, O=SwissSign AG, CN=SwissSign Platinum CA - G2
+ {0x3B, 0x22, 0x2E, 0x56, 0x67, 0x11, 0xE9, 0x92, 0x30, 0x0D, 0xC0, 0xB1,
+ 0x5A, 0xB9, 0x47, 0x3D, 0xAF, 0xDE, 0xF8, 0xC8, 0x4D, 0x0C, 0xEF, 0x7D,
+ 0x33, 0x17, 0xB4, 0xC1, 0x82, 0x1D, 0x14, 0x36},
+ // C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden Root CA - G3
+ {0x3C, 0x4F, 0xB0, 0xB9, 0x5A, 0xB8, 0xB3, 0x00, 0x32, 0xF4, 0x32, 0xB8,
+ 0x6F, 0x53, 0x5F, 0xE1, 0x72, 0xC1, 0x85, 0xD0, 0xFD, 0x39, 0x86, 0x58,
+ 0x37, 0xCF, 0x36, 0x18, 0x7F, 0xA6, 0xF4, 0x28},
+ // C=HU, L=Budapest, O=Microsec Ltd., CN=Microsec e-Szigno Root CA
+ // 2009/emailAddress=info@e-szigno.hu
+ {0x3C, 0x5F, 0x81, 0xFE, 0xA5, 0xFA, 0xB8, 0x2C, 0x64, 0xBF, 0xA2, 0xEA,
+ 0xEC, 0xAF, 0xCD, 0xE8, 0xE0, 0x77, 0xFC, 0x86, 0x20, 0xA7, 0xCA, 0xE5,
+ 0x37, 0x16, 0x3D, 0xF3, 0x6E, 0xDB, 0xF3, 0x78},
+ // CN=ComSign Advanced Security CA
+ {0x3C, 0xCC, 0x3C, 0xCF, 0xE4, 0x54, 0x96, 0xD0, 0x7B, 0x62, 0x0D, 0xBF,
+ 0x13, 0x28, 0xE8, 0xA1, 0x49, 0x00, 0x18, 0xF4, 0x86, 0x33, 0xC8, 0xA2,
+ 0x8A, 0x99, 0x5C, 0xA6, 0x04, 0x08, 0xB0, 0xBE},
+ // C=AT, O=A-Trust Ges. f\xFCr Sicherheitssysteme im elektr. Datenverkehr
+ // GmbH, OU=A-Trust-Qual-01, CN=A-Trust-Qual-01
+ {0x3D, 0xEA, 0xE6, 0xAE, 0x97, 0x52, 0x84, 0xE0, 0xE6, 0xFA, 0x2E, 0xB7,
+ 0x6C, 0xE4, 0x6E, 0x12, 0x44, 0x18, 0x69, 0xA2, 0xA7, 0xD4, 0xE6, 0x7D,
+ 0xC7, 0xAB, 0x86, 0x64, 0xFE, 0xFD, 0xBB, 0xB0},
+ // C=EE, O=AS Sertifitseerimiskeskus, CN=EE Certification Centre Root
+ // CA/emailAddress=pki@sk.ee
+ {0x3E, 0x84, 0xBA, 0x43, 0x42, 0x90, 0x85, 0x16, 0xE7, 0x75, 0x73, 0xC0,
+ 0x99, 0x2F, 0x09, 0x79, 0xCA, 0x08, 0x4E, 0x46, 0x85, 0x68, 0x1F, 0xF1,
+ 0x95, 0xCC, 0xBA, 0x8A, 0x22, 0x9B, 0x8A, 0x76},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA
+ {0x3E, 0x90, 0x99, 0xB5, 0x01, 0x5E, 0x8F, 0x48, 0x6C, 0x00, 0xBC, 0xEA,
+ 0x9D, 0x11, 0x1E, 0xE7, 0x21, 0xFA, 0xBA, 0x35, 0x5A, 0x89, 0xBC, 0xF1,
+ 0xDF, 0x69, 0x56, 0x1E, 0x3D, 0xC6, 0x32, 0x5C},
+ // C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=Trusted
+ // Certificate Services
+ {0x3F, 0x06, 0xE5, 0x56, 0x81, 0xD4, 0x96, 0xF5, 0xBE, 0x16, 0x9E, 0xB5,
+ 0x38, 0x9F, 0x9F, 0x2B, 0x8F, 0xF6, 0x1E, 0x17, 0x08, 0xDF, 0x68, 0x81,
+ 0x72, 0x48, 0x49, 0xCD, 0x5D, 0x27, 0xCB, 0x69},
+ // C=GB, O=Trustis Limited, OU=Trustis EVS Root CA
+ {0x3F, 0x9D, 0xA4, 0x74, 0x4E, 0xC9, 0x67, 0x6C, 0xD3, 0x8B, 0x53, 0x0E,
+ 0x50, 0x0A, 0x46, 0x3F, 0xBC, 0xB1, 0x81, 0x65, 0x97, 0x7F, 0xF0, 0xDA,
+ 0x6D, 0x59, 0x93, 0xC3, 0xFE, 0x5F, 0xAB, 0x7C},
+ // C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc,
+ // OU=Certification Services Division, CN=Thawte Premium Server
+ // CA/emailAddress=premium-server@thawte.com
+ {0x3F, 0x9F, 0x27, 0xD5, 0x83, 0x20, 0x4B, 0x9E, 0x09, 0xC8, 0xA3, 0xD2,
+ 0x06, 0x6C, 0x4B, 0x57, 0xD3, 0xA2, 0x47, 0x9C, 0x36, 0x93, 0x65, 0x08,
+ 0x80, 0x50, 0x56, 0x98, 0x10, 0x5D, 0xBC, 0xE9},
+ // C=KR, O=Government of Korea, OU=GPKI, CN=GPKIRootCA1
+ {0x40, 0x7C, 0x27, 0x6B, 0xEA, 0xD2, 0xE4, 0xAF, 0x06, 0x61, 0xEF, 0x66,
+ 0x97, 0x34, 0x1D, 0xEC, 0x0A, 0x1F, 0x94, 0x34, 0xE4, 0xEA, 0xFB, 0x2D,
+ 0x3D, 0x32, 0xA9, 0x05, 0x49, 0xD9, 0xDE, 0x4A},
+ // C=NL, O=Digidentity B.V., CN=Digidentity L3 Root CA - G2
+ {0x41, 0x7D, 0xCF, 0x31, 0x80, 0xF4, 0xED, 0x1A, 0x37, 0x47, 0xAC, 0xF1,
+ 0x17, 0x93, 0x16, 0xCD, 0x48, 0xCB, 0x05, 0xC5, 0x78, 0x84, 0x35, 0x16,
+ 0x8A, 0xED, 0x98, 0xC9, 0x8C, 0xDC, 0xB6, 0x15},
+ // C=CH, O=WISeKey, OU=Copyright (c) 2005, OU=OISTE Foundation Endorsed,
+ // CN=OISTE WISeKey Global Root GA CA
+ {0x41, 0xC9, 0x23, 0x86, 0x6A, 0xB4, 0xCA, 0xD6, 0xB7, 0xAD, 0x57, 0x80,
+ 0x81, 0x58, 0x2E, 0x02, 0x07, 0x97, 0xA6, 0xCB, 0xDF, 0x4F, 0xFF, 0x78,
+ 0xCE, 0x83, 0x96, 0xB3, 0x89, 0x37, 0xD7, 0xF5},
+ // C=US, O=SecureTrust Corporation, CN=Secure Global CA
+ {0x42, 0x00, 0xF5, 0x04, 0x3A, 0xC8, 0x59, 0x0E, 0xBB, 0x52, 0x7D, 0x20,
+ 0x9E, 0xD1, 0x50, 0x30, 0x29, 0xFB, 0xCB, 0xD4, 0x1C, 0xA1, 0xB5, 0x06,
+ 0xEC, 0x27, 0xF1, 0x5A, 0xDE, 0x7D, 0xAC, 0x69},
+ // C=FR, O=KEYNECTIS, OU=ROOT, CN=KEYNECTIS ROOT CA
+ {0x42, 0x10, 0xF1, 0x99, 0x49, 0x9A, 0x9A, 0xC3, 0x3C, 0x8D, 0xE0, 0x2B,
+ 0xA6, 0xDB, 0xAA, 0x14, 0x40, 0x8B, 0xDD, 0x8A, 0x6E, 0x32, 0x46, 0x89,
+ 0xC1, 0x92, 0x2D, 0x06, 0x97, 0x15, 0xA3, 0x32},
+ // C=FR, O=Certeurope, OU=0002 434202180, CN=Certeurope Root CA 2
+ {0x42, 0x14, 0x3A, 0x51, 0x1A, 0x3A, 0xFC, 0xDD, 0x80, 0xD5, 0x55, 0xDE,
+ 0xBB, 0x41, 0x91, 0xEC, 0x6B, 0xB2, 0x85, 0xEE, 0x66, 0xE6, 0x2E, 0xC6,
+ 0x57, 0xED, 0x20, 0xAD, 0xF7, 0xD5, 0x5F, 0xAA},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
+ {0x43, 0x48, 0xA0, 0xE9, 0x44, 0x4C, 0x78, 0xCB, 0x26, 0x5E, 0x05, 0x8D,
+ 0x5E, 0x89, 0x44, 0xB4, 0xD8, 0x4F, 0x96, 0x62, 0xBD, 0x26, 0xDB, 0x25,
+ 0x7F, 0x89, 0x34, 0xA4, 0x43, 0xC7, 0x01, 0x61},
+ // C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009
+ // Entrust, Inc. - for authorized use only, CN=Entrust Root Certification
+ // Authority - G2
+ {0x43, 0xDF, 0x57, 0x74, 0xB0, 0x3E, 0x7F, 0xEF, 0x5F, 0xE4, 0x0D, 0x93,
+ 0x1A, 0x7B, 0xED, 0xF1, 0xBB, 0x2E, 0x6B, 0x42, 0x73, 0x8C, 0x4E, 0x6D,
+ 0x38, 0x41, 0x10, 0x3D, 0x3A, 0xA7, 0xF3, 0x39},
+ // CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1, C=TR, L=ANKARA, O=(c) 2005
+ // T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve Bili\xC5\x9Fim
+ // G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E.
+ {0x44, 0x04, 0xE3, 0x3B, 0x5E, 0x14, 0x0D, 0xCF, 0x99, 0x80, 0x51, 0xFD,
+ 0xFC, 0x80, 0x28, 0xC7, 0xC8, 0x16, 0x15, 0xC5, 0xEE, 0x73, 0x7B, 0x11,
+ 0x1B, 0x58, 0x82, 0x33, 0xA9, 0xB5, 0x35, 0xA0},
+ // C=US, O=VeriSign, Inc., OU=Class 4 Public Primary Certification Authority
+ // - G2, OU=(c) 1998 VeriSign, Inc. - For authorized use only, OU=VeriSign
+ // Trust Network
+ {0x44, 0x64, 0x0A, 0x0A, 0x0E, 0x4D, 0x00, 0x0F, 0xBD, 0x57, 0x4D, 0x2B,
+ 0x8A, 0x07, 0xBD, 0xB4, 0xD1, 0xDF, 0xED, 0x3B, 0x45, 0xBA, 0xAB, 0xA7,
+ 0x6F, 0x78, 0x57, 0x78, 0xC7, 0x01, 0x19, 0x61},
+ // C=GR, L=Athens, O=Hellenic Academic and Research Institutions Cert.
+ // Authority, CN=Hellenic Academic and Research Institutions ECC RootCA 2015
+ {0x44, 0xB5, 0x45, 0xAA, 0x8A, 0x25, 0xE6, 0x5A, 0x73, 0xCA, 0x15, 0xDC,
+ 0x27, 0xFC, 0x36, 0xD2, 0x4C, 0x1C, 0xB9, 0x95, 0x3A, 0x06, 0x65, 0x39,
+ 0xB1, 0x15, 0x82, 0xDC, 0x48, 0x7B, 0x48, 0x33},
+ // C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root
+ // Certificate Authority - G2
+ {0x45, 0x14, 0x0B, 0x32, 0x47, 0xEB, 0x9C, 0xC8, 0xC5, 0xB4, 0xF0, 0xD7,
+ 0xB5, 0x30, 0x91, 0xF7, 0x32, 0x92, 0x08, 0x9E, 0x6E, 0x5A, 0x63, 0xE2,
+ 0x74, 0x9D, 0xD3, 0xAC, 0xA9, 0x19, 0x8E, 0xDA},
+ // C=UY, O=ADMINISTRACION NACIONAL DE CORREOS, OU=SERVICIOS ELECTRONICOS,
+ // CN=Correo Uruguayo - Root CA
+ {0x46, 0x27, 0x32, 0x85, 0x61, 0x5D, 0x96, 0xE5, 0x2D, 0xA9, 0xFC, 0x2E,
+ 0xD8, 0xC0, 0x36, 0xF1, 0x0A, 0xF3, 0xD9, 0xF6, 0x28, 0x0F, 0x8D, 0x28,
+ 0x87, 0x06, 0xC5, 0x2B, 0x20, 0x11, 0xB4, 0xDA},
+ // C=PT, O=SCEE, CN=ECRaizEstado
+ {0x48, 0x8E, 0x13, 0x4F, 0x30, 0xC5, 0xDB, 0x56, 0xB7, 0x64, 0x73, 0xE6,
+ 0x08, 0x08, 0x68, 0x42, 0xBF, 0x21, 0xAF, 0x8A, 0xB3, 0xCD, 0x7A, 0xC6,
+ 0x7E, 0xBD, 0xF1, 0x25, 0xD5, 0x31, 0x83, 0x4E},
+ // C=PA, ST=Panama, L=Panama City, O=TrustCor Systems S. de R.L.,
+ // OU=TrustCor Certificate Authority, CN=TrustCor RootCert CA-1
+ {0x48, 0x8F, 0xCA, 0x18, 0x9E, 0xAA, 0xDF, 0x54, 0xA3, 0xF9, 0x20, 0xED,
+ 0x39, 0xE5, 0x87, 0x18, 0x3B, 0xA5, 0x12, 0x23, 0x29, 0x99, 0xFA, 0xE3,
+ 0xE4, 0xA2, 0x85, 0xFE, 0x98, 0xE2, 0x98, 0xD1},
+ // C=DK, O=TDC Internet, OU=TDC Internet Root CA
+ {0x48, 0x98, 0xC6, 0x88, 0x8C, 0x0C, 0xFF, 0xB0, 0xD3, 0xE3, 0x1A, 0xCA,
+ 0x8A, 0x37, 0xD4, 0xE3, 0x51, 0x5F, 0xF7, 0x46, 0xD0, 0x26, 0x35, 0xD8,
+ 0x66, 0x46, 0xCF, 0xA0, 0xA3, 0x18, 0x5A, 0xE7},
+ // C=TR, L=Ankara, O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve
+ // Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E.,
+ // CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1 H5
+ {0x49, 0x35, 0x1B, 0x90, 0x34, 0x44, 0xC1, 0x85, 0xCC, 0xDC, 0x5C, 0x69,
+ 0x3D, 0x24, 0xD8, 0x55, 0x5C, 0xB2, 0x08, 0xD6, 0xA8, 0x14, 0x13, 0x07,
+ 0x69, 0x9F, 0x4A, 0xF0, 0x63, 0x19, 0x9D, 0x78},
+ // C=us, ST=Utah, L=Salt Lake City, O=Digital Signature Trust Co.,
+ // OU=National Retail Federation, CN=DST (NRF)
+ // RootCA/emailAddress=ca@digsigtrust.com
+ {0x49, 0xC8, 0x17, 0x5A, 0x98, 0x15, 0xE0, 0x8B, 0xEF, 0x12, 0x9A, 0x92,
+ 0x9D, 0xE1, 0xBA, 0xCA, 0xD0, 0x4E, 0x4D, 0xB6, 0x7A, 0x8C, 0x83, 0x92,
+ 0x93, 0x95, 0x3E, 0x50, 0x31, 0xC8, 0x1C, 0xA0},
+ // C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 3 CA 2 2009
+ {0x49, 0xE7, 0xA4, 0x42, 0xAC, 0xF0, 0xEA, 0x62, 0x87, 0x05, 0x00, 0x54,
+ 0xB5, 0x25, 0x64, 0xB6, 0x50, 0xE4, 0xF4, 0x9E, 0x42, 0xE3, 0x48, 0xD6,
+ 0xAA, 0x38, 0xE0, 0x39, 0xE9, 0x57, 0xB1, 0xC1},
+ // C=US, O=Digital Signature Trust Co., CN=Baltimore EZ by
+ // DST/mail=ca@digsigtrust.com
+ {0x49, 0xF7, 0x4F, 0x82, 0x4F, 0x2E, 0x05, 0x9F, 0xE9, 0x9C, 0x98, 0xAF,
+ 0x32, 0x19, 0xEC, 0x0D, 0x9A, 0x00, 0x4D, 0x1B, 0x64, 0xDD, 0x2F, 0xD1,
+ 0x45, 0x26, 0x16, 0x31, 0x8A, 0xB8, 0x06, 0xC0},
+ // C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008
+ // thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3
+ {0x4B, 0x03, 0xF4, 0x58, 0x07, 0xAD, 0x70, 0xF2, 0x1B, 0xFC, 0x2C, 0xAE,
+ 0x71, 0xC9, 0xFD, 0xE4, 0x60, 0x4C, 0x06, 0x4C, 0xF5, 0xFF, 0xB6, 0x86,
+ 0xBA, 0xE5, 0xDB, 0xAA, 0xD7, 0xFD, 0xD3, 0x4C},
+ // C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign
+ {0x4B, 0x22, 0xD5, 0xA6, 0xAE, 0xC9, 0x9F, 0x3C, 0xDB, 0x79, 0xAA, 0x5E,
+ 0xC0, 0x68, 0x38, 0x47, 0x9C, 0xD5, 0xEC, 0xBA, 0x71, 0x64, 0xF7, 0xF2,
+ 0x2D, 0xC1, 0xD6, 0x5F, 0x63, 0xD8, 0x57, 0x08},
+ // C=BR, O=Certisign Certificadora Digital Ltda., OU=Certisign - Autoridade
+ // Certificadora - AC4
+ {0x4B, 0xDB, 0x74, 0x18, 0xBD, 0xF7, 0xFF, 0xE3, 0x3B, 0xA0, 0x88, 0x4A,
+ 0xFA, 0x7C, 0x0C, 0x61, 0xFD, 0x85, 0xA1, 0x53, 0x97, 0x2F, 0x65, 0xF7,
+ 0xD0, 0x1C, 0xB3, 0xEC, 0x7E, 0xB4, 0x07, 0x3C},
+ // C=ES, O=Agencia Notarial de Certificacion S.L.U. - CIF B83395988,
+ // CN=ANCERT Certificados Notariales V2
+ {0x4B, 0xE8, 0xB5, 0xA1, 0xC7, 0x6C, 0x6A, 0xEA, 0xD0, 0x61, 0x19, 0x18,
+ 0xFC, 0xCF, 0x9D, 0xBD, 0x39, 0x8B, 0x67, 0xFB, 0x12, 0x29, 0x47, 0x58,
+ 0xBD, 0xF9, 0x94, 0xD0, 0xF9, 0x68, 0x2F, 0x60},
+ // C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden EV Root CA
+ {0x4D, 0x24, 0x91, 0x41, 0x4C, 0xFE, 0x95, 0x67, 0x46, 0xEC, 0x4C, 0xEF,
+ 0xA6, 0xCF, 0x6F, 0x72, 0xE2, 0x8A, 0x13, 0x29, 0x43, 0x2F, 0x9D, 0x8A,
+ 0x90, 0x7A, 0xC4, 0xCB, 0x5D, 0xAD, 0xC1, 0x5A},
+ // C=ES, O=FNMT-RCM, OU=AC RAIZ FNMT-RCM
+ {0x4D, 0x9E, 0xBB, 0x28, 0x82, 0x5C, 0x96, 0x43, 0xAB, 0x15, 0xD5, 0x4E,
+ 0x5F, 0x96, 0x14, 0xF1, 0x3C, 0xB3, 0xE9, 0x5D, 0xE3, 0xCF, 0x4E, 0xAC,
+ 0x97, 0x13, 0x01, 0xF3, 0x20, 0xF9, 0x22, 0x6E},
+ // C=AT, O=Telekom-Control-Kommission, CN=Telekom-Control-Kommission Top 1
+ {0x4D, 0xBB, 0x01, 0x57, 0xA6, 0x91, 0xFA, 0x73, 0x82, 0x28, 0x9D, 0x65,
+ 0xC0, 0x33, 0x2D, 0xDB, 0x1D, 0xCB, 0x64, 0x0B, 0x40, 0xAD, 0x10, 0xF0,
+ 0x10, 0xA4, 0x3E, 0x20, 0xF3, 0xAF, 0xED, 0x1E},
+ // C=AT, ST=Austria, L=Vienna, O=Arge Daten Oesterreichische Gesellschaft
+ // fuer Datenschutz/emailAddress=a-cert@argedaten.at
+ {0x4E, 0x74, 0x80, 0xAD, 0x70, 0x2A, 0x37, 0x9D, 0xC5, 0x89, 0xAD, 0xB4,
+ 0xFA, 0xA6, 0x25, 0xE6, 0xA5, 0x99, 0x3F, 0x87, 0xEF, 0x23, 0x75, 0xD5,
+ 0x43, 0x7F, 0xFE, 0x3B, 0x79, 0xBE, 0x4E, 0x96},
+ // C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust
+ // ECC Certification Authority
+ {0x4F, 0xF4, 0x60, 0xD5, 0x4B, 0x9C, 0x86, 0xDA, 0xBF, 0xBC, 0xFC, 0x57,
+ 0x12, 0xE0, 0x40, 0x0D, 0x2B, 0xED, 0x3F, 0xBC, 0x4D, 0x4F, 0xBD, 0xAA,
+ 0x86, 0xE0, 0x6A, 0xDC, 0xD2, 0xA9, 0xAD, 0x7A},
+ // CN=ComSign Secured CA, O=ComSign, C=IL
+ {0x50, 0x79, 0x41, 0xC7, 0x44, 0x60, 0xA0, 0xB4, 0x70, 0x86, 0x22, 0x0D,
+ 0x4E, 0x99, 0x32, 0x57, 0x2A, 0xB5, 0xD1, 0xB5, 0xBB, 0xCB, 0x89, 0x80,
+ 0xAB, 0x1C, 0xB1, 0x76, 0x51, 0xA8, 0x44, 0xD2},
+ // C=JP, O=SECOM Trust Systems CO.,LTD., OU=Security Communication RootCA2
+ {0x51, 0x3B, 0x2C, 0xEC, 0xB8, 0x10, 0xD4, 0xCD, 0xE5, 0xDD, 0x85, 0x39,
+ 0x1A, 0xDF, 0xC6, 0xC2, 0xDD, 0x60, 0xD8, 0x7B, 0xB7, 0x36, 0xD2, 0xB5,
+ 0x21, 0x48, 0x4A, 0xA4, 0x7A, 0x0E, 0xBE, 0xF6},
+ // O=eSign Australia, OU=Public Secure Services, CN=eSign Imperito Primary
+ // Root CA
+ {0x52, 0x7A, 0x42, 0x26, 0x7D, 0xAE, 0xA8, 0xD8, 0xF5, 0x4E, 0x91, 0xD2,
+ 0x82, 0xD5, 0xC2, 0x5B, 0x61, 0x5B, 0xC0, 0xDC, 0x73, 0xDC, 0x63, 0xA5,
+ 0x8F, 0x91, 0x6C, 0x4E, 0xD5, 0xBF, 0x59, 0xAC},
+ // C=US, O=GTE Corporation, CN=GTE CyberTrust Root
+ {0x52, 0x7B, 0x05, 0x05, 0x27, 0xDF, 0x52, 0x9C, 0x0F, 0x7A, 0xD0, 0x0C,
+ 0xEF, 0x1E, 0x7B, 0xA4, 0x21, 0x78, 0x81, 0x82, 0x61, 0x5C, 0x32, 0x6C,
+ 0x8B, 0x6D, 0x1A, 0x20, 0x61, 0xA0, 0xBD, 0x7C},
+ // C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO
+ // RSA Certification Authority
+ {0x52, 0xF0, 0xE1, 0xC4, 0xE5, 0x8E, 0xC6, 0x29, 0x29, 0x1B, 0x60, 0x31,
+ 0x7F, 0x07, 0x46, 0x71, 0xB8, 0x5D, 0x7E, 0xA8, 0x0D, 0x5B, 0x07, 0x27,
+ 0x34, 0x63, 0x53, 0x4B, 0x32, 0xB4, 0x02, 0x34},
+ // C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec
+ // Class 3 Public Primary Certification Authority - G4
+ {0x53, 0xDF, 0xDF, 0xA4, 0xE2, 0x97, 0xFC, 0xFE, 0x07, 0x59, 0x4E, 0x8C,
+ 0x62, 0xD5, 0xB8, 0xAB, 0x06, 0xB3, 0x2C, 0x75, 0x49, 0xF3, 0x8A, 0x16,
+ 0x30, 0x94, 0xFD, 0x64, 0x29, 0xD5, 0xDA, 0x43},
+ // C=JP, O=LGPKI, CN=Application CA G3 Root
+ {0x54, 0xB4, 0xFC, 0x43, 0xD4, 0x4A, 0xA4, 0xCA, 0x9F, 0xC0, 0x3C, 0xA7,
+ 0xE9, 0x94, 0x9F, 0xBA, 0xE2, 0x67, 0xA0, 0x64, 0xD0, 0x2D, 0xA2, 0x18,
+ 0x52, 0x41, 0x2A, 0x38, 0x1B, 0x5D, 0x15, 0x37},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Trusted Root G4
+ {0x55, 0x2F, 0x7B, 0xDC, 0xF1, 0xA7, 0xAF, 0x9E, 0x6C, 0xE6, 0x72, 0x01,
+ 0x7F, 0x4F, 0x12, 0xAB, 0xF7, 0x72, 0x40, 0xC7, 0x8E, 0x76, 0x1A, 0xC2,
+ 0x03, 0xD1, 0xD9, 0xD2, 0x0A, 0xC8, 0x99, 0x88},
+ // CN=Autoridad Certificadora Ra\xC3\xADz Nacional de Uruguay, O=AGESIC,
+ // C=UY
+ {0x55, 0x33, 0xA0, 0x40, 0x1F, 0x61, 0x2C, 0x68, 0x8E, 0xBC, 0xE5, 0xBF,
+ 0x53, 0xF2, 0xEC, 0x14, 0xA7, 0x34, 0xEB, 0x17, 0x8B, 0xFA, 0xE0, 0x0E,
+ 0x50, 0xE8, 0x5D, 0xAE, 0x67, 0x23, 0x07, 0x8A},
+ // C=IT, L=Milan, O=Actalis S.p.A./03358520967, CN=Actalis Authentication
+ // Root CA
+ {0x55, 0x92, 0x60, 0x84, 0xEC, 0x96, 0x3A, 0x64, 0xB9, 0x6E, 0x2A, 0xBE,
+ 0x01, 0xCE, 0x0B, 0xA8, 0x6A, 0x64, 0xFB, 0xFE, 0xBC, 0xC7, 0xAA, 0xB5,
+ 0xAF, 0xC1, 0x55, 0xB3, 0x7F, 0xD7, 0x60, 0x66},
+ // C=ES, O=Consejo General de la Abogacia NIF:Q-2863006I, CN=Autoridad de
+ // Certificacion de la Abogacia
+ {0x56, 0x07, 0xE2, 0x60, 0x16, 0x3F, 0x49, 0xC8, 0xEA, 0x41, 0x75, 0xA1,
+ 0xC0, 0xA5, 0x3B, 0x13, 0x19, 0x5C, 0xB7, 0xD0, 0x78, 0x45, 0x61, 0x1E,
+ 0x94, 0x3A, 0x2F, 0xF5, 0x07, 0x03, 0x68, 0x34},
+ // C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc.,
+ // CN=Starfield Services Root Certificate Authority - G2
+ {0x56, 0x8D, 0x69, 0x05, 0xA2, 0xC8, 0x87, 0x08, 0xA4, 0xB3, 0x02, 0x51,
+ 0x90, 0xED, 0xCF, 0xED, 0xB1, 0x97, 0x4A, 0x60, 0x6A, 0x13, 0xC6, 0xE5,
+ 0x29, 0x0F, 0xCB, 0x2A, 0xE6, 0x3E, 0xDA, 0xB5},
+ // C=FR, O=OpenTrust, CN=OpenTrust Root CA G1
+ {0x56, 0xC7, 0x71, 0x28, 0xD9, 0x8C, 0x18, 0xD9, 0x1B, 0x4C, 0xFD, 0xFF,
+ 0xBC, 0x25, 0xEE, 0x91, 0x03, 0xD4, 0x75, 0x8E, 0xA2, 0xAB, 0xAD, 0x82,
+ 0x6A, 0x90, 0xF3, 0x45, 0x7D, 0x46, 0x0E, 0xB4},
+ // CN=T\xC3\x9CRKTRUST Elektronik \xC4\xB0\xC5\x9Flem Hizmetleri, C=TR,
+ // L=Ankara, O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve
+ // Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E. (c)
+ // Kas\xC4\xB1m 2005
+ {0x56, 0xCE, 0x34, 0x7C, 0xC6, 0xDF, 0x4C, 0x35, 0x94, 0x3D, 0xFD, 0xEA,
+ 0xEE, 0x02, 0x3F, 0x97, 0x39, 0xA3, 0xF1, 0xCE, 0xDE, 0xEE, 0x0C, 0xD8,
+ 0x8D, 0xC2, 0x38, 0x6B, 0xC8, 0xA9, 0x1E, 0xAF},
+ // L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 2
+ // Policy Validation Authority,
+ // CN=http://www.valicert.com//emailAddress=info@valicert.com
+ {0x58, 0xD0, 0x17, 0x27, 0x9C, 0xD4, 0xDC, 0x63, 0xAB, 0xDD, 0xB1, 0x96,
+ 0xA6, 0xC9, 0x90, 0x6C, 0x30, 0xC4, 0xE0, 0x87, 0x83, 0xEA, 0xE8, 0xC1,
+ 0x60, 0x99, 0x54, 0xD6, 0x93, 0x55, 0x59, 0x6B},
+ // C=TW, O=TAIWAN-CA, OU=Root CA, CN=TWCA Global Root CA
+ {0x59, 0x76, 0x90, 0x07, 0xF7, 0x68, 0x5D, 0x0F, 0xCD, 0x50, 0x87, 0x2F,
+ 0x9F, 0x95, 0xD5, 0x75, 0x5A, 0x5B, 0x2B, 0x45, 0x7D, 0x81, 0xF3, 0x69,
+ 0x2B, 0x61, 0x0A, 0x98, 0x67, 0x2F, 0x0E, 0x1B},
+ // C=CH, O=SwissSign AG, CN=SwissSign Platinum Root CA - G3
+ {0x59, 0xB3, 0x82, 0x9F, 0x1F, 0xF4, 0x43, 0x34, 0x49, 0x58, 0xFA, 0xE8,
+ 0xBF, 0xF6, 0x21, 0xB6, 0x84, 0xC8, 0x48, 0xCF, 0xBF, 0x7E, 0xAD, 0x6B,
+ 0x63, 0xA6, 0xCA, 0x50, 0xF2, 0x79, 0x4F, 0x89},
+ // C=SI, O=Halcom, CN=Halcom CA FO
+ {0x5A, 0x1B, 0x5D, 0x6B, 0xC6, 0x55, 0x23, 0xB4, 0x0A, 0x6D, 0xEF, 0xFA,
+ 0x45, 0xB4, 0x8E, 0x42, 0x88, 0xAE, 0x8D, 0xD8, 0x6D, 0xD7, 0x0A, 0x5B,
+ 0x85, 0x8D, 0x4A, 0x5A, 0xFF, 0xC9, 0x4F, 0x71},
+ // CN=AC1 RAIZ MTIN/serialNumber=S2819001E, OU=PRESTADOR DE SERVICIOS DE
+ // CERTIFICACION MTIN, OU=SUBDIRECCION GENERAL DE PROCESO DE DATOS,
+ // O=MINISTERIO DE TRABAJO E INMIGRACION, L=MADRID, C=ES
+ {0x5B, 0x1D, 0x9D, 0x24, 0xDE, 0x0A, 0xFE, 0xA8, 0xB3, 0x5B, 0xA0, 0x4A,
+ 0x1C, 0x3E, 0x25, 0xD0, 0x81, 0x2C, 0xDF, 0x7C, 0x46, 0x25, 0xDE, 0x0A,
+ 0x89, 0xAF, 0x9F, 0xE4, 0xBB, 0xD1, 0xBB, 0x15},
+ // C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority,
+ // CN=Certum Trusted Network CA
+ {0x5C, 0x58, 0x46, 0x8D, 0x55, 0xF5, 0x8E, 0x49, 0x7E, 0x74, 0x39, 0x82,
+ 0xD2, 0xB5, 0x00, 0x10, 0xB6, 0xD1, 0x65, 0x37, 0x4A, 0xCF, 0x83, 0xA7,
+ 0xD4, 0xA3, 0x2D, 0xB7, 0x68, 0xC4, 0x40, 0x8E},
+ // C=CN, O=China Financial Certification Authority, CN=CFCA EV ROOT
+ {0x5C, 0xC3, 0xD7, 0x8E, 0x4E, 0x1D, 0x5E, 0x45, 0x54, 0x7A, 0x04, 0xE6,
+ 0x87, 0x3E, 0x64, 0xF9, 0x0C, 0xF9, 0x53, 0x6D, 0x1C, 0xCC, 0x2E, 0xF8,
+ 0x00, 0xF3, 0x55, 0xC4, 0xC5, 0xFD, 0x70, 0xFD},
+ // C=US, O=IdenTrust, CN=IdenTrust Commercial Root CA 1
+ {0x5D, 0x56, 0x49, 0x9B, 0xE4, 0xD2, 0xE0, 0x8B, 0xCF, 0xCA, 0xD0, 0x8A,
+ 0x3E, 0x38, 0x72, 0x3D, 0x50, 0x50, 0x3B, 0xDE, 0x70, 0x69, 0x48, 0xE4,
+ 0x2F, 0x55, 0x60, 0x30, 0x19, 0xE5, 0x28, 0xAE},
+ // C=AT, L=Vienna, ST=Austria, O=ARGE DATEN - Austrian Society for Data
+ // Protection, OU=GLOBALTRUST Certification Service,
+ // CN=GLOBALTRUST/emailAddress=info@globaltrust.info
+ {0x5E, 0x35, 0x71, 0xF3, 0x3F, 0x45, 0xA7, 0xDF, 0x15, 0x37, 0xA6, 0x8B,
+ 0x5F, 0xFB, 0x9E, 0x03, 0x6A, 0xF9, 0xD2, 0xF5, 0xBC, 0x4C, 0x97, 0x17,
+ 0x13, 0x0D, 0xC4, 0x3D, 0x71, 0x75, 0xAA, 0xC7},
+ // C=US, O=GeoTrust Inc., OU=(c) 2007 GeoTrust Inc. - For authorized use
+ // only, CN=GeoTrust Primary Certification Authority - G2
+ {0x5E, 0xDB, 0x7A, 0xC4, 0x3B, 0x82, 0xA0, 0x6A, 0x87, 0x61, 0xE8, 0xD7,
+ 0xBE, 0x49, 0x79, 0xEB, 0xF2, 0x61, 0x1F, 0x7D, 0xD7, 0x9B, 0xF9, 0x1C,
+ 0x1C, 0x6B, 0x56, 0x6A, 0x21, 0x9E, 0xD7, 0x66},
+ // C=US, O=Equifax Secure Inc., CN=Equifax Secure Global eBusiness CA-1
+ {0x5F, 0x0B, 0x62, 0xEA, 0xB5, 0xE3, 0x53, 0xEA, 0x65, 0x21, 0x65, 0x16,
+ 0x58, 0xFB, 0xB6, 0x53, 0x59, 0xF4, 0x43, 0x28, 0x0A, 0x4A, 0xFB, 0xD1,
+ 0x04, 0xD7, 0x7D, 0x10, 0xF9, 0xF0, 0x4C, 0x07},
+ // C=JP, O=Japan Certification Services, Inc., CN=SecureSign RootCA1
+ {0x5F, 0x96, 0x0E, 0xEB, 0xD7, 0x16, 0xDB, 0xCB, 0x4D, 0x8A, 0x78, 0xB9,
+ 0x96, 0xE6, 0x80, 0xEC, 0x25, 0x47, 0x44, 0x1E, 0x69, 0xB4, 0xE4, 0x4E,
+ 0x98, 0xA5, 0x95, 0x50, 0x2E, 0x28, 0xA0, 0x02},
+ // C=PT, O=MULTICERT - Servi\xC3\xA7os de Certifica\xC3\xA7\xC3\xA3o
+ // Electr\xC3\xB3nica S.A., CN=MULTICERT Root Certification Authority 01
+ {0x60, 0x4D, 0x32, 0xD0, 0x36, 0x89, 0x5A, 0xED, 0x3B, 0xFE, 0xFA, 0xEB,
+ 0x72, 0x7C, 0x00, 0x9E, 0xC0, 0xF2, 0xB3, 0xCD, 0xFA, 0x42, 0xA1, 0xC7,
+ 0x17, 0x30, 0xE6, 0xA7, 0x2C, 0x3B, 0xE9, 0xD4},
+ // C=KR, O=Government of Korea, OU=GPKI, CN=GPKIRootCA
+ {0x60, 0x62, 0x23, 0xD9, 0xDB, 0x80, 0xDF, 0x39, 0x39, 0x60, 0x1E, 0x74,
+ 0xB7, 0xE8, 0x28, 0xE2, 0x80, 0x0C, 0xCE, 0x42, 0x73, 0xF7, 0x6F, 0x27,
+ 0x6A, 0xA6, 0x2D, 0xB0, 0xA8, 0xE3, 0xB6, 0xC1},
+ // C=DE, ST=Hamburg, L=Hamburg, O=TC TrustCenter for Security in Data
+ // Networks GmbH, OU=TC TrustCenter Class 1
+ // CA/emailAddress=certificate@trustcenter.de
+ {0x61, 0x4F, 0xD1, 0x8D, 0xA1, 0x49, 0x05, 0x60, 0xCD, 0xAD, 0x11, 0x96,
+ 0xE2, 0x49, 0x2A, 0xB7, 0x06, 0x2E, 0xAB, 0x1A, 0x67, 0xB3, 0xA3, 0x0F,
+ 0x1D, 0x05, 0x85, 0xA7, 0xD6, 0xBA, 0x68, 0x24},
+ // C=US, O=VeriSign, Inc., OU=Class 4 Public Primary Certification Authority
+ // - G2, OU=(c) 1998 VeriSign, Inc. - For authorized use only, OU=VeriSign
+ // Trust Network
+ {0x61, 0xDC, 0x0C, 0x03, 0x91, 0x69, 0x4C, 0x65, 0x52, 0x00, 0xC1, 0x50,
+ 0x5E, 0xBC, 0xC9, 0xE4, 0xE2, 0x16, 0xBC, 0x31, 0xA5, 0xC5, 0x1A, 0x36,
+ 0x11, 0x28, 0x34, 0x23, 0xC1, 0xD8, 0x9E, 0x37},
+ // C=ES, O=FNMT, OU=FNMT Clase 2 CA
+ {0x62, 0xB9, 0x26, 0x72, 0x66, 0x21, 0x28, 0x32, 0xA8, 0xE2, 0x2D, 0xAB,
+ 0x93, 0x3D, 0x91, 0xC7, 0x01, 0x12, 0x74, 0xAC, 0xF7, 0x17, 0x03, 0xF9,
+ 0xCC, 0x97, 0x83, 0x37, 0x51, 0xA6, 0xE9, 0x4F},
+ // C=CH, O=SwissSign AG, CN=SwissSign Gold CA - G2
+ {0x62, 0xDD, 0x0B, 0xE9, 0xB9, 0xF5, 0x0A, 0x16, 0x3E, 0xA0, 0xF8, 0xE7,
+ 0x5C, 0x05, 0x3B, 0x1E, 0xCA, 0x57, 0xEA, 0x55, 0xC8, 0x68, 0x8F, 0x64,
+ 0x7C, 0x68, 0x81, 0xF2, 0xC8, 0x35, 0x7B, 0x95},
+ // C=US, O=Entrust.net, OU=www.entrust.net/CPS incorp. by ref. (limits
+ // liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Secure Server
+ // Certification Authority
+ {0x62, 0xF2, 0x40, 0x27, 0x8C, 0x56, 0x4C, 0x4D, 0xD8, 0xBF, 0x7D, 0x9D,
+ 0x4F, 0x6F, 0x36, 0x6E, 0xA8, 0x94, 0xD2, 0x2F, 0x5F, 0x34, 0xD9, 0x89,
+ 0xA9, 0x83, 0xAC, 0xEC, 0x2F, 0xFF, 0xED, 0x50},
+ // C=US, O=Digital Signature Trust Co., OU=DSTCA E1
+ {0x63, 0x04, 0x19, 0xAE, 0xC4, 0x78, 0xCB, 0xB4, 0xBB, 0x80, 0x83, 0xDE,
+ 0x9D, 0x9C, 0xF2, 0x79, 0x75, 0x2F, 0x03, 0x9D, 0xEF, 0x16, 0xE4, 0x64,
+ 0x71, 0xB6, 0x79, 0xCA, 0x93, 0x00, 0x2D, 0xB0},
+ // C=TW, O=TAIWAN-CA, OU=Root CA, CN=TWCA Root Certification Authority
+ {0x63, 0x2D, 0x80, 0xBB, 0x09, 0x6D, 0x20, 0x96, 0x77, 0xD1, 0x73, 0x4E,
+ 0x5B, 0x35, 0xEA, 0x9D, 0x30, 0x19, 0xB9, 0xC4, 0x4F, 0x8F, 0xCB, 0x26,
+ 0x40, 0xC8, 0x79, 0x03, 0x9A, 0xC9, 0x4E, 0xE8},
+ // C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden Root CA - G2
+ {0x66, 0x8C, 0x83, 0x94, 0x7D, 0xA6, 0x3B, 0x72, 0x4B, 0xEC, 0xE1, 0x74,
+ 0x3C, 0x31, 0xA0, 0xE6, 0xAE, 0xD0, 0xDB, 0x8E, 0xC5, 0xB3, 0x1B, 0xE3,
+ 0x77, 0xBB, 0x78, 0x4F, 0x91, 0xB6, 0x71, 0x6F},
+ // O=eSign Australia, OU=Gatekeeper PKI, CN=Gatekeeper Root CA
+ {0x67, 0xEC, 0x20, 0x59, 0xFB, 0xF5, 0x2D, 0x2E, 0x6A, 0xB5, 0x1A, 0x5A,
+ 0x9B, 0x3F, 0xC2, 0xE1, 0xDC, 0xD6, 0x58, 0xA1, 0xEF, 0x3A, 0x8F, 0x31,
+ 0x10, 0x7B, 0xC9, 0x80, 0x28, 0xB4, 0x94, 0xA2},
+ // C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ {0x68, 0x72, 0x58, 0x62, 0x19, 0xC3, 0x49, 0xD8, 0x5A, 0xAA, 0x45, 0x86,
+ 0xA1, 0x44, 0x51, 0xF2, 0x45, 0x1A, 0xE3, 0xB6, 0x09, 0x2D, 0xBB, 0x1E,
+ 0xFF, 0xB0, 0x14, 0x7C, 0x33, 0xBF, 0x0F, 0xD4},
+ // C=BR, O=ICP-Brasil, OU=Instituto Nacional de Tecnologia da Informacao -
+ // ITI, L=Brasilia, ST=DF, CN=Autoridade Certificadora Raiz Brasileira
+ {0x68, 0x7E, 0xA8, 0x90, 0x89, 0x30, 0x9D, 0x2C, 0xFE, 0x10, 0x7D, 0xB0,
+ 0x59, 0xFB, 0x10, 0xD6, 0x76, 0xF4, 0x5D, 0x32, 0x83, 0xAE, 0xE0, 0x56,
+ 0x90, 0x3E, 0xEA, 0x0C, 0xF3, 0xC1, 0x88, 0xF8},
+ // C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust
+ // External CA Root
+ {0x68, 0x7F, 0xA4, 0x51, 0x38, 0x22, 0x78, 0xFF, 0xF0, 0xC8, 0xB1, 0x1F,
+ 0x8D, 0x43, 0xD5, 0x76, 0x67, 0x1C, 0x6E, 0xB2, 0xBC, 0xEA, 0xB4, 0x13,
+ 0xFB, 0x83, 0xD9, 0x65, 0xD0, 0x6D, 0x2F, 0xF2},
+ // C=US, O=Verizon Business, OU=OmniRoot, CN=Verizon Global Root CA
+ {0x68, 0xAD, 0x50, 0x90, 0x9B, 0x04, 0x36, 0x3C, 0x60, 0x5E, 0xF1, 0x35,
+ 0x81, 0xA9, 0x39, 0xFF, 0x2C, 0x96, 0x37, 0x2E, 0x3F, 0x12, 0x32, 0x5B,
+ 0x0A, 0x68, 0x61, 0xE1, 0xD5, 0x9F, 0x66, 0x03},
+ // C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2007 VeriSign,
+ // Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary
+ // Certification Authority - G4
+ {0x69, 0xDD, 0xD7, 0xEA, 0x90, 0xBB, 0x57, 0xC9, 0x3E, 0x13, 0x5D, 0xC8,
+ 0x5E, 0xA6, 0xFC, 0xD5, 0x48, 0x0B, 0x60, 0x32, 0x39, 0xBD, 0xC4, 0x54,
+ 0xFC, 0x75, 0x8B, 0x2A, 0x26, 0xCF, 0x7F, 0x79},
+ // C=US, O=VISA, OU=Visa International Service Association, CN=Visa
+ // eCommerce Root
+ {0x69, 0xFA, 0xC9, 0xBD, 0x55, 0xFB, 0x0A, 0xC7, 0x8D, 0x53, 0xBB, 0xEE,
+ 0x5C, 0xF1, 0xD5, 0x97, 0x98, 0x9F, 0xD0, 0xAA, 0xAB, 0x20, 0xA2, 0x51,
+ 0x51, 0xBD, 0xF1, 0x73, 0x3E, 0xE7, 0xD1, 0x22},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-Qual-03, CN=A-Trust-Qual-03
+ {0x6B, 0xAF, 0x50, 0xAE, 0x34, 0x67, 0xEF, 0xF3, 0xC3, 0x5F, 0xEF, 0xDC,
+ 0x76, 0xA0, 0x2A, 0x97, 0xFA, 0xB6, 0x26, 0x77, 0x23, 0xED, 0xA9, 0x1E,
+ 0x99, 0xF1, 0xB3, 0xDC, 0x2B, 0x28, 0xF8, 0x2E},
+ // C=HU, L=Budapest, O=NetLock Kft.,
+ // OU=Tan\xC3\xBAs\xC3\xADtv\xC3\xA1nykiad\xC3\xB3k (Certification
+ // Services), CN=NetLock Arany (Class Gold)
+ // F\xC5\x91tan\xC3\xBAs\xC3\xADtv\xC3\xA1ny
+ {0x6C, 0x61, 0xDA, 0xC3, 0xA2, 0xDE, 0xF0, 0x31, 0x50, 0x6B, 0xE0, 0x36,
+ 0xD2, 0xA6, 0xFE, 0x40, 0x19, 0x94, 0xFB, 0xD1, 0x3D, 0xF9, 0xC8, 0xD4,
+ 0x66, 0x59, 0x92, 0x74, 0xC4, 0x46, 0xEC, 0x98},
+ // C=FR, O=Certplus, CN=Certplus Root CA G2
+ {0x6C, 0xC0, 0x50, 0x41, 0xE6, 0x44, 0x5E, 0x74, 0x69, 0x6C, 0x4C, 0xFB,
+ 0xC9, 0xF8, 0x0F, 0x54, 0x3B, 0x7E, 0xAB, 0xBB, 0x44, 0xB4, 0xCE, 0x6F,
+ 0x78, 0x7C, 0x6A, 0x99, 0x71, 0xC4, 0x2F, 0x17},
+ // C=AU, O=GOV, OU=DoD, OU=PKI, OU=CAs, CN=ADOCA02
+ {0x6C, 0xCF, 0xD3, 0x02, 0xFC, 0x44, 0xBF, 0x45, 0x99, 0x32, 0x9B, 0x97,
+ 0x50, 0x87, 0x8E, 0xA4, 0x4E, 0x7E, 0x85, 0x66, 0x56, 0x4B, 0xCB, 0xD5,
+ 0x86, 0x16, 0x97, 0x62, 0xDD, 0x10, 0xC7, 0x4E},
+ // O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits
+ // liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification
+ // Authority (2048)
+ {0x6D, 0xC4, 0x71, 0x72, 0xE0, 0x1C, 0xBC, 0xB0, 0xBF, 0x62, 0x58, 0x0D,
+ 0x89, 0x5F, 0xE2, 0xB8, 0xAC, 0x9A, 0xD4, 0xF8, 0x73, 0x80, 0x1E, 0x0C,
+ 0x10, 0xB9, 0xC8, 0x37, 0xD2, 0x1E, 0xB1, 0x77},
+ // C=ES, ST=Madrid, L=Madrid, O=IPS Certification Authority s.l. ipsCA,
+ // OU=ipsCA, CN=ipsCA Global CA Root/emailAddress=global01@ipsca.com
+ {0x6D, 0xEA, 0x86, 0xA1, 0xE6, 0x66, 0x20, 0xA0, 0x40, 0xC3, 0xC5, 0x94,
+ 0x3C, 0xB2, 0x15, 0xD2, 0xCA, 0x87, 0xFB, 0x6A, 0xC0, 0x9B, 0x59, 0x70,
+ 0x7E, 0x29, 0xD2, 0xFA, 0xCB, 0xD6, 0x6B, 0x4E},
+ // C=us, O=U.S. Government, OU=FBCA, CN=Common Policy
+ {0x6E, 0x5E, 0x93, 0xAE, 0x86, 0x7F, 0xD3, 0xE3, 0xE7, 0x83, 0x04, 0xE0,
+ 0x54, 0xD1, 0xA6, 0xAE, 0xAE, 0xD0, 0x29, 0x5D, 0x58, 0xC0, 0xE3, 0xFC,
+ 0x4C, 0x9F, 0xFE, 0x31, 0x0A, 0x34, 0x88, 0xCC},
+ // C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network,
+ // OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware
+ {0x6E, 0xA5, 0x47, 0x41, 0xD0, 0x04, 0x66, 0x7E, 0xED, 0x1B, 0x48, 0x16,
+ 0x63, 0x4A, 0xA3, 0xA7, 0x9E, 0x6E, 0x4B, 0x96, 0x95, 0x0F, 0x82, 0x79,
+ 0xDA, 0xFC, 0x8D, 0x9B, 0xD8, 0x81, 0x21, 0x37},
+ // C=CH, O=The Federal Authorities of the Swiss Confederation, OU=Services,
+ // OU=Certification Authorities, CN=Swiss Government Root CA I
+ {0x6E, 0xC6, 0x61, 0x4E, 0x9A, 0x8E, 0xFD, 0x47, 0xD6, 0x31, 0x8F, 0xFD,
+ 0xFD, 0x0B, 0xF6, 0x5B, 0x49, 0x3A, 0x14, 0x1F, 0x77, 0xC3, 0x8D, 0x0B,
+ 0x31, 0x9B, 0xE1, 0xBB, 0xBC, 0x05, 0x3D, 0xD2},
+ // C=KR, O=KISA, OU=Korea Certification Authority Central, CN=KISA RootCA 1
+ {0x6F, 0xDB, 0x3F, 0x76, 0xC8, 0xB8, 0x01, 0xA7, 0x53, 0x38, 0xD8, 0xA5,
+ 0x0A, 0x7C, 0x02, 0x87, 0x9F, 0x61, 0x98, 0xB5, 0x7E, 0x59, 0x4D, 0x31,
+ 0x8D, 0x38, 0x32, 0x90, 0x0F, 0xED, 0xCD, 0x79},
+ // C=US, O=AffirmTrust, CN=AffirmTrust Premium
+ {0x70, 0xA7, 0x3F, 0x7F, 0x37, 0x6B, 0x60, 0x07, 0x42, 0x48, 0x90, 0x45,
+ 0x34, 0xB1, 0x14, 0x82, 0xD5, 0xBF, 0x0E, 0x69, 0x8E, 0xCC, 0x49, 0x8D,
+ 0xF5, 0x25, 0x77, 0xEB, 0xF2, 0xE9, 0x3B, 0x9A},
+ // C=TW, O=Government Root Certification Authority
+ {0x70, 0xB9, 0x22, 0xBF, 0xDA, 0x0E, 0x3F, 0x4A, 0x34, 0x2E, 0x4E, 0xE2,
+ 0x2D, 0x57, 0x9A, 0xE5, 0x98, 0xD0, 0x71, 0xCC, 0x5E, 0xC9, 0xC3, 0x0F,
+ 0x12, 0x36, 0x80, 0x34, 0x03, 0x88, 0xAE, 0xA5},
+ // C=PL, O=Telekomunikacja Polska S.A., OU=Signet Certification Authority,
+ // CN=Signet Root CA
+ {0x72, 0x86, 0xCE, 0x24, 0x9F, 0xE9, 0xE3, 0x2B, 0xD4, 0x75, 0x22, 0x57,
+ 0xC1, 0x7C, 0xD8, 0xF6, 0x99, 0x1A, 0x9C, 0x1E, 0x6F, 0x1A, 0x3C, 0xC7,
+ 0x33, 0x04, 0xED, 0x02, 0x3E, 0x6A, 0xE4, 0xEB},
+ // C=NL, O=PTT Post, OU=KeyMail, CN=PTT Post Root CA/mail=ca@ptt-post.nl
+ {0x73, 0x0B, 0x61, 0x9E, 0xAA, 0x75, 0x98, 0x63, 0xC6, 0x53, 0x60, 0xB7,
+ 0x41, 0x2E, 0x14, 0x57, 0xEC, 0xA9, 0x68, 0x44, 0xEF, 0x2F, 0x16, 0xD9,
+ 0x1F, 0xCF, 0x2E, 0xFE, 0x46, 0xA6, 0x47, 0xE9},
+ // C=TR, O=Elektronik Bilgi Guvenligi A.S., CN=E-GUVEN Kok Elektronik
+ // Sertifika Hizmet Saglayicisi S2
+ {0x73, 0x2F, 0xF5, 0xBC, 0x47, 0x3C, 0x33, 0xEF, 0xAA, 0xD9, 0xB1, 0x87,
+ 0xFB, 0x45, 0x9A, 0x73, 0x2F, 0xFB, 0xEE, 0xA5, 0x9D, 0xF0, 0xFD, 0xFB,
+ 0x8E, 0x2F, 0xB5, 0xDE, 0xF4, 0x03, 0x2A, 0xFE},
+ // C=ES, O=DIRECCION GENERAL DE LA POLICIA, OU=DNIE, CN=AC RAIZ DNIE
+ {0x73, 0x97, 0x10, 0xC5, 0x24, 0x5E, 0x33, 0xEC, 0x8A, 0x24, 0x3A, 0x1B,
+ 0x20, 0x04, 0x8F, 0xC9, 0xD5, 0xF4, 0x52, 0x85, 0x99, 0x21, 0x38, 0x45,
+ 0xC1, 0x64, 0xD0, 0x04, 0xB8, 0xB6, 0x67, 0xF9},
+ // C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by
+ // reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification
+ // Authority
+ {0x73, 0xC1, 0x76, 0x43, 0x4F, 0x1B, 0xC6, 0xD5, 0xAD, 0xF4, 0x5B, 0x0E,
+ 0x76, 0xE7, 0x27, 0x28, 0x7C, 0x8D, 0xE5, 0x76, 0x16, 0xC1, 0xE6, 0xE6,
+ 0x14, 0x1A, 0x2B, 0x2C, 0xBC, 0x7D, 0x8E, 0x4C},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV
+ // Root CA
+ {0x74, 0x31, 0xE5, 0xF4, 0xC3, 0xC1, 0xCE, 0x46, 0x90, 0x77, 0x4F, 0x0B,
+ 0x61, 0xE0, 0x54, 0x40, 0x88, 0x3B, 0xA9, 0xA0, 0x1E, 0xD0, 0x0B, 0xA6,
+ 0xAB, 0xD7, 0x80, 0x6E, 0xD3, 0xB1, 0x18, 0xCF},
+ // C=PA, ST=Panama, L=Panama City, O=TrustCor Systems S. de R.L.,
+ // OU=TrustCor Certificate Authority, CN=TrustCor ECA-1
+ {0x74, 0x4B, 0x11, 0x47, 0xB4, 0xA9, 0xA6, 0x9C, 0x32, 0x78, 0x5E, 0x9E,
+ 0x37, 0xC3, 0x32, 0x32, 0x41, 0xEF, 0x29, 0xF6, 0x3E, 0x76, 0xF1, 0x60,
+ 0x3D, 0x67, 0x61, 0xA7, 0x83, 0xD8, 0xA0, 0xFE},
+ // C=si, O=state-institutions, OU=sigov-ca
+ {0x74, 0xCB, 0x3A, 0x4E, 0xA7, 0x91, 0xAF, 0xB0, 0xA2, 0xD1, 0xA0, 0xB1,
+ 0x33, 0x01, 0xB3, 0xBE, 0xE0, 0xE5, 0x0A, 0xD5, 0xC7, 0x9A, 0x1A, 0x6F,
+ 0x2C, 0x66, 0x3E, 0x6F, 0x4E, 0xE7, 0xA4, 0x84},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-Qual-02, CN=A-Trust-Qual-02
+ {0x75, 0xC9, 0xD4, 0x36, 0x1C, 0xB9, 0x6E, 0x99, 0x3A, 0xBD, 0x96, 0x20,
+ 0xCF, 0x04, 0x3B, 0xE9, 0x40, 0x7A, 0x46, 0x33, 0xF2, 0x02, 0xF0, 0xF4,
+ 0xC0, 0xE1, 0x78, 0x51, 0xCC, 0x60, 0x89, 0xCD},
+ // C=TW, O=Government Root Certification Authority
+ {0x76, 0x00, 0x29, 0x5E, 0xEF, 0xE8, 0x5B, 0x9E, 0x1F, 0xD6, 0x24, 0xDB,
+ 0x76, 0x06, 0x2A, 0xAA, 0xAE, 0x59, 0x81, 0x8A, 0x54, 0xD2, 0x77, 0x4C,
+ 0xD4, 0xC0, 0xB2, 0xC0, 0x11, 0x31, 0xE1, 0xB3},
+ // C=US, O=Digital Signature Trust, OU=DST ACES, CN=DST ACES CA X6
+ {0x76, 0x7C, 0x95, 0x5A, 0x76, 0x41, 0x2C, 0x89, 0xAF, 0x68, 0x8E, 0x90,
+ 0xA1, 0xC7, 0x0F, 0x55, 0x6C, 0xFD, 0x6B, 0x60, 0x25, 0xDB, 0xEA, 0x10,
+ 0x41, 0x6D, 0x7E, 0xB6, 0x83, 0x1F, 0x8C, 0x40},
+ // C=DE, ST=Hamburg, L=Hamburg, O=TC TrustCenter for Security in Data
+ // Networks GmbH, OU=TC TrustCenter Class 3
+ // CA/emailAddress=certificate@trustcenter.de
+ {0x76, 0xEF, 0x47, 0x62, 0xE5, 0x73, 0x20, 0x60, 0x06, 0xCB, 0xC3, 0x38,
+ 0xB1, 0x7C, 0xA4, 0xBC, 0x20, 0x05, 0x74, 0xA1, 0x19, 0x28, 0xD9, 0x0C,
+ 0x3E, 0xF3, 0x1C, 0x5E, 0x80, 0x3E, 0x6C, 0x6F},
+ // L=Alvaro Obregon, ST=Distrito Federal,
+ // C=MX/postalCode=01030/street=Insurgentes Sur 1940, CN=Autoridad
+ // Certificadora Raiz de la Secretaria de Economia, OU=Direccion General de
+ // Normatividad Mercantil, O=Secretaria de
+ // Economia/emailAddress=acrse@economia.gob.mx
+ {0x77, 0xE0, 0x4C, 0x9A, 0x75, 0x1C, 0x73, 0xF2, 0x3E, 0x2A, 0x13, 0x36,
+ 0x11, 0x2E, 0xC8, 0xD5, 0x15, 0x3D, 0x38, 0x2A, 0x15, 0x2F, 0xED, 0x89,
+ 0xD7, 0x53, 0x2C, 0x31, 0x02, 0x77, 0x1F, 0x3C},
+ // C=SG, O=Netrust Certificate Authority 1, OU=Netrust CA1
+ {0x78, 0x1D, 0x64, 0xDF, 0xA7, 0x7B, 0x00, 0xF2, 0xC0, 0x06, 0x70, 0x0B,
+ 0x1F, 0xDA, 0x86, 0xBF, 0x68, 0xB8, 0x65, 0xA6, 0x03, 0xC7, 0xA6, 0x56,
+ 0xF9, 0x2E, 0x90, 0xC0, 0x42, 0xCA, 0x28, 0x73},
+ // C=FI, O=Sonera, CN=Sonera Class2 CA
+ {0x79, 0x08, 0xB4, 0x03, 0x14, 0xC1, 0x38, 0x10, 0x0B, 0x51, 0x8D, 0x07,
+ 0x35, 0x80, 0x7F, 0xFB, 0xFC, 0xF8, 0x51, 0x8A, 0x00, 0x95, 0x33, 0x71,
+ 0x05, 0xBA, 0x38, 0x6B, 0x15, 0x3D, 0xD9, 0x27},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-nQual-03, CN=A-Trust-nQual-03
+ {0x79, 0x3C, 0xBF, 0x45, 0x59, 0xB9, 0xFD, 0xE3, 0x8A, 0xB2, 0x2D, 0xF1,
+ 0x68, 0x69, 0xF6, 0x98, 0x81, 0xAE, 0x14, 0xC4, 0xB0, 0x13, 0x9A, 0xC7,
+ 0x88, 0xA7, 0x8A, 0x1A, 0xFC, 0xCA, 0x02, 0xFB},
+ // C=ZA, ST=Western Cape, L=Somerset West, O=South African Post Office
+ // Limited, OU=SAPO Trust Centre, CN=SAPO Class 3 Root
+ // CA/emailAddress=pkiadmin@trustcentre.co.za
+ {0x79, 0x6B, 0x93, 0xD0, 0xA3, 0xBA, 0x22, 0xE1, 0x91, 0xF2, 0x49, 0x5F,
+ 0x15, 0x0A, 0x5F, 0x9B, 0xFE, 0xE2, 0xCE, 0x15, 0x03, 0xDA, 0x21, 0x7B,
+ 0x74, 0xB8, 0xA9, 0x84, 0x68, 0x51, 0x10, 0xF1},
+ // C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ // - G2, OU=(c) 1998 VeriSign, Inc. - For authorized use only, OU=VeriSign
+ // Trust Network
+ {0x79, 0x7E, 0x51, 0xF8, 0x83, 0xE8, 0x55, 0xD0, 0x21, 0xE5, 0xC7, 0x70,
+ 0x56, 0x66, 0x92, 0x99, 0x94, 0x07, 0x89, 0x55, 0x93, 0x23, 0x5D, 0xEF,
+ 0x52, 0xA0, 0x11, 0xF7, 0x16, 0xF8, 0xB6, 0xBF},
+ // C=US, ST=MN, L=Minneapolis, O=Open Access Technology International Inc,
+ // CN=OATI WebCARES Root CA
+ {0x7A, 0x77, 0xC6, 0xC6, 0x1E, 0xEE, 0xB9, 0xAA, 0x65, 0xC4, 0xEA, 0x41,
+ 0x0D, 0x65, 0xD8, 0x95, 0xB2, 0x6A, 0x81, 0x12, 0x32, 0x83, 0x00, 0x9D,
+ 0xB1, 0x04, 0xB4, 0x8D, 0xE8, 0x0B, 0x24, 0x79},
+ // C=CH, O=SwissSign AG, CN=SwissSign Gold Root CA - G3
+ {0x7A, 0xF6, 0xEA, 0x9F, 0x75, 0x3A, 0x1E, 0x70, 0x9B, 0xD6, 0x4D, 0x0B,
+ 0xEB, 0x86, 0x7C, 0x11, 0xE8, 0xC2, 0x95, 0xA5, 0x6E, 0x24, 0xA6, 0xE0,
+ 0x47, 0x14, 0x59, 0xDC, 0xCD, 0xAA, 0x15, 0x58},
+ // C=us, ST=Utah, L=Salt Lake City, O=Digital Signature Trust Co., OU=DSTCA
+ // X1, CN=DST RootCA X1/emailAddress=ca@digsigtrust.com
+ {0x7B, 0x1A, 0x15, 0xD7, 0xE5, 0xE1, 0x30, 0xC5, 0x79, 0xE6, 0x8F, 0xCA,
+ 0x18, 0x92, 0x57, 0xF8, 0x37, 0xB5, 0xC1, 0x88, 0xF1, 0xB2, 0xB2, 0xA7,
+ 0x91, 0xE9, 0x67, 0xCC, 0x88, 0xCC, 0x65, 0x28},
+ // C=AT, O=A-Trust, OU=A-Trust-nQual-01, CN=A-Trust-nQual-01
+ {0x7B, 0x1F, 0x8D, 0x8E, 0xFF, 0x5D, 0x73, 0x49, 0xFE, 0xDB, 0x7E, 0xAE,
+ 0x89, 0xC2, 0x9A, 0xAC, 0xC4, 0x17, 0x04, 0xF1, 0x50, 0x3A, 0xE3, 0xC8,
+ 0xC2, 0xEB, 0xA1, 0x02, 0x25, 0xD0, 0xF5, 0x68},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G2
+ {0x7D, 0x05, 0xEB, 0xB6, 0x82, 0x33, 0x9F, 0x8C, 0x94, 0x51, 0xEE, 0x09,
+ 0x4E, 0xEB, 0xFE, 0xFA, 0x79, 0x53, 0xA1, 0x14, 0xED, 0xB2, 0xF4, 0x49,
+ 0x49, 0x45, 0x2F, 0xAB, 0x7D, 0x2F, 0xC1, 0x85},
+ // C=ES, O=Colegio de Registradores de la Propiedad y Mercantiles de
+ // Espa\xC3\xB1a, OU=Certificado Propio, CN=Registradores de Espa\xC3\xB1a -
+ // CA Ra\xC3\xADz
+ {0x7D, 0x2B, 0xF3, 0x48, 0x9E, 0xBC, 0x9A, 0xD3, 0x44, 0x8B, 0x8B, 0x08,
+ 0x27, 0x71, 0x5A, 0x3C, 0xBF, 0xE3, 0xD5, 0x23, 0xE3, 0xB5, 0x6A, 0x9B,
+ 0x5F, 0xC1, 0xD2, 0xA2, 0xDA, 0x2F, 0x20, 0xFE},
+ // C=US, O=America Online Inc., CN=America Online Root Certification
+ // Authority 2
+ {0x7D, 0x3B, 0x46, 0x5A, 0x60, 0x14, 0xE5, 0x26, 0xC0, 0xAF, 0xFC, 0xEE,
+ 0x21, 0x27, 0xD2, 0x31, 0x17, 0x27, 0xAD, 0x81, 0x1C, 0x26, 0x84, 0x2D,
+ 0x00, 0x6A, 0xF3, 0x73, 0x06, 0xCC, 0x80, 0xBD},
+ // C=FR, O=Certplus, CN=Class 1 Primary CA
+ {0x7D, 0x8C, 0xE8, 0x22, 0x22, 0x2B, 0x90, 0xC0, 0xB1, 0x43, 0x42, 0xC7,
+ 0xA8, 0x14, 0x5D, 0x1F, 0x24, 0x35, 0x1F, 0x4D, 0x1A, 0x1F, 0xE0, 0xED,
+ 0xFD, 0x31, 0x2E, 0xE7, 0x3F, 0xB0, 0x01, 0x49},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G3
+ {0x7E, 0x37, 0xCB, 0x8B, 0x4C, 0x47, 0x09, 0x0C, 0xAB, 0x36, 0x55, 0x1B,
+ 0xA6, 0xF4, 0x5D, 0xB8, 0x40, 0x68, 0x0F, 0xBA, 0x16, 0x6A, 0x95, 0x2D,
+ 0xB1, 0x00, 0x71, 0x7F, 0x43, 0x05, 0x3F, 0xC2},
+ // C=HU, ST=Hungary, L=Budapest, O=NetLock Halozatbiztonsagi Kft.,
+ // OU=Tanusitvanykiadok, CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado
+ {0x7F, 0x12, 0xCD, 0x5F, 0x7E, 0x5E, 0x29, 0x0E, 0xC7, 0xD8, 0x51, 0x79,
+ 0xD5, 0xB7, 0x2C, 0x20, 0xA5, 0xBE, 0x75, 0x08, 0xFF, 0xDB, 0x5B, 0xF8,
+ 0x1A, 0xB9, 0x68, 0x4A, 0x7F, 0xC9, 0xF6, 0x67},
+ // C=ES, O=Agencia Notarial de Certificacion S.L. Unipersonal - CIF
+ // B83395988, CN=ANCERT Certificados CGN
+ {0x81, 0x77, 0xD1, 0xA8, 0x2B, 0xA5, 0x01, 0xAF, 0xDD, 0x1E, 0x94, 0x83,
+ 0xAD, 0x7D, 0xA9, 0x12, 0xEE, 0x1E, 0x9F, 0xCB, 0x2A, 0x5A, 0x06, 0x1F,
+ 0xA3, 0xC4, 0x79, 0xFA, 0x80, 0x4C, 0xE6, 0xBA},
+ // C=TR, O=Elektronik Bilgi Guvenligi A.S., CN=E-GUVEN Kok Elektronik
+ // Sertifika Hizmet Saglayicisi S3
+ {0x82, 0xD4, 0x2D, 0xB3, 0xD6, 0x57, 0xF1, 0x94, 0x4E, 0x65, 0xC1, 0x92,
+ 0xB1, 0xDD, 0x58, 0xDB, 0x8D, 0xF8, 0x41, 0x7B, 0x89, 0x16, 0x5B, 0x04,
+ 0x5F, 0x5C, 0x6A, 0x70, 0xC5, 0xF8, 0x93, 0x9E},
+ // O=Cisco Systems, CN=Cisco Root CA 2048
+ {0x83, 0x27, 0xBC, 0x8C, 0x9D, 0x69, 0x94, 0x7B, 0x3D, 0xE3, 0xC2, 0x75,
+ 0x11, 0x53, 0x72, 0x67, 0xF5, 0x9C, 0x21, 0xB9, 0xFA, 0x7B, 0x61, 0x3F,
+ 0xAF, 0xBC, 0xCD, 0x53, 0xB7, 0x02, 0x40, 0x00},
+ // C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ // - G2, OU=(c) 1998 VeriSign, Inc. - For authorized use only, OU=VeriSign
+ // Trust Network
+ {0x83, 0xCE, 0x3C, 0x12, 0x29, 0x68, 0x8A, 0x59, 0x3D, 0x48, 0x5F, 0x81,
+ 0x97, 0x3C, 0x0F, 0x91, 0x95, 0x43, 0x1E, 0xDA, 0x37, 0xCC, 0x5E, 0x36,
+ 0x43, 0x0E, 0x79, 0xC7, 0xA8, 0x88, 0x63, 0x8B},
+ // C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft
+ // Root Certificate Authority 2011
+ {0x84, 0x7D, 0xF6, 0xA7, 0x84, 0x97, 0x94, 0x3F, 0x27, 0xFC, 0x72, 0xEB,
+ 0x93, 0xF9, 0xA6, 0x37, 0x32, 0x0A, 0x02, 0xB5, 0x61, 0xD0, 0xA9, 0x1B,
+ 0x09, 0xE8, 0x7A, 0x78, 0x07, 0xED, 0x7C, 0x61},
+ // C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2
+ {0x85, 0xA0, 0xDD, 0x7D, 0xD7, 0x20, 0xAD, 0xB7, 0xFF, 0x05, 0xF8, 0x3D,
+ 0x54, 0x2B, 0x20, 0x9D, 0xC7, 0xFF, 0x45, 0x28, 0xF7, 0xD6, 0x77, 0xB1,
+ 0x83, 0x89, 0xFE, 0xA5, 0xE5, 0xC4, 0x9E, 0x86},
+ // C=BR, O=Certisign Certificadora Digital Ltda., OU=Certisign Autoridade
+ // Certificadora AC1S
+ {0x85, 0xE0, 0xDF, 0xAE, 0x3E, 0x55, 0xA8, 0x43, 0x19, 0x5F, 0x8B, 0x08,
+ 0xC8, 0x34, 0x90, 0x50, 0xE4, 0x68, 0x93, 0x72, 0xF6, 0xE1, 0x33, 0xAD,
+ 0x0D, 0x19, 0x9A, 0xF9, 0x6E, 0x95, 0xCC, 0x08},
+ // C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network,
+ // OU=http://www.usertrust.com, CN=UTN - DATACorp SGC
+ {0x85, 0xFB, 0x2F, 0x91, 0xDD, 0x12, 0x27, 0x5A, 0x01, 0x45, 0xB6, 0x36,
+ 0x53, 0x4F, 0x84, 0x02, 0x4A, 0xD6, 0x8B, 0x69, 0xB8, 0xEE, 0x88, 0x68,
+ 0x4F, 0xF7, 0x11, 0x37, 0x58, 0x05, 0xB3, 0x48},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-nQual-03, CN=A-Trust-nQual-03
+ {0x86, 0x88, 0xE5, 0x8F, 0x4C, 0x7A, 0x94, 0x5F, 0xAD, 0xCE, 0x7F, 0x62,
+ 0xBF, 0xEF, 0x52, 0x1B, 0x82, 0xDA, 0x7D, 0xC3, 0x8B, 0xFD, 0xB0, 0x16,
+ 0x34, 0x78, 0xA5, 0xFE, 0x42, 0xE5, 0x78, 0x70},
+ // C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc,
+ // OU=Certification Services Division, CN=Thawte Server
+ // CA/emailAddress=server-certs@thawte.com
+ {0x87, 0xC6, 0x78, 0xBF, 0xB8, 0xB2, 0x5F, 0x38, 0xF7, 0xE9, 0x7B, 0x33,
+ 0x69, 0x56, 0xBB, 0xCF, 0x14, 0x4B, 0xBA, 0xCA, 0xA5, 0x36, 0x47, 0xE6,
+ 0x1A, 0x23, 0x25, 0xBC, 0x10, 0x55, 0x31, 0x6B},
+ // C=ES, O=Agencia Catalana de Certificacio (NIF Q-0801176-I), OU=Serveis
+ // Publics de Certificacio, OU=Vegeu https://www.catcert.net/verarrel (c)03,
+ // OU=Jerarquia Entitats de Certificacio Catalanes, CN=EC-ACC
+ {0x88, 0x49, 0x7F, 0x01, 0x60, 0x2F, 0x31, 0x54, 0x24, 0x6A, 0xE2, 0x8C,
+ 0x4D, 0x5A, 0xEF, 0x10, 0xF1, 0xD8, 0x7E, 0xBB, 0x76, 0x62, 0x6F, 0x4A,
+ 0xE0, 0xB7, 0xF9, 0x5B, 0xA7, 0x96, 0x87, 0x99},
+ // DC=com, DC=microsoft, CN=Microsoft Root Certificate Authority
+ {0x88, 0x5D, 0xE6, 0x4C, 0x34, 0x0E, 0x3E, 0xA7, 0x06, 0x58, 0xF0, 0x1E,
+ 0x11, 0x45, 0xF9, 0x57, 0xFC, 0xDA, 0x27, 0xAA, 0xBE, 0xEA, 0x1A, 0xB9,
+ 0xFA, 0xA9, 0xFD, 0xB0, 0x10, 0x2D, 0x40, 0x77},
+ // C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3 G3
+ {0x88, 0xEF, 0x81, 0xDE, 0x20, 0x2E, 0xB0, 0x18, 0x45, 0x2E, 0x43, 0xF8,
+ 0x64, 0x72, 0x5C, 0xEA, 0x5F, 0xBD, 0x1F, 0xC2, 0xD9, 0xD2, 0x05, 0x73,
+ 0x07, 0x09, 0xC5, 0xD8, 0xB8, 0x69, 0x0F, 0x46},
+ // C=SI, O=ACNLB
+ {0x89, 0x4C, 0xE6, 0xDD, 0xB0, 0x12, 0xCB, 0x3F, 0x73, 0x69, 0x54, 0x66,
+ 0x8D, 0xE6, 0x3F, 0x43, 0x60, 0x80, 0xE9, 0x5F, 0x17, 0xB7, 0xA8, 0x1B,
+ 0xD9, 0x24, 0xEB, 0x21, 0xBE, 0xE9, 0xE4, 0x40},
+ // C=US, O=U.S. Government, OU=FPKI, CN=Federal Common Policy CA
+ {0x89, 0x4E, 0xBC, 0x0B, 0x23, 0xDA, 0x2A, 0x50, 0xC0, 0x18, 0x6B, 0x7F,
+ 0x8F, 0x25, 0xEF, 0x1F, 0x6B, 0x29, 0x35, 0xAF, 0x32, 0xA9, 0x45, 0x84,
+ 0xEF, 0x80, 0xAA, 0xF8, 0x77, 0xA3, 0xA0, 0x6E},
+ // C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 1 G3
+ {0x8A, 0x86, 0x6F, 0xD1, 0xB2, 0x76, 0xB5, 0x7E, 0x57, 0x8E, 0x92, 0x1C,
+ 0x65, 0x82, 0x8A, 0x2B, 0xED, 0x58, 0xE9, 0xF2, 0xF2, 0x88, 0x05, 0x41,
+ 0x34, 0xB7, 0xF1, 0xF4, 0xBF, 0xC9, 0xCC, 0x74},
+ // C=SI, O=Halcom, CN=Halcom Root CA
+ {0x8B, 0x3F, 0xDB, 0x15, 0x1A, 0xF7, 0x59, 0xC5, 0x66, 0x14, 0x3E, 0x07,
+ 0xC9, 0x50, 0xED, 0xE4, 0xF9, 0xE8, 0xC7, 0xCF, 0x80, 0x84, 0x53, 0xD3,
+ 0x3B, 0xCB, 0x78, 0xE5, 0x2A, 0x40, 0x0A, 0xF9},
+ // C=CN, O=WoSign CA Limited, CN=CA WoSign ECC Root
+ {0x8B, 0x45, 0xDA, 0x1C, 0x06, 0xF7, 0x91, 0xEB, 0x0C, 0xAB, 0xF2, 0x6B,
+ 0xE5, 0x88, 0xF5, 0xFB, 0x23, 0x16, 0x5C, 0x2E, 0x61, 0x4B, 0xF8, 0x85,
+ 0x56, 0x2D, 0x0D, 0xCE, 0x50, 0xB2, 0x9B, 0x02},
+ // C=ES, O=Generalitat Valenciana, OU=PKIGVA, CN=Root CA Generalitat
+ // Valenciana
+ {0x8C, 0x4E, 0xDF, 0xD0, 0x43, 0x48, 0xF3, 0x22, 0x96, 0x9E, 0x7E, 0x29,
+ 0xA4, 0xCD, 0x4D, 0xCA, 0x00, 0x46, 0x55, 0x06, 0x1C, 0x16, 0xE1, 0xB0,
+ 0x76, 0x42, 0x2E, 0xF3, 0x42, 0xAD, 0x63, 0x0E},
+ // C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006
+ // thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
+ {0x8D, 0x72, 0x2F, 0x81, 0xA9, 0xC1, 0x13, 0xC0, 0x79, 0x1D, 0xF1, 0x36,
+ 0xA2, 0x96, 0x6D, 0xB2, 0x6C, 0x95, 0x0A, 0x97, 0x1D, 0xB4, 0x6B, 0x41,
+ 0x99, 0xF4, 0xEA, 0x54, 0xB7, 0x8B, 0xFB, 0x9F},
+ // C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 2 CA 2007
+ {0x8D, 0xA7, 0x5F, 0x13, 0x27, 0x21, 0x7C, 0x88, 0x06, 0x0F, 0xD2, 0x52,
+ 0x9E, 0xFF, 0x28, 0x16, 0xE5, 0x0B, 0x0C, 0x74, 0x54, 0x1E, 0xA4, 0xEA,
+ 0x3D, 0xFC, 0xEE, 0x66, 0xA7, 0x1E, 0xFE, 0x09},
+ // C=DE, ST=Hamburg, L=Hamburg, O=TC TrustCenter for Security in Data
+ // Networks GmbH, OU=TC TrustCenter Class 4
+ // CA/emailAddress=certificate@trustcenter.de
+ {0x8D, 0xBB, 0x5A, 0x7C, 0x06, 0xC2, 0x0E, 0xF6, 0x2D, 0xD9, 0x12, 0xA3,
+ 0x67, 0x40, 0x99, 0x2F, 0xF6, 0xE1, 0xE8, 0x58, 0x3D, 0x42, 0xED, 0xE2,
+ 0x57, 0xC3, 0xAF, 0xFD, 0x7C, 0x76, 0x93, 0x99},
+ // C=TR, L=Ankara, O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve
+ // Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E.,
+ // CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1 H6
+ {0x8D, 0xE7, 0x86, 0x55, 0xE1, 0xBE, 0x7F, 0x78, 0x47, 0x80, 0x0B, 0x93,
+ 0xF6, 0x94, 0xD2, 0x1D, 0x36, 0x8C, 0xC0, 0x6E, 0x03, 0x3E, 0x7F, 0xAB,
+ 0x04, 0xBB, 0x5E, 0xB9, 0x9D, 0xA6, 0xB7, 0x00},
+ // C=HU, L=Budapest, O=Microsec Ltd., CN=Microsec e-Szigno Root CA
+ // 2009/emailAddress=info@e-szigno.hu
+ {0x8E, 0x8C, 0x6E, 0xBF, 0x77, 0xDC, 0x73, 0xDB, 0x3E, 0x38, 0xE9, 0x3F,
+ 0x48, 0x03, 0xE6, 0x2B, 0x6B, 0x59, 0x33, 0xBE, 0xB5, 0x1E, 0xE4, 0x15,
+ 0x2F, 0x68, 0xD7, 0xAA, 0x14, 0x42, 0x6B, 0x31},
+ // CN=SG TRUST SERVICES RACINE, OU=0002 43525289500022, O=SG TRUST SERVICES,
+ // C=FR
+ {0x8F, 0x1E, 0xCD, 0xAF, 0x29, 0xBC, 0xD5, 0x6E, 0xDD, 0xD6, 0xB5, 0xD5,
+ 0x6A, 0x07, 0xFC, 0xAC, 0x2B, 0x74, 0xD4, 0xBC, 0xD1, 0x79, 0x17, 0x91,
+ 0x44, 0xA0, 0x36, 0x5C, 0x27, 0xDC, 0xF1, 0x4B},
+ // C=US, O=Digital Signature Trust Co., OU=DSTCA E2
+ {0x8F, 0x62, 0xD7, 0x73, 0x6F, 0x99, 0xDB, 0xD3, 0x3E, 0xE0, 0x0E, 0x10,
+ 0xC7, 0xE3, 0x29, 0x33, 0x9C, 0x98, 0x8A, 0x5B, 0x47, 0xEF, 0x25, 0xF4,
+ 0x08, 0x29, 0x3C, 0xF2, 0x42, 0x6B, 0x4D, 0x44},
+ // C=US, O=First Data Digital Certificates Inc., CN=First Data Digital
+ // Certificates Inc. Certification Authority
+ {0x8F, 0x63, 0x3D, 0xF0, 0x19, 0x1A, 0x41, 0x7D, 0xCD, 0x4F, 0x63, 0x31,
+ 0xF0, 0xE9, 0x0E, 0xB9, 0x47, 0x15, 0x8C, 0x8A, 0x3E, 0xA5, 0x9B, 0xFE,
+ 0x81, 0x42, 0x00, 0x41, 0x31, 0x5E, 0xAC, 0x6C},
+ // C=DE, ST=Hamburg, L=Hamburg, O=TC TrustCenter for Security in Data
+ // Networks GmbH, OU=TC TrustCenter Class 2
+ // CA/emailAddress=certificate@trustcenter.de
+ {0x8F, 0x9E, 0x27, 0x51, 0xDC, 0xD5, 0x74, 0xE9, 0xBA, 0x90, 0xE7, 0x44,
+ 0xEA, 0x92, 0x58, 0x1F, 0xD0, 0xAF, 0x64, 0x0A, 0xE8, 0x6A, 0xC1, 0xCE,
+ 0x21, 0x98, 0xC9, 0x0F, 0x96, 0xB4, 0x48, 0x23},
+ // C=KR, O=KISA, OU=Korea Certification Authority Central, CN=KISA RootCA 3
+ {0x8F, 0xDD, 0x29, 0x8D, 0x1C, 0x93, 0xB2, 0x2B, 0xFC, 0x42, 0xAA, 0xB1,
+ 0xC3, 0xA1, 0x5F, 0x0D, 0x01, 0x83, 0x2C, 0xA0, 0xA1, 0xAE, 0xF2, 0x8D,
+ 0x56, 0x80, 0xF0, 0x6E, 0x6C, 0x7F, 0xD4, 0xEF},
+ // C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2 G3
+ {0x8F, 0xE4, 0xFB, 0x0A, 0xF9, 0x3A, 0x4D, 0x0D, 0x67, 0xDB, 0x0B, 0xEB,
+ 0xB2, 0x3E, 0x37, 0xC7, 0x1B, 0xF3, 0x25, 0xDC, 0xBC, 0xDD, 0x24, 0x0E,
+ 0xA0, 0x4D, 0xAF, 0x58, 0xB4, 0x7E, 0x18, 0x40},
+ // C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 3 CA 2007
+ {0x90, 0xF3, 0xE0, 0x53, 0x96, 0x99, 0x5F, 0xF2, 0x09, 0x22, 0xC4, 0x45,
+ 0x92, 0xDB, 0x62, 0xD7, 0x84, 0x5E, 0x1B, 0xF6, 0x4A, 0xEF, 0x51, 0x2C,
+ 0xCA, 0x75, 0xBC, 0x66, 0x9C, 0xAA, 0x24, 0x79},
+ // C=PA, ST=Panama, L=Panama City, O=TrustCor Systems S. de R.L.,
+ // OU=TrustCor Certificate Authority, CN=TrustCor RootCert CA-2
+ {0x91, 0x11, 0x24, 0x07, 0x47, 0xE1, 0xF6, 0x52, 0xF6, 0x6D, 0x1F, 0x71,
+ 0x2A, 0x11, 0xF6, 0x98, 0x96, 0x3B, 0x49, 0x17, 0x02, 0xE3, 0x12, 0xF7,
+ 0x51, 0x3D, 0xA3, 0xD0, 0xFC, 0x1E, 0x5A, 0x28},
+ // C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center,
+ // CN=T-TeleSec GlobalRoot Class 2
+ {0x91, 0xE2, 0xF5, 0x78, 0x8D, 0x58, 0x10, 0xEB, 0xA7, 0xBA, 0x58, 0x73,
+ 0x7D, 0xE1, 0x54, 0x8A, 0x8E, 0xCA, 0xCD, 0x01, 0x45, 0x98, 0xBC, 0x0B,
+ 0x14, 0x3E, 0x04, 0x1B, 0x17, 0x05, 0x25, 0x52},
+ // C=SK, L=Bratislava, O=Disig a.s., CN=CA Disig
+ {0x92, 0xBF, 0x51, 0x19, 0xAB, 0xEC, 0xCA, 0xD0, 0xB1, 0x33, 0x2D, 0xC4,
+ 0xE1, 0xD0, 0x5F, 0xBA, 0x75, 0xB5, 0x67, 0x90, 0x44, 0xEE, 0x0C, 0xA2,
+ 0x6E, 0x93, 0x1F, 0x74, 0x4F, 0x2F, 0x33, 0xCF},
+ // C=CN, O=UniTrust, CN=UCA Root
+ {0x93, 0xE6, 0x5E, 0xC7, 0x62, 0xF0, 0x55, 0xDC, 0x71, 0x8A, 0x33, 0x25,
+ 0x82, 0xC4, 0x1A, 0x04, 0x43, 0x0D, 0x72, 0xE3, 0xCB, 0x87, 0xE8, 0xB8,
+ 0x97, 0xB6, 0x75, 0x16, 0xF0, 0xD1, 0xAA, 0x39},
+ // C=KR, O=KISA, OU=ROOTCA, CN=CertRSA01
+ {0x95, 0x60, 0x57, 0x51, 0x7F, 0xF3, 0xBB, 0x35, 0x04, 0x93, 0x42, 0x28,
+ 0x8C, 0x1C, 0x9D, 0xCE, 0x85, 0x2D, 0xAC, 0xA6, 0x52, 0xB4, 0x65, 0xE9,
+ 0x74, 0x72, 0x53, 0xB5, 0xF9, 0x3B, 0x1F, 0x5E},
+ // O=Cybertrust, Inc, CN=Cybertrust Global Root
+ {0x96, 0x0A, 0xDF, 0x00, 0x63, 0xE9, 0x63, 0x56, 0x75, 0x0C, 0x29, 0x65,
+ 0xDD, 0x0A, 0x08, 0x67, 0xDA, 0x0B, 0x9C, 0xBD, 0x6E, 0x77, 0x71, 0x4A,
+ 0xEA, 0xFB, 0x23, 0x49, 0xAB, 0x39, 0x3D, 0xA3},
+ // CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1, C=TR, L=Ankara,
+ // O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve Bili\xC5\x9Fim
+ // G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E. (c) Aral\xC4\xB1k 2007
+ {0x97, 0x8C, 0xD9, 0x66, 0xF2, 0xFA, 0xA0, 0x7B, 0xA7, 0xAA, 0x95, 0x00,
+ 0xD9, 0xC0, 0x2E, 0x9D, 0x77, 0xF2, 0xCD, 0xAD, 0xA6, 0xAD, 0x6B, 0xA7,
+ 0x4A, 0xF4, 0xB9, 0x1C, 0x66, 0x59, 0x3C, 0x50},
+ // C=DE, O=Deutsche Telekom AG, OU=T-TeleSec Trust Center, CN=Deutsche
+ // Telekom Root CA 1
+ {0x98, 0x06, 0xAB, 0x85, 0x09, 0xE2, 0xF3, 0x5E, 0x19, 0x2F, 0x27, 0x5F,
+ 0x0C, 0x30, 0x8B, 0x94, 0x09, 0xB4, 0x25, 0x12, 0xF9, 0x0C, 0x65, 0x95,
+ 0x98, 0xC2, 0x2B, 0xE6, 0x13, 0x96, 0x22, 0x72},
+ // C=NO, O=Buypass AS-983163327, CN=Buypass Class 2 Root CA
+ {0x9A, 0x11, 0x40, 0x25, 0x19, 0x7C, 0x5B, 0xB9, 0x5D, 0x94, 0xE6, 0x3D,
+ 0x55, 0xCD, 0x43, 0x79, 0x08, 0x47, 0xB6, 0x46, 0xB2, 0x3C, 0xDF, 0x11,
+ 0xAD, 0xA4, 0xA0, 0x0E, 0xFF, 0x15, 0xFB, 0x48},
+ // CN=ACCVRAIZ1, OU=PKIACCV, O=ACCV, C=ES
+ {0x9A, 0x6E, 0xC0, 0x12, 0xE1, 0xA7, 0xDA, 0x9D, 0xBE, 0x34, 0x19, 0x4D,
+ 0x47, 0x8A, 0xD7, 0xC0, 0xDB, 0x18, 0x22, 0xFB, 0x07, 0x1D, 0xF1, 0x29,
+ 0x81, 0x49, 0x6E, 0xD1, 0x04, 0x38, 0x41, 0x13},
+ // C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign,
+ // Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary
+ // Certification Authority - G5
+ {0x9A, 0xCF, 0xAB, 0x7E, 0x43, 0xC8, 0xD8, 0x80, 0xD0, 0x6B, 0x26, 0x2A,
+ 0x94, 0xDE, 0xEE, 0xE4, 0xB4, 0x65, 0x99, 0x89, 0xC3, 0xD0, 0xCA, 0xF1,
+ 0x9B, 0xAF, 0x64, 0x05, 0xE4, 0x1A, 0xB7, 0xDF},
+ // C=SE, O=Swedish Social Insurance Agency, CN=Swedish Government Root
+ // Authority v2
+ {0x9C, 0xEF, 0xB0, 0xCB, 0x7B, 0x74, 0xE6, 0x42, 0x93, 0x25, 0x32, 0x83,
+ 0x1E, 0x0D, 0xC8, 0xF4, 0xD6, 0x8A, 0xD4, 0x14, 0x26, 0x1F, 0xC3, 0xF4,
+ 0x74, 0xB7, 0x95, 0xE7, 0x2A, 0x16, 0x4E, 0x57},
+ // C=EU, O=AC Camerfirma SA CIF A82743287, OU=http://www.chambersign.org,
+ // CN=Public Notary Root
+ {0x9D, 0xB9, 0x30, 0xA7, 0xBC, 0xED, 0x5A, 0x59, 0x9D, 0xA6, 0x73, 0xD0,
+ 0xBB, 0x12, 0xC4, 0xC6, 0xC7, 0xAB, 0x5B, 0x3F, 0x88, 0xF3, 0x9C, 0x24,
+ 0xEE, 0x20, 0xA2, 0x47, 0x16, 0xB3, 0x79, 0xDF},
+ // C=US, O=Digital Signature Trust Co., OU=DST (ANX Network) CA
+ {0x9D, 0xF0, 0xEC, 0x44, 0xF5, 0x5B, 0x36, 0xD7, 0x9D, 0x4B, 0x53, 0xC2,
+ 0x08, 0xBE, 0xF8, 0xCB, 0x63, 0xD7, 0x8D, 0xCC, 0x8F, 0xCA, 0xFD, 0xE1,
+ 0x66, 0x23, 0x12, 0xF2, 0x12, 0x20, 0x4A, 0x37},
+ // C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority,
+ // CN=Certum Trusted Network CA 2
+ {0x9F, 0x8B, 0x05, 0x13, 0x7F, 0x20, 0xAC, 0xDE, 0x9B, 0x99, 0x64, 0x10,
+ 0xF4, 0xD0, 0xBF, 0x79, 0x71, 0xA1, 0x00, 0x6D, 0xC9, 0x9E, 0x09, 0x4C,
+ 0x34, 0x6D, 0x27, 0x9B, 0x93, 0xCF, 0xF7, 0xAE},
+ // C=US, O=GeoTrust Inc., CN=GeoTrust Universal CA 2
+ {0xA0, 0x23, 0x4F, 0x3B, 0xC8, 0x52, 0x7C, 0xA5, 0x62, 0x8E, 0xEC, 0x81,
+ 0xAD, 0x5D, 0x69, 0x89, 0x5D, 0xA5, 0x68, 0x0D, 0xC9, 0x1D, 0x1C, 0xB8,
+ 0x47, 0x7F, 0x33, 0xF8, 0x78, 0xB9, 0x5B, 0x0B},
+ // C=GR, L=Athens, O=Hellenic Academic and Research Institutions Cert.
+ // Authority, CN=Hellenic Academic and Research Institutions RootCA 2015
+ {0xA0, 0x40, 0x92, 0x9A, 0x02, 0xCE, 0x53, 0xB4, 0xAC, 0xF4, 0xF2, 0xFF,
+ 0xC6, 0x98, 0x1C, 0xE4, 0x49, 0x6F, 0x75, 0x5E, 0x6D, 0x45, 0xFE, 0x0B,
+ 0x2A, 0x69, 0x2B, 0xCD, 0x52, 0x52, 0x3F, 0x36},
+ // C=US, O=GeoTrust Inc., CN=GeoTrust Universal CA
+ {0xA0, 0x45, 0x9B, 0x9F, 0x63, 0xB2, 0x25, 0x59, 0xF5, 0xFA, 0x5D, 0x4C,
+ 0x6D, 0xB3, 0xF9, 0xF7, 0x2F, 0xF1, 0x93, 0x42, 0x03, 0x35, 0x78, 0xF0,
+ 0x73, 0xBF, 0x1D, 0x1B, 0x46, 0xCB, 0xB9, 0x12},
+ // C=LU, O=LuxTrust s.a., CN=LuxTrust Global Root
+ {0xA1, 0xB2, 0xDB, 0xEB, 0x64, 0xE7, 0x06, 0xC6, 0x16, 0x9E, 0x3C, 0x41,
+ 0x18, 0xB2, 0x3B, 0xAA, 0x09, 0x01, 0x8A, 0x84, 0x27, 0x66, 0x6D, 0x8B,
+ 0xF0, 0xE2, 0x88, 0x91, 0xEC, 0x05, 0x19, 0x50},
+ // C=CN, O=UniTrust, CN=UCA Global Root
+ {0xA1, 0xF0, 0x5C, 0xCB, 0x80, 0xC2, 0xD7, 0x10, 0xEC, 0x7D, 0x47, 0x9A,
+ 0xBD, 0xCB, 0xB8, 0x79, 0xE5, 0x8D, 0x7E, 0xDB, 0x71, 0x49, 0xFE, 0x78,
+ 0xA8, 0x78, 0x84, 0xE3, 0xD0, 0xBA, 0xD0, 0xF9},
+ // C=JP, O=SECOM Trust Systems CO.,LTD., OU=Security Communication EV
+ // RootCA1
+ {0xA2, 0x2D, 0xBA, 0x68, 0x1E, 0x97, 0x37, 0x6E, 0x2D, 0x39, 0x7D, 0x72,
+ 0x8A, 0xAE, 0x3A, 0x9B, 0x62, 0x96, 0xB9, 0xFD, 0xBA, 0x60, 0xBC, 0x2E,
+ 0x11, 0xF6, 0x47, 0xF2, 0xC6, 0x75, 0xFB, 0x37},
+ // C=ch, O=admin, OU=Services, OU=Certification Authorities,
+ // CN=Admin-Root-CA
+ {0xA3, 0x1F, 0x09, 0x30, 0x53, 0xBD, 0x12, 0xC1, 0xF5, 0xC3, 0xC6, 0xEF,
+ 0xD4, 0x98, 0x02, 0x3F, 0xD2, 0x91, 0x4D, 0x77, 0x58, 0xD0, 0x5D, 0x69,
+ 0x8C, 0xE0, 0x84, 0xB5, 0x06, 0x26, 0xE0, 0xE5},
+ // C=CH, O=The Federal Authorities of the Swiss Confederation, OU=Services,
+ // OU=Certification Authorities, CN=Swiss Government Root CA II
+ {0xA3, 0xD7, 0x43, 0x5A, 0x18, 0xC4, 0x6B, 0x23, 0xB6, 0xA4, 0xF8, 0x92,
+ 0x9C, 0xD5, 0x90, 0x50, 0xC9, 0x16, 0x8B, 0x03, 0xA7, 0xFA, 0xD5, 0x32,
+ 0x62, 0x6F, 0x29, 0x7C, 0xAC, 0x53, 0x56, 0xE4},
+ // C=US, O=thawte, Inc., OU=(c) 2007 thawte, Inc. - For authorized use only,
+ // CN=thawte Primary Root CA - G2
+ {0xA4, 0x31, 0x0D, 0x50, 0xAF, 0x18, 0xA6, 0x44, 0x71, 0x90, 0x37, 0x2A,
+ 0x86, 0xAF, 0xAF, 0x8B, 0x95, 0x1F, 0xFB, 0x43, 0x1D, 0x83, 0x7F, 0x1E,
+ 0x56, 0x88, 0xB4, 0x59, 0x71, 0xED, 0x15, 0x57},
+ // C=BM, O=QuoVadis Limited, OU=Root Certification Authority, CN=QuoVadis
+ // Root Certification Authority
+ {0xA4, 0x5E, 0xDE, 0x3B, 0xBB, 0xF0, 0x9C, 0x8A, 0xE1, 0x5C, 0x72, 0xEF,
+ 0xC0, 0x72, 0x68, 0xD6, 0x93, 0xA2, 0x1C, 0x99, 0x6F, 0xD5, 0x1E, 0x67,
+ 0xCA, 0x07, 0x94, 0x60, 0xFD, 0x6D, 0x88, 0x73},
+ // C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ {0xA4, 0xB6, 0xB3, 0x99, 0x6F, 0xC2, 0xF3, 0x06, 0xB3, 0xFD, 0x86, 0x81,
+ 0xBD, 0x63, 0x41, 0x3D, 0x8C, 0x50, 0x09, 0xCC, 0x4F, 0xA3, 0x29, 0xC2,
+ 0xCC, 0xF0, 0xE2, 0xFA, 0x1B, 0x14, 0x03, 0x05},
+ // C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE
+ // CyberTrust Global Root
+ {0xA5, 0x31, 0x25, 0x18, 0x8D, 0x21, 0x10, 0xAA, 0x96, 0x4B, 0x02, 0xC7,
+ 0xB7, 0xC6, 0xDA, 0x32, 0x03, 0x17, 0x08, 0x94, 0xE5, 0xFB, 0x71, 0xFF,
+ 0xFB, 0x66, 0x67, 0xD5, 0xE6, 0x81, 0x0A, 0x36},
+ // C=US, O=Wells Fargo WellsSecure, OU=Wells Fargo Bank NA, CN=WellsSecure
+ // Public Root Certificate Authority
+ {0xA7, 0x12, 0x72, 0xAE, 0xAA, 0xA3, 0xCF, 0xE8, 0x72, 0x7F, 0x7F, 0xB3,
+ 0x9F, 0x0F, 0xB3, 0xD1, 0xE5, 0x42, 0x6E, 0x90, 0x60, 0xB0, 0x6E, 0xE6,
+ 0xF1, 0x3E, 0x9A, 0x3C, 0x58, 0x33, 0xCD, 0x43},
+ // C=GR, O=Athens Exchange S.A., CN=ATHEX Root CA
+ {0xA7, 0x35, 0x63, 0xE8, 0x59, 0xCB, 0xCF, 0xA1, 0x73, 0xCF, 0x32, 0x85,
+ 0xDE, 0xBF, 0x25, 0x78, 0xED, 0xE1, 0x5D, 0x47, 0xA3, 0xBE, 0xE3, 0x85,
+ 0x86, 0x1A, 0xB7, 0xA4, 0xFB, 0x6D, 0x7B, 0x6E},
+ // C=TN, O=ANCE, OU=ANCE WEB, CN=Agence Nationale de Certification
+ // Electronique/emailAddress=ance@certification.tn
+ {0xA7, 0x98, 0xA1, 0xC7, 0x0E, 0x9B, 0x6D, 0x50, 0xEA, 0xA5, 0x72, 0x4A,
+ 0x26, 0xFA, 0xC7, 0x99, 0x18, 0x48, 0xED, 0xC6, 0x1B, 0xF4, 0x8D, 0x79,
+ 0x81, 0x6B, 0xCA, 0xFB, 0x66, 0x97, 0x21, 0x28},
+ // C=US, ST=DC, L=Washington, O=ABA.ECOM, INC., CN=ABA.ECOM Root
+ // CA/emailAddress=admin@digsigtrust.com
+ {0xA9, 0xA9, 0xCA, 0x22, 0x89, 0x0D, 0x69, 0x49, 0x19, 0xC0, 0x95, 0xBB,
+ 0x80, 0x64, 0xCB, 0xC4, 0xA5, 0x25, 0xA5, 0xDB, 0xFA, 0xF8, 0x01, 0xEC,
+ 0x93, 0x5D, 0xBC, 0xCC, 0x07, 0xC8, 0xBA, 0xEE},
+ // C=my, O=TM, OU=TM Applied Business Certification Authority, CN=TM Applied
+ // Business Root Certificate
+ {0xA9, 0xC7, 0x7A, 0xF1, 0xBC, 0xDF, 0xAA, 0x37, 0x39, 0x44, 0x2B, 0x0B,
+ 0x27, 0x34, 0xC6, 0x8E, 0xAF, 0x2E, 0x98, 0x33, 0xF0, 0xD7, 0x66, 0xFB,
+ 0xCA, 0xA6, 0xF2, 0xAE, 0xB4, 0x2D, 0xEC, 0x02},
+ // C=LV, O=VAS Latvijas Pasts - Vien.reg.Nr.40003052790, OU=Sertifikacijas
+ // pakalpojumi, CN=VAS Latvijas Pasts SSI(RCA)
+ {0xAA, 0xD9, 0xCE, 0xED, 0x5A, 0xA6, 0xB1, 0xCE, 0xA2, 0x85, 0x96, 0xA8,
+ 0xE4, 0xE1, 0xAB, 0xED, 0x93, 0x86, 0xD6, 0xEB, 0xC9, 0xD4, 0xAA, 0xD9,
+ 0xAC, 0xDE, 0x0F, 0xA3, 0x6B, 0xA0, 0x69, 0xD0},
+ // C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc,
+ // OU=Certification Services Division, CN=Thawte Premium Server
+ // CA/emailAddress=premium-server@thawte.com
+ {0xAB, 0x70, 0x36, 0x36, 0x5C, 0x71, 0x54, 0xAA, 0x29, 0xC2, 0xC2, 0x9F,
+ 0x5D, 0x41, 0x91, 0x16, 0x3B, 0x16, 0x2A, 0x22, 0x25, 0x01, 0x13, 0x57,
+ 0xD5, 0x6D, 0x07, 0xFF, 0xA7, 0xBC, 0x1F, 0x72},
+ // C=CZ, O=\xC4\x8Cesk\xC3\xA1 po\xC5\xA1ta, s.p. [I\xC4\x8C 47114983],
+ // CN=PostSignum Root QCA 2
+ {0xAD, 0x01, 0x6F, 0x95, 0x80, 0x50, 0xE0, 0xE7, 0xE4, 0x6F, 0xAE, 0x7D,
+ 0xCC, 0x50, 0x19, 0x7E, 0xD8, 0xE3, 0xFF, 0x0A, 0x4B, 0x26, 0x2E, 0x5D,
+ 0xDC, 0xDB, 0x3E, 0xDD, 0xDC, 0x7D, 0x65, 0x78},
+ // C=US, O=Wells Fargo WellsSecure, OU=Wells Fargo Bank NA, CN=WellsSecure
+ // Public Root Certification Authority 01 G2
+ {0xAD, 0x75, 0x39, 0xE5, 0xCD, 0xC9, 0x85, 0xFA, 0x95, 0x24, 0x40, 0x55,
+ 0xA9, 0x20, 0x2D, 0x63, 0x46, 0x0E, 0xC9, 0x21, 0x46, 0x7D, 0x03, 0x4C,
+ 0xFD, 0xBE, 0x87, 0xEC, 0x6D, 0x00, 0xFE, 0xDC},
+ // C=AT, O=A-Trust, OU=A-Trust-nQual-01, CN=A-Trust-nQual-01
+ {0xAE, 0x2F, 0xEC, 0x82, 0x91, 0x18, 0xA2, 0x45, 0x5A, 0xD6, 0xA4, 0x15,
+ 0xE7, 0x18, 0x23, 0xEB, 0x9B, 0x7B, 0x6E, 0x35, 0x78, 0xA5, 0x1A, 0xC8,
+ 0xA5, 0x14, 0x46, 0xEA, 0xDB, 0xB0, 0x97, 0x9C},
+ // CN=ComSign CA, O=ComSign, C=IL
+ {0xAE, 0x44, 0x57, 0xB4, 0x0D, 0x9E, 0xDA, 0x96, 0x67, 0x7B, 0x0D, 0x3C,
+ 0x92, 0xD5, 0x7B, 0x51, 0x77, 0xAB, 0xD7, 0xAC, 0x10, 0x37, 0x95, 0x83,
+ 0x56, 0xD1, 0xE0, 0x94, 0x51, 0x8B, 0xE5, 0xF2},
+ // C=JP, O=Japan Certification Services, Inc., CN=SecureSign RootCA3
+ {0xAE, 0x92, 0xE9, 0x00, 0x00, 0x54, 0x1A, 0x9E, 0xBC, 0x10, 0x1B, 0x70,
+ 0xB6, 0xC3, 0x3A, 0x62, 0xF5, 0xA5, 0x3A, 0x55, 0xBA, 0x81, 0x5E, 0x81,
+ 0xD3, 0x1A, 0xBD, 0xDF, 0x03, 0x50, 0x7F, 0x5D},
+ // C=JP, O=Japan Certification Services, Inc., CN=SecureSign RootCA2
+ {0xAF, 0x6D, 0x08, 0xEE, 0xF3, 0xCA, 0xC4, 0xE1, 0x58, 0x4A, 0xBC, 0x63,
+ 0xC8, 0xA9, 0x47, 0x2A, 0xC5, 0x29, 0xAF, 0x99, 0xF3, 0xF7, 0x91, 0x31,
+ 0x9A, 0x43, 0x77, 0x60, 0x63, 0xF5, 0x8D, 0xCA},
+ // L=Bogota AV Calle 26 N 68D-35, C=CO, O=Entidad de Certificacion Digital
+ // Abierta Certicamara S.A., CN=CERTICAMARA S.A.
+ {0xAF, 0x71, 0xA3, 0xBC, 0xA3, 0x22, 0xE5, 0x22, 0x4D, 0xF5, 0x46, 0x89,
+ 0x56, 0x96, 0xCE, 0x44, 0x9A, 0x8B, 0xD2, 0xBD, 0x13, 0x0F, 0x7A, 0x7A,
+ 0xE4, 0x57, 0x76, 0x7F, 0x5C, 0x23, 0xD8, 0xF8},
+ // O=RSA Security Inc, OU=RSA Security 2048 V3
+ {0xAF, 0x8B, 0x67, 0x62, 0xA1, 0xE5, 0x28, 0x22, 0x81, 0x61, 0xA9, 0x5D,
+ 0x5C, 0x55, 0x9E, 0xE2, 0x66, 0x27, 0x8F, 0x75, 0xD7, 0x9E, 0x83, 0x01,
+ 0x89, 0xA5, 0x03, 0x50, 0x6A, 0xBD, 0x6B, 0x4C},
+ // C=IT, L=Milano, O=Actalis S.p.A./03358520967, CN=Actalis Authentication
+ // CA G1
+ {0xAF, 0xE8, 0x0A, 0x97, 0xEA, 0x11, 0x15, 0x91, 0x90, 0xE9, 0x27, 0xE0,
+ 0x8E, 0xC2, 0xE6, 0x0C, 0x59, 0xA4, 0x05, 0x59, 0x48, 0x3A, 0x3F, 0xEE,
+ 0x83, 0x8A, 0x85, 0x32, 0x1B, 0x3A, 0xEA, 0xAD},
+ // O=eSign Australia, OU=Public Secure Services, CN=Primary Utility Root CA
+ {0xB0, 0x4D, 0x70, 0x8F, 0x1A, 0xE0, 0x45, 0x62, 0x65, 0xDD, 0x1B, 0x66,
+ 0x90, 0x7A, 0x26, 0x91, 0xA2, 0x86, 0x80, 0xB8, 0x53, 0xE0, 0x31, 0xDF,
+ 0x3D, 0xF9, 0x08, 0x3A, 0xF7, 0x16, 0x14, 0xD7},
+ // C=ES, O=IZENPE S.A. - CIF A-01337260-RMerc.Vitoria-Gasteiz T1055 F62 S8,
+ // L=Avda del Mediterraneo Etorbidea 3 - 01010 Vitoria-Gasteiz,
+ // CN=Izenpe.com/emailAddress=Info@izenpe.com
+ {0xB0, 0x87, 0x7A, 0xEE, 0x2D, 0x39, 0x27, 0x4D, 0xF8, 0x31, 0xF6, 0x6F,
+ 0xDE, 0xEB, 0x77, 0x17, 0x55, 0x7C, 0x25, 0x8F, 0xC9, 0xEB, 0x55, 0x23,
+ 0x1A, 0x9F, 0x8A, 0x64, 0x7A, 0x75, 0x43, 0x3F},
+ // C=TR, L=Ankara, O=E-Tu\xC4\x9Fra EBG Bili\xC5\x9Fim Teknolojileri ve
+ // Hizmetleri A.\xC5\x9E., OU=E-Tugra Sertifikasyon Merkezi, CN=E-Tugra
+ // Certification Authority
+ {0xB0, 0xBF, 0xD5, 0x2B, 0xB0, 0xD7, 0xD9, 0xBD, 0x92, 0xBF, 0x5D, 0x4D,
+ 0xC1, 0x3D, 0xA2, 0x55, 0xC0, 0x2C, 0x54, 0x2F, 0x37, 0x83, 0x65, 0xEA,
+ 0x89, 0x39, 0x11, 0xF5, 0x5E, 0x55, 0xF2, 0x3C},
+ // C=FR, O=NATIXIS, OU=0002 542044524, CN=CESAM
+ {0xB2, 0x25, 0x99, 0x96, 0xFF, 0xF7, 0x35, 0xAB, 0x35, 0x01, 0x4E, 0xF6,
+ 0x3F, 0x3D, 0x41, 0x31, 0x90, 0x07, 0x9D, 0xD0, 0x3A, 0x09, 0x62, 0x43,
+ 0x26, 0x35, 0xA8, 0x69, 0x5F, 0x99, 0x53, 0x05},
+ // C=SE, O=Carelink, CN=SITHS CA v3
+ {0xB2, 0xF3, 0xC4, 0x21, 0x6A, 0xF7, 0xAF, 0xF7, 0x24, 0x62, 0x46, 0x6D,
+ 0xC1, 0x3C, 0xD2, 0x81, 0x0D, 0xB8, 0xEE, 0xD8, 0x53, 0xEA, 0xBB, 0x9A,
+ 0x06, 0x3A, 0x60, 0x8E, 0xFC, 0x18, 0xFB, 0xE8},
+ // C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec
+ // Class 3 Public Primary Certification Authority - G6
+ {0xB3, 0x23, 0x96, 0x74, 0x64, 0x53, 0x44, 0x2F, 0x35, 0x3E, 0x61, 0x62,
+ 0x92, 0xBB, 0x20, 0xBB, 0xAA, 0x5D, 0x23, 0xB5, 0x46, 0x45, 0x0F, 0xDB,
+ 0x9C, 0x54, 0xB8, 0x38, 0x61, 0x67, 0xD5, 0x29},
+ // C=au, O=SecureNet CA Class B
+ {0xB3, 0xC9, 0x62, 0xD3, 0x40, 0x19, 0xFB, 0x38, 0xAB, 0x9F, 0xE9, 0xC6,
+ 0x23, 0x99, 0x74, 0x2A, 0xB2, 0x6C, 0x43, 0xC2, 0xD1, 0x8C, 0xE3, 0xF2,
+ 0xB1, 0x3C, 0x14, 0x32, 0x1E, 0x52, 0x96, 0x4B},
+ // x500UniqueIdentifier=SEC-830101-9V9, L=Alvaro Obregon, ST=Distrito
+ // Federal, C=MX/postalCode=01030/street=Insurgentes Sur 1940, CN=Autoridad
+ // Certificadora Raiz de la Secretaria de Economia, OU=Direccion General de
+ // Normatividad Mercantil, O=Secretaria de
+ // Economia/emailAddress=acrse@economia.gob.mx
+ {0xB4, 0x1D, 0x51, 0x6A, 0x53, 0x51, 0xD4, 0x2D, 0xEE, 0xA1, 0x91, 0xFA,
+ 0x6E, 0xDF, 0x2A, 0x67, 0xDE, 0xE2, 0xF3, 0x6D, 0xC9, 0x69, 0x01, 0x2C,
+ 0x76, 0x66, 0x9E, 0x61, 0x6B, 0x90, 0x0D, 0xDF},
+ // C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc,
+ // OU=Certification Services Division, CN=Thawte Server
+ // CA/emailAddress=server-certs@thawte.com
+ {0xB4, 0x41, 0x0B, 0x73, 0xE2, 0xE6, 0xEA, 0xCA, 0x47, 0xFB, 0xC4, 0x2F,
+ 0x8F, 0xA4, 0x01, 0x8A, 0xF4, 0x38, 0x1D, 0xC5, 0x4C, 0xFA, 0xA8, 0x44,
+ 0x50, 0x46, 0x1E, 0xED, 0x09, 0x45, 0x4D, 0xE9},
+ // C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use
+ // only, CN=GeoTrust Primary Certification Authority - G3
+ {0xB4, 0x78, 0xB8, 0x12, 0x25, 0x0D, 0xF8, 0x78, 0x63, 0x5C, 0x2A, 0xA7,
+ 0xEC, 0x7D, 0x15, 0x5E, 0xAA, 0x62, 0x5E, 0xE8, 0x29, 0x16, 0xE2, 0xCD,
+ 0x29, 0x43, 0x61, 0x88, 0x6C, 0xD1, 0xFB, 0xD4},
+ // C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc.,
+ // OU=http://certificates.starfieldtech.com/repository/, CN=Starfield
+ // Services Root Certificate Authority
+ {0xB5, 0xBD, 0x2C, 0xB7, 0x9C, 0xBD, 0x19, 0x07, 0x29, 0x8D, 0x6B, 0xDF,
+ 0x48, 0x42, 0xE5, 0x16, 0xD8, 0xC7, 0x8F, 0xA6, 0xFC, 0x96, 0xD2, 0x5F,
+ 0x71, 0xAF, 0x81, 0x4E, 0x16, 0xCC, 0x24, 0x5E},
+ // C=DE, O=Deutsche Telekom AG, OU=T-TeleSec Trust Center, CN=Deutsche
+ // Telekom Root CA 2
+ {0xB6, 0x19, 0x1A, 0x50, 0xD0, 0xC3, 0x97, 0x7F, 0x7D, 0xA9, 0x9B, 0xCD,
+ 0xAA, 0xC8, 0x6A, 0x22, 0x7D, 0xAE, 0xB9, 0x67, 0x9E, 0xC7, 0x0B, 0xA3,
+ 0xB0, 0xC9, 0xD9, 0x22, 0x71, 0xC1, 0x70, 0xD3},
+ // C=ES, ST=Barcelona, L=Barcelona (see current address at
+ // https://www.anf.es/address/), O=ANF Autoridad de Certificaci\xC3\xB3n,
+ // OU=ANF Clase 1 CA/serialNumber=G63287510, CN=ANF Server CA
+ {0xB6, 0x44, 0xD9, 0x55, 0xFF, 0xF2, 0x9B, 0x74, 0xE3, 0xB5, 0x68, 0x7E,
+ 0x90, 0x8E, 0xE7, 0xC3, 0xC9, 0x19, 0x7B, 0xA3, 0x33, 0x6C, 0xC6, 0x32,
+ 0x85, 0x31, 0xF6, 0xC0, 0x57, 0xD6, 0x77, 0xFD},
+ // C=NO, O=Buypass AS-983163327, CN=Buypass Class 3 CA 1
+ {0xB7, 0xB1, 0x2B, 0x17, 0x1F, 0x82, 0x1D, 0xAA, 0x99, 0x0C, 0xD0, 0xFE,
+ 0x50, 0x87, 0xB1, 0x28, 0x44, 0x8B, 0xA8, 0xE5, 0x18, 0x4F, 0x84, 0xC5,
+ 0x1E, 0x02, 0xB5, 0xC8, 0xFB, 0x96, 0x2B, 0x24},
+ // C=FR, O=OpenTrust, CN=OpenTrust Root CA G3
+ {0xB7, 0xC3, 0x62, 0x31, 0x70, 0x6E, 0x81, 0x07, 0x8C, 0x36, 0x7C, 0xB8,
+ 0x96, 0x19, 0x8F, 0x1E, 0x32, 0x08, 0xDD, 0x92, 0x69, 0x49, 0xDD, 0x8F,
+ 0x57, 0x09, 0xA4, 0x10, 0xF7, 0x5B, 0x62, 0x92},
+ // C=MO, O=Macao Post, CN=Macao Post eSignTrust Root Certification Authority
+ {0xB8, 0xBB, 0xE5, 0x23, 0xBF, 0xCA, 0x3B, 0x11, 0xD5, 0x0F, 0x73, 0xF7,
+ 0xF1, 0x0B, 0x3E, 0xC8, 0xEC, 0x95, 0x8A, 0xA1, 0xDC, 0x86, 0xF6, 0x6D,
+ 0x95, 0x41, 0x90, 0x7F, 0xF1, 0xA1, 0x10, 0xEF},
+ // C=FR, ST=France, L=Paris, O=PM/SGDN, OU=DCSSI,
+ // CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr
+ {0xB9, 0xBE, 0xA7, 0x86, 0x0A, 0x96, 0x2E, 0xA3, 0x61, 0x1D, 0xAB, 0x97,
+ 0xAB, 0x6D, 0xA3, 0xE2, 0x1C, 0x10, 0x68, 0xB9, 0x7D, 0x55, 0x57, 0x5E,
+ 0xD0, 0xE1, 0x12, 0x79, 0xC1, 0x1C, 0x89, 0x32},
+ // C=GR, O=Hellenic Academic and Research Institutions Cert. Authority,
+ // CN=Hellenic Academic and Research Institutions RootCA 2011
+ {0xBC, 0x10, 0x4F, 0x15, 0xA4, 0x8B, 0xE7, 0x09, 0xDC, 0xA5, 0x42, 0xA7,
+ 0xE1, 0xD4, 0xB9, 0xDF, 0x6F, 0x05, 0x45, 0x27, 0xE8, 0x02, 0xEA, 0xA9,
+ 0x2D, 0x59, 0x54, 0x44, 0x25, 0x8A, 0xFE, 0x71},
+ // L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 3
+ // Policy Validation Authority,
+ // CN=http://www.valicert.com//emailAddress=info@valicert.com
+ {0xBC, 0x23, 0xF9, 0x8A, 0x31, 0x3C, 0xB9, 0x2D, 0xE3, 0xBB, 0xFC, 0x3A,
+ 0x5A, 0x9F, 0x44, 0x61, 0xAC, 0x39, 0x49, 0x4C, 0x4A, 0xE1, 0x5A, 0x9E,
+ 0x9D, 0xF1, 0x31, 0xE9, 0x9B, 0x73, 0x01, 0x9A},
+ // C=HK, O=Hongkong Post, CN=Hongkong Post Root CA
+ {0xBC, 0xDD, 0x8D, 0xF4, 0x27, 0x63, 0x66, 0xD7, 0xFF, 0x4B, 0x68, 0x8D,
+ 0xC8, 0x15, 0x00, 0xD8, 0xE9, 0x82, 0x52, 0xC0, 0x49, 0xC8, 0xFF, 0x1E,
+ 0x8C, 0x82, 0xF2, 0xBA, 0xEC, 0x9D, 0x5C, 0x16},
+ // C=US, O=AffirmTrust, CN=AffirmTrust Premium ECC
+ {0xBD, 0x71, 0xFD, 0xF6, 0xDA, 0x97, 0xE4, 0xCF, 0x62, 0xD1, 0x64, 0x7A,
+ 0xDD, 0x25, 0x81, 0xB0, 0x7D, 0x79, 0xAD, 0xF8, 0x39, 0x7E, 0xB4, 0xEC,
+ 0xBA, 0x9C, 0x5E, 0x84, 0x88, 0x82, 0x14, 0x23},
+ // C=CH, O=SwissSign AG, CN=SwissSign Silver CA - G2
+ {0xBE, 0x6C, 0x4D, 0xA2, 0xBB, 0xB9, 0xBA, 0x59, 0xB6, 0xF3, 0x93, 0x97,
+ 0x68, 0x37, 0x42, 0x46, 0xC3, 0xC0, 0x05, 0x99, 0x3F, 0xA9, 0x8F, 0x02,
+ 0x0D, 0x1D, 0xED, 0xBE, 0xD4, 0x8A, 0x81, 0xD5},
+ // OU=GlobalSign ECC Root CA - R4, O=GlobalSign, CN=GlobalSign
+ {0xBE, 0xC9, 0x49, 0x11, 0xC2, 0x95, 0x56, 0x76, 0xDB, 0x6C, 0x0A, 0x55,
+ 0x09, 0x86, 0xD7, 0x6E, 0x3B, 0xA0, 0x05, 0x66, 0x7C, 0x44, 0x2C, 0x97,
+ 0x62, 0xB4, 0xFB, 0xB7, 0x73, 0xDE, 0x22, 0x8C},
+ // C=JP, O=Japan Certification Services, Inc., CN=SecureSign RootCA11
+ {0xBF, 0x0F, 0xEE, 0xFB, 0x9E, 0x3A, 0x58, 0x1A, 0xD5, 0xF9, 0xE9, 0xDB,
+ 0x75, 0x89, 0x98, 0x57, 0x43, 0xD2, 0x61, 0x08, 0x5C, 0x4D, 0x31, 0x4F,
+ 0x6F, 0x5D, 0x72, 0x59, 0xAA, 0x42, 0x16, 0x12},
+ // C=TW, O=TAIWAN-CA, OU=Root CA, CN=TWCA Root Certification Authority
+ {0xBF, 0xD8, 0x8F, 0xE1, 0x10, 0x1C, 0x41, 0xAE, 0x3E, 0x80, 0x1B, 0xF8,
+ 0xBE, 0x56, 0x35, 0x0E, 0xE9, 0xBA, 0xD1, 0xA6, 0xB9, 0xBD, 0x51, 0x5E,
+ 0xDC, 0x5C, 0x6D, 0x5B, 0x87, 0x11, 0xAC, 0x44},
+ // C=CN, O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD., CN=GDCA TrustAUTH R5
+ // ROOT
+ {0xBF, 0xFF, 0x8F, 0xD0, 0x44, 0x33, 0x48, 0x7D, 0x6A, 0x8A, 0xA6, 0x0C,
+ 0x1A, 0x29, 0x76, 0x7A, 0x9F, 0xC2, 0xBB, 0xB0, 0x5E, 0x42, 0x0F, 0x71,
+ 0x3A, 0x13, 0xB9, 0x92, 0x89, 0x1D, 0x38, 0x93},
+ // C=TW, O=Chunghwa Telecom Co., Ltd., OU=ePKI Root Certification Authority
+ {0xC0, 0xA6, 0xF4, 0xDC, 0x63, 0xA2, 0x4B, 0xFD, 0xCF, 0x54, 0xEF, 0x2A,
+ 0x6A, 0x08, 0x2A, 0x0A, 0x72, 0xDE, 0x35, 0x80, 0x3E, 0x2F, 0xF5, 0xFF,
+ 0x52, 0x7A, 0xE5, 0xD8, 0x72, 0x06, 0xDF, 0xD5},
+ // C=CL, ST=Region Metropolitana, L=Santiago, O=E-CERTCHILE, OU=Autoridad
+ // Certificadora/emailAddress=sclientes@ccs.cl, CN=E-CERT ROOT CA
+ {0xC1, 0x09, 0xE0, 0xD1, 0xB6, 0x40, 0x00, 0xB0, 0x1E, 0x89, 0x4B, 0xDA,
+ 0xA9, 0x55, 0xE1, 0xFF, 0x91, 0xB6, 0xD0, 0x84, 0xA8, 0x38, 0xD9, 0x0E,
+ 0x04, 0x4B, 0x9E, 0x3F, 0xCD, 0x2A, 0x8B, 0xFA},
+ // C=FR, O=Certplus, CN=Class 3 Primary CA
+ {0xC1, 0xB1, 0x2F, 0x48, 0x00, 0x20, 0x33, 0x6E, 0x5B, 0x04, 0xF5, 0x20,
+ 0xBC, 0x19, 0xC2, 0xE2, 0xE1, 0x0A, 0xB4, 0x2C, 0x9D, 0x92, 0x35, 0xF0,
+ 0x5C, 0xBE, 0xC3, 0x3F, 0xFA, 0x4D, 0x4D, 0xEA},
+ // C=GB, O=Trustis Limited, OU=Trustis FPS Root CA
+ {0xC1, 0xB4, 0x82, 0x99, 0xAB, 0xA5, 0x20, 0x8F, 0xE9, 0x63, 0x0A, 0xCE,
+ 0x55, 0xCA, 0x68, 0xA0, 0x3E, 0xDA, 0x5A, 0x51, 0x9C, 0x88, 0x02, 0xA0,
+ 0xD3, 0xA6, 0x73, 0xBE, 0x8F, 0x8E, 0x55, 0x7D},
+ // C=ES, L=C/ Muntaner 244 Barcelona, CN=Autoridad de Certificacion
+ // Firmaprofesional CIF A62634068/emailAddress=ca@firmaprofesional.com
+ {0xC1, 0xCF, 0x0B, 0x52, 0x09, 0x64, 0x35, 0xE3, 0xF1, 0xB7, 0x1D, 0xAA,
+ 0xEC, 0x45, 0x5A, 0x23, 0x11, 0xC8, 0x40, 0x4F, 0x55, 0x83, 0xA9, 0xE2,
+ 0x13, 0xC6, 0x9D, 0x85, 0x7D, 0x94, 0x33, 0x05},
+ // C=HU, L=Budapest, O=NISZ Nemzeti Infokommunik\xC3\xA1ci\xC3\xB3s
+ // Szolg\xC3\xA1ltat\xC3\xB3 Zrt.,
+ // CN=F\xC5\x91tan\xC3\xBAs\xC3\xADtv\xC3\xA1nykiad\xC3\xB3 -
+ // Korm\xC3\xA1nyzati Hiteles\xC3\xADt\xC3\xA9s Szolg\xC3\xA1ltat\xC3\xB3
+ {0xC2, 0x15, 0x73, 0x09, 0xD9, 0xAE, 0xE1, 0x7B, 0xF3, 0x4F, 0x4D, 0xF5,
+ 0xE8, 0x8D, 0xBA, 0xEB, 0xA5, 0x7E, 0x03, 0x61, 0xEB, 0x81, 0x4C, 0xBC,
+ 0x23, 0x9F, 0x4D, 0x54, 0xD3, 0x29, 0xA3, 0x8D},
+ // C=CO, L=Carrera 9 16-21 Bogota, O=Certicamara S.A. Entidad de
+ // Certificacion, CN=Certificado Empresarial Clase-A
+ {0xC2, 0x95, 0x9D, 0xB8, 0x33, 0x9E, 0x8D, 0xBC, 0xF6, 0x40, 0x9C, 0xA9,
+ 0x2A, 0x66, 0xC4, 0x9F, 0xD2, 0xE3, 0x24, 0x94, 0x94, 0x0A, 0x90, 0x11,
+ 0x43, 0xBD, 0x7E, 0xB7, 0x28, 0x27, 0xDE, 0xC2},
+ // C=LT, O=Skaitmeninio sertifikavimo centras, OU=CA ROOT Services, CN=SSC
+ // GDL CA Root B
+ {0xC3, 0x1E, 0xEF, 0x56, 0x82, 0xAB, 0xB5, 0x51, 0xEB, 0xC8, 0x28, 0xDE,
+ 0xD8, 0x40, 0x98, 0x51, 0x8A, 0x67, 0x68, 0x52, 0x6D, 0x15, 0x2E, 0xE1,
+ 0x64, 0xCF, 0xB9, 0x72, 0xA1, 0x42, 0x5D, 0x53},
+ // C=IN, O=India PKI, CN=CCA India 2015 SPL
+ {0xC3, 0x4C, 0x5D, 0xF5, 0x30, 0x80, 0x07, 0x8F, 0xFE, 0x45, 0xB2, 0x1A,
+ 0x7F, 0x60, 0x04, 0x69, 0x91, 0x72, 0x04, 0xF4, 0xF0, 0x29, 0x3F, 0x1D,
+ 0x72, 0x09, 0x39, 0x3E, 0x52, 0x65, 0xC0, 0x4F},
+ // C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification
+ // Authority
+ {0xC3, 0x84, 0x6B, 0xF2, 0x4B, 0x9E, 0x93, 0xCA, 0x64, 0x27, 0x4C, 0x0E,
+ 0xC6, 0x7C, 0x1E, 0xCC, 0x5E, 0x02, 0x4F, 0xFC, 0xAC, 0xD2, 0xD7, 0x40,
+ 0x19, 0x35, 0x0E, 0x81, 0xFE, 0x54, 0x6A, 0xE4},
+ // C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network,
+ // OU=http://www.usertrust.com, CN=UTN-USERFirst-Network Applications
+ {0xC3, 0x8D, 0xCB, 0x38, 0x95, 0x93, 0x93, 0x35, 0x86, 0x91, 0xEA, 0x4D,
+ 0x4F, 0x3C, 0xE4, 0x95, 0xCE, 0x74, 0x89, 0x96, 0xE6, 0x4E, 0xD1, 0x89,
+ 0x1D, 0x89, 0x7A, 0x0F, 0xC4, 0xDD, 0x55, 0xC6},
+ // CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1, C=TR, L=Ankara,
+ // O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve Bili\xC5\x9Fim
+ // G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E. (c) Kas\xC4\xB1m 2005
+ {0xC4, 0x70, 0xCF, 0x54, 0x7E, 0x23, 0x02, 0xB9, 0x77, 0xFB, 0x29, 0xDD,
+ 0x71, 0xA8, 0x9A, 0x7B, 0x6C, 0x1F, 0x60, 0x77, 0x7B, 0x03, 0x29, 0xF5,
+ 0x60, 0x17, 0xF3, 0x28, 0xBF, 0x4F, 0x6B, 0xE6},
+ // CN=T\xC3\x9CRKTRUST Elektronik \xC4\xB0\xC5\x9Flem Hizmetleri, C=TR,
+ // L=ANKARA, O=(c) 2005 T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve
+ // Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E.
+ {0xC4, 0x99, 0xF6, 0xCE, 0xCC, 0x5D, 0xA4, 0xD6, 0x1F, 0x14, 0xED, 0x04,
+ 0x05, 0x27, 0x0C, 0x52, 0x49, 0xD0, 0xE7, 0x96, 0x15, 0xB0, 0xDA, 0x42,
+ 0x65, 0x9E, 0xD2, 0xD7, 0xFF, 0xEF, 0x8A, 0x40},
+ // C=US, O=VISA, OU=Visa International Service Association, CN=Visa
+ // Information Delivery Root CA
+ {0xC5, 0x7A, 0x3A, 0xCB, 0xE8, 0xC0, 0x6B, 0xA1, 0x98, 0x8A, 0x83, 0x48,
+ 0x5B, 0xF3, 0x26, 0xF2, 0x44, 0x87, 0x75, 0x37, 0x98, 0x49, 0xDE, 0x01,
+ 0xCA, 0x43, 0x57, 0x1A, 0xF3, 0x57, 0xE7, 0x4B},
+ // C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom
+ // Certification Authority
+ {0xC7, 0x66, 0xA9, 0xBE, 0xF2, 0xD4, 0x07, 0x1C, 0x86, 0x3A, 0x31, 0xAA,
+ 0x49, 0x20, 0xE8, 0x13, 0xB2, 0xD1, 0x98, 0x60, 0x8C, 0xB7, 0xB7, 0xCF,
+ 0xE2, 0x11, 0x43, 0xB8, 0x36, 0xDF, 0x09, 0xEA},
+ // C=TN, CN=Tunisian Root Certificate Authority - TunRootCA2, O=National
+ // Digital Certification Agency
+ {0xC7, 0x95, 0xFF, 0x8F, 0xF2, 0x0C, 0x96, 0x66, 0x88, 0xF0, 0x64, 0xA1,
+ 0xE0, 0x91, 0x42, 0x1D, 0x31, 0x10, 0xA3, 0x45, 0x6C, 0x17, 0xEC, 0x24,
+ 0x04, 0xB9, 0x98, 0x73, 0x87, 0x41, 0xF6, 0x22},
+ // C=IL, O=StartCom Ltd., CN=StartCom Certification Authority G2
+ {0xC7, 0xBA, 0x65, 0x67, 0xDE, 0x93, 0xA7, 0x98, 0xAE, 0x1F, 0xAA, 0x79,
+ 0x1E, 0x71, 0x2D, 0x37, 0x8F, 0xAE, 0x1F, 0x93, 0xC4, 0x39, 0x7F, 0xEA,
+ 0x44, 0x1B, 0xB7, 0xCB, 0xE6, 0xFD, 0x59, 0x95},
+ // C=US, O=GeoTrust Inc., CN=GeoTrust Global CA 2
+ {0xCA, 0x2D, 0x82, 0xA0, 0x86, 0x77, 0x07, 0x2F, 0x8A, 0xB6, 0x76, 0x4F,
+ 0xF0, 0x35, 0x67, 0x6C, 0xFE, 0x3E, 0x5E, 0x32, 0x5E, 0x01, 0x21, 0x72,
+ 0xDF, 0x3F, 0x92, 0x09, 0x6D, 0xB7, 0x9B, 0x85},
+ // OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
+ {0xCA, 0x42, 0xDD, 0x41, 0x74, 0x5F, 0xD0, 0xB8, 0x1E, 0xB9, 0x02, 0x36,
+ 0x2C, 0xF9, 0xD8, 0xBF, 0x71, 0x9D, 0xA1, 0xBD, 0x1B, 0x1E, 0xFC, 0x94,
+ 0x6F, 0x5B, 0x4C, 0x99, 0xF4, 0x2C, 0x1B, 0x9E},
+ // CN=Autoridad de Certificacion Raiz del Estado Venezolano, C=VE,
+ // L=Caracas, ST=Distrito Capital, O=Sistema Nacional de Certificacion
+ // Electronica, OU=Superintendencia de Servicios de Certificacion
+ // Electronica/emailAddress=acraiz@suscerte.gob.ve
+ {0xCA, 0x7A, 0x5E, 0x68, 0xC5, 0x3D, 0x2C, 0x51, 0xF7, 0x2F, 0x6B, 0x46,
+ 0x5D, 0x3E, 0xD7, 0x53, 0xF5, 0x90, 0x3E, 0xC7, 0x90, 0x1C, 0x8D, 0x0F,
+ 0x55, 0xD8, 0x68, 0x33, 0x7C, 0x81, 0x97, 0x5A},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
+ {0xCB, 0x3C, 0xCB, 0xB7, 0x60, 0x31, 0xE5, 0xE0, 0x13, 0x8F, 0x8D, 0xD3,
+ 0x9A, 0x23, 0xF9, 0xDE, 0x47, 0xFF, 0xC3, 0x5E, 0x43, 0xC1, 0x14, 0x4C,
+ 0xEA, 0x27, 0xD4, 0x6A, 0x5A, 0xB1, 0xCB, 0x5F},
+ // OU=GlobalSign Root CA - R3, O=GlobalSign, CN=GlobalSign
+ {0xCB, 0xB5, 0x22, 0xD7, 0xB7, 0xF1, 0x27, 0xAD, 0x6A, 0x01, 0x13, 0x86,
+ 0x5B, 0xDF, 0x1C, 0xD4, 0x10, 0x2E, 0x7D, 0x07, 0x59, 0xAF, 0x63, 0x5A,
+ 0x7C, 0xF4, 0x72, 0x0D, 0xC9, 0x63, 0xC5, 0x3B},
+ // C=BR, O=ICP-Brasil, OU=Instituto Nacional de Tecnologia da Informacao -
+ // ITI, CN=Autoridade Certificadora Raiz Brasileira v1
+ {0xCB, 0xD8, 0xED, 0x38, 0xD4, 0xA2, 0xD6, 0x77, 0xD4, 0x53, 0xD7, 0x0D,
+ 0xD8, 0x89, 0x0A, 0xF4, 0xF6, 0x37, 0x4C, 0xBA, 0x62, 0x99, 0x94, 0x3F,
+ 0x1A, 0xB3, 0xA6, 0x93, 0x6C, 0x6F, 0xD7, 0x95},
+ // C=FR, O=Certplus, CN=Class 3P Primary CA
+ {0xCC, 0xC8, 0x94, 0x89, 0x37, 0x1B, 0xAD, 0x11, 0x1C, 0x90, 0x61, 0x9B,
+ 0xEA, 0x24, 0x0A, 0x2E, 0x6D, 0xAD, 0xD9, 0x9F, 0x9F, 0x6E, 0x1D, 0x4D,
+ 0x41, 0xE5, 0x8E, 0xD6, 0xDE, 0x3D, 0x02, 0x85},
+ // C=LV, OU=Sertifikacijas pakalpojumu dala, CN=E-ME SSI (RCA)
+ {0xCD, 0x0B, 0x3B, 0x2A, 0xA1, 0x74, 0xB5, 0x5F, 0x18, 0xC7, 0x50, 0x2F,
+ 0x3C, 0x3A, 0x76, 0xF2, 0x19, 0x81, 0x75, 0xCE, 0x45, 0x63, 0x73, 0x70,
+ 0xCF, 0x4F, 0x48, 0xB9, 0xC2, 0xCE, 0x4F, 0xBF},
+ // DC=rs, DC=posta, DC=ca, CN=Configuration, CN=Services, CN=Public Key
+ // Services, CN=AIA, CN=Posta CA Root
+ {0xCD, 0x20, 0x12, 0x56, 0xFE, 0x5C, 0xED, 0x0B, 0xFF, 0xF8, 0xDF, 0x59,
+ 0x5F, 0xFF, 0x36, 0xB1, 0x41, 0x6D, 0x53, 0x13, 0xA9, 0x99, 0xF5, 0x32,
+ 0xEF, 0x4A, 0x99, 0x15, 0xDF, 0x96, 0xDE, 0xE0},
+ // C=FR, O=Certplus, CN=Class 3TS Primary CA
+ {0xCE, 0x7D, 0xD0, 0x96, 0xC8, 0xFD, 0xE2, 0xBF, 0x5C, 0x43, 0x8E, 0xDB,
+ 0x57, 0x4B, 0xD6, 0x45, 0x43, 0x85, 0x33, 0x4E, 0xE8, 0xFF, 0x10, 0x6C,
+ 0x0F, 0x93, 0xD5, 0x05, 0x1B, 0xE6, 0xBA, 0xC3},
+ // C=US, OU=www.xrampsecurity.com, O=XRamp Security Services Inc, CN=XRamp
+ // Global Certification Authority
+ {0xCE, 0xCD, 0xDC, 0x90, 0x50, 0x99, 0xD8, 0xDA, 0xDF, 0xC5, 0xB1, 0xD2,
+ 0x09, 0xB7, 0x37, 0xCB, 0xE2, 0xC1, 0x8C, 0xFB, 0x2C, 0x10, 0xC0, 0xFF,
+ 0x0B, 0xCF, 0x0D, 0x32, 0x86, 0xFC, 0x1A, 0xA2},
+ // C=US, O=Equifax Secure Inc., CN=Equifax Secure eBusiness CA-1
+ {0xCF, 0x56, 0xFF, 0x46, 0xA4, 0xA1, 0x86, 0x10, 0x9D, 0xD9, 0x65, 0x84,
+ 0xB5, 0xEE, 0xB5, 0x8A, 0x51, 0x0C, 0x42, 0x75, 0xB0, 0xE5, 0xF9, 0x4F,
+ 0x40, 0xBB, 0xAE, 0x86, 0x5E, 0x19, 0xF6, 0x73},
+ // O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits
+ // liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification
+ // Authority (2048)
+ {0xD1, 0xC3, 0x39, 0xEA, 0x27, 0x84, 0xEB, 0x87, 0x0F, 0x93, 0x4F, 0xC5,
+ 0x63, 0x4E, 0x4A, 0xA9, 0xAD, 0x55, 0x05, 0x01, 0x64, 0x01, 0xF2, 0x64,
+ 0x65, 0xD3, 0x7A, 0x57, 0x46, 0x63, 0x35, 0x9F},
+ // C=CZ, O=Prvn\xC3\xAD certifika\xC4\x8Dn\xC3\xAD autorita, a.s., CN=I.CA
+ // Root CA/RSA/serialNumber=NTRCZ-26439395
+ {0xD3, 0xD6, 0x07, 0xA9, 0xFF, 0x24, 0xA1, 0x95, 0x23, 0xB6, 0xDA, 0x9D,
+ 0x2C, 0x64, 0x94, 0x46, 0xF8, 0x78, 0x8C, 0xB9, 0x6D, 0x9F, 0xD1, 0x30,
+ 0x97, 0x2E, 0x12, 0x0C, 0x13, 0x67, 0x77, 0x30},
+ // C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden Root CA
+ {0xD4, 0x1D, 0x82, 0x9E, 0x8C, 0x16, 0x59, 0x82, 0x2A, 0xF9, 0x3F, 0xCE,
+ 0x62, 0xBF, 0xFC, 0xDE, 0x26, 0x4F, 0xC8, 0x4E, 0x8B, 0x95, 0x0C, 0x5F,
+ 0xF2, 0x75, 0xD0, 0x52, 0x35, 0x46, 0x95, 0xA3},
+ // C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign G2
+ {0xD4, 0x87, 0xA5, 0x6F, 0x83, 0xB0, 0x74, 0x82, 0xE8, 0x5E, 0x96, 0x33,
+ 0x94, 0xC1, 0xEC, 0xC2, 0xC9, 0xE5, 0x1D, 0x09, 0x03, 0xEE, 0x94, 0x6B,
+ 0x02, 0xC3, 0x01, 0x58, 0x1E, 0xD9, 0x9E, 0x16},
+ // C=CN, O=WoSign CA Limited, CN=CA
+ // \xE6\xB2\x83\xE9\x80\x9A\xE6\xA0\xB9\xE8\xAF\x81\xE4\xB9\xA6
+ {0xD6, 0xF0, 0x34, 0xBD, 0x94, 0xAA, 0x23, 0x3F, 0x02, 0x97, 0xEC, 0xA4,
+ 0x24, 0x5B, 0x28, 0x39, 0x73, 0xE4, 0x47, 0xAA, 0x59, 0x0F, 0x31, 0x0C,
+ 0x77, 0xF4, 0x8F, 0xDF, 0x83, 0x11, 0x22, 0x54},
+ // C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA
+ // Certificate Services
+ {0xD7, 0xA7, 0xA0, 0xFB, 0x5D, 0x7E, 0x27, 0x31, 0xD7, 0x71, 0xE9, 0x48,
+ 0x4E, 0xBC, 0xDE, 0xF7, 0x1D, 0x5F, 0x0C, 0x3E, 0x0A, 0x29, 0x48, 0x78,
+ 0x2B, 0xC8, 0x3E, 0xE0, 0xEA, 0x69, 0x9E, 0xF4},
+ // C=DE, O=Deutscher Sparkassen Verlag GmbH, OU=S-TRUST Certification
+ // Services, CN=S-TRUST Universal Root CA
+ {0xD8, 0x0F, 0xEF, 0x91, 0x0A, 0xE3, 0xF1, 0x04, 0x72, 0x3B, 0x04, 0x5C,
+ 0xEC, 0x2D, 0x01, 0x9F, 0x44, 0x1C, 0xE6, 0x21, 0x3A, 0xDF, 0x15, 0x67,
+ 0x91, 0xE7, 0x0C, 0x17, 0x90, 0x11, 0x0A, 0x31},
+ // C=PL, O=Unizeto Sp. z o.o., CN=Certum CA
+ {0xD8, 0xE0, 0xFE, 0xBC, 0x1D, 0xB2, 0xE3, 0x8D, 0x00, 0x94, 0x0F, 0x37,
+ 0xD2, 0x7D, 0x41, 0x34, 0x4D, 0x99, 0x3E, 0x73, 0x4B, 0x99, 0xD5, 0x65,
+ 0x6D, 0x97, 0x78, 0xD4, 0xD8, 0x14, 0x36, 0x24},
+ // C=ch, O=Swisscom, OU=Digital Certificate Services, CN=Swisscom Root EV CA
+ // 2
+ {0xD9, 0x5F, 0xEA, 0x3C, 0xA4, 0xEE, 0xDC, 0xE7, 0x4C, 0xD7, 0x6E, 0x75,
+ 0xFC, 0x6D, 0x1F, 0xF6, 0x2C, 0x44, 0x1F, 0x0F, 0xA8, 0xBC, 0x77, 0xF0,
+ 0x34, 0xB1, 0x9E, 0x5D, 0xB2, 0x58, 0x01, 0x5D},
+ // O=TeliaSonera, CN=TeliaSonera Root CA v1
+ {0xDD, 0x69, 0x36, 0xFE, 0x21, 0xF8, 0xF0, 0x77, 0xC1, 0x23, 0xA1, 0xA5,
+ 0x21, 0xC1, 0x22, 0x24, 0xF7, 0x22, 0x55, 0xB7, 0x3E, 0x03, 0xA7, 0x26,
+ 0x06, 0x93, 0xE8, 0xA2, 0x4B, 0x0F, 0xA3, 0x89},
+ // C=BE, O=Certipost s.a./n.v., CN=Certipost E-Trust TOP Root CA
+ {0xDD, 0xFF, 0x53, 0xEC, 0xD7, 0x74, 0x3B, 0x60, 0xBB, 0x7B, 0x27, 0x95,
+ 0xFF, 0x57, 0x32, 0xFA, 0x78, 0x5F, 0x9A, 0x14, 0xDF, 0x11, 0x20, 0xFB,
+ 0x40, 0xA3, 0x8C, 0xF8, 0x4C, 0xA2, 0xA5, 0x66},
+ // C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft
+ // Root Certificate Authority 2010
+ {0xDF, 0x54, 0x5B, 0xF9, 0x19, 0xA2, 0x43, 0x9C, 0x36, 0x98, 0x3B, 0x54,
+ 0xCD, 0xFC, 0x90, 0x3D, 0xFA, 0x4F, 0x37, 0xD3, 0x99, 0x6D, 0x8D, 0x84,
+ 0xB4, 0xC3, 0x1E, 0xEC, 0x6F, 0x3C, 0x16, 0x3E},
+ // C=ES, ST=Barcelona, L=Barcelona (see current address at
+ // http://www.anf.es/es/address-direccion.html ), O=ANF Autoridad de
+ // Certificacion, OU=ANF Clase 1
+ // CA/emailAddress=info@anf.es/serialNumber=G63287510, CN=ANF Global Root CA
+ {0xE0, 0xE1, 0x7A, 0xEA, 0x06, 0xCF, 0x9C, 0xE1, 0x2A, 0xAE, 0x81, 0x90,
+ 0x34, 0x5A, 0x2C, 0x59, 0x72, 0x01, 0x30, 0xA7, 0xD8, 0xFF, 0x72, 0xF3,
+ 0x74, 0x5A, 0xD7, 0x5D, 0xBA, 0xA3, 0x65, 0xB6},
+ // C=SK, L=Bratislava, O=Disig a.s., CN=CA Disig Root R2
+ {0xE2, 0x3D, 0x4A, 0x03, 0x6D, 0x7B, 0x70, 0xE9, 0xF5, 0x95, 0xB1, 0x42,
+ 0x20, 0x79, 0xD2, 0xB9, 0x1E, 0xDF, 0xBB, 0x1F, 0xB6, 0x51, 0xA0, 0x63,
+ 0x3E, 0xAA, 0x8A, 0x9D, 0xC5, 0xF8, 0x07, 0x03},
+ // C=CN, O=CNNIC, CN=CNNIC ROOT
+ {0xE2, 0x83, 0x93, 0x77, 0x3D, 0xA8, 0x45, 0xA6, 0x79, 0xF2, 0x08, 0x0C,
+ 0xC7, 0xFB, 0x44, 0xA3, 0xB7, 0xA1, 0xC3, 0x79, 0x2C, 0xB7, 0xEB, 0x77,
+ 0x29, 0xFD, 0xCB, 0x6A, 0x8D, 0x99, 0xAE, 0xA7},
+ // C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 1999 VeriSign,
+ // Inc. - For authorized use only, CN=VeriSign Class 4 Public Primary
+ // Certification Authority - G3
+ {0xE3, 0x89, 0x36, 0x0D, 0x0F, 0xDB, 0xAE, 0xB3, 0xD2, 0x50, 0x58, 0x4B,
+ 0x47, 0x30, 0x31, 0x4E, 0x22, 0x2F, 0x39, 0xC1, 0x56, 0xA0, 0x20, 0x14,
+ 0x4E, 0x8D, 0x96, 0x05, 0x61, 0x79, 0x15, 0x06},
+ // C=FR, O=Dhimyotis, CN=Certigna
+ {0xE3, 0xB6, 0xA2, 0xDB, 0x2E, 0xD7, 0xCE, 0x48, 0x84, 0x2F, 0x7A, 0xC5,
+ 0x32, 0x41, 0xC7, 0xB7, 0x1D, 0x54, 0x14, 0x4B, 0xFB, 0x40, 0xC1, 0x1F,
+ 0x3F, 0x1D, 0x0B, 0x42, 0xF5, 0xEE, 0xA1, 0x2D},
+ // C=TR, L=Gebze - Kocaeli, O=T\xC3\xBCrkiye Bilimsel ve Teknolojik
+ // Ara\xC5\x9Ft\xC4\xB1rma Kurumu - T\xC3\x9CB\xC4\xB0TAK, OU=Ulusal
+ // Elektronik ve Kriptoloji Ara\xC5\x9Ft\xC4\xB1rma Enstit\xC3\xBCs\xC3\xBC
+ // - UEKAE, OU=Kamu Sertifikasyon Merkezi, CN=T\xC3\x9CB\xC4\xB0TAK UEKAE
+ // K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1 -
+ // S\xC3\xBCr\xC3\xBCm 3
+ {0xE4, 0xC7, 0x34, 0x30, 0xD7, 0xA5, 0xB5, 0x09, 0x25, 0xDF, 0x43, 0x37,
+ 0x0A, 0x0D, 0x21, 0x6E, 0x9A, 0x79, 0xB9, 0xD6, 0xDB, 0x83, 0x73, 0xA0,
+ 0xC6, 0x9E, 0xB1, 0xCC, 0x31, 0xC7, 0xC5, 0x2A},
+ // C=us, ST=Utah, L=Salt Lake City, O=Digital Signature Trust Co., OU=DSTCA
+ // X2, CN=DST RootCA X2/emailAddress=ca@digsigtrust.com
+ {0xE5, 0x72, 0x10, 0xAB, 0x81, 0x2C, 0x8D, 0xF3, 0x08, 0x26, 0x7C, 0xB4,
+ 0x29, 0x1B, 0x98, 0xE9, 0x56, 0x59, 0x7C, 0xA3, 0x6E, 0xC2, 0xB9, 0x51,
+ 0x89, 0xEF, 0x17, 0x23, 0x39, 0x6B, 0xCA, 0xC8},
+ // C=BR, O=Serasa S.A., OU=Serasa CA III, CN=Serasa Certificate Authority
+ // III
+ {0xE5, 0xBD, 0xA8, 0x20, 0xE5, 0xCE, 0x15, 0xBF, 0xD0, 0x7B, 0xA1, 0x1F,
+ 0xFB, 0x1C, 0x7C, 0x8A, 0x59, 0x10, 0xCE, 0x1B, 0x90, 0x17, 0x5C, 0x34,
+ 0x30, 0x8B, 0xC2, 0x50, 0x04, 0x53, 0xCC, 0xDC},
+ // C=KR, O=Government of Korea, OU=GPKI, CN=Root CA
+ {0xE5, 0xC0, 0x1C, 0xB4, 0x09, 0x32, 0x79, 0xFA, 0xA1, 0x9F, 0xCF, 0xA2,
+ 0x4E, 0xA4, 0x3E, 0xB1, 0xB2, 0x6D, 0x07, 0xA6, 0x15, 0xAD, 0xF7, 0x24,
+ 0x01, 0x84, 0xA1, 0xE7, 0x16, 0xB7, 0x61, 0xC9},
+ // C=TR, O=Elektronik Bilgi Guvenligi A.S., CN=e-Guven Kok Elektronik
+ // Sertifika Hizmet Saglayicisi
+ {0xE6, 0x09, 0x07, 0x84, 0x65, 0xA4, 0x19, 0x78, 0x0C, 0xB6, 0xAC, 0x4C,
+ 0x1C, 0x0B, 0xFB, 0x46, 0x53, 0xD9, 0xD9, 0xCC, 0x6E, 0xB3, 0x94, 0x6E,
+ 0xB7, 0xF3, 0xD6, 0x99, 0x97, 0xBA, 0xD5, 0x98},
+ // C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Class 2 CA, CN=TC
+ // TrustCenter Class 2 CA II
+ {0xE6, 0xB8, 0xF8, 0x76, 0x64, 0x85, 0xF8, 0x07, 0xAE, 0x7F, 0x8D, 0xAC,
+ 0x16, 0x70, 0x46, 0x1F, 0x07, 0xC0, 0xA1, 0x3E, 0xEF, 0x3A, 0x1F, 0xF7,
+ 0x17, 0x53, 0x8D, 0x7A, 0xBA, 0xD3, 0x91, 0xB4},
+ // C=LT, O=Skaitmeninio sertifikavimo centras, OU=Certification Authority,
+ // CN=SSC Root CA C
+ {0xE6, 0xE4, 0xA9, 0x51, 0xEC, 0xBF, 0x7D, 0x8E, 0xDC, 0x01, 0xBC, 0x87,
+ 0x3F, 0x7B, 0x6F, 0xD3, 0x58, 0x68, 0xBD, 0xB1, 0x0E, 0xD7, 0x86, 0xF3,
+ 0xA1, 0xB1, 0xEE, 0x16, 0xD8, 0xCE, 0xC3, 0xE9},
+ // C=JP, O=SECOM Trust.net, OU=Security Communication RootCA1
+ {0xE7, 0x5E, 0x72, 0xED, 0x9F, 0x56, 0x0E, 0xEC, 0x6E, 0xB4, 0x80, 0x00,
+ 0x73, 0xA4, 0x3F, 0xC3, 0xAD, 0x19, 0x19, 0x5A, 0x39, 0x22, 0x82, 0x01,
+ 0x78, 0x95, 0x97, 0x4A, 0x99, 0x02, 0x6B, 0x6C},
+ // C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ {0xE7, 0x68, 0x56, 0x34, 0xEF, 0xAC, 0xF6, 0x9A, 0xCE, 0x93, 0x9A, 0x6B,
+ 0x25, 0x5B, 0x7B, 0x4F, 0xAB, 0xEF, 0x42, 0x93, 0x5B, 0x50, 0xA2, 0x65,
+ 0xAC, 0xB5, 0xCB, 0x60, 0x27, 0xE4, 0x4E, 0x70},
+ // C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust
+ // RSA Certification Authority
+ {0xE7, 0x93, 0xC9, 0xB0, 0x2F, 0xD8, 0xAA, 0x13, 0xE2, 0x1C, 0x31, 0x22,
+ 0x8A, 0xCC, 0xB0, 0x81, 0x19, 0x64, 0x3B, 0x74, 0x9C, 0x89, 0x89, 0x64,
+ 0xB1, 0x74, 0x6D, 0x46, 0xC3, 0xD4, 0xCB, 0xD2},
+ // C=us, ST=Utah, L=Salt Lake City, O=Digital Signature Trust Co., OU=United
+ // Parcel Service, CN=DST (UPS) RootCA/emailAddress=ca@digsigtrust.com
+ {0xE8, 0x73, 0xD4, 0x08, 0x2A, 0x7B, 0x46, 0x32, 0x93, 0x4F, 0x48, 0xA5,
+ 0xCC, 0x1E, 0xE5, 0x00, 0x93, 0x2F, 0x66, 0x1E, 0x56, 0xC3, 0x46, 0x7C,
+ 0x5C, 0x84, 0xD3, 0x14, 0x47, 0x47, 0x6B, 0x0C},
+ // C=AT, O=A-Trust Ges. f\xFCr Sicherheitssysteme im elektr. Datenverkehr
+ // GmbH, OU=A-Trust-Qual-01, CN=A-Trust-Qual-01
+ {0xE8, 0xA2, 0xF4, 0x41, 0x65, 0x76, 0x78, 0x97, 0x5F, 0x2B, 0x97, 0xD7,
+ 0x75, 0x71, 0x9C, 0x7D, 0x49, 0xD9, 0x22, 0x34, 0x55, 0x45, 0x40, 0xEC,
+ 0x14, 0xD9, 0x2E, 0x16, 0xFE, 0x27, 0xD2, 0xCB},
+ // C=BR, O=Certisign Certificadora Digital Ltda., OU=Certisign - Autoridade
+ // Certificadora - AC2
+ {0xE8, 0xB2, 0x8D, 0x2A, 0x3D, 0x81, 0xF6, 0x3B, 0x4E, 0x44, 0x67, 0xC2,
+ 0x19, 0x0A, 0x63, 0x1F, 0xC0, 0x62, 0x35, 0x3B, 0x5F, 0x2D, 0x25, 0x85,
+ 0x1D, 0xDA, 0x6B, 0x64, 0x4A, 0xC7, 0x8B, 0x3F},
+ // C=DE, O=D-Trust GmbH, CN=D-TRUST Qualified Root CA 1 2007:PN
+ {0xE8, 0xC6, 0xAA, 0x6B, 0x5F, 0x58, 0xA8, 0xF2, 0xA6, 0x36, 0x5C, 0xF9,
+ 0x8E, 0x65, 0x69, 0x35, 0x63, 0xA3, 0x8B, 0x7B, 0x2F, 0x32, 0xCF, 0x1B,
+ 0xE0, 0x6F, 0x2D, 0x22, 0x29, 0xD4, 0xBF, 0x59},
+ // C=BG, O=InfoNotary PLC, DC=root-ca, CN=InfoNotary CSP Root, OU=InfoNotary
+ // CSP Root/emailAddress=csp@infonotary.com
+ {0xEA, 0x7E, 0x31, 0x2E, 0xCE, 0x48, 0x7B, 0x4C, 0x0A, 0xA6, 0x3C, 0xC8,
+ 0x0A, 0xB9, 0xFC, 0xB3, 0x3C, 0x72, 0x05, 0x73, 0xF8, 0x94, 0x5F, 0x77,
+ 0x61, 0x74, 0x5F, 0xC6, 0x38, 0x63, 0xD3, 0x9D},
+ // C=RO, O=certSIGN, OU=certSIGN ROOT CA
+ {0xEA, 0xA9, 0x62, 0xC4, 0xFA, 0x4A, 0x6B, 0xAF, 0xEB, 0xE4, 0x15, 0x19,
+ 0x6D, 0x35, 0x1C, 0xCD, 0x88, 0x8D, 0x4F, 0x53, 0xF3, 0xFA, 0x8A, 0xE6,
+ 0xD7, 0xC4, 0x66, 0xA9, 0x4E, 0x60, 0x42, 0xBB},
+ // C=CH, O=admin, OU=Services, OU=Certification Authorities,
+ // CN=AdminCA-CD-T01
+ {0xEA, 0xC0, 0x22, 0x0C, 0x5C, 0x9F, 0xEC, 0xC5, 0x12, 0x1D, 0x37, 0x20,
+ 0x87, 0x2D, 0x06, 0x70, 0x7B, 0x52, 0x66, 0xBE, 0x25, 0xD4, 0xEB, 0xB5,
+ 0x6A, 0xB8, 0x04, 0xBB, 0xBF, 0x85, 0xFE, 0x03},
+ // C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 1999 VeriSign,
+ // Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary
+ // Certification Authority - G3
+ {0xEB, 0x04, 0xCF, 0x5E, 0xB1, 0xF3, 0x9A, 0xFA, 0x76, 0x2F, 0x2B, 0xB1,
+ 0x20, 0xF2, 0x96, 0xCB, 0xA5, 0x20, 0xC1, 0xB9, 0x7D, 0xB1, 0x58, 0x95,
+ 0x65, 0xB8, 0x1C, 0xB9, 0xA1, 0x7B, 0x72, 0x44},
+ // C=HU, L=Budapest, O=NetLock Kft.,
+ // OU=Tan\xC3\xBAs\xC3\xADtv\xC3\xA1nykiad\xC3\xB3k (Certification
+ // Services), CN=NetLock Platina (Class Platinum)
+ // F\xC5\x91tan\xC3\xBAs\xC3\xADtv\xC3\xA1ny
+ {0xEB, 0x7E, 0x05, 0xAA, 0x58, 0xE7, 0xBD, 0x32, 0x8A, 0x28, 0x2B, 0xF8,
+ 0x86, 0x70, 0x33, 0xF3, 0xC0, 0x35, 0x34, 0x2B, 0x51, 0x6E, 0xE8, 0x5C,
+ 0x01, 0x67, 0x3D, 0xFF, 0xFF, 0xBB, 0xFE, 0x58},
+ // C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
+ {0xEB, 0xD4, 0x10, 0x40, 0xE4, 0xBB, 0x3E, 0xC7, 0x42, 0xC9, 0xE3, 0x81,
+ 0xD3, 0x1E, 0xF2, 0xA4, 0x1A, 0x48, 0xB6, 0x68, 0x5C, 0x96, 0xE7, 0xCE,
+ 0xF3, 0xC1, 0xDF, 0x6C, 0xD4, 0x33, 0x1C, 0x99},
+ // C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Universal CA, CN=TC
+ // TrustCenter Universal CA I
+ {0xEB, 0xF3, 0xC0, 0x2A, 0x87, 0x89, 0xB1, 0xFB, 0x7D, 0x51, 0x19, 0x95,
+ 0xD6, 0x63, 0xB7, 0x29, 0x06, 0xD9, 0x13, 0xCE, 0x0D, 0x5E, 0x10, 0x56,
+ 0x8A, 0x8A, 0x77, 0xE2, 0x58, 0x61, 0x67, 0xE7},
+ // emailAddress=pki@sk.ee, C=EE, O=AS Sertifitseerimiskeskus, CN=Juur-SK
+ {0xEC, 0xC3, 0xE9, 0xC3, 0x40, 0x75, 0x03, 0xBE, 0xE0, 0x91, 0xAA, 0x95,
+ 0x2F, 0x41, 0x34, 0x8F, 0xF8, 0x8B, 0xAA, 0x86, 0x3B, 0x22, 0x64, 0xBE,
+ 0xFA, 0xC8, 0x07, 0x90, 0x15, 0x74, 0xE9, 0x39},
+ // C=NO, O=Buypass AS-983163327, CN=Buypass Class 3 Root CA
+ {0xED, 0xF7, 0xEB, 0xBC, 0xA2, 0x7A, 0x2A, 0x38, 0x4D, 0x38, 0x7B, 0x7D,
+ 0x40, 0x10, 0xC6, 0x66, 0xE2, 0xED, 0xB4, 0x84, 0x3E, 0x4C, 0x29, 0xB4,
+ 0xAE, 0x1D, 0x5B, 0x93, 0x32, 0xE6, 0xB2, 0x4D},
+ // C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 3 CA 2 EV 2009
+ {0xEE, 0xC5, 0x49, 0x6B, 0x98, 0x8C, 0xE9, 0x86, 0x25, 0xB9, 0x34, 0x09,
+ 0x2E, 0xEC, 0x29, 0x08, 0xBE, 0xD0, 0xB0, 0xF3, 0x16, 0xC2, 0xD4, 0x73,
+ 0x0C, 0x84, 0xEA, 0xF1, 0xF3, 0xD3, 0x48, 0x81},
+ // C=ES, ST=Madrid, L=Madrid, O=IPS Certification Authority s.l. ipsCA,
+ // OU=ipsCA, CN=ipsCA Main CA Root/emailAddress=main01@ipsca.com
+ {0xEE, 0xFC, 0xA8, 0x88, 0xDB, 0x44, 0x2C, 0xEA, 0x1F, 0x03, 0xFA, 0xC5,
+ 0xDE, 0x5B, 0x1A, 0xF2, 0x10, 0xAE, 0x03, 0xF5, 0xE1, 0x65, 0x8D, 0xDB,
+ 0x88, 0x0C, 0x64, 0x5E, 0x78, 0x62, 0x45, 0x46},
+ // C=EU, O=AC Camerfirma SA CIF A82743287, OU=http://www.chambersign.org,
+ // CN=Global Chambersign Root
+ {0xEF, 0x3C, 0xB4, 0x17, 0xFC, 0x8E, 0xBF, 0x6F, 0x97, 0x87, 0x6C, 0x9E,
+ 0x4E, 0xCE, 0x39, 0xDE, 0x1E, 0xA5, 0xFE, 0x64, 0x91, 0x41, 0xD1, 0x02,
+ 0x8B, 0x7D, 0x11, 0xC0, 0xB2, 0x29, 0x8C, 0xED},
+ // C=BE, O=Certipost s.a./n.v., CN=Certipost E-Trust Primary Normalised CA
+ {0xF0, 0x03, 0x55, 0xEE, 0xF1, 0x01, 0xC7, 0xDF, 0x4E, 0x46, 0xCC, 0xE6,
+ 0x41, 0x7D, 0xFF, 0xCE, 0x3D, 0xB8, 0x2D, 0xBB, 0x13, 0x69, 0xC3, 0xB4,
+ 0x39, 0xC4, 0xE3, 0x3B, 0xEE, 0x44, 0x5C, 0x42},
+ // C=FI, ST=Finland, O=Vaestorekisterikeskus CA, OU=Certification Authority
+ // Services, OU=Varmennepalvelut, CN=VRK Gov. Root CA
+ {0xF0, 0x08, 0x73, 0x3E, 0xC5, 0x00, 0xDC, 0x49, 0x87, 0x63, 0xCC, 0x92,
+ 0x64, 0xC6, 0xFC, 0xEA, 0x40, 0xEC, 0x22, 0x00, 0x0E, 0x92, 0x7D, 0x05,
+ 0x3C, 0xE9, 0xC9, 0x0B, 0xFA, 0x04, 0x6C, 0xB2},
+ // C=ch, O=Swisscom, OU=Digital Certificate Services, CN=Swisscom Root CA 2
+ {0xF0, 0x9B, 0x12, 0x2C, 0x71, 0x14, 0xF4, 0xA0, 0x9B, 0xD4, 0xEA, 0x4F,
+ 0x4A, 0x99, 0xD5, 0x58, 0xB4, 0x6E, 0x4C, 0x25, 0xCD, 0x81, 0x14, 0x0D,
+ 0x29, 0xC0, 0x56, 0x13, 0x91, 0x4C, 0x38, 0x41},
+ // C=LT, O=Skaitmeninio sertifikavimo centras, OU=Certification Authority,
+ // CN=SSC Root CA A
+ {0xF1, 0xB1, 0x3F, 0x5C, 0x9A, 0x32, 0x64, 0x03, 0xB0, 0xF3, 0x1B, 0xBE,
+ 0x76, 0x99, 0xCD, 0x17, 0xC7, 0xD1, 0xC0, 0xB9, 0x81, 0x58, 0x6D, 0xD1,
+ 0xA7, 0xB2, 0x19, 0xC5, 0x25, 0x08, 0xFE, 0x99},
+ // C=US, O=SecureTrust Corporation, CN=SecureTrust CA
+ {0xF1, 0xC1, 0xB5, 0x0A, 0xE5, 0xA2, 0x0D, 0xD8, 0x03, 0x0E, 0xC9, 0xF6,
+ 0xBC, 0x24, 0x82, 0x3D, 0xD3, 0x67, 0xB5, 0x25, 0x57, 0x59, 0xB4, 0xE7,
+ 0x1B, 0x61, 0xFC, 0xE9, 0xF7, 0x37, 0x5D, 0x73},
+ // C=ES, ST=BARCELONA, L=BARCELONA, O=IPS Seguridad CA, OU=Certificaciones,
+ // CN=IPS SERVIDORES/emailAddress=ips@mail.ips.es
+ {0xF1, 0xF3, 0xCC, 0x20, 0x7A, 0x6D, 0x47, 0x94, 0x7B, 0x8C, 0xB9, 0xC3,
+ 0x04, 0x22, 0x22, 0x9D, 0xE0, 0xD7, 0x1F, 0xB8, 0x67, 0xE0, 0xB9, 0xA3,
+ 0xED, 0xA0, 0x8E, 0x0E, 0x17, 0x36, 0xBC, 0x28},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-Qual-02, CN=A-Trust-Qual-02
+ {0xF2, 0x86, 0x30, 0xBA, 0xBF, 0x25, 0x6E, 0x56, 0x7B, 0x58, 0x21, 0x06,
+ 0x9F, 0xCF, 0x13, 0x14, 0x8A, 0xB9, 0xA2, 0x3E, 0x28, 0xFC, 0x0D, 0x70,
+ 0x61, 0x5A, 0xAE, 0x6E, 0xD2, 0x84, 0xF4, 0xC8},
+ // CN=Atos TrustedRoot 2011, O=Atos, C=DE
+ {0xF3, 0x56, 0xBE, 0xA2, 0x44, 0xB7, 0xA9, 0x1E, 0xB3, 0x5D, 0x53, 0xCA,
+ 0x9A, 0xD7, 0x86, 0x4A, 0xCE, 0x01, 0x8E, 0x2D, 0x35, 0xD5, 0xF8, 0xF9,
+ 0x6D, 0xDF, 0x68, 0xA6, 0xF4, 0x1A, 0xA4, 0x74},
+ // C=IN, O=India PKI, CN=CCA India 2007
+ {0xF3, 0x75, 0xE2, 0xF7, 0x7A, 0x10, 0x8B, 0xAC, 0xC4, 0x23, 0x48, 0x94,
+ 0xA9, 0xAF, 0x30, 0x8E, 0xDE, 0xCA, 0x1A, 0xCD, 0x8F, 0xBD, 0xE0, 0xE7,
+ 0xAA, 0xA9, 0x63, 0x4E, 0x9D, 0xAF, 0x7E, 0x1C},
+ // OU=Copyright (c) 1997 Microsoft Corp., OU=Microsoft Corporation,
+ // CN=Microsoft Root Authority
+ {0xF3, 0x84, 0x06, 0xE5, 0x40, 0xD7, 0xA9, 0xD9, 0x0C, 0xB4, 0xA9, 0x47,
+ 0x92, 0x99, 0x64, 0x0F, 0xFB, 0x6D, 0xF9, 0xE2, 0x24, 0xEC, 0xC7, 0xA0,
+ 0x1C, 0x0D, 0x95, 0x58, 0xD8, 0xDA, 0xD7, 0x7D},
+ // C=ES, O=Agencia Notarial de Certificacion S.L.U. - CIF B83395988,
+ // CN=ANCERT Certificados CGN V2
+ {0xF4, 0x33, 0x6B, 0xC2, 0xAC, 0x75, 0x95, 0x0B, 0xEC, 0xCF, 0x1C, 0x1F,
+ 0x2F, 0x9D, 0xA6, 0xDD, 0xDA, 0xFD, 0x1F, 0x41, 0x16, 0x1C, 0xA7, 0x1F,
+ 0x59, 0xC7, 0x68, 0x89, 0xBD, 0x47, 0x40, 0x33},
+ // L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 1
+ // Policy Validation Authority,
+ // CN=http://www.valicert.com//emailAddress=info@valicert.com
+ {0xF4, 0xC1, 0x49, 0x55, 0x1A, 0x30, 0x13, 0xA3, 0x5B, 0xC7, 0xBF, 0xFE,
+ 0x17, 0xA7, 0xF3, 0x44, 0x9B, 0xC1, 0xAB, 0x5B, 0x5A, 0x0A, 0xE7, 0x4B,
+ 0x06, 0xC2, 0x3B, 0x90, 0x00, 0x4C, 0x01, 0x04},
+ // C=IT, O=SIA S.p.A., L=Milano, CN=SIA Secure Server CA
+ {0xF5, 0x63, 0xC5, 0xC3, 0xE5, 0x12, 0xE6, 0x3B, 0x97, 0xB5, 0x43, 0x8F,
+ 0x2B, 0xD4, 0xA9, 0xAE, 0x78, 0xA4, 0xF9, 0xEA, 0xD9, 0x2B, 0xCC, 0x34,
+ 0xFE, 0x97, 0x3B, 0xDC, 0x7C, 0x6D, 0x21, 0x48},
+ // C=SE, O=Swedish Social Insurance Agency, CN=Swedish Government Root
+ // Authority v1
+ {0xF6, 0x57, 0xA6, 0x33, 0xEE, 0xB9, 0xBC, 0x5D, 0x15, 0xA4, 0x61, 0x75,
+ 0x17, 0x49, 0xEA, 0x4B, 0x31, 0x67, 0x27, 0xDC, 0xF1, 0xA9, 0xF9, 0x86,
+ 0xB5, 0x45, 0x84, 0x45, 0xF6, 0x48, 0x5D, 0xDE},
+ // C=UY, O=ADMINISTRACION NACIONAL DE CORREOS, OU=SERVICIOS ELECTRONICOS,
+ // CN=SERVICIOS DE CERTIFICACION - A.N.C./mail=correo_cert@correo.com.uy
+ {0xF7, 0x73, 0xBC, 0x65, 0x65, 0x9F, 0x1B, 0xC5, 0x90, 0x87, 0xBF, 0x21,
+ 0x4E, 0xEA, 0xD8, 0x64, 0x01, 0x0D, 0x58, 0x87, 0xCD, 0x2C, 0xD8, 0x4E,
+ 0x4F, 0x1B, 0xA7, 0x52, 0x3F, 0xE5, 0x56, 0x40},
+ // C=SK, L=Bratislava, O=Disig a.s., CN=CA Disig Root R1
+ {0xF9, 0x6F, 0x23, 0xF4, 0xC3, 0xE7, 0x9C, 0x07, 0x7A, 0x46, 0x98, 0x8D,
+ 0x5A, 0xF5, 0x90, 0x06, 0x76, 0xA0, 0xF0, 0x39, 0xCB, 0x64, 0x5D, 0xD1,
+ 0x75, 0x49, 0xB2, 0x16, 0xC8, 0x24, 0x40, 0xCE},
+ // C=HK, O=Hongkong Post, CN=Hongkong Post Root CA 1
+ {0xF9, 0xE6, 0x7D, 0x33, 0x6C, 0x51, 0x00, 0x2A, 0xC0, 0x54, 0xC6, 0x32,
+ 0x02, 0x2D, 0x66, 0xDD, 0xA2, 0xE7, 0xE3, 0xFF, 0xF1, 0x0A, 0xD0, 0x61,
+ 0xED, 0x31, 0xD8, 0xBB, 0xB4, 0x10, 0xCF, 0xB2},
+ // C=PL, O=Krajowa Izba Rozliczeniowa S.A., CN=SZAFIR ROOT CA
+ {0xFA, 0xBC, 0xF5, 0x19, 0x7C, 0xDD, 0x7F, 0x45, 0x8A, 0xC3, 0x38, 0x32,
+ 0xD3, 0x28, 0x40, 0x21, 0xDB, 0x24, 0x25, 0xFD, 0x6B, 0xEA, 0x7A, 0x2E,
+ 0x69, 0xB7, 0x48, 0x6E, 0x8F, 0x51, 0xF9, 0xCC},
+ // C=BR, O=ICP-Brasil, OU=Instituto Nacional de Tecnologia da Informacao -
+ // ITI, CN=Autoridade Certificadora Raiz Brasileira v2
+ {0xFB, 0x47, 0xD9, 0x2A, 0x99, 0x09, 0xFD, 0x4F, 0xA9, 0xBE, 0xC0, 0x27,
+ 0x37, 0x54, 0x3E, 0x1F, 0x35, 0x14, 0xCE, 0xD7, 0x47, 0x40, 0x7A, 0x8D,
+ 0x9C, 0xFA, 0x39, 0x7B, 0x09, 0x15, 0x06, 0x7C},
+ // C=IT, O=SIA S.p.A., L=Milano, CN=SIA Secure Client CA
+ {0xFC, 0x0A, 0x0F, 0xE2, 0x7C, 0x9D, 0xC1, 0x3C, 0x81, 0x23, 0x8A, 0x59,
+ 0x13, 0xA1, 0xDA, 0xF8, 0x18, 0x41, 0x68, 0xBE, 0xB7, 0xE5, 0xA4, 0x51,
+ 0x2A, 0x77, 0x1F, 0xD4, 0xF4, 0x53, 0x65, 0x1D},
+ // C=SE, O=Inera AB, CN=SITHS Root CA v1
+ {0xFC, 0x50, 0xB2, 0x6B, 0xDC, 0x4A, 0x8F, 0xDF, 0x13, 0x44, 0xCC, 0x80,
+ 0x15, 0x7A, 0xE1, 0x3A, 0xC6, 0x71, 0xE2, 0x70, 0x6F, 0xAC, 0xFC, 0x06,
+ 0x05, 0xFE, 0x34, 0xE2, 0x49, 0xEB, 0x72, 0xD6},
+ // C=FR, O=Certinomis, OU=0002 433998903, CN=Certinomis - Autorit\xC3\xA9
+ // Racine
+ {0xFC, 0xBF, 0xE2, 0x88, 0x62, 0x06, 0xF7, 0x2B, 0x27, 0x59, 0x3C, 0x8B,
+ 0x07, 0x02, 0x97, 0xE1, 0x2D, 0x76, 0x9E, 0xD1, 0x0E, 0xD7, 0x93, 0x07,
+ 0x05, 0xA8, 0x09, 0x8E, 0xFF, 0xC1, 0x4D, 0x17},
+ // C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center,
+ // CN=T-TeleSec GlobalRoot Class 3
+ {0xFD, 0x73, 0xDA, 0xD3, 0x1C, 0x64, 0x4F, 0xF1, 0xB4, 0x3B, 0xEF, 0x0C,
+ 0xCD, 0xDA, 0x96, 0x71, 0x0B, 0x9C, 0xD9, 0x87, 0x5E, 0xCA, 0x7E, 0x31,
+ 0x70, 0x7A, 0xF3, 0xE9, 0x6D, 0x52, 0x2B, 0xBD},
+ // C=SI, O=Halcom, CN=Halcom CA PO 2
+ {0xFE, 0x71, 0x14, 0xD0, 0x7A, 0x14, 0x77, 0x59, 0x89, 0x1F, 0xF3, 0x7B,
+ 0x4F, 0x53, 0xEB, 0x43, 0x56, 0x82, 0x96, 0xBC, 0x3B, 0xF8, 0x9B, 0xC1,
+ 0x2C, 0xAF, 0xB1, 0x86, 0x98, 0x5E, 0xF2, 0x8D},
+ // C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
+ {0xFF, 0x85, 0x6A, 0x2D, 0x25, 0x1D, 0xCD, 0x88, 0xD3, 0x66, 0x56, 0xF4,
+ 0x50, 0x12, 0x67, 0x98, 0xCF, 0xAB, 0xAA, 0xDE, 0x40, 0x79, 0x9C, 0x72,
+ 0x2D, 0xE4, 0xD2, 0xB5, 0xDB, 0x36, 0xA7, 0x3A},
+ // C=BR, O=Serasa S.A., OU=Serasa CA II, CN=Serasa Certificate Authority II
+ {0xFF, 0xCE, 0xF2, 0x22, 0x4E, 0x29, 0xB0, 0xB3, 0x6E, 0xC8, 0x31, 0x4E,
+ 0x68, 0x68, 0x22, 0xF3, 0xAC, 0x0F, 0x1C, 0x5E, 0x0C, 0x2D, 0x5C, 0x0E,
+ 0xB2, 0x48, 0x4C, 0xE7, 0xE2, 0x54, 0x0F, 0xD0},
};
#endif // NET_CERT_X509_CERTIFICATE_KNOWN_ROOTS_WIN_H_
diff --git a/chromium/net/cert/x509_certificate_mac.cc b/chromium/net/cert/x509_certificate_mac.cc
index 64457e4d7e1..e27576ab265 100644
--- a/chromium/net/cert/x509_certificate_mac.cc
+++ b/chromium/net/cert/x509_certificate_mac.cc
@@ -148,8 +148,8 @@ void AddCertificatesFromBytes(const char* data, size_t length,
X509Certificate::OSCertHandles* output) {
SecExternalFormat input_format = format;
ScopedCFTypeRef<CFDataRef> local_data(CFDataCreateWithBytesNoCopy(
- kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data), length,
- kCFAllocatorNull));
+ kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data),
+ base::checked_cast<CFIndex>(length), kCFAllocatorNull));
CFArrayRef items = NULL;
OSStatus status;
@@ -298,7 +298,8 @@ bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
- const char* data, int length) {
+ const char* data,
+ size_t length) {
CSSM_DATA cert_data;
cert_data.Data = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(data));
cert_data.Length = length;
@@ -319,7 +320,9 @@ X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
// static
X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
- const char* data, int length, Format format) {
+ const char* data,
+ size_t length,
+ Format format) {
OSCertHandles results;
switch (format) {
diff --git a/chromium/net/cert/x509_certificate_net_log_param.cc b/chromium/net/cert/x509_certificate_net_log_param.cc
index 72b1e919aa7..0a1bc8ed85b 100644
--- a/chromium/net/cert/x509_certificate_net_log_param.cc
+++ b/chromium/net/cert/x509_certificate_net_log_param.cc
@@ -5,6 +5,7 @@
#include "net/cert/x509_certificate_net_log_param.h"
#include <string>
+#include <utility>
#include <vector>
#include "base/values.h"
@@ -21,8 +22,8 @@ scoped_ptr<base::Value> NetLogX509CertificateCallback(
certificate->GetPEMEncodedChain(&encoded_chain);
for (size_t i = 0; i < encoded_chain.size(); ++i)
certs->Append(new base::StringValue(encoded_chain[i]));
- dict->Set("certificates", certs.Pass());
- return dict.Pass();
+ dict->Set("certificates", std::move(certs));
+ return std::move(dict);
}
} // namespace net
diff --git a/chromium/net/cert/x509_certificate_nss.cc b/chromium/net/cert/x509_certificate_nss.cc
index f8646cb0369..1c5359198bc 100644
--- a/chromium/net/cert/x509_certificate_nss.cc
+++ b/chromium/net/cert/x509_certificate_nss.cc
@@ -16,6 +16,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
@@ -41,7 +42,7 @@ void X509Certificate::Initialize() {
// static
X509Certificate* X509Certificate::CreateFromBytesWithNickname(
const char* data,
- int length,
+ size_t length,
const char* nickname) {
OSCertHandle cert_handle = CreateOSCertHandleFromBytesWithNickname(data,
length,
@@ -160,19 +161,16 @@ bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
- const char* data, int length) {
+ const char* data,
+ size_t length) {
return CreateOSCertHandleFromBytesWithNickname(data, length, NULL);
}
// static
X509Certificate::OSCertHandle
-X509Certificate::CreateOSCertHandleFromBytesWithNickname(
- const char* data,
- int length,
- const char* nickname) {
- if (length < 0)
- return NULL;
-
+X509Certificate::CreateOSCertHandleFromBytesWithNickname(const char* data,
+ size_t length,
+ const char* nickname) {
crypto::EnsureNSSInit();
if (!NSS_IsInitialized())
@@ -180,7 +178,7 @@ X509Certificate::CreateOSCertHandleFromBytesWithNickname(
SECItem der_cert;
der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
- der_cert.len = length;
+ der_cert.len = base::checked_cast<unsigned>(length);
der_cert.type = siDERCertBuffer;
// Parse into a certificate structure.
@@ -192,7 +190,7 @@ X509Certificate::CreateOSCertHandleFromBytesWithNickname(
// static
X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
const char* data,
- int length,
+ size_t length,
Format format) {
return x509_util::CreateOSCertHandlesFromBytes(data, length, format);
}
diff --git a/chromium/net/cert/x509_certificate_openssl.cc b/chromium/net/cert/x509_certificate_openssl.cc
index 6e803619db7..ec31e6e371b 100644
--- a/chromium/net/cert/x509_certificate_openssl.cc
+++ b/chromium/net/cert/x509_certificate_openssl.cc
@@ -13,7 +13,9 @@
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
+#include "base/macros.h"
#include "base/memory/singleton.h"
+#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
@@ -38,7 +40,8 @@ using ScopedGENERAL_NAMES =
crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>;
void CreateOSCertHandlesFromPKCS7Bytes(
- const char* data, int length,
+ const char* data,
+ size_t length,
X509Certificate::OSCertHandles* handles) {
crypto::EnsureOpenSSLInit();
crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE);
@@ -260,24 +263,23 @@ SHA1HashValue X509Certificate::CalculateCAFingerprint(
// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
- const char* data, int length) {
- if (length < 0)
- return NULL;
+ const char* data,
+ size_t length) {
crypto::EnsureOpenSSLInit();
const unsigned char* d2i_data =
reinterpret_cast<const unsigned char*>(data);
// Don't cache this data for x509_util::GetDER as this wire format
// may be not be identical from the i2d_X509 roundtrip.
- X509* cert = d2i_X509(NULL, &d2i_data, length);
+ X509* cert = d2i_X509(NULL, &d2i_data, base::checked_cast<long>(length));
return cert;
}
// static
X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
- const char* data, int length, Format format) {
+ const char* data,
+ size_t length,
+ Format format) {
OSCertHandles results;
- if (length < 0)
- return results;
switch (format) {
case FORMAT_SINGLE_CERTIFICATE: {
diff --git a/chromium/net/cert/x509_certificate_unittest.cc b/chromium/net/cert/x509_certificate_unittest.cc
index ec9342ac852..362f7ff0991 100644
--- a/chromium/net/cert/x509_certificate_unittest.cc
+++ b/chromium/net/cert/x509_certificate_unittest.cc
@@ -1175,7 +1175,7 @@ const struct PublicKeyInfoTestData {
// need to be renegerated with a larger key. See https://crbug.com/472291.
{"large_key.pem", 0, X509Certificate::kPublicKeyTypeUnknown},
#else
- {"large_key.pem", 4104, X509Certificate::kPublicKeyTypeRSA},
+ {"large_key.pem", 8200, X509Certificate::kPublicKeyTypeRSA},
#endif
};
diff --git a/chromium/net/cert/x509_certificate_win.cc b/chromium/net/cert/x509_certificate_win.cc
index 808a2847f9b..d2077821b8c 100644
--- a/chromium/net/cert/x509_certificate_win.cc
+++ b/chromium/net/cert/x509_certificate_win.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/sha1.h"
#include "base/strings/string_util.h"
@@ -94,7 +95,7 @@ void AddCertsFromStore(HCERTSTORE store,
X509Certificate::OSCertHandles ParsePKCS7(const char* data, size_t length) {
X509Certificate::OSCertHandles results;
CERT_BLOB data_blob;
- data_blob.cbData = length;
+ data_blob.cbData = base::checked_cast<DWORD>(length);
data_blob.pbData = reinterpret_cast<BYTE*>(const_cast<char*>(data));
HCERTSTORE out_store = NULL;
@@ -250,18 +251,25 @@ bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
- const char* data, int length) {
- OSCertHandle cert_handle = NULL;
+ const char* data,
+ size_t length) {
+ if (!base::IsValueInRangeForNumericType<DWORD>(length))
+ return nullptr;
+ OSCertHandle cert_handle = nullptr;
if (!CertAddEncodedCertificateToStore(
- NULL, X509_ASN_ENCODING, reinterpret_cast<const BYTE*>(data),
- length, CERT_STORE_ADD_USE_EXISTING, &cert_handle))
- return NULL;
+ NULL, X509_ASN_ENCODING, reinterpret_cast<const BYTE*>(data),
+ base::checked_cast<DWORD>(length), CERT_STORE_ADD_USE_EXISTING,
+ &cert_handle)) {
+ return nullptr;
+ }
return cert_handle;
}
X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
- const char* data, int length, Format format) {
+ const char* data,
+ size_t length,
+ Format format) {
OSCertHandles results;
switch (format) {
case FORMAT_SINGLE_CERTIFICATE: {
diff --git a/chromium/net/cert/x509_util.h b/chromium/net/cert/x509_util.h
index a1c29689468..fb8c20f080d 100644
--- a/chromium/net/cert/x509_util.h
+++ b/chromium/net/cert/x509_util.h
@@ -6,6 +6,7 @@
#define NET_CERT_X509_UTIL_H_
#include <stdint.h>
+
#include <string>
#include "base/memory/ref_counted.h"
@@ -30,14 +31,6 @@ enum DigestAlgorithm {
DIGEST_SHA256
};
-// Returns true if the times can be used to create an X.509 certificate.
-// Certificates can accept dates from Jan 1st, 1 to Dec 31, 9999. A bug in NSS
-// limited the range to 1950-9999
-// (https://bugzilla.mozilla.org/show_bug.cgi?id=786531). This function will
-// return whether it is supported by the currently used crypto library.
-NET_EXPORT_PRIVATE bool IsSupportedValidityRange(base::Time not_valid_before,
- base::Time not_valid_after);
-
// Creates a public-private keypair and a self-signed certificate.
// Subject, serial number and validity period are given as parameters.
// The certificate is signed by the private key in |key|. The key length and
diff --git a/chromium/net/cert/x509_util_android.cc b/chromium/net/cert/x509_util_android.cc
index 2a91f4a2792..ee47845f57e 100644
--- a/chromium/net/cert/x509_util_android.cc
+++ b/chromium/net/cert/x509_util_android.cc
@@ -5,7 +5,7 @@
#include "net/cert/x509_util_android.h"
#include "base/android/build_info.h"
-#include "base/android/jni_android.h"
+#include "base/android/context_utils.h"
#include "base/metrics/histogram_macros.h"
#include "jni/X509Util_jni.h"
#include "net/cert/cert_database.h"
@@ -27,16 +27,6 @@ void RecordCertVerifyCapabilitiesHistogram(JNIEnv* env,
}
}
-ScopedJavaLocalRef<jobject> GetApplicationContext(
- JNIEnv* env,
- const JavaParamRef<jclass>& clazz) {
- ScopedJavaLocalRef<jobject> r;
- // Must use Reset to force creation of a new local ref, instead of trying to
- // adopt the global-ref'ed jobject as a local ref as the constructor would.
- r.Reset(env, base::android::GetApplicationContext());
- return r;
-}
-
bool RegisterX509Util(JNIEnv* env) {
return RegisterNativesImpl(env);
}
diff --git a/chromium/net/cert/x509_util_nss.cc b/chromium/net/cert/x509_util_nss.cc
index fa6dc1c652a..2dbff2c76fc 100644
--- a/chromium/net/cert/x509_util_nss.cc
+++ b/chromium/net/cert/x509_util_nss.cc
@@ -180,19 +180,6 @@ bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
return true;
}
-bool IsSupportedValidityRange(base::Time not_valid_before,
- base::Time not_valid_after) {
- CERTValidity* validity = CERT_CreateValidity(
- crypto::BaseTimeToPRTime(not_valid_before),
- crypto::BaseTimeToPRTime(not_valid_after));
-
- if (!validity)
- return false;
-
- CERT_DestroyValidity(validity);
- return true;
-}
-
} // namespace x509_util
} // namespace net
diff --git a/chromium/net/cert/x509_util_nss.h b/chromium/net/cert/x509_util_nss.h
index bb9bed955cd..55e562effba 100644
--- a/chromium/net/cert/x509_util_nss.h
+++ b/chromium/net/cert/x509_util_nss.h
@@ -5,6 +5,8 @@
#ifndef NET_CERT_X509_UTIL_NSS_H_
#define NET_CERT_X509_UTIL_NSS_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
@@ -47,7 +49,7 @@ void GetSubjectAltName(CERTCertificate* cert_handle,
// |format|. Returns an empty collection on failure.
X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes(
const char* data,
- int length,
+ size_t length,
X509Certificate::Format format);
// Reads a single certificate from |pickle_iter| and returns a platform-specific
diff --git a/chromium/net/cert/x509_util_nss_certs.cc b/chromium/net/cert/x509_util_nss_certs.cc
index 78112b44f59..1ec360d31e6 100644
--- a/chromium/net/cert/x509_util_nss_certs.cc
+++ b/chromium/net/cert/x509_util_nss_certs.cc
@@ -16,6 +16,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
+#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/strings/stringprintf.h"
#include "crypto/ec_private_key.h"
@@ -201,11 +202,9 @@ void GetSubjectAltName(CERTCertificate* cert_handle,
X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes(
const char* data,
- int length,
+ size_t length,
X509Certificate::Format format) {
X509Certificate::OSCertHandles results;
- if (length < 0)
- return results;
crypto::EnsureNSSInit();
@@ -224,8 +223,9 @@ X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes(
// Make a copy since CERT_DecodeCertPackage may modify it
std::vector<char> data_copy(data, data + length);
- SECStatus result = CERT_DecodeCertPackage(&data_copy[0], length,
- CollectCertsCallback, &results);
+ SECStatus result = CERT_DecodeCertPackage(
+ data_copy.data(), base::checked_cast<int>(data_copy.size()),
+ CollectCertsCallback, &results);
if (result != SECSuccess)
results.clear();
break;
diff --git a/chromium/net/cert/x509_util_openssl.cc b/chromium/net/cert/x509_util_openssl.cc
index baf7d127613..c81a3a49b39 100644
--- a/chromium/net/cert/x509_util_openssl.cc
+++ b/chromium/net/cert/x509_util_openssl.cc
@@ -4,6 +4,7 @@
#include "net/cert/x509_util_openssl.h"
+#include <limits.h>
#include <openssl/asn1.h>
#include <openssl/mem.h>
@@ -11,6 +12,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "crypto/ec_private_key.h"
@@ -197,39 +199,6 @@ base::LazyInstance<DERCacheInitSingleton>::Leaky g_der_cache_singleton =
} // namespace
-bool IsSupportedValidityRange(base::Time not_valid_before,
- base::Time not_valid_after) {
- if (not_valid_before > not_valid_after)
- return false;
-
- // The validity field of a certificate can only encode years 1-9999.
-
- // Compute the base::Time values corresponding to Jan 1st,0001 and
- // Jan 1st, 10000 respectively. Done by using the pre-computed numbers
- // of days between these dates and the Unix epoch, i.e. Jan 1st, 1970,
- // using the following Python script:
- //
- // from datetime import date as D
- // print (D(1970,1,1)-D(1,1,1)) # -> 719162 days
- // print (D(9999,12,31)-D(1970,1,1)) # -> 2932896 days
- //
- // Note: This ignores leap seconds, but should be enough in practice.
- //
- const int64_t kDaysFromYear0001ToUnixEpoch = 719162;
- const int64_t kDaysFromUnixEpochToYear10000 = 2932896 + 1;
- const base::Time kEpoch = base::Time::UnixEpoch();
- const base::Time kYear0001 = kEpoch -
- base::TimeDelta::FromDays(kDaysFromYear0001ToUnixEpoch);
- const base::Time kYear10000 = kEpoch +
- base::TimeDelta::FromDays(kDaysFromUnixEpochToYear10000);
-
- if (not_valid_before < kYear0001 || not_valid_before >= kYear10000 ||
- not_valid_after < kYear0001 || not_valid_after >= kYear10000)
- return false;
-
- return true;
-}
-
bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
DigestAlgorithm alg,
const std::string& common_name,
diff --git a/chromium/net/cert/x509_util_openssl_unittest.cc b/chromium/net/cert/x509_util_openssl_unittest.cc
deleted file mode 100644
index 9eebff8a32e..00000000000
--- a/chromium/net/cert/x509_util_openssl_unittest.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/memory/scoped_ptr.h"
-#include "crypto/ec_private_key.h"
-#include "crypto/openssl_util.h"
-#include "crypto/scoped_openssl_types.h"
-#include "net/cert/x509_util.h"
-#include "net/cert/x509_util_openssl.h"
-#include "net/ssl/scoped_openssl_types.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-
-TEST(X509UtilOpenSSLTest, IsSupportedValidityRange) {
- base::Time now = base::Time::Now();
- EXPECT_TRUE(x509_util::IsSupportedValidityRange(now, now));
- EXPECT_FALSE(x509_util::IsSupportedValidityRange(
- now, now - base::TimeDelta::FromSeconds(1)));
-
- // See x509_util_openssl.cc to see how these were computed.
- const int64_t kDaysFromYear0001ToUnixEpoch = 719162;
- const int64_t kDaysFromUnixEpochToYear10000 = 2932896 + 1;
-
- // When computing too_old / too_late, add one day to account for
- // possible leap seconds.
- base::Time too_old = base::Time::UnixEpoch() -
- base::TimeDelta::FromDays(kDaysFromYear0001ToUnixEpoch + 1);
-
- base::Time too_late = base::Time::UnixEpoch() +
- base::TimeDelta::FromDays(kDaysFromUnixEpochToYear10000 + 1);
-
- EXPECT_FALSE(x509_util::IsSupportedValidityRange(too_old, too_old));
- EXPECT_FALSE(x509_util::IsSupportedValidityRange(too_old, now));
-
- EXPECT_FALSE(x509_util::IsSupportedValidityRange(now, too_late));
- EXPECT_FALSE(x509_util::IsSupportedValidityRange(too_late, too_late));
-}
-
-} // namespace net