// 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/signature_algorithm.h"

#include <memory>
#include <utility>

#include "base/memory/ptr_util.h"
#include "base/numerics/safe_math.h"
#include "net/cert/internal/cert_error_params.h"
#include "net/cert/internal/cert_errors.h"
#include "net/der/input.h"
#include "net/der/parse_values.h"
#include "net/der/parser.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/digest.h"

namespace net {

namespace {

// md2WithRSAEncryption
// In dotted notation: 1.2.840.113549.1.1.2
const uint8_t kOidMd2WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                            0x0d, 0x01, 0x01, 0x02};

// md4WithRSAEncryption
// In dotted notation: 1.2.840.113549.1.1.3
const uint8_t kOidMd4WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                            0x0d, 0x01, 0x01, 0x03};

// md5WithRSAEncryption
// In dotted notation: 1.2.840.113549.1.1.4
const uint8_t kOidMd5WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                            0x0d, 0x01, 0x01, 0x04};

// 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:
//
//     dsa-with-sha1 OBJECT IDENTIFIER ::=  {
//      iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 3 }
//
// In dotted notation: 1.2.840.10040.4.3
const uint8_t kOidDsaWithSha1[] = {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x03};

// From RFC 5912:
//
//     dsa-with-sha256 OBJECT IDENTIFIER  ::=  {
//      joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
//      csor(3) algorithms(4) id-dsa-with-sha2(3) 2 }
//
// In dotted notation: 2.16.840.1.101.3.4.3.2
const uint8_t kOidDsaWithSha256[] = {0x60, 0x86, 0x48, 0x01, 0x65,
                                     0x03, 0x04, 0x03, 0x02};

// 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};

// RFC 5280 section 4.1.1.2 defines signatureAlgorithm as:
//
//     AlgorithmIdentifier  ::=  SEQUENCE  {
//          algorithm               OBJECT IDENTIFIER,
//          parameters              ANY DEFINED BY algorithm OPTIONAL  }
WARN_UNUSED_RESULT 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();
}

// Returns true if |input| is empty.
WARN_UNUSED_RESULT bool IsEmpty(const der::Input& input) {
  return input.Length() == 0;
}

// Returns true if the entirety of the input is a NULL value.
WARN_UNUSED_RESULT 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();
}

// Parses an RSA PKCS#1 v1.5 signature algorithm given the DER-encoded
// "parameters" from the parsed AlgorithmIdentifier, and the hash algorithm
// that was implied by the AlgorithmIdentifier's OID.
//
// Returns a nullptr on failure.
//
// 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:
//
//     sa-rsaWithSHA1 SIGNATURE-ALGORITHM ::= {
//      IDENTIFIER sha1WithRSAEncryption
//      PARAMS TYPE NULL ARE required
//      HASHES { mda-sha1 }
//      PUBLIC-KEYS { pk-rsa }
//      SMIME-CAPS {IDENTIFIED BY sha1WithRSAEncryption }
//     }
//
//     sa-sha256WithRSAEncryption SIGNATURE-ALGORITHM ::= {
//         IDENTIFIER sha256WithRSAEncryption
//         PARAMS TYPE NULL ARE required
//         HASHES { mda-sha256 }
//         PUBLIC-KEYS { pk-rsa }
//         SMIME-CAPS { IDENTIFIED BY sha256WithRSAEncryption }
//     }
//
//     sa-sha384WithRSAEncryption SIGNATURE-ALGORITHM ::= {
//         IDENTIFIER sha384WithRSAEncryption
//         PARAMS TYPE NULL ARE required
//         HASHES { mda-sha384 }
//         PUBLIC-KEYS { pk-rsa }
//         SMIME-CAPS { IDENTIFIED BY sha384WithRSAEncryption }
//     }
//
//     sa-sha512WithRSAEncryption SIGNATURE-ALGORITHM ::= {
//         IDENTIFIER sha512WithRSAEncryption
//         PARAMS TYPE NULL ARE required
//         HASHES { mda-sha512 }
//         PUBLIC-KEYS { pk-rsa }
//         SMIME-CAPS { IDENTIFIED BY sha512WithRSAEncryption }
//     }
std::unique_ptr<SignatureAlgorithm> ParseRsaPkcs1(DigestAlgorithm digest,
                                                  const der::Input& params) {
  // TODO(svaldez): Add warning about non-strict parsing.
  if (!IsNull(params) && !IsEmpty(params))
    return nullptr;

  return SignatureAlgorithm::CreateRsaPkcs1(digest);
}

// Parses a DSA signature algorithm given the DER-encoded
// "parameters" from the parsed AlgorithmIdentifier, and the hash algorithm
// that was implied by the AlgorithmIdentifier's OID.
//
// Returns a nullptr on failure.
//
// RFC 5912 requires that the parameters for DSA algorithms be absent.
std::unique_ptr<SignatureAlgorithm> ParseDsa(DigestAlgorithm digest,
                                             const der::Input& params) {
  // TODO(svaldez): Add warning about non-strict parsing.
  if (!IsNull(params) && !IsEmpty(params))
    return nullptr;

  return SignatureAlgorithm::CreateDsa(digest);
}

// Parses an ECDSA signature algorithm given the DER-encoded "parameters" from
// the parsed AlgorithmIdentifier, and the hash algorithm that was implied by
// the AlgorithmIdentifier's OID.
//
// On failure returns a nullptr.
//
// RFC 5912 requires that the parameters for ECDSA algorithms be absent
// ("PARAMS TYPE NULL ARE absent"):
//
//     sa-ecdsaWithSHA1 SIGNATURE-ALGORITHM ::= {
//      IDENTIFIER ecdsa-with-SHA1
//      VALUE ECDSA-Sig-Value
//      PARAMS TYPE NULL ARE absent
//      HASHES { mda-sha1 }
//      PUBLIC-KEYS { pk-ec }
//      SMIME-CAPS {IDENTIFIED BY ecdsa-with-SHA1 }
//     }
//
//     sa-ecdsaWithSHA256 SIGNATURE-ALGORITHM ::= {
//      IDENTIFIER ecdsa-with-SHA256
//      VALUE ECDSA-Sig-Value
//      PARAMS TYPE NULL ARE absent
//      HASHES { mda-sha256 }
//      PUBLIC-KEYS { pk-ec }
//      SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA256 }
//     }
//
//     sa-ecdsaWithSHA384 SIGNATURE-ALGORITHM ::= {
//      IDENTIFIER ecdsa-with-SHA384
//      VALUE ECDSA-Sig-Value
//      PARAMS TYPE NULL ARE absent
//      HASHES { mda-sha384 }
//      PUBLIC-KEYS { pk-ec }
//      SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA384 }
//     }
//
//     sa-ecdsaWithSHA512 SIGNATURE-ALGORITHM ::= {
//      IDENTIFIER ecdsa-with-SHA512
//      VALUE ECDSA-Sig-Value
//      PARAMS TYPE NULL ARE absent
//      HASHES { mda-sha512 }
//      PUBLIC-KEYS { pk-ec }
//      SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA512 }
//     }
std::unique_ptr<SignatureAlgorithm> ParseEcdsa(DigestAlgorithm digest,
                                               const der::Input& params) {
  if (!IsEmpty(params))
    return nullptr;

  return SignatureAlgorithm::CreateEcdsa(digest);
}

// 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.
WARN_UNUSED_RESULT 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);
}

// Consumes an optional, explicitly-tagged INTEGER from |parser|, using the
// indicated context-specific class number. Values greater than 32-bits will be
// rejected.
//
// Returns true on success and sets |*present| to true if the field was present.
WARN_UNUSED_RESULT bool ReadOptionalContextSpecificUint32(der::Parser* parser,
                                                          uint8_t class_number,
                                                          uint32_t* out,
                                                          bool* present) {
  der::Input value;
  bool has_value;

  // Read the context specific value.
  if (!parser->ReadOptionalTag(der::ContextSpecificConstructed(class_number),
                               &value, &has_value)) {
    return false;
  }

  if (has_value) {
    // Parse the integer contained in it.
    der::Parser number_parser(value);
    uint64_t uint64_value;

    if (!number_parser.ReadUint64(&uint64_value))
      return false;
    if (number_parser.HasMore())
      return false;

    // Cast the number to a uint32_t
    base::CheckedNumeric<uint32_t> casted(uint64_value);
    if (!casted.IsValid())
      return false;
    *out = casted.ValueOrDie();
  }

  *present = has_value;
  return true;
}

// 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.
std::unique_ptr<SignatureAlgorithm> ParseRsaPss(const der::Input& params) {
  der::Parser parser(params);
  der::Parser params_parser;
  if (!parser.ReadSequence(&params_parser))
    return nullptr;

  // There shouldn't be anything after the sequence (by definition the
  // parameters is a single sequence).
  if (parser.HasMore())
    return nullptr;

  bool has_field;
  der::Input field;

  // Parse:
  //     hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
  DigestAlgorithm hash = DigestAlgorithm::Sha1;
  if (!params_parser.ReadOptionalTag(der::ContextSpecificConstructed(0), &field,
                                     &has_field)) {
    return nullptr;
  }
  if (has_field && !ParseHashAlgorithm(field, &hash))
    return nullptr;

  // Parse:
  //     maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
  DigestAlgorithm mgf1_hash = DigestAlgorithm::Sha1;
  if (!params_parser.ReadOptionalTag(der::ContextSpecificConstructed(1), &field,
                                     &has_field)) {
    return nullptr;
  }
  if (has_field && !ParseMaskGenAlgorithm(field, &mgf1_hash))
    return nullptr;

  // Parse:
  //     saltLength        [2] INTEGER DEFAULT 20,
  uint32_t salt_length = 20u;
  if (!ReadOptionalContextSpecificUint32(&params_parser, 2, &salt_length,
                                         &has_field)) {
    return nullptr;
  }

  // Parse:
  //     trailerField      [3] INTEGER DEFAULT 1
  uint32_t trailer_field = 1u;
  if (!ReadOptionalContextSpecificUint32(&params_parser, 3, &trailer_field,
                                         &has_field)) {
    return nullptr;
  }

  // RFC 4055 says that the trailer field must be 1:
  //
  //     The trailerField field is an integer.  It provides
  //     compatibility with IEEE Std 1363a-2004 [P1363A].  The value
  //     MUST be 1, which represents the trailer field with hexadecimal
  //     value 0xBC.  Other trailer fields, including the trailer field
  //     composed of HashID concatenated with 0xCC that is specified in
  //     IEEE Std 1363a, are not supported.  Implementations that
  //     perform signature generation MUST omit the trailerField field,
  //     indicating that the default trailer field value was used.
  //     Implementations that perform signature validation MUST
  //     recognize both a present trailerField field with value 1 and an
  //     absent trailerField field.
  if (trailer_field != 1)
    return nullptr;

  // There must not be any unconsumed data left. (RFC 5912 does not explicitly
  // include an extensibility point for RSASSA-PSS-params)
  if (params_parser.HasMore())
    return nullptr;

  return SignatureAlgorithm::CreateRsaPss(hash, mgf1_hash, salt_length);
}

DEFINE_CERT_ERROR_ID(kUnknownAlgorithmIdentifierOid,
                     "Unknown AlgorithmIdentifier OID");

}  // namespace

WARN_UNUSED_RESULT 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;
}

RsaPssParameters::RsaPssParameters(DigestAlgorithm mgf1_hash,
                                   uint32_t salt_length)
    : mgf1_hash_(mgf1_hash), salt_length_(salt_length) {
}

SignatureAlgorithm::~SignatureAlgorithm() = default;

std::unique_ptr<SignatureAlgorithm> SignatureAlgorithm::Create(
    const der::Input& algorithm_identifier,
    CertErrors* errors) {
  // TODO(crbug.com/634443): Add useful error information.

  der::Input oid;
  der::Input params;
  if (!ParseAlgorithmIdentifier(algorithm_identifier, &oid, &params))
    return nullptr;

  // TODO(eroman): Each OID is tested for equality in order, which is not
  // particularly efficient.

  if (oid == der::Input(kOidSha1WithRsaEncryption))
    return ParseRsaPkcs1(DigestAlgorithm::Sha1, params);

  if (oid == der::Input(kOidSha256WithRsaEncryption))
    return ParseRsaPkcs1(DigestAlgorithm::Sha256, params);

  if (oid == der::Input(kOidSha384WithRsaEncryption))
    return ParseRsaPkcs1(DigestAlgorithm::Sha384, params);

  if (oid == der::Input(kOidSha512WithRsaEncryption))
    return ParseRsaPkcs1(DigestAlgorithm::Sha512, params);

  if (oid == der::Input(kOidEcdsaWithSha1))
    return ParseEcdsa(DigestAlgorithm::Sha1, params);

  if (oid == der::Input(kOidEcdsaWithSha256))
    return ParseEcdsa(DigestAlgorithm::Sha256, params);

  if (oid == der::Input(kOidEcdsaWithSha384))
    return ParseEcdsa(DigestAlgorithm::Sha384, params);

  if (oid == der::Input(kOidEcdsaWithSha512))
    return ParseEcdsa(DigestAlgorithm::Sha512, params);

  if (oid == der::Input(kOidRsaSsaPss))
    return ParseRsaPss(params);

  if (oid == der::Input(kOidSha1WithRsaSignature))
    return ParseRsaPkcs1(DigestAlgorithm::Sha1, params);

  if (oid == der::Input(kOidMd2WithRsaEncryption))
    return ParseRsaPkcs1(DigestAlgorithm::Md2, params);

  if (oid == der::Input(kOidMd4WithRsaEncryption))
    return ParseRsaPkcs1(DigestAlgorithm::Md4, params);

  if (oid == der::Input(kOidMd5WithRsaEncryption))
    return ParseRsaPkcs1(DigestAlgorithm::Md5, params);

  if (oid == der::Input(kOidDsaWithSha1))
    return ParseDsa(DigestAlgorithm::Sha1, params);

  if (oid == der::Input(kOidDsaWithSha256))
    return ParseDsa(DigestAlgorithm::Sha256, params);

  // Unknown OID.
  if (errors) {
    errors->AddError(kUnknownAlgorithmIdentifierOid,
                     CreateCertErrorParams2Der("oid", oid, "params", params));
  }
  return nullptr;
}

std::unique_ptr<SignatureAlgorithm> SignatureAlgorithm::CreateRsaPkcs1(
    DigestAlgorithm digest) {
  return base::WrapUnique(
      new SignatureAlgorithm(SignatureAlgorithmId::RsaPkcs1, digest, nullptr));
}

std::unique_ptr<SignatureAlgorithm> SignatureAlgorithm::CreateDsa(
    DigestAlgorithm digest) {
  return base::WrapUnique(
      new SignatureAlgorithm(SignatureAlgorithmId::Dsa, digest, nullptr));
}

std::unique_ptr<SignatureAlgorithm> SignatureAlgorithm::CreateEcdsa(
    DigestAlgorithm digest) {
  return base::WrapUnique(
      new SignatureAlgorithm(SignatureAlgorithmId::Ecdsa, digest, nullptr));
}

std::unique_ptr<SignatureAlgorithm> SignatureAlgorithm::CreateRsaPss(
    DigestAlgorithm digest,
    DigestAlgorithm mgf1_hash,
    uint32_t salt_length) {
  return base::WrapUnique(new SignatureAlgorithm(
      SignatureAlgorithmId::RsaPss, digest,
      std::make_unique<RsaPssParameters>(mgf1_hash, salt_length)));
}

const RsaPssParameters* SignatureAlgorithm::ParamsForRsaPss() const {
  if (algorithm_ == SignatureAlgorithmId::RsaPss)
    return static_cast<RsaPssParameters*>(params_.get());
  return nullptr;
}

bool SignatureAlgorithm::IsEquivalent(const der::Input& alg1_tlv,
                                      const der::Input& alg2_tlv) {
  if (alg1_tlv == alg2_tlv)
    return true;

  std::unique_ptr<SignatureAlgorithm> alg1 = Create(alg1_tlv, nullptr);
  std::unique_ptr<SignatureAlgorithm> alg2 = Create(alg2_tlv, nullptr);

  // Do checks that apply to all algorithms.
  if (!alg1 || !alg2 || (alg1->algorithm() != alg2->algorithm()) ||
      (alg1->digest() != alg2->digest())) {
    return false;
  }

  // Check algorithm-specific parameters for equality.
  switch (alg1->algorithm()) {
    case SignatureAlgorithmId::RsaPkcs1:
    case SignatureAlgorithmId::Ecdsa:
    case SignatureAlgorithmId::Dsa:
      DCHECK(!alg1->has_params());
      DCHECK(!alg2->has_params());
      return true;
    case SignatureAlgorithmId::RsaPss: {
      const RsaPssParameters* params1 = alg1->ParamsForRsaPss();
      const RsaPssParameters* params2 = alg2->ParamsForRsaPss();
      return params1 && params2 &&
             (params1->salt_length() == params2->salt_length()) &&
             (params1->mgf1_hash() == params2->mgf1_hash());
    }
  }

  return false;
}

SignatureAlgorithm::SignatureAlgorithm(
    SignatureAlgorithmId algorithm,
    DigestAlgorithm digest,
    std::unique_ptr<SignatureAlgorithmParameters> params)
    : algorithm_(algorithm), digest_(digest), params_(std::move(params)) {}

}  // namespace net
