bool SerializedScriptValueReaderForModules::doReadRsaHashedKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& type)
{
    WebCryptoAlgorithmId id;
    if (!doReadAlgorithmId(id))
        return false;

    if (!doReadAsymmetricKeyType(type))
        return false;

    uint32_t modulusLengthBits;
    if (!doReadUint32(&modulusLengthBits))
        return false;

    uint32_t publicExponentSize;
    if (!doReadUint32(&publicExponentSize))
        return false;

    if (position() + publicExponentSize > length())
        return false;

    const uint8_t* publicExponent = allocate(publicExponentSize);
    WebCryptoAlgorithmId hash;
    if (!doReadAlgorithmId(hash))
        return false;
    algorithm = WebCryptoKeyAlgorithm::createRsaHashed(id, modulusLengthBits, publicExponent, publicExponentSize, hash);

    return !algorithm.isNull();
}
bool SerializedScriptValueReaderForModules::readCryptoKey(
    v8::Local<v8::Value>* value) {
  uint32_t rawKeyType;
  if (!doReadUint32(&rawKeyType))
    return false;

  WebCryptoKeyAlgorithm algorithm;
  WebCryptoKeyType type = WebCryptoKeyTypeSecret;

  switch (static_cast<CryptoKeySubTag>(rawKeyType)) {
    case AesKeyTag:
      if (!doReadAesKey(algorithm, type))
        return false;
      break;
    case HmacKeyTag:
      if (!doReadHmacKey(algorithm, type))
        return false;
      break;
    case RsaHashedKeyTag:
      if (!doReadRsaHashedKey(algorithm, type))
        return false;
      break;
    case EcKeyTag:
      if (!doReadEcKey(algorithm, type))
        return false;
      break;
    case NoParamsKeyTag:
      if (!doReadKeyWithoutParams(algorithm, type))
        return false;
      break;
    default:
      return false;
  }

  WebCryptoKeyUsageMask usages;
  bool extractable;
  if (!doReadKeyUsages(usages, extractable))
    return false;

  uint32_t keyDataLength;
  if (!doReadUint32(&keyDataLength))
    return false;

  if (position() + keyDataLength > length())
    return false;

  const uint8_t* keyData = allocate(keyDataLength);
  WebCryptoKey key = WebCryptoKey::createNull();
  if (!Platform::current()->crypto()->deserializeKeyForClone(
          algorithm, type, extractable, usages, keyData, keyDataLength, key)) {
    return false;
  }

  *value = toV8(CryptoKey::create(key), getScriptState()->context()->Global(),
                isolate());
  return !value->IsEmpty();
}
bool SerializedScriptValueReaderForModules::doReadAlgorithmId(WebCryptoAlgorithmId& id)
{
    uint32_t rawId;
    if (!doReadUint32(&rawId))
        return false;

    switch (static_cast<CryptoKeyAlgorithmTag>(rawId)) {
    case AesCbcTag:
        id = WebCryptoAlgorithmIdAesCbc;
        return true;
    case HmacTag:
        id = WebCryptoAlgorithmIdHmac;
        return true;
    case RsaSsaPkcs1v1_5Tag:
        id = WebCryptoAlgorithmIdRsaSsaPkcs1v1_5;
        return true;
    case Sha1Tag:
        id = WebCryptoAlgorithmIdSha1;
        return true;
    case Sha256Tag:
        id = WebCryptoAlgorithmIdSha256;
        return true;
    case Sha384Tag:
        id = WebCryptoAlgorithmIdSha384;
        return true;
    case Sha512Tag:
        id = WebCryptoAlgorithmIdSha512;
        return true;
    case AesGcmTag:
        id = WebCryptoAlgorithmIdAesGcm;
        return true;
    case RsaOaepTag:
        id = WebCryptoAlgorithmIdRsaOaep;
        return true;
    case AesCtrTag:
        id = WebCryptoAlgorithmIdAesCtr;
        return true;
    case AesKwTag:
        id = WebCryptoAlgorithmIdAesKw;
        return true;
    case RsaPssTag:
        id = WebCryptoAlgorithmIdRsaPss;
        return true;
    case EcdsaTag:
        id = WebCryptoAlgorithmIdEcdsa;
        return true;
    case EcdhTag:
        id = WebCryptoAlgorithmIdEcdh;
        return true;
    case HkdfTag:
        id = WebCryptoAlgorithmIdHkdf;
        return true;
    case Pbkdf2Tag:
        id = WebCryptoAlgorithmIdPbkdf2;
        return true;
    }

    return false;
}
bool SerializedScriptValueReaderForModules::doReadAesKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& type)
{
    WebCryptoAlgorithmId id;
    if (!doReadAlgorithmId(id))
        return false;
    uint32_t lengthBytes;
    if (!doReadUint32(&lengthBytes))
        return false;
    algorithm = WebCryptoKeyAlgorithm::createAes(id, lengthBytes * 8);
    type = WebCryptoKeyTypeSecret;
    return !algorithm.isNull();
}
bool SerializedScriptValueReaderForModules::doReadHmacKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& type)
{
    uint32_t lengthBytes;
    if (!doReadUint32(&lengthBytes))
        return false;
    WebCryptoAlgorithmId hash;
    if (!doReadAlgorithmId(hash))
        return false;
    algorithm = WebCryptoKeyAlgorithm::createHmac(hash, lengthBytes * 8);
    type = WebCryptoKeyTypeSecret;
    return !algorithm.isNull();
}
bool SerializedScriptValueReaderForModules::readDOMFileSystem(v8::Local<v8::Value>* value)
{
    uint32_t type;
    String name;
    String url;
    if (!doReadUint32(&type))
        return false;
    if (!readWebCoreString(&name))
        return false;
    if (!readWebCoreString(&url))
        return false;
    DOMFileSystem* fs = DOMFileSystem::create(scriptState()->executionContext(), name, static_cast<FileSystemType>(type), KURL(ParsedURLString, url));
    *value = toV8(fs, scriptState()->context()->Global(), isolate());
    return true;
}
bool SerializedScriptValueReaderForModules::doReadAsymmetricKeyType(WebCryptoKeyType& type)
{
    uint32_t rawType;
    if (!doReadUint32(&rawType))
        return false;

    switch (static_cast<AssymetricCryptoKeyType>(rawType)) {
    case PublicKeyType:
        type = WebCryptoKeyTypePublic;
        return true;
    case PrivateKeyType:
        type = WebCryptoKeyTypePrivate;
        return true;
    }

    return false;
}
bool SerializedScriptValueReaderForModules::doReadNamedCurve(WebCryptoNamedCurve& namedCurve)
{
    uint32_t rawName;
    if (!doReadUint32(&rawName))
        return false;

    switch (static_cast<NamedCurveTag>(rawName)) {
    case P256Tag:
        namedCurve = WebCryptoNamedCurveP256;
        return true;
    case P384Tag:
        namedCurve = WebCryptoNamedCurveP384;
        return true;
    case P521Tag:
        namedCurve = WebCryptoNamedCurveP521;
        return true;
    }

    return false;
}
bool SerializedScriptValueReaderForModules::doReadKeyUsages(
    WebCryptoKeyUsageMask& usages,
    bool& extractable) {
  // Reminder to update this when adding new key usages.
  static_assert(EndOfWebCryptoKeyUsage == (1 << 7) + 1,
                "update required when adding new key usages");
  const uint32_t allPossibleUsages =
      ExtractableUsage | EncryptUsage | DecryptUsage | SignUsage | VerifyUsage |
      DeriveKeyUsage | WrapKeyUsage | UnwrapKeyUsage | DeriveBitsUsage;

  uint32_t rawUsages;
  if (!doReadUint32(&rawUsages))
    return false;

  // Make sure it doesn't contain an unrecognized usage value.
  if (rawUsages & ~allPossibleUsages)
    return false;

  usages = 0;

  extractable = rawUsages & ExtractableUsage;

  if (rawUsages & EncryptUsage)
    usages |= WebCryptoKeyUsageEncrypt;
  if (rawUsages & DecryptUsage)
    usages |= WebCryptoKeyUsageDecrypt;
  if (rawUsages & SignUsage)
    usages |= WebCryptoKeyUsageSign;
  if (rawUsages & VerifyUsage)
    usages |= WebCryptoKeyUsageVerify;
  if (rawUsages & DeriveKeyUsage)
    usages |= WebCryptoKeyUsageDeriveKey;
  if (rawUsages & WrapKeyUsage)
    usages |= WebCryptoKeyUsageWrapKey;
  if (rawUsages & UnwrapKeyUsage)
    usages |= WebCryptoKeyUsageUnwrapKey;
  if (rawUsages & DeriveBitsUsage)
    usages |= WebCryptoKeyUsageDeriveBits;

  return true;
}