// Copyright 2013 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 "media/cdm/json_web_key.h"

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

#include "base/base64.h"
#include "base/logging.h"
#include "base/macros.h"
#include "media/base/content_decryption_module.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

class JSONWebKeyTest : public testing::Test {
 public:
  JSONWebKeyTest() {}

 protected:
  void ExtractJWKKeysAndExpect(const std::string& jwk,
                               bool expected_result,
                               size_t expected_number_of_keys) {
    DCHECK(!jwk.empty());
    KeyIdAndKeyPairs keys;
    CdmSessionType session_type;
    EXPECT_EQ(expected_result,
              ExtractKeysFromJWKSet(jwk, &keys, &session_type));
    EXPECT_EQ(expected_number_of_keys, keys.size());
  }

  void ExtractSessionTypeAndExpect(const std::string& jwk,
                                   bool expected_result,
                                   CdmSessionType expected_type) {
    DCHECK(!jwk.empty());
    KeyIdAndKeyPairs keys;
    CdmSessionType session_type;
    EXPECT_EQ(expected_result,
              ExtractKeysFromJWKSet(jwk, &keys, &session_type));
    if (expected_result) {
      // Only check if successful.
      EXPECT_EQ(expected_type, session_type);
    }
  }

  void CreateLicenseAndExpect(const uint8_t* key_id,
                              int key_id_length,
                              CdmSessionType session_type,
                              const std::string& expected_result) {
    std::vector<uint8_t> result;
    KeyIdList key_ids;
    key_ids.push_back(std::vector<uint8_t>(key_id, key_id + key_id_length));
    CreateLicenseRequest(key_ids, session_type, &result);
    std::string s(result.begin(), result.end());
    EXPECT_EQ(expected_result, s);
  }

  void ExtractKeyFromLicenseAndExpect(const std::string& license,
                                      bool expected_result,
                                      const uint8_t* expected_key,
                                      int expected_key_length) {
    std::vector<uint8_t> license_vector(license.begin(), license.end());
    std::vector<uint8_t> key;
    EXPECT_EQ(expected_result,
              ExtractFirstKeyIdFromLicenseRequest(license_vector, &key));
    if (expected_result)
      VerifyKeyId(key, expected_key, expected_key_length);
  }

  void VerifyKeyId(std::vector<uint8_t> key,
                   const uint8_t* expected_key,
                   int expected_key_length) {
    std::vector<uint8_t> key_result(expected_key,
                                    expected_key + expected_key_length);
    EXPECT_EQ(key_result, key);
  }

  KeyIdAndKeyPair MakeKeyIdAndKeyPair(const uint8_t* key,
                                      int key_length,
                                      const uint8_t* key_id,
                                      int key_id_length) {
    return std::make_pair(std::string(key_id, key_id + key_id_length),
                          std::string(key, key + key_length));
  }
};

TEST_F(JSONWebKeyTest, GenerateJWKSet) {
  const uint8_t data1[] = {0x01, 0x02};
  const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04};
  const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                           0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};

  EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
            GenerateJWKSet(data1, arraysize(data1), data1, arraysize(data1)));
  EXPECT_EQ(
      "{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}",
      GenerateJWKSet(data2, arraysize(data2), data2, arraysize(data2)));
  EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}",
            GenerateJWKSet(data1, arraysize(data1), data2, arraysize(data2)));
  EXPECT_EQ("{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
            GenerateJWKSet(data2, arraysize(data2), data1, arraysize(data1)));
  EXPECT_EQ(
      "{\"keys\":[{\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":"
      "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":\"oct\"}]}",
      GenerateJWKSet(data3, arraysize(data3), data3, arraysize(data3)));

  KeyIdAndKeyPairs keys;
  keys.push_back(
      MakeKeyIdAndKeyPair(data1, arraysize(data1), data1, arraysize(data1)));
  EXPECT_EQ(
      "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
      "\"temporary\"}",
      GenerateJWKSet(keys, CdmSessionType::TEMPORARY_SESSION));
  keys.push_back(
      MakeKeyIdAndKeyPair(data2, arraysize(data2), data2, arraysize(data2)));
  EXPECT_EQ(
      "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"},{\"k\":"
      "\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}],\"type\":\"persistent-"
      "license\"}",
      GenerateJWKSet(keys, CdmSessionType::PERSISTENT_LICENSE_SESSION));
  keys.push_back(
      MakeKeyIdAndKeyPair(data3, arraysize(data3), data3, arraysize(data3)));
  EXPECT_EQ(
      "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"},{\"k\":"
      "\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"},{\"k\":"
      "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":"
      "\"oct\"}],\"type\":\"persistent-release-message\"}",
      GenerateJWKSet(keys, CdmSessionType::PERSISTENT_RELEASE_MESSAGE_SESSION));
}

TEST_F(JSONWebKeyTest, ExtractValidJWKKeys) {
  // Try an empty 'keys' dictionary.
  ExtractJWKKeysAndExpect("{ \"keys\": [] }", true, 0);

  // Try a key list with one entry.
  const std::string kJwksOneEntry =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
      "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksOneEntry, true, 1);

  // Try a key list with multiple entries.
  const std::string kJwksMultipleEntries =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
      "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
      "    },"
      "    {"
      "      \"kty\": \"oct\","
      "      \"kid\": \"JCUmJygpKissLS4vMA\","
      "      \"k\":\"MTIzNDU2Nzg5Ojs8PT4_QA\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksMultipleEntries, true, 2);

  // Try a key with no spaces and some \n plus additional fields.
  const std::string kJwksNoSpaces =
      "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\","
      "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg"
      "\",\"foo\":\"bar\"}]}\n\n";
  ExtractJWKKeysAndExpect(kJwksNoSpaces, true, 1);

  // Try a list with multiple keys with the same kid.
  const std::string kJwksDuplicateKids =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"kid\": \"JCUmJygpKissLS4vMA\","
      "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
      "    },"
      "    {"
      "      \"kty\": \"oct\","
      "      \"kid\": \"JCUmJygpKissLS4vMA\","
      "      \"k\":\"MTIzNDU2Nzg5Ojs8PT4_QA\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksDuplicateKids, true, 2);
}

TEST_F(JSONWebKeyTest, ExtractInvalidJWKKeys) {
  // Try a simple JWK key (i.e. not in a set)
  const std::string kJwkSimple =
      "{"
      "  \"kty\": \"oct\","
      "  \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
      "  \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
      "}";
  ExtractJWKKeysAndExpect(kJwkSimple, false, 0);

  // Try some non-ASCII characters.
  ExtractJWKKeysAndExpect(
      "This is not ASCII due to \xff\xfe\xfd in it.", false, 0);

  // Try some non-ASCII characters in an otherwise valid JWK.
  const std::string kJwksInvalidCharacters =
      "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\","
      "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"\xff\xfe\xfd"
      "\",\"foo\":\"bar\"}]}\n\n";
  ExtractJWKKeysAndExpect(kJwksInvalidCharacters, false, 0);

  // Try a badly formatted key. Assume that the JSON parser is fully tested,
  // so we won't try a lot of combinations. However, need a test to ensure
  // that the code doesn't crash if invalid JSON received.
  ExtractJWKKeysAndExpect("This is not a JSON key.", false, 0);

  // Try passing some valid JSON that is not a dictionary at the top level.
  ExtractJWKKeysAndExpect("40", false, 0);

  // Try an empty dictionary.
  ExtractJWKKeysAndExpect("{ }", false, 0);

  // Try with 'keys' not a dictionary.
  ExtractJWKKeysAndExpect("{ \"keys\":\"1\" }", false, 0);

  // Try with 'keys' a list of integers.
  ExtractJWKKeysAndExpect("{ \"keys\": [ 1, 2, 3 ] }", false, 0);

  // Try padding(=) at end of 'k' base64 string.
  const std::string kJwksWithPaddedKey =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"kid\": \"AAECAw\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithPaddedKey, false, 0);

  // Try padding(=) at end of 'kid' base64 string.
  const std::string kJwksWithPaddedKeyId =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"kid\": \"AAECAw==\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithPaddedKeyId, false, 0);

  // Try a key with invalid base64 encoding.
  const std::string kJwksWithInvalidBase64 =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"kid\": \"!@#$%^&*()\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithInvalidBase64, false, 0);

  // Empty key id.
  const std::string kJwksWithEmptyKeyId =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"kid\": \"\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithEmptyKeyId, false, 0);
}

TEST_F(JSONWebKeyTest, KeyType) {
  // Valid key type.
  const std::string kJwksWithValidKeyType =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithValidKeyType, true, 1);

  // Empty key type.
  const std::string kJwksWithEmptyKeyType =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"\","
      "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithEmptyKeyType, false, 0);

  // Key type is case sensitive.
  const std::string kJwksWithUppercaseKeyType =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"OCT\","
      "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithUppercaseKeyType, false, 0);

  // Wrong key type.
  const std::string kJwksWithWrongKeyType =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"RSA\","
      "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithWrongKeyType, false, 0);
}

TEST_F(JSONWebKeyTest, Alg) {
  // 'alg' is ignored, so verify that anything is allowed.
  // Valid alg.
  const std::string kJwksWithValidAlg =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"alg\": \"A128KW\","
      "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithValidAlg, true, 1);

  // Empty alg.
  const std::string kJwksWithEmptyAlg =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"alg\": \"\","
      "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithEmptyAlg, true, 1);

  // Alg is case sensitive.
  const std::string kJwksWithLowercaseAlg =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"alg\": \"a128kw\","
      "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithLowercaseAlg, true, 1);

  // Wrong alg.
  const std::string kJwksWithWrongAlg =
      "{"
      "  \"keys\": ["
      "    {"
      "      \"kty\": \"oct\","
      "      \"alg\": \"RS256\","
      "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
      "    }"
      "  ]"
      "}";
  ExtractJWKKeysAndExpect(kJwksWithWrongAlg, true, 1);
}

TEST_F(JSONWebKeyTest, CdmSessionType) {
  ExtractSessionTypeAndExpect(
      "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}", true,
      CdmSessionType::TEMPORARY_SESSION);
  ExtractSessionTypeAndExpect(
      "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
      "\"temporary\"}",
      true, CdmSessionType::TEMPORARY_SESSION);
  ExtractSessionTypeAndExpect(
      "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
      "\"persistent-license\"}",
      true, CdmSessionType::PERSISTENT_LICENSE_SESSION);
  ExtractSessionTypeAndExpect(
      "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
      "\"persistent-release-message\"}",
      true, CdmSessionType::PERSISTENT_RELEASE_MESSAGE_SESSION);
  ExtractSessionTypeAndExpect(
      "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
      "\"unknown\"}",
      false, CdmSessionType::TEMPORARY_SESSION);
  ExtractSessionTypeAndExpect(
      "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":3}",
      false, CdmSessionType::TEMPORARY_SESSION);
}

TEST_F(JSONWebKeyTest, CreateLicense) {
  const uint8_t data1[] = {0x01, 0x02};
  const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04};
  const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                           0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};

  CreateLicenseAndExpect(data1, arraysize(data1),
                         CdmSessionType::TEMPORARY_SESSION,
                         "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}");
  CreateLicenseAndExpect(
      data1, arraysize(data1), CdmSessionType::PERSISTENT_LICENSE_SESSION,
      "{\"kids\":[\"AQI\"],\"type\":\"persistent-license\"}");
  CreateLicenseAndExpect(
      data1, arraysize(data1),
      CdmSessionType::PERSISTENT_RELEASE_MESSAGE_SESSION,
      "{\"kids\":[\"AQI\"],\"type\":\"persistent-release-message\"}");
  CreateLicenseAndExpect(data2, arraysize(data2),
                         CdmSessionType::TEMPORARY_SESSION,
                         "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}");
  CreateLicenseAndExpect(data3, arraysize(data3),
                         CdmSessionType::PERSISTENT_LICENSE_SESSION,
                         "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":"
                         "\"persistent-license\"}");
}

TEST_F(JSONWebKeyTest, ExtractLicense) {
  const uint8_t data1[] = {0x01, 0x02};
  const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04};
  const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                           0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};

  ExtractKeyFromLicenseAndExpect(
      "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}",
      true,
      data1,
      arraysize(data1));
  ExtractKeyFromLicenseAndExpect(
      "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}",
      true,
      data2,
      arraysize(data2));
  ExtractKeyFromLicenseAndExpect(
      "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":\"persistent\"}",
      true,
      data3,
      arraysize(data3));

  // Try some incorrect JSON.
  ExtractKeyFromLicenseAndExpect("", false, NULL, 0);
  ExtractKeyFromLicenseAndExpect("!@#$%^&*()", false, NULL, 0);

  // Valid JSON, but not a dictionary.
  ExtractKeyFromLicenseAndExpect("6", false, NULL, 0);
  ExtractKeyFromLicenseAndExpect("[\"AQI\"]", false, NULL, 0);

  // Dictionary, but missing expected tag.
  ExtractKeyFromLicenseAndExpect("{\"kid\":[\"AQI\"]}", false, NULL, 0);

  // Correct tag, but empty list.
  ExtractKeyFromLicenseAndExpect("{\"kids\":[]}", false, NULL, 0);

  // Correct tag, but list doesn't contain a string.
  ExtractKeyFromLicenseAndExpect("{\"kids\":[[\"AQI\"]]}", false, NULL, 0);

  // Correct tag, but invalid base64 encoding.
  ExtractKeyFromLicenseAndExpect("{\"kids\":[\"!@#$%^&*()\"]}", false, NULL, 0);
}

TEST_F(JSONWebKeyTest, Base64UrlEncoding) {
  const uint8_t data1[] = {0xfb, 0xfd, 0xfb, 0xfd, 0xfb, 0xfd, 0xfb};

  // Verify that |data1| contains invalid base64url characters '+' and '/'
  // and is padded with = when converted to base64.
  std::string encoded_text;
  base::Base64Encode(
      std::string(reinterpret_cast<const char*>(&data1[0]), arraysize(data1)),
      &encoded_text);
  EXPECT_EQ(encoded_text, "+/37/fv9+w==");
  EXPECT_NE(encoded_text.find('+'), std::string::npos);
  EXPECT_NE(encoded_text.find('/'), std::string::npos);
  EXPECT_NE(encoded_text.find('='), std::string::npos);

  // base64url characters '-' and '_' not in base64 encoding.
  EXPECT_EQ(encoded_text.find('-'), std::string::npos);
  EXPECT_EQ(encoded_text.find('_'), std::string::npos);

  CreateLicenseAndExpect(data1, arraysize(data1),
                         CdmSessionType::TEMPORARY_SESSION,
                         "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}");

  ExtractKeyFromLicenseAndExpect(
      "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}", true, data1,
      arraysize(data1));
}

TEST_F(JSONWebKeyTest, MultipleKeys) {
  const uint8_t data1[] = {0x01, 0x02};
  const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04};
  const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                           0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};

  std::vector<uint8_t> result;
  KeyIdList key_ids;
  key_ids.push_back(std::vector<uint8_t>(data1, data1 + arraysize(data1)));
  key_ids.push_back(std::vector<uint8_t>(data2, data2 + arraysize(data2)));
  key_ids.push_back(std::vector<uint8_t>(data3, data3 + arraysize(data3)));
  CreateLicenseRequest(key_ids, CdmSessionType::TEMPORARY_SESSION, &result);
  std::string s(result.begin(), result.end());
  EXPECT_EQ(
      "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":"
      "\"temporary\"}",
      s);
}

TEST_F(JSONWebKeyTest, ExtractKeyIds) {
  const uint8_t data1[] = {0x01, 0x02};
  const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04};
  const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                           0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};

  KeyIdList key_ids;
  std::string error_message;

  EXPECT_TRUE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"AQI\"]}", &key_ids,
                                              &error_message));
  EXPECT_EQ(1u, key_ids.size());
  EXPECT_EQ(0u, error_message.length());
  VerifyKeyId(key_ids[0], data1, arraysize(data1));

  EXPECT_TRUE(ExtractKeyIdsFromKeyIdsInitData(
      "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"]}", &key_ids,
      &error_message));
  EXPECT_EQ(3u, key_ids.size());
  EXPECT_EQ(0u, error_message.length());
  VerifyKeyId(key_ids[0], data1, arraysize(data1));
  VerifyKeyId(key_ids[1], data2, arraysize(data2));
  VerifyKeyId(key_ids[2], data3, arraysize(data3));

  // Expect failure when non-ascii.
  EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData(
      "This is not ASCII due to \xff\xfe\x0a in it.", &key_ids,
      &error_message));
  EXPECT_EQ(3u, key_ids.size());  // |key_ids| should be unchanged.
  EXPECT_EQ(error_message,
            "Non ASCII: This is not ASCII due to \\u00FF\\u00FE\\n in it.");

  // Expect failure when not JSON or not a dictionary.
  EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("This is invalid.", &key_ids,
                                               &error_message));
  EXPECT_EQ(3u, key_ids.size());  // |key_ids| should be unchanged.
  EXPECT_EQ(error_message, "Not valid JSON: This is invalid.");
  EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("6", &key_ids, &error_message));
  EXPECT_EQ(3u, key_ids.size());  // |key_ids| should be unchanged.
  EXPECT_EQ(error_message, "Not valid JSON: 6");
  EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData(
      "This is a very long string that is longer than 64 characters and is "
      "invalid.",
      &key_ids, &error_message));
  EXPECT_EQ(3u, key_ids.size());  // |key_ids| should be unchanged.
  EXPECT_EQ(error_message,
            "Not valid JSON: This is a very long string that is longer than 64 "
            "characters ...");

  // Expect failure when "kids" not specified.
  EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"keys\":[\"AQI\"]}", &key_ids,
                                               &error_message));
  EXPECT_EQ(3u, key_ids.size());  // |key_ids| should be unchanged.
  EXPECT_EQ(error_message, "Missing 'kids' parameter or not a list");

  // Expect failure when invalid key_ids specified.
  EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[1]}", &key_ids,
                                               &error_message));
  EXPECT_EQ(3u, key_ids.size());  // |key_ids| should be unchanged.
  EXPECT_EQ(error_message, "'kids'[0] is not string.");
  EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\": {\"id\":\"AQI\" }}",
                                               &key_ids, &error_message));
  EXPECT_EQ(3u, key_ids.size());  // |key_ids| should be unchanged.
  EXPECT_EQ(error_message, "Missing 'kids' parameter or not a list");

  // Expect failure when non-base64 key_ids specified.
  EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"AQI+\"]}",
                                               &key_ids, &error_message));
  EXPECT_EQ(3u, key_ids.size());  // |key_ids| should be unchanged.
  EXPECT_EQ(error_message,
            "'kids'[0] is not valid base64url encoded. Value: AQI+");
  EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"AQI\",\"AQI/\"]}",
                                               &key_ids, &error_message));
  EXPECT_EQ(3u, key_ids.size());  // |key_ids| should be unchanged.
  EXPECT_EQ(error_message,
            "'kids'[1] is not valid base64url encoded. Value: AQI/");
}

TEST_F(JSONWebKeyTest, CreateInitData) {
  const uint8_t data1[] = {0x01, 0x02};
  const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04};
  const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                           0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};

  KeyIdList key_ids;
  std::string error_message;

  key_ids.push_back(std::vector<uint8_t>(data1, data1 + arraysize(data1)));
  std::vector<uint8_t> init_data1;
  CreateKeyIdsInitData(key_ids, &init_data1);
  std::string result1(init_data1.begin(), init_data1.end());
  EXPECT_EQ(result1, "{\"kids\":[\"AQI\"]}");

  key_ids.push_back(std::vector<uint8_t>(data2, data2 + arraysize(data2)));
  std::vector<uint8_t> init_data2;
  CreateKeyIdsInitData(key_ids, &init_data2);
  std::string result2(init_data2.begin(), init_data2.end());
  EXPECT_EQ(result2, "{\"kids\":[\"AQI\",\"AQIDBA\"]}");

  key_ids.push_back(std::vector<uint8_t>(data3, data3 + arraysize(data3)));
  std::vector<uint8_t> init_data3;
  CreateKeyIdsInitData(key_ids, &init_data3);
  std::string result3(init_data3.begin(), init_data3.end());
  EXPECT_EQ(result3,
            "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"]}");
}

}  // namespace media

