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::doReadKeyWithoutParams(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& type)
{
    WebCryptoAlgorithmId id;
    if (!doReadAlgorithmId(id))
        return false;
    algorithm = WebCryptoKeyAlgorithm::createWithoutParams(id);
    type = WebCryptoKeyTypeSecret;
    return !algorithm.isNull();
}
 WebCryptoKeyPrivate(PassOwnPtr<WebCryptoKeyHandle> handle, WebCryptoKeyType type, bool extractable, const WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyUsageMask usages)
     : handle(std::move(handle))
     , type(type)
     , extractable(extractable)
     , algorithm(algorithm)
     , usages(usages)
 {
     ASSERT(!algorithm.isNull());
 }
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::doReadEcKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& type)
{
    WebCryptoAlgorithmId id;
    if (!doReadAlgorithmId(id))
        return false;

    if (!doReadAsymmetricKeyType(type))
        return false;

    WebCryptoNamedCurve namedCurve;
    if (!doReadNamedCurve(namedCurve))
        return false;

    algorithm = WebCryptoKeyAlgorithm::createEc(id, namedCurve);
    return !algorithm.isNull();
}
CryptoKey* V8ScriptValueDeserializerForModules::readCryptoKey() {
  // Read params.
  uint8_t rawKeyType;
  if (!readOneByte(&rawKeyType))
    return nullptr;
  WebCryptoKeyAlgorithm algorithm;
  WebCryptoKeyType keyType = WebCryptoKeyTypeSecret;
  switch (rawKeyType) {
    case AesKeyTag: {
      uint32_t rawId;
      WebCryptoAlgorithmId id;
      uint32_t lengthBytes;
      if (!readUint32(&rawId) || !algorithmIdFromWireFormat(rawId, &id) ||
          !readUint32(&lengthBytes) ||
          lengthBytes > std::numeric_limits<unsigned short>::max() / 8u)
        return nullptr;
      algorithm = WebCryptoKeyAlgorithm::createAes(id, lengthBytes * 8);
      keyType = WebCryptoKeyTypeSecret;
      break;
    }
    case HmacKeyTag: {
      uint32_t lengthBytes;
      uint32_t rawHash;
      WebCryptoAlgorithmId hash;
      if (!readUint32(&lengthBytes) ||
          lengthBytes > std::numeric_limits<unsigned>::max() / 8 ||
          !readUint32(&rawHash) || !algorithmIdFromWireFormat(rawHash, &hash))
        return nullptr;
      algorithm = WebCryptoKeyAlgorithm::createHmac(hash, lengthBytes * 8);
      keyType = WebCryptoKeyTypeSecret;
      break;
    }
    case RsaHashedKeyTag: {
      uint32_t rawId;
      WebCryptoAlgorithmId id;
      uint32_t rawKeyType;
      uint32_t modulusLengthBits;
      uint32_t publicExponentSize;
      const void* publicExponentBytes;
      uint32_t rawHash;
      WebCryptoAlgorithmId hash;
      if (!readUint32(&rawId) || !algorithmIdFromWireFormat(rawId, &id) ||
          !readUint32(&rawKeyType) ||
          !asymmetricKeyTypeFromWireFormat(rawKeyType, &keyType) ||
          !readUint32(&modulusLengthBits) || !readUint32(&publicExponentSize) ||
          !readRawBytes(publicExponentSize, &publicExponentBytes) ||
          !readUint32(&rawHash) || !algorithmIdFromWireFormat(rawHash, &hash))
        return nullptr;
      algorithm = WebCryptoKeyAlgorithm::createRsaHashed(
          id, modulusLengthBits,
          reinterpret_cast<const unsigned char*>(publicExponentBytes),
          publicExponentSize, hash);
      break;
    }
    case EcKeyTag: {
      uint32_t rawId;
      WebCryptoAlgorithmId id;
      uint32_t rawKeyType;
      uint32_t rawNamedCurve;
      WebCryptoNamedCurve namedCurve;
      if (!readUint32(&rawId) || !algorithmIdFromWireFormat(rawId, &id) ||
          !readUint32(&rawKeyType) ||
          !asymmetricKeyTypeFromWireFormat(rawKeyType, &keyType) ||
          !readUint32(&rawNamedCurve) ||
          !namedCurveFromWireFormat(rawNamedCurve, &namedCurve))
        return nullptr;
      algorithm = WebCryptoKeyAlgorithm::createEc(id, namedCurve);
      break;
    }
    case NoParamsKeyTag: {
      uint32_t rawId;
      WebCryptoAlgorithmId id;
      if (!readUint32(&rawId) || !algorithmIdFromWireFormat(rawId, &id))
        return nullptr;
      algorithm = WebCryptoKeyAlgorithm::createWithoutParams(id);
      break;
    }
  }
  if (algorithm.isNull())
    return nullptr;

  // Read key usages.
  uint32_t rawUsages;
  WebCryptoKeyUsageMask usages;
  bool extractable;
  if (!readUint32(&rawUsages) ||
      !keyUsagesFromWireFormat(rawUsages, &usages, &extractable))
    return nullptr;

  // Read key data.
  uint32_t keyDataLength;
  const void* keyData;
  if (!readUint32(&keyDataLength) || !readRawBytes(keyDataLength, &keyData))
    return nullptr;

  WebCryptoKey key = WebCryptoKey::createNull();
  if (!Platform::current()->crypto()->deserializeKeyForClone(
          algorithm, keyType, extractable, usages,
          reinterpret_cast<const unsigned char*>(keyData), keyDataLength, key))
    return nullptr;

  return CryptoKey::create(key);
}