// 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.

#include <stddef.h>
#include <stdint.h>

#include "base/logging.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "components/webcrypto/algorithm_dispatch.h"
#include "components/webcrypto/algorithms/test_helpers.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
#include "third_party/blink/public/platform/web_crypto_key.h"
#include "third_party/blink/public/platform/web_crypto_key_algorithm.h"

namespace webcrypto {

namespace {

// Helper for ImportJwkRsaFailures. Restores the JWK JSON
// dictionary to a good state
void RestoreJwkRsaDictionary(base::DictionaryValue* dict) {
  dict->Clear();
  dict->SetString("kty", "RSA");
  dict->SetString("alg", "RS256");
  dict->SetString("use", "sig");
  dict->SetBoolean("ext", false);
  dict->SetString(
      "n",
      "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk"
      "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm"
      "e7PUJHYW1PW6ENTP0ibeiNOfFvs");
  dict->SetString("e", "AQAB");
}

class WebCryptoRsaSsaTest : public WebCryptoTestBase {};

TEST_F(WebCryptoRsaSsaTest, ImportExportSpki) {
  // Passing case: Import a valid RSA key in SPKI format.
  blink::WebCryptoKey key;
  ASSERT_EQ(Status::Success(),
            ImportKey(blink::kWebCryptoKeyFormatSpki,
                      CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
                      CreateRsaHashedImportAlgorithm(
                          blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                          blink::kWebCryptoAlgorithmIdSha256),
                      true, blink::kWebCryptoKeyUsageVerify, &key));
  EXPECT_TRUE(key.Handle());
  EXPECT_EQ(blink::kWebCryptoKeyTypePublic, key.GetType());
  EXPECT_TRUE(key.Extractable());
  EXPECT_EQ(blink::kWebCryptoKeyUsageVerify, key.Usages());
  EXPECT_EQ(kModulusLengthBits,
            key.Algorithm().RsaHashedParams()->ModulusLengthBits());
  EXPECT_BYTES_EQ_HEX(
      "010001",
      CryptoData(key.Algorithm().RsaHashedParams()->PublicExponent()));

  // Failing case: Import RSA key but provide an inconsistent input algorithm.
  EXPECT_EQ(Status::ErrorUnsupportedImportKeyFormat(),
            ImportKey(blink::kWebCryptoKeyFormatSpki,
                      CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
                      CreateAlgorithm(blink::kWebCryptoAlgorithmIdAesCbc), true,
                      blink::kWebCryptoKeyUsageEncrypt, &key));

  // Passing case: Export a previously imported RSA public key in SPKI format
  // and compare to original data.
  std::vector<uint8_t> output;
  ASSERT_EQ(Status::Success(),
            ExportKey(blink::kWebCryptoKeyFormatSpki, key, &output));
  EXPECT_BYTES_EQ_HEX(kPublicKeySpkiDerHex, output);

  // Failing case: Try to export a previously imported RSA public key in raw
  // format (not allowed for a public key).
  EXPECT_EQ(Status::ErrorUnsupportedExportKeyFormat(),
            ExportKey(blink::kWebCryptoKeyFormatRaw, key, &output));

  // Failing case: Try to export a non-extractable key
  ASSERT_EQ(Status::Success(),
            ImportKey(blink::kWebCryptoKeyFormatSpki,
                      CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
                      CreateRsaHashedImportAlgorithm(
                          blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                          blink::kWebCryptoAlgorithmIdSha256),
                      false, blink::kWebCryptoKeyUsageVerify, &key));
  EXPECT_TRUE(key.Handle());
  EXPECT_FALSE(key.Extractable());
  EXPECT_EQ(Status::ErrorKeyNotExtractable(),
            ExportKey(blink::kWebCryptoKeyFormatSpki, key, &output));

  // TODO(eroman): Failing test: Import a SPKI with an unrecognized hash OID
  // TODO(eroman): Failing test: Import a SPKI with invalid algorithm params
  // TODO(eroman): Failing test: Import a SPKI with inconsistent parameters
  // (e.g. SHA-1 in OID, SHA-256 in params)
  // TODO(eroman): Failing test: Import a SPKI for RSA-SSA, but with params
  // as OAEP/PSS
}

TEST_F(WebCryptoRsaSsaTest, ImportExportPkcs8) {
  // Passing case: Import a valid RSA key in PKCS#8 format.
  blink::WebCryptoKey key;
  ASSERT_EQ(Status::Success(),
            ImportKey(blink::kWebCryptoKeyFormatPkcs8,
                      CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
                      CreateRsaHashedImportAlgorithm(
                          blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                          blink::kWebCryptoAlgorithmIdSha1),
                      true, blink::kWebCryptoKeyUsageSign, &key));
  EXPECT_TRUE(key.Handle());
  EXPECT_EQ(blink::kWebCryptoKeyTypePrivate, key.GetType());
  EXPECT_TRUE(key.Extractable());
  EXPECT_EQ(blink::kWebCryptoKeyUsageSign, key.Usages());
  EXPECT_EQ(blink::kWebCryptoAlgorithmIdSha1,
            key.Algorithm().RsaHashedParams()->GetHash().Id());
  EXPECT_EQ(kModulusLengthBits,
            key.Algorithm().RsaHashedParams()->ModulusLengthBits());
  EXPECT_BYTES_EQ_HEX(
      "010001",
      CryptoData(key.Algorithm().RsaHashedParams()->PublicExponent()));

  std::vector<uint8_t> exported_key;
  ASSERT_EQ(Status::Success(),
            ExportKey(blink::kWebCryptoKeyFormatPkcs8, key, &exported_key));
  EXPECT_BYTES_EQ_HEX(kPrivateKeyPkcs8DerHex, exported_key);

  // Failing case: Import RSA key but provide an inconsistent input algorithm
  // and usage. Several issues here:
  //   * AES-CBC doesn't support PKCS8 key format
  //   * AES-CBC doesn't support "sign" usage
  EXPECT_EQ(Status::ErrorUnsupportedImportKeyFormat(),
            ImportKey(blink::kWebCryptoKeyFormatPkcs8,
                      CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
                      CreateAlgorithm(blink::kWebCryptoAlgorithmIdAesCbc), true,
                      blink::kWebCryptoKeyUsageSign, &key));
}

// Tests JWK import and export by doing a roundtrip key conversion and ensuring
// it was lossless:
//
//   PKCS8 --> JWK --> PKCS8
TEST_F(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkToPkcs8RoundTrip) {
  blink::WebCryptoKey key;
  ASSERT_EQ(Status::Success(),
            ImportKey(blink::kWebCryptoKeyFormatPkcs8,
                      CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
                      CreateRsaHashedImportAlgorithm(
                          blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                          blink::kWebCryptoAlgorithmIdSha1),
                      true, blink::kWebCryptoKeyUsageSign, &key));

  std::vector<uint8_t> exported_key_jwk;
  ASSERT_EQ(Status::Success(),
            ExportKey(blink::kWebCryptoKeyFormatJwk, key, &exported_key_jwk));

  // All of the optional parameters (p, q, dp, dq, qi) should be present in the
  // output.
  const char* expected_jwk =
      "{\"alg\":\"RS1\",\"d\":\"M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-"
      "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ"
      "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU\",\"dp\":"
      "\"KPoTk4ZVvh-"
      "KFZy6ylpy6hkMMAieGc0nSlVvNsT24Z9VSzTAd3kEJ7vdjdPt4kSDKPOF2Bsw6OQ7L_-"
      "gJ4YZeQ\",\"dq\":\"Gos485j6cSBJiY1_t57gp3ZoeRKZzfoJ78DlB6yyHtdDAe9b_Ui-"
      "RV6utuFnglWCdYCo5OjhQVHRUQqCo_LnKQ\",\"e\":\"AQAB\",\"ext\":true,\"key_"
      "ops\":[\"sign\"],\"kty\":\"RSA\",\"n\":"
      "\"pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_"
      "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_"
      "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc\",\"p\":\"5-"
      "iUJyCod1Fyc6NWBT6iobwMlKpy1VxuhilrLfyWeUjApyy8zKfqyzVwbgmh31WhU1vZs8w0Fg"
      "s7bc0-2o5kQw\",\"q\":\"tp3KHPfU1-yB51uQ_MqHSrzeEj_"
      "ScAGAqpBHm25I3o1n7ST58Z2FuidYdPVCzSDccj5pYzZKH5QlRSsmmmeZ_Q\",\"qi\":"
      "\"JxVqukEm0kqB86Uoy_sn9WiG-"
      "ECp9uhuF6RLlP6TGVhLjiL93h5aLjvYqluo2FhBlOshkKz4MrhH8To9JKefTQ\"}";

  ASSERT_EQ(CryptoData(std::string(expected_jwk)),
            CryptoData(exported_key_jwk));

  ASSERT_EQ(
      Status::Success(),
      ImportKey(blink::kWebCryptoKeyFormatJwk, CryptoData(exported_key_jwk),
                CreateRsaHashedImportAlgorithm(
                    blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                    blink::kWebCryptoAlgorithmIdSha1),
                true, blink::kWebCryptoKeyUsageSign, &key));

  std::vector<uint8_t> exported_key_pkcs8;
  ASSERT_EQ(Status::Success(), ExportKey(blink::kWebCryptoKeyFormatPkcs8, key,
                                         &exported_key_pkcs8));

  ASSERT_EQ(CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
            CryptoData(exported_key_pkcs8));
}

// Tests importing multiple RSA private keys from JWK, and then exporting to
// PKCS8.
//
// This is a regression test for http://crbug.com/378315, for which importing
// a sequence of keys from JWK could yield the wrong key. The first key would
// be imported correctly, however every key after that would actually import
// the first key.
TEST_F(WebCryptoRsaSsaTest, ImportMultipleRSAPrivateKeysJwk) {
  base::ListValue key_list;
  ASSERT_TRUE(ReadJsonTestFileToList("rsa_private_keys.json", &key_list));

  // For this test to be meaningful the keys MUST be kept alive before importing
  // new keys.
  std::vector<blink::WebCryptoKey> live_keys;

  for (size_t key_index = 0; key_index < key_list.GetSize(); ++key_index) {
    SCOPED_TRACE(key_index);

    base::DictionaryValue* key_values;
    ASSERT_TRUE(key_list.GetDictionary(key_index, &key_values));

    // Get the JWK representation of the key.
    base::DictionaryValue* key_jwk;
    ASSERT_TRUE(key_values->GetDictionary("jwk", &key_jwk));

    // Get the PKCS8 representation of the key.
    std::string pkcs8_hex_string;
    ASSERT_TRUE(key_values->GetString("pkcs8", &pkcs8_hex_string));
    std::vector<uint8_t> pkcs8_bytes = HexStringToBytes(pkcs8_hex_string);

    // Get the modulus length for the key.
    int modulus_length_bits = 0;
    ASSERT_TRUE(key_values->GetInteger("modulusLength", &modulus_length_bits));

    blink::WebCryptoKey private_key;

    // Import the key from JWK.
    ASSERT_EQ(Status::Success(),
              ImportKeyJwkFromDict(
                  *key_jwk,
                  CreateRsaHashedImportAlgorithm(
                      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                      blink::kWebCryptoAlgorithmIdSha256),
                  true, blink::kWebCryptoKeyUsageSign, &private_key));

    live_keys.push_back(private_key);

    EXPECT_EQ(
        modulus_length_bits,
        static_cast<int>(
            private_key.Algorithm().RsaHashedParams()->ModulusLengthBits()));

    // Export to PKCS8 and verify that it matches expectation.
    std::vector<uint8_t> exported_key_pkcs8;
    ASSERT_EQ(Status::Success(), ExportKey(blink::kWebCryptoKeyFormatPkcs8,
                                           private_key, &exported_key_pkcs8));

    EXPECT_BYTES_EQ(pkcs8_bytes, exported_key_pkcs8);
  }
}

// Import an RSA private key using JWK. Next import a JWK containing the same
// modulus, but mismatched parameters for the rest. It should NOT be possible
// that the second import retrieves the first key. See http://crbug.com/378315
// for how that could happen.
TEST_F(WebCryptoRsaSsaTest, ImportJwkExistingModulusAndInvalid) {
  base::ListValue key_list;
  ASSERT_TRUE(ReadJsonTestFileToList("rsa_private_keys.json", &key_list));

  // Import a 1024-bit private key.
  base::DictionaryValue* key1_props;
  ASSERT_TRUE(key_list.GetDictionary(1, &key1_props));
  base::DictionaryValue* key1_jwk;
  ASSERT_TRUE(key1_props->GetDictionary("jwk", &key1_jwk));

  blink::WebCryptoKey key1;
  ASSERT_EQ(
      Status::Success(),
      ImportKeyJwkFromDict(*key1_jwk,
                           CreateRsaHashedImportAlgorithm(
                               blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                               blink::kWebCryptoAlgorithmIdSha256),
                           true, blink::kWebCryptoKeyUsageSign, &key1));

  ASSERT_EQ(1024u, key1.Algorithm().RsaHashedParams()->ModulusLengthBits());

  // Construct a JWK using the modulus of key1, but all the other fields from
  // another key (also a 1024-bit private key).
  base::DictionaryValue* key2_props;
  ASSERT_TRUE(key_list.GetDictionary(5, &key2_props));
  base::DictionaryValue* key2_jwk;
  ASSERT_TRUE(key2_props->GetDictionary("jwk", &key2_jwk));
  std::string modulus;
  key1_jwk->GetString("n", &modulus);
  key2_jwk->SetString("n", modulus);

  // This should fail, as the n,e,d parameters are not consistent. It MUST NOT
  // somehow return the key created earlier.
  blink::WebCryptoKey key2;
  ASSERT_EQ(
      Status::OperationError(),
      ImportKeyJwkFromDict(*key2_jwk,
                           CreateRsaHashedImportAlgorithm(
                               blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                               blink::kWebCryptoAlgorithmIdSha256),
                           true, blink::kWebCryptoKeyUsageSign, &key2));
}

TEST_F(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
  // Note: using unrealistic short key lengths here to avoid bogging down tests.

  // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation (sha256)
  const unsigned int modulus_length = 256;
  const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");
  blink::WebCryptoAlgorithm algorithm = CreateRsaHashedKeyGenAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha256, modulus_length, public_exponent);
  bool extractable = true;
  const blink::WebCryptoKeyUsageMask public_usages =
      blink::kWebCryptoKeyUsageVerify;
  const blink::WebCryptoKeyUsageMask private_usages =
      blink::kWebCryptoKeyUsageSign;
  const blink::WebCryptoKeyUsageMask usages = public_usages | private_usages;
  blink::WebCryptoKey public_key;
  blink::WebCryptoKey private_key;

  EXPECT_EQ(Status::Success(), GenerateKeyPair(algorithm, extractable, usages,
                                               &public_key, &private_key));
  ASSERT_FALSE(public_key.IsNull());
  ASSERT_FALSE(private_key.IsNull());
  EXPECT_EQ(blink::kWebCryptoKeyTypePublic, public_key.GetType());
  EXPECT_EQ(blink::kWebCryptoKeyTypePrivate, private_key.GetType());
  EXPECT_EQ(modulus_length,
            public_key.Algorithm().RsaHashedParams()->ModulusLengthBits());
  EXPECT_EQ(modulus_length,
            private_key.Algorithm().RsaHashedParams()->ModulusLengthBits());
  EXPECT_EQ(blink::kWebCryptoAlgorithmIdSha256,
            public_key.Algorithm().RsaHashedParams()->GetHash().Id());
  EXPECT_EQ(blink::kWebCryptoAlgorithmIdSha256,
            private_key.Algorithm().RsaHashedParams()->GetHash().Id());
  EXPECT_TRUE(public_key.Extractable());
  EXPECT_EQ(extractable, private_key.Extractable());
  EXPECT_EQ(public_usages, public_key.Usages());
  EXPECT_EQ(private_usages, private_key.Usages());

  // Try exporting the generated key pair, and then re-importing to verify that
  // the exported data was valid.
  std::vector<uint8_t> public_key_spki;
  EXPECT_EQ(Status::Success(), ExportKey(blink::kWebCryptoKeyFormatSpki,
                                         public_key, &public_key_spki));

  public_key = blink::WebCryptoKey::CreateNull();
  ASSERT_EQ(
      Status::Success(),
      ImportKey(blink::kWebCryptoKeyFormatSpki, CryptoData(public_key_spki),
                CreateRsaHashedImportAlgorithm(
                    blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                    blink::kWebCryptoAlgorithmIdSha256),
                true, public_usages, &public_key));
  EXPECT_EQ(modulus_length,
            public_key.Algorithm().RsaHashedParams()->ModulusLengthBits());

  std::vector<uint8_t> private_key_pkcs8;
  EXPECT_EQ(Status::Success(), ExportKey(blink::kWebCryptoKeyFormatPkcs8,
                                         private_key, &private_key_pkcs8));
  private_key = blink::WebCryptoKey::CreateNull();
  ASSERT_EQ(
      Status::Success(),
      ImportKey(blink::kWebCryptoKeyFormatPkcs8, CryptoData(private_key_pkcs8),
                CreateRsaHashedImportAlgorithm(
                    blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                    blink::kWebCryptoAlgorithmIdSha256),
                true, private_usages, &private_key));
  EXPECT_EQ(modulus_length,
            private_key.Algorithm().RsaHashedParams()->ModulusLengthBits());

  // Fail with bad modulus.
  algorithm = CreateRsaHashedKeyGenAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha256, 0, public_exponent);
  EXPECT_EQ(Status::ErrorGenerateRsaUnsupportedModulus(),
            GenerateKeyPair(algorithm, extractable, usages, &public_key,
                            &private_key));

  // Fail with bad exponent: larger than unsigned long.
  unsigned int exponent_length = sizeof(unsigned long) + 1;  // NOLINT
  const std::vector<uint8_t> long_exponent(exponent_length, 0x01);
  algorithm = CreateRsaHashedKeyGenAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha256, modulus_length, long_exponent);
  EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
            GenerateKeyPair(algorithm, extractable, usages, &public_key,
                            &private_key));

  // Fail with bad exponent: empty.
  const std::vector<uint8_t> empty_exponent;
  algorithm = CreateRsaHashedKeyGenAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha256, modulus_length, empty_exponent);
  EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
            GenerateKeyPair(algorithm, extractable, usages, &public_key,
                            &private_key));

  // Fail with bad exponent: all zeros.
  std::vector<uint8_t> exponent_with_leading_zeros(15, 0x00);
  algorithm = CreateRsaHashedKeyGenAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha256, modulus_length,
      exponent_with_leading_zeros);
  EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
            GenerateKeyPair(algorithm, extractable, usages, &public_key,
                            &private_key));

  // Key generation success using exponent with leading zeros.
  exponent_with_leading_zeros.insert(exponent_with_leading_zeros.end(),
                                     public_exponent.begin(),
                                     public_exponent.end());
  algorithm = CreateRsaHashedKeyGenAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha256, modulus_length,
      exponent_with_leading_zeros);
  EXPECT_EQ(Status::Success(), GenerateKeyPair(algorithm, extractable, usages,
                                               &public_key, &private_key));
  EXPECT_FALSE(public_key.IsNull());
  EXPECT_FALSE(private_key.IsNull());
  EXPECT_EQ(blink::kWebCryptoKeyTypePublic, public_key.GetType());
  EXPECT_EQ(blink::kWebCryptoKeyTypePrivate, private_key.GetType());
  EXPECT_TRUE(public_key.Extractable());
  EXPECT_EQ(extractable, private_key.Extractable());
  EXPECT_EQ(public_usages, public_key.Usages());
  EXPECT_EQ(private_usages, private_key.Usages());

  // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation (sha1)
  algorithm = CreateRsaHashedKeyGenAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha1, modulus_length, public_exponent);
  EXPECT_EQ(Status::Success(), GenerateKeyPair(algorithm, false, usages,
                                               &public_key, &private_key));
  EXPECT_FALSE(public_key.IsNull());
  EXPECT_FALSE(private_key.IsNull());
  EXPECT_EQ(blink::kWebCryptoKeyTypePublic, public_key.GetType());
  EXPECT_EQ(blink::kWebCryptoKeyTypePrivate, private_key.GetType());
  EXPECT_EQ(modulus_length,
            public_key.Algorithm().RsaHashedParams()->ModulusLengthBits());
  EXPECT_EQ(modulus_length,
            private_key.Algorithm().RsaHashedParams()->ModulusLengthBits());
  EXPECT_EQ(blink::kWebCryptoAlgorithmIdSha1,
            public_key.Algorithm().RsaHashedParams()->GetHash().Id());
  EXPECT_EQ(blink::kWebCryptoAlgorithmIdSha1,
            private_key.Algorithm().RsaHashedParams()->GetHash().Id());
  // Even though "extractable" was set to false, the public key remains
  // extractable.
  EXPECT_TRUE(public_key.Extractable());
  EXPECT_FALSE(private_key.Extractable());
  EXPECT_EQ(public_usages, public_key.Usages());
  EXPECT_EQ(private_usages, private_key.Usages());

  // Exporting a private key as SPKI format doesn't make sense. However this
  // will first fail because the key is not extractable.
  std::vector<uint8_t> output;
  EXPECT_EQ(Status::ErrorKeyNotExtractable(),
            ExportKey(blink::kWebCryptoKeyFormatSpki, private_key, &output));

  // Re-generate an extractable private_key and try to export it as SPKI format.
  // This should fail since spki is for public keys.
  EXPECT_EQ(Status::Success(), GenerateKeyPair(algorithm, true, usages,
                                               &public_key, &private_key));
  EXPECT_EQ(Status::ErrorUnexpectedKeyType(),
            ExportKey(blink::kWebCryptoKeyFormatSpki, private_key, &output));
}

TEST_F(WebCryptoRsaSsaTest, GenerateKeyPairRsaBadModulusLength) {
  const unsigned int kBadModulusBits[] = {
      0,
      248,         // Too small.
      257,         // Not a multiple of 8.
      1023,        // Not a multiple of 8.
      0xFFFFFFFF,  // Too big.
      16384 + 8,   // 16384 is the maxmimum length that NSS succeeds for.
  };

  const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");

  for (size_t i = 0; i < base::size(kBadModulusBits); ++i) {
    const unsigned int modulus_length_bits = kBadModulusBits[i];
    blink::WebCryptoAlgorithm algorithm = CreateRsaHashedKeyGenAlgorithm(
        blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
        blink::kWebCryptoAlgorithmIdSha256, modulus_length_bits,
        public_exponent);
    bool extractable = true;
    const blink::WebCryptoKeyUsageMask usages = blink::kWebCryptoKeyUsageSign;
    blink::WebCryptoKey public_key;
    blink::WebCryptoKey private_key;

    EXPECT_EQ(Status::ErrorGenerateRsaUnsupportedModulus(),
              GenerateKeyPair(algorithm, extractable, usages, &public_key,
                              &private_key));
  }
}

// Try generating RSA key pairs using unsupported public exponents. Only
// exponents of 3 and 65537 are supported. Although OpenSSL can support other
// values, it can also hang when given invalid exponents. To avoid hanging, use
// a whitelist of known safe exponents.
TEST_F(WebCryptoRsaSsaTest, GenerateKeyPairRsaBadExponent) {
  const unsigned int modulus_length = 1024;

  const char* const kPublicExponents[] = {
      "11",  // 17 - This is a valid public exponent, but currently disallowed.
      "00",
      "01",
      "02",
      "010000",  // 65536
  };

  for (size_t i = 0; i < base::size(kPublicExponents); ++i) {
    SCOPED_TRACE(i);
    blink::WebCryptoAlgorithm algorithm = CreateRsaHashedKeyGenAlgorithm(
        blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
        blink::kWebCryptoAlgorithmIdSha256, modulus_length,
        HexStringToBytes(kPublicExponents[i]));

    blink::WebCryptoKey public_key;
    blink::WebCryptoKey private_key;

    EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
              GenerateKeyPair(algorithm, true, blink::kWebCryptoKeyUsageSign,
                              &public_key, &private_key));
  }
}

TEST_F(WebCryptoRsaSsaTest, SignVerifyFailures) {
  // Import a key pair.
  blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha1);
  blink::WebCryptoKey public_key;
  blink::WebCryptoKey private_key;
  ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
      HexStringToBytes(kPublicKeySpkiDerHex),
      HexStringToBytes(kPrivateKeyPkcs8DerHex), import_algorithm, false,
      blink::kWebCryptoKeyUsageVerify, blink::kWebCryptoKeyUsageSign,
      &public_key, &private_key));

  blink::WebCryptoAlgorithm algorithm =
      CreateAlgorithm(blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5);

  std::vector<uint8_t> signature;
  bool signature_match;

  // Compute a signature.
  const std::vector<uint8_t> data = HexStringToBytes("010203040506070809");
  ASSERT_EQ(Status::Success(),
            Sign(algorithm, private_key, CryptoData(data), &signature));

  // Ensure truncated signature does not verify by passing one less byte.
  EXPECT_EQ(Status::Success(),
            Verify(algorithm, public_key,
                   CryptoData(signature.data(),
                              static_cast<unsigned int>(signature.size()) - 1),
                   CryptoData(data), &signature_match));
  EXPECT_FALSE(signature_match);

  // Ensure truncated signature does not verify by passing no bytes.
  EXPECT_EQ(Status::Success(), Verify(algorithm, public_key, CryptoData(),
                                      CryptoData(data), &signature_match));
  EXPECT_FALSE(signature_match);

  // Ensure corrupted signature does not verify.
  std::vector<uint8_t> corrupt_sig = signature;
  corrupt_sig[corrupt_sig.size() / 2] ^= 0x1;
  EXPECT_EQ(Status::Success(),
            Verify(algorithm, public_key, CryptoData(corrupt_sig),
                   CryptoData(data), &signature_match));
  EXPECT_FALSE(signature_match);

  // Ensure signatures that are greater than the modulus size fail.
  const unsigned int long_message_size_bytes = 1024;
  DCHECK_GT(long_message_size_bytes, kModulusLengthBits / 8);
  const unsigned char kLongSignature[long_message_size_bytes] = {0};
  EXPECT_EQ(Status::Success(),
            Verify(algorithm, public_key,
                   CryptoData(kLongSignature, sizeof(kLongSignature)),
                   CryptoData(data), &signature_match));
  EXPECT_FALSE(signature_match);

  // Ensure that signing and verifying with an incompatible algorithm fails.
  algorithm = CreateAlgorithm(blink::kWebCryptoAlgorithmIdRsaOaep);

  EXPECT_EQ(Status::ErrorUnexpected(),
            Sign(algorithm, private_key, CryptoData(data), &signature));
  EXPECT_EQ(Status::ErrorUnexpected(),
            Verify(algorithm, public_key, CryptoData(signature),
                   CryptoData(data), &signature_match));

  // Some crypto libraries (NSS) can automatically select the RSA SSA inner hash
  // based solely on the contents of the input signature data. In the Web Crypto
  // implementation, the inner hash should be specified uniquely by the key
  // algorithm parameter. To validate this behavior, call Verify with a computed
  // signature that used one hash type (SHA-1), but pass in a key with a
  // different inner hash type (SHA-256). If the hash type is determined by the
  // signature itself (undesired), the verify will pass, while if the hash type
  // is specified by the key algorithm (desired), the verify will fail.

  // Compute a signature using SHA-1 as the inner hash.
  EXPECT_EQ(Status::Success(),
            Sign(CreateAlgorithm(blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5),
                 private_key, CryptoData(data), &signature));

  blink::WebCryptoKey public_key_256;
  EXPECT_EQ(Status::Success(),
            ImportKey(blink::kWebCryptoKeyFormatSpki,
                      CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
                      CreateRsaHashedImportAlgorithm(
                          blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                          blink::kWebCryptoAlgorithmIdSha256),
                      true, blink::kWebCryptoKeyUsageVerify, &public_key_256));

  // Now verify using an algorithm whose inner hash is SHA-256, not SHA-1. The
  // signature should not verify.
  // NOTE: public_key was produced by generateKey, and so its associated
  // algorithm has WebCryptoRsaKeyGenParams and not WebCryptoRsaSsaParams. Thus
  // it has no inner hash to conflict with the input algorithm.
  EXPECT_EQ(blink::kWebCryptoAlgorithmIdSha1,
            private_key.Algorithm().RsaHashedParams()->GetHash().Id());
  EXPECT_EQ(blink::kWebCryptoAlgorithmIdSha256,
            public_key_256.Algorithm().RsaHashedParams()->GetHash().Id());

  bool is_match;
  EXPECT_EQ(Status::Success(),
            Verify(CreateAlgorithm(blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5),
                   public_key_256, CryptoData(signature), CryptoData(data),
                   &is_match));
  EXPECT_FALSE(is_match);
}

TEST_F(WebCryptoRsaSsaTest, SignVerifyKnownAnswer) {
  base::ListValue tests;
  ASSERT_TRUE(ReadJsonTestFileToList("pkcs1v15_sign.json", &tests));

  // Import the key pair.
  blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha1);
  blink::WebCryptoKey public_key;
  blink::WebCryptoKey private_key;
  ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
      HexStringToBytes(kPublicKeySpkiDerHex),
      HexStringToBytes(kPrivateKeyPkcs8DerHex), import_algorithm, false,
      blink::kWebCryptoKeyUsageVerify, blink::kWebCryptoKeyUsageSign,
      &public_key, &private_key));

  blink::WebCryptoAlgorithm algorithm =
      CreateAlgorithm(blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5);

  // Validate the signatures are computed and verified as expected.
  std::vector<uint8_t> signature;
  for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
    SCOPED_TRACE(test_index);

    base::DictionaryValue* test;
    ASSERT_TRUE(tests.GetDictionary(test_index, &test));

    std::vector<uint8_t> test_message =
        GetBytesFromHexString(test, "message_hex");
    std::vector<uint8_t> test_signature =
        GetBytesFromHexString(test, "signature_hex");

    signature.clear();
    ASSERT_EQ(Status::Success(), Sign(algorithm, private_key,
                                      CryptoData(test_message), &signature));
    EXPECT_BYTES_EQ(test_signature, signature);

    bool is_match = false;
    ASSERT_EQ(Status::Success(),
              Verify(algorithm, public_key, CryptoData(test_signature),
                     CryptoData(test_message), &is_match));
    EXPECT_TRUE(is_match);
  }
}

// Try importing an RSA-SSA public key with unsupported key usages using SPKI
// format. RSA-SSA public keys only support the 'verify' usage.
TEST_F(WebCryptoRsaSsaTest, ImportRsaSsaPublicKeyBadUsage_SPKI) {
  const blink::WebCryptoAlgorithm algorithm = CreateRsaHashedImportAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha256);

  blink::WebCryptoKeyUsageMask bad_usages[] = {
      blink::kWebCryptoKeyUsageSign,
      blink::kWebCryptoKeyUsageSign | blink::kWebCryptoKeyUsageVerify,
      blink::kWebCryptoKeyUsageEncrypt,
      blink::kWebCryptoKeyUsageEncrypt | blink::kWebCryptoKeyUsageDecrypt,
  };

  for (size_t i = 0; i < base::size(bad_usages); ++i) {
    SCOPED_TRACE(i);

    blink::WebCryptoKey public_key;
    ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
              ImportKey(blink::kWebCryptoKeyFormatSpki,
                        CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
                        algorithm, false, bad_usages[i], &public_key));
  }
}

// Try importing an RSA-SSA public key with unsupported key usages using JWK
// format. RSA-SSA public keys only support the 'verify' usage.
TEST_F(WebCryptoRsaSsaTest, ImportRsaSsaPublicKeyBadUsage_JWK) {
  const blink::WebCryptoAlgorithm algorithm = CreateRsaHashedImportAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha256);

  blink::WebCryptoKeyUsageMask bad_usages[] = {
      blink::kWebCryptoKeyUsageSign,
      blink::kWebCryptoKeyUsageSign | blink::kWebCryptoKeyUsageVerify,
      blink::kWebCryptoKeyUsageEncrypt,
      blink::kWebCryptoKeyUsageEncrypt | blink::kWebCryptoKeyUsageDecrypt,
  };

  base::DictionaryValue dict;
  RestoreJwkRsaDictionary(&dict);
  dict.Remove("use", nullptr);
  dict.SetString("alg", "RS256");

  for (size_t i = 0; i < base::size(bad_usages); ++i) {
    SCOPED_TRACE(i);

    blink::WebCryptoKey public_key;
    ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
              ImportKeyJwkFromDict(dict, algorithm, false, bad_usages[i],
                                   &public_key));
  }
}

// Generate an RSA-SSA key pair with invalid usages. RSA-SSA supports:
//   'sign', 'verify'
TEST_F(WebCryptoRsaSsaTest, GenerateKeyBadUsages) {
  blink::WebCryptoKeyUsageMask bad_usages[] = {
      blink::kWebCryptoKeyUsageDecrypt,
      blink::kWebCryptoKeyUsageVerify | blink::kWebCryptoKeyUsageDecrypt,
      blink::kWebCryptoKeyUsageWrapKey,
  };

  const unsigned int modulus_length = 256;
  const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");

  for (size_t i = 0; i < base::size(bad_usages); ++i) {
    SCOPED_TRACE(i);

    blink::WebCryptoKey public_key;
    blink::WebCryptoKey private_key;

    ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
              GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
                                  blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                                  blink::kWebCryptoAlgorithmIdSha256,
                                  modulus_length, public_exponent),
                              true, bad_usages[i], &public_key, &private_key));
  }
}

// Generate an RSA-SSA key pair. The public and private keys should select the
// key usages which are applicable, and not have the exact same usages as was
// specified to GenerateKey
TEST_F(WebCryptoRsaSsaTest, GenerateKeyPairIntersectUsages) {
  const unsigned int modulus_length = 256;
  const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");

  blink::WebCryptoKey public_key;
  blink::WebCryptoKey private_key;

  ASSERT_EQ(
      Status::Success(),
      GenerateKeyPair(
          CreateRsaHashedKeyGenAlgorithm(
              blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
              blink::kWebCryptoAlgorithmIdSha256, modulus_length,
              public_exponent),
          true, blink::kWebCryptoKeyUsageSign | blink::kWebCryptoKeyUsageVerify,
          &public_key, &private_key));

  EXPECT_EQ(blink::kWebCryptoKeyUsageVerify, public_key.Usages());
  EXPECT_EQ(blink::kWebCryptoKeyUsageSign, private_key.Usages());

  // Try again but this time without the Verify usages.
  ASSERT_EQ(Status::Success(),
            GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
                                blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                                blink::kWebCryptoAlgorithmIdSha256,
                                modulus_length, public_exponent),
                            true, blink::kWebCryptoKeyUsageSign, &public_key,
                            &private_key));

  EXPECT_EQ(0, public_key.Usages());
  EXPECT_EQ(blink::kWebCryptoKeyUsageSign, private_key.Usages());
}

TEST_F(WebCryptoRsaSsaTest, GenerateKeyPairEmptyUsages) {
  const unsigned int modulus_length = 256;
  const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");

  blink::WebCryptoKey public_key;
  blink::WebCryptoKey private_key;

  ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
            GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
                                blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                                blink::kWebCryptoAlgorithmIdSha256,
                                modulus_length, public_exponent),
                            true, 0, &public_key, &private_key));
}

TEST_F(WebCryptoRsaSsaTest, ImportKeyEmptyUsages) {
  blink::WebCryptoKey public_key;
  blink::WebCryptoKey private_key;

  // Public without usage does not throw an error.
  ASSERT_EQ(Status::Success(),
            ImportKey(blink::kWebCryptoKeyFormatSpki,
                      CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
                      CreateRsaHashedImportAlgorithm(
                          blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                          blink::kWebCryptoAlgorithmIdSha256),
                      true, 0, &public_key));
  EXPECT_EQ(0, public_key.Usages());

  // Private empty usage will throw an error.
  ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
            ImportKey(blink::kWebCryptoKeyFormatPkcs8,
                      CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
                      CreateRsaHashedImportAlgorithm(
                          blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                          blink::kWebCryptoAlgorithmIdSha1),
                      true, 0, &private_key));

  std::vector<uint8_t> public_jwk;
  ASSERT_EQ(Status::Success(),
            ExportKey(blink::kWebCryptoKeyFormatJwk, public_key, &public_jwk));

  ASSERT_EQ(Status::Success(),
            ImportKey(blink::kWebCryptoKeyFormatJwk, CryptoData(public_jwk),
                      CreateRsaHashedImportAlgorithm(
                          blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                          blink::kWebCryptoAlgorithmIdSha256),
                      true, 0, &public_key));
  EXPECT_EQ(0, public_key.Usages());

  // With correct usage to get correct imported private_key
  std::vector<uint8_t> private_jwk;
  ImportKey(blink::kWebCryptoKeyFormatPkcs8,
            CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
            CreateRsaHashedImportAlgorithm(
                blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                blink::kWebCryptoAlgorithmIdSha1),
            true, blink::kWebCryptoKeyUsageSign, &private_key);

  ASSERT_EQ(Status::Success(), ExportKey(blink::kWebCryptoKeyFormatJwk,
                                         private_key, &private_jwk));

  ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
            ImportKey(blink::kWebCryptoKeyFormatJwk, CryptoData(private_jwk),
                      CreateRsaHashedImportAlgorithm(
                          blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                          blink::kWebCryptoAlgorithmIdSha1),
                      true, 0, &private_key));
}

TEST_F(WebCryptoRsaSsaTest, ImportExportJwkRsaPublicKey) {
  struct TestCase {
    const blink::WebCryptoAlgorithmId hash;
    const blink::WebCryptoKeyUsageMask usage;
    const char* const jwk_alg;
  };
  const TestCase kTests[] = {{blink::kWebCryptoAlgorithmIdSha1,
                              blink::kWebCryptoKeyUsageVerify, "RS1"},
                             {blink::kWebCryptoAlgorithmIdSha256,
                              blink::kWebCryptoKeyUsageVerify, "RS256"},
                             {blink::kWebCryptoAlgorithmIdSha384,
                              blink::kWebCryptoKeyUsageVerify, "RS384"},
                             {blink::kWebCryptoAlgorithmIdSha512,
                              blink::kWebCryptoKeyUsageVerify, "RS512"}};

  for (size_t test_index = 0; test_index < base::size(kTests); ++test_index) {
    SCOPED_TRACE(test_index);
    const TestCase& test = kTests[test_index];

    const blink::WebCryptoAlgorithm import_algorithm =
        CreateRsaHashedImportAlgorithm(
            blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5, test.hash);

    // Import the spki to create a public key
    blink::WebCryptoKey public_key;
    ASSERT_EQ(Status::Success(),
              ImportKey(blink::kWebCryptoKeyFormatSpki,
                        CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
                        import_algorithm, true, test.usage, &public_key));

    // Export the public key as JWK and verify its contents
    std::vector<uint8_t> jwk;
    ASSERT_EQ(Status::Success(),
              ExportKey(blink::kWebCryptoKeyFormatJwk, public_key, &jwk));
    EXPECT_TRUE(VerifyPublicJwk(jwk, test.jwk_alg, kPublicKeyModulusHex,
                                kPublicKeyExponentHex, test.usage));

    // Import the JWK back in to create a new key
    blink::WebCryptoKey public_key2;
    ASSERT_EQ(Status::Success(),
              ImportKey(blink::kWebCryptoKeyFormatJwk, CryptoData(jwk),
                        import_algorithm, true, test.usage, &public_key2));
    ASSERT_TRUE(public_key2.Handle());
    EXPECT_EQ(blink::kWebCryptoKeyTypePublic, public_key2.GetType());
    EXPECT_TRUE(public_key2.Extractable());
    EXPECT_EQ(import_algorithm.Id(), public_key2.Algorithm().Id());

    // Export the new key as spki and compare to the original.
    std::vector<uint8_t> spki;
    ASSERT_EQ(Status::Success(),
              ExportKey(blink::kWebCryptoKeyFormatSpki, public_key2, &spki));
    EXPECT_BYTES_EQ_HEX(kPublicKeySpkiDerHex, CryptoData(spki));
  }
}

TEST_F(WebCryptoRsaSsaTest, ImportJwkRsaFailures) {
  base::DictionaryValue dict;
  RestoreJwkRsaDictionary(&dict);
  blink::WebCryptoAlgorithm algorithm = CreateRsaHashedImportAlgorithm(
      blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
      blink::kWebCryptoAlgorithmIdSha256);
  blink::WebCryptoKeyUsageMask usages = blink::kWebCryptoKeyUsageVerify;
  blink::WebCryptoKey key;

  // An RSA public key JWK _must_ have an "n" (modulus) and an "e" (exponent)
  // entry, while an RSA private key must have those plus at least a "d"
  // (private exponent) entry.
  // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
  // section 6.3.

  // Baseline pass.
  EXPECT_EQ(Status::Success(),
            ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
  EXPECT_EQ(algorithm.Id(), key.Algorithm().Id());
  EXPECT_FALSE(key.Extractable());
  EXPECT_EQ(blink::kWebCryptoKeyUsageVerify, key.Usages());
  EXPECT_EQ(blink::kWebCryptoKeyTypePublic, key.GetType());

  // The following are specific failure cases for when kty = "RSA".

  // Fail if either "n" or "e" is not present or malformed.
  const std::string kKtyParmName[] = {"n", "e"};
  for (size_t idx = 0; idx < base::size(kKtyParmName); ++idx) {
    // Fail on missing parameter.
    dict.Remove(kKtyParmName[idx], nullptr);
    EXPECT_NE(Status::Success(),
              ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
    RestoreJwkRsaDictionary(&dict);

    // Fail on bad b64 parameter encoding.
    dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0");
    EXPECT_NE(Status::Success(),
              ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
    RestoreJwkRsaDictionary(&dict);

    // Fail on empty parameter.
    dict.SetString(kKtyParmName[idx], "");
    EXPECT_EQ(Status::ErrorJwkEmptyBigInteger(kKtyParmName[idx]),
              ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
    RestoreJwkRsaDictionary(&dict);
  }
}

// Try importing an RSA-SSA key from JWK format, having specified both Sign and
// Verify usage, AND an invalid JWK.
//
// Parsing the invalid JWK will fail before the usage check is done.
TEST_F(WebCryptoRsaSsaTest, ImportRsaSsaJwkBadUsageAndData) {
  std::string bad_data = "hello";

  blink::WebCryptoKey key;
  ASSERT_EQ(
      Status::ErrorJwkNotDictionary(),
      ImportKey(blink::kWebCryptoKeyFormatJwk, CryptoData(bad_data),
                CreateRsaHashedImportAlgorithm(
                    blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                    blink::kWebCryptoAlgorithmIdSha256),
                true,
                blink::kWebCryptoKeyUsageVerify | blink::kWebCryptoKeyUsageSign,
                &key));
}

// Imports invalid JWK/SPKI/PKCS8 data and verifies that it fails as expected.
TEST_F(WebCryptoRsaSsaTest, ImportInvalidKeyData) {
  base::ListValue tests;
  ASSERT_TRUE(ReadJsonTestFileToList("bad_rsa_keys.json", &tests));

  for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
    SCOPED_TRACE(test_index);

    const base::DictionaryValue* test;
    ASSERT_TRUE(tests.GetDictionary(test_index, &test));

    blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test);
    std::vector<uint8_t> key_data =
        GetKeyDataFromJsonTestCase(test, key_format);
    std::string test_error;
    ASSERT_TRUE(test->GetString("error", &test_error));

    blink::WebCryptoKeyUsageMask usages = blink::kWebCryptoKeyUsageSign;
    if (key_format == blink::kWebCryptoKeyFormatSpki)
      usages = blink::kWebCryptoKeyUsageVerify;
    blink::WebCryptoKey key;
    Status status = ImportKey(key_format, CryptoData(key_data),
                              CreateRsaHashedImportAlgorithm(
                                  blink::kWebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                                  blink::kWebCryptoAlgorithmIdSha256),
                              true, usages, &key);
    EXPECT_EQ(test_error, StatusToString(status));
  }
}

}  // namespace

}  // namespace webcrypto
