Bring in the core of  chromium certificate verifier as libpki

Initially this leaves the canonical source in chrome, Additions
and fillins are committed directly, the chrome files are coverted
using the IMPORT script run from the pki directory for the moment.

The intention here is to continue frequent automatic conversion
(and avoid wholesale cosmetic changes in here for now) until
chrome converts to use these files in place of it's versions.
At that point these will become the definiative files, and the
IMPORT script can be tossed out.

A middle step along the way will be to change google3's verify.cc
in third_party/chromium_certificate_verifier to use this instead
of it's own extracted copy.

Status (and what is not done yet) being roughly tracked in README.md

Bug: chromium:1322914

Change-Id: Ibdb5479bc68985fa61ce6b10f98f31f6b3a7cbdf
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60285
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/pki/signature_algorithm.cc b/pki/signature_algorithm.cc
new file mode 100644
index 0000000..e66ef12
--- /dev/null
+++ b/pki/signature_algorithm.cc
@@ -0,0 +1,420 @@
+// Copyright 2015 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "signature_algorithm.h"
+
+#include "input.h"
+#include "parse_values.h"
+#include "parser.h"
+#include <openssl/bytestring.h>
+#include <openssl/digest.h>
+
+namespace bssl {
+
+namespace {
+
+// From RFC 5912:
+//
+//     sha1WithRSAEncryption OBJECT IDENTIFIER ::= {
+//      iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+//      pkcs-1(1) 5 }
+//
+// In dotted notation: 1.2.840.113549.1.1.5
+const uint8_t kOidSha1WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
+                                             0x0d, 0x01, 0x01, 0x05};
+
+// sha1WithRSASignature is a deprecated equivalent of
+// sha1WithRSAEncryption.
+//
+// It originates from the NIST Open Systems Environment (OSE)
+// Implementor's Workshop (OIW).
+//
+// It is supported for compatibility with Microsoft's certificate APIs and
+// tools, particularly makecert.exe, which default(ed/s) to this OID for SHA-1.
+//
+// See also: https://bugzilla.mozilla.org/show_bug.cgi?id=1042479
+//
+// In dotted notation: 1.3.14.3.2.29
+const uint8_t kOidSha1WithRsaSignature[] = {0x2b, 0x0e, 0x03, 0x02, 0x1d};
+
+// From RFC 5912:
+//
+//     pkcs-1  OBJECT IDENTIFIER  ::=
+//         { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
+
+// From RFC 5912:
+//
+//     sha256WithRSAEncryption  OBJECT IDENTIFIER  ::=  { pkcs-1 11 }
+//
+// In dotted notation: 1.2.840.113549.1.1.11
+const uint8_t kOidSha256WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
+                                               0x0d, 0x01, 0x01, 0x0b};
+
+// From RFC 5912:
+//
+//     sha384WithRSAEncryption  OBJECT IDENTIFIER  ::=  { pkcs-1 12 }
+//
+// In dotted notation: 1.2.840.113549.1.1.11
+const uint8_t kOidSha384WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
+                                               0x0d, 0x01, 0x01, 0x0c};
+
+// From RFC 5912:
+//
+//     sha512WithRSAEncryption  OBJECT IDENTIFIER  ::=  { pkcs-1 13 }
+//
+// In dotted notation: 1.2.840.113549.1.1.13
+const uint8_t kOidSha512WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
+                                               0x0d, 0x01, 0x01, 0x0d};
+
+// From RFC 5912:
+//
+//     ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
+//      iso(1) member-body(2) us(840) ansi-X9-62(10045)
+//      signatures(4) 1 }
+//
+// In dotted notation: 1.2.840.10045.4.1
+const uint8_t kOidEcdsaWithSha1[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01};
+
+// From RFC 5912:
+//
+//     ecdsa-with-SHA256 OBJECT IDENTIFIER ::= {
+//      iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+//      ecdsa-with-SHA2(3) 2 }
+//
+// In dotted notation: 1.2.840.10045.4.3.2
+const uint8_t kOidEcdsaWithSha256[] = {0x2a, 0x86, 0x48, 0xce,
+                                       0x3d, 0x04, 0x03, 0x02};
+
+// From RFC 5912:
+//
+//     ecdsa-with-SHA384 OBJECT IDENTIFIER ::= {
+//      iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+//      ecdsa-with-SHA2(3) 3 }
+//
+// In dotted notation: 1.2.840.10045.4.3.3
+const uint8_t kOidEcdsaWithSha384[] = {0x2a, 0x86, 0x48, 0xce,
+                                       0x3d, 0x04, 0x03, 0x03};
+
+// From RFC 5912:
+//
+//     ecdsa-with-SHA512 OBJECT IDENTIFIER ::= {
+//      iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+//      ecdsa-with-SHA2(3) 4 }
+//
+// In dotted notation: 1.2.840.10045.4.3.4
+const uint8_t kOidEcdsaWithSha512[] = {0x2a, 0x86, 0x48, 0xce,
+                                       0x3d, 0x04, 0x03, 0x04};
+
+// From RFC 5912:
+//
+//     id-RSASSA-PSS  OBJECT IDENTIFIER  ::=  { pkcs-1 10 }
+//
+// In dotted notation: 1.2.840.113549.1.1.10
+const uint8_t kOidRsaSsaPss[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
+                                 0x0d, 0x01, 0x01, 0x0a};
+
+// From RFC 5912:
+//
+//     id-mgf1  OBJECT IDENTIFIER  ::=  { pkcs-1 8 }
+//
+// In dotted notation: 1.2.840.113549.1.1.8
+const uint8_t kOidMgf1[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
+                            0x0d, 0x01, 0x01, 0x08};
+
+// Returns true if |input| is empty.
+[[nodiscard]] bool IsEmpty(const der::Input& input) {
+  return input.Length() == 0;
+}
+
+// Returns true if the entirety of the input is a NULL value.
+[[nodiscard]] bool IsNull(const der::Input& input) {
+  der::Parser parser(input);
+  der::Input null_value;
+  if (!parser.ReadTag(der::kNull, &null_value))
+    return false;
+
+  // NULL values are TLV encoded; the value is expected to be empty.
+  if (!IsEmpty(null_value))
+    return false;
+
+  // By definition of this function, the entire input must be a NULL.
+  return !parser.HasMore();
+}
+
+[[nodiscard]] bool IsNullOrEmpty(const der::Input& input) {
+  return IsNull(input) || IsEmpty(input);
+}
+
+// Parses a MaskGenAlgorithm as defined by RFC 5912:
+//
+//     MaskGenAlgorithm ::= AlgorithmIdentifier{ALGORITHM,
+//                             {PKCS1MGFAlgorithms}}
+//
+//     mgf1SHA1 MaskGenAlgorithm ::= {
+//         algorithm id-mgf1,
+//         parameters HashAlgorithm : sha1Identifier
+//     }
+//
+//     --
+//     --  Define the set of mask generation functions
+//     --
+//     --  If the identifier is id-mgf1, any of the listed hash
+//     --    algorithms may be used.
+//     --
+//
+//     PKCS1MGFAlgorithms ALGORITHM ::= {
+//         { IDENTIFIER id-mgf1 PARAMS TYPE HashAlgorithm ARE required },
+//         ...
+//     }
+//
+// Note that the possible mask gen algorithms is extensible. However at present
+// the only function supported is MGF1, as that is the singular mask gen
+// function defined by RFC 4055 / RFC 5912.
+[[nodiscard]] bool ParseMaskGenAlgorithm(const der::Input input,
+                                         DigestAlgorithm* mgf1_hash) {
+  der::Input oid;
+  der::Input params;
+  if (!ParseAlgorithmIdentifier(input, &oid, &params))
+    return false;
+
+  // MGF1 is the only supported mask generation algorithm.
+  if (oid != der::Input(kOidMgf1))
+    return false;
+
+  return ParseHashAlgorithm(params, mgf1_hash);
+}
+
+// Parses the parameters for an RSASSA-PSS signature algorithm, as defined by
+// RFC 5912:
+//
+//     sa-rsaSSA-PSS SIGNATURE-ALGORITHM ::= {
+//         IDENTIFIER id-RSASSA-PSS
+//         PARAMS TYPE RSASSA-PSS-params ARE required
+//         HASHES { mda-sha1 | mda-sha224 | mda-sha256 | mda-sha384
+//                      | mda-sha512 }
+//         PUBLIC-KEYS { pk-rsa | pk-rsaSSA-PSS }
+//         SMIME-CAPS { IDENTIFIED BY id-RSASSA-PSS }
+//     }
+//
+//     RSASSA-PSS-params  ::=  SEQUENCE  {
+//         hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
+//         maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
+//         saltLength        [2] INTEGER DEFAULT 20,
+//         trailerField      [3] INTEGER DEFAULT 1
+//     }
+//
+// Which is to say the parameters MUST be present, and of type
+// RSASSA-PSS-params. Additionally, we only support the RSA-PSS parameter
+// combinations representable by TLS 1.3 (RFC 8446).
+//
+// Note also that DER encoding (ITU-T X.690 section 11.5) prohibits
+// specifying default values explicitly. The parameter should instead be
+// omitted to indicate a default value.
+std::optional<SignatureAlgorithm> ParseRsaPss(const der::Input& params) {
+  der::Parser parser(params);
+  der::Parser params_parser;
+  if (!parser.ReadSequence(&params_parser)) {
+    return std::nullopt;
+  }
+
+  // There shouldn't be anything after the sequence (by definition the
+  // parameters is a single sequence).
+  if (parser.HasMore()) {
+    return std::nullopt;
+  }
+
+  // The default values for hashAlgorithm, maskGenAlgorithm, and saltLength
+  // correspond to SHA-1, which we do not support with RSA-PSS, so treat them as
+  // required fields. Explicitly-specified defaults will be rejected later, when
+  // we limit combinations. Additionally, as the trailerField is required to be
+  // the default, we simply ignore it and reject it as any other trailing data.
+  //
+  //     hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
+  //     maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
+  //     saltLength        [2] INTEGER DEFAULT 20,
+  //     trailerField      [3] INTEGER DEFAULT 1
+  der::Input field;
+  DigestAlgorithm hash, mgf1_hash;
+  der::Parser salt_length_parser;
+  uint64_t salt_length;
+  if (!params_parser.ReadTag(der::ContextSpecificConstructed(0), &field) ||
+      !ParseHashAlgorithm(field, &hash) ||
+      !params_parser.ReadTag(der::ContextSpecificConstructed(1), &field) ||
+      !ParseMaskGenAlgorithm(field, &mgf1_hash) ||
+      !params_parser.ReadConstructed(der::ContextSpecificConstructed(2),
+                                     &salt_length_parser) ||
+      !salt_length_parser.ReadUint64(&salt_length) ||
+      salt_length_parser.HasMore() || params_parser.HasMore()) {
+    return std::nullopt;
+  }
+
+  // Only combinations of RSASSA-PSS-params specified by TLS 1.3 (RFC 8446) are
+  // supported.
+  if (hash != mgf1_hash) {
+    return std::nullopt;  // TLS 1.3 always matches MGF-1 and message hash.
+  }
+  if (hash == DigestAlgorithm::Sha256 && salt_length == 32) {
+    return SignatureAlgorithm::kRsaPssSha256;
+  }
+  if (hash == DigestAlgorithm::Sha384 && salt_length == 48) {
+    return SignatureAlgorithm::kRsaPssSha384;
+  }
+  if (hash == DigestAlgorithm::Sha512 && salt_length == 64) {
+    return SignatureAlgorithm::kRsaPssSha512;
+  }
+
+  return std::nullopt;
+}
+
+}  // namespace
+
+[[nodiscard]] bool ParseAlgorithmIdentifier(const der::Input& input,
+                                            der::Input* algorithm,
+                                            der::Input* parameters) {
+  der::Parser parser(input);
+
+  der::Parser algorithm_identifier_parser;
+  if (!parser.ReadSequence(&algorithm_identifier_parser))
+    return false;
+
+  // There shouldn't be anything after the sequence. This is by definition,
+  // as the input to this function is expected to be a single
+  // AlgorithmIdentifier.
+  if (parser.HasMore())
+    return false;
+
+  if (!algorithm_identifier_parser.ReadTag(der::kOid, algorithm))
+    return false;
+
+  // Read the optional parameters to a der::Input. The parameters can be at
+  // most one TLV (for instance NULL or a sequence).
+  //
+  // Note that nothing is allowed after the single optional "parameters" TLV.
+  // This is because RFC 5912's notation for AlgorithmIdentifier doesn't
+  // explicitly list an extension point after "parameters".
+  *parameters = der::Input();
+  if (algorithm_identifier_parser.HasMore() &&
+      !algorithm_identifier_parser.ReadRawTLV(parameters)) {
+    return false;
+  }
+  return !algorithm_identifier_parser.HasMore();
+}
+
+[[nodiscard]] bool ParseHashAlgorithm(const der::Input& input,
+                                      DigestAlgorithm* out) {
+  CBS cbs;
+  CBS_init(&cbs, input.UnsafeData(), input.Length());
+  const EVP_MD* md = EVP_parse_digest_algorithm(&cbs);
+
+  if (md == EVP_sha1()) {
+    *out = DigestAlgorithm::Sha1;
+  } else if (md == EVP_sha256()) {
+    *out = DigestAlgorithm::Sha256;
+  } else if (md == EVP_sha384()) {
+    *out = DigestAlgorithm::Sha384;
+  } else if (md == EVP_sha512()) {
+    *out = DigestAlgorithm::Sha512;
+  } else {
+    // TODO(eroman): Support MD2, MD4, MD5 for completeness?
+    // Unsupported digest algorithm.
+    return false;
+  }
+
+  return true;
+}
+
+std::optional<SignatureAlgorithm> ParseSignatureAlgorithm(
+    const der::Input& algorithm_identifier) {
+  der::Input oid;
+  der::Input params;
+  if (!ParseAlgorithmIdentifier(algorithm_identifier, &oid, &params)) {
+    return std::nullopt;
+  }
+
+  // TODO(eroman): Each OID is tested for equality in order, which is not
+  // particularly efficient.
+
+  // RFC 5912 requires that the parameters for RSA PKCS#1 v1.5 algorithms be
+  // NULL ("PARAMS TYPE NULL ARE required"), however an empty parameter is also
+  // allowed for compatibility with non-compliant OCSP responders.
+  //
+  // TODO(svaldez): Add warning about non-strict parsing.
+  if (oid == der::Input(kOidSha1WithRsaEncryption) && IsNullOrEmpty(params)) {
+    return SignatureAlgorithm::kRsaPkcs1Sha1;
+  }
+  if (oid == der::Input(kOidSha256WithRsaEncryption) && IsNullOrEmpty(params)) {
+    return SignatureAlgorithm::kRsaPkcs1Sha256;
+  }
+  if (oid == der::Input(kOidSha384WithRsaEncryption) && IsNullOrEmpty(params)) {
+    return SignatureAlgorithm::kRsaPkcs1Sha384;
+  }
+  if (oid == der::Input(kOidSha512WithRsaEncryption) && IsNullOrEmpty(params)) {
+    return SignatureAlgorithm::kRsaPkcs1Sha512;
+  }
+  if (oid == der::Input(kOidSha1WithRsaSignature) && IsNullOrEmpty(params)) {
+    return SignatureAlgorithm::kRsaPkcs1Sha1;
+  }
+
+  // RFC 5912 requires that the parameters for ECDSA algorithms be absent
+  // ("PARAMS TYPE NULL ARE absent"):
+  if (oid == der::Input(kOidEcdsaWithSha1) && IsEmpty(params)) {
+    return SignatureAlgorithm::kEcdsaSha1;
+  }
+  if (oid == der::Input(kOidEcdsaWithSha256) && IsEmpty(params)) {
+    return SignatureAlgorithm::kEcdsaSha256;
+  }
+  if (oid == der::Input(kOidEcdsaWithSha384) && IsEmpty(params)) {
+    return SignatureAlgorithm::kEcdsaSha384;
+  }
+  if (oid == der::Input(kOidEcdsaWithSha512) && IsEmpty(params)) {
+    return SignatureAlgorithm::kEcdsaSha512;
+  }
+
+  if (oid == der::Input(kOidRsaSsaPss)) {
+    return ParseRsaPss(params);
+  }
+
+  // Unknown signature algorithm.
+  return std::nullopt;
+}
+
+std::optional<DigestAlgorithm> GetTlsServerEndpointDigestAlgorithm(
+    SignatureAlgorithm alg) {
+  // See RFC 5929, section 4.1. RFC 5929 breaks the signature algorithm
+  // abstraction by trying to extract individual digest algorithms. (While
+  // common, this is not a universal property of signature algorithms.) We
+  // implement this within the library, so callers do not need to condition over
+  // all algorithms.
+  switch (alg) {
+    // If the single digest algorithm is SHA-1, use SHA-256.
+    case SignatureAlgorithm::kRsaPkcs1Sha1:
+    case SignatureAlgorithm::kEcdsaSha1:
+      return DigestAlgorithm::Sha256;
+
+    case SignatureAlgorithm::kRsaPkcs1Sha256:
+    case SignatureAlgorithm::kEcdsaSha256:
+      return DigestAlgorithm::Sha256;
+
+    case SignatureAlgorithm::kRsaPkcs1Sha384:
+    case SignatureAlgorithm::kEcdsaSha384:
+      return DigestAlgorithm::Sha384;
+
+    case SignatureAlgorithm::kRsaPkcs1Sha512:
+    case SignatureAlgorithm::kEcdsaSha512:
+      return DigestAlgorithm::Sha512;
+
+    // It is ambiguous whether hash-matching RSASSA-PSS instantiations count as
+    // using one or multiple digests, but the corresponding digest is the only
+    // reasonable interpretation.
+    case SignatureAlgorithm::kRsaPssSha256:
+      return DigestAlgorithm::Sha256;
+    case SignatureAlgorithm::kRsaPssSha384:
+      return DigestAlgorithm::Sha384;
+    case SignatureAlgorithm::kRsaPssSha512:
+      return DigestAlgorithm::Sha512;
+  }
+  return std::nullopt;
+}
+
+}  // namespace net