private static string DownloadAndVerifyMsi()

in JetBrains.Etw.HostService.Updater/src/Views/DownloadingWindow.xaml.cs [73:153]


    private static string DownloadAndVerifyMsi(Util.ILogger logger,
      [NotNull] UpdateRequest updateRequest,
      [NotNull] IProgress mainProgress,
      CancellationToken ct,
      bool downloadDelay = false)
    {
      logger.Info($"{Logger.Context} size={updateRequest.Size}\n\tlink={updateRequest.Link}\n\tchecksumLink={updateRequest.ChecksumLink}\n\tsignedChecksumLink={updateRequest.SignedChecksumLink}");
      mainProgress.Start(100);
      var digestSha256 = updateRequest.ChecksumLink.OpenSeekableStreamFromWeb(dataStream =>
        {
          var verificationResult = PgpSignaturesVerifier.MasterPublicKey.OpenStreamFromString(masterPublicKeyStream =>
            PgpSignaturesVerifier.PublicKeysUri.OpenSeekableStreamFromWeb(publicKeysStream =>
              updateRequest.SignedChecksumLink.OpenSeekableStreamFromWeb(signaturesStream =>
                {
                  mainProgress.Advance(5);
                  return PgpSignaturesVerifier.Verify(masterPublicKeyStream, publicKeysStream, signaturesStream, dataStream, new SubLogger(logger, SpecialContext));
                })));
          mainProgress.Advance(4);

          if (!verificationResult)
            throw new InvalidOperationException("The PGP signature for SHA256 checksum file is incorrect");

          dataStream.Position = 0;
          using var reader = new BinaryReader(dataStream, Encoding.UTF8, false);
          return reader.ReadChars(2 * 256 / 8).FromHexString();
        });
      logger.Info($"{Logger.Context} digestSha256={digestSha256.ToLoverHexString()}");
      mainProgress.Advance(1);
      ct.ThrowIfCancellationRequested();

      var fileProgress = new SubProgress(mainProgress, 90);
      var downloadFile = Path.GetTempFileName();
      logger.Info($"{Logger.Context} downloadFile={downloadFile}");
      try
      {
        using var fileStream = File.Create(downloadFile);
        var fileSha256 = updateRequest.Link.OpenStreamFromWeb(stream =>
          {
            fileProgress.Start(Math.Max(1, updateRequest.Size));

            var buffer = new byte[4 * 1024];
            using var hasher = SHA256.Create();
            while (true)
            {
              var received = stream.Read(buffer, 0, buffer.Length);
              ct.ThrowIfCancellationRequested();
              if (received == 0)
              {
                hasher.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
                ct.ThrowIfCancellationRequested();
                return hasher.Hash;
              }

              hasher.TransformBlock(buffer, 0, received, null, 0);
              ct.ThrowIfCancellationRequested();

              fileStream.Write(buffer, 0, received);
              ct.ThrowIfCancellationRequested();

              fileProgress.Advance(received);

              if (downloadDelay)
                Thread.Sleep(1);
            }
          }).NotNull();
        fileProgress.Stop();

        logger.Info($"{Logger.Context} fileSha256={fileSha256.ToLoverHexString()}");
        if (!digestSha256.SequenceEqual(fileSha256))
          throw new InvalidOperationException("The file has invalid SHA256 checksum");

        mainProgress.Stop();
        return downloadFile;
      }
      catch
      {
        if (File.Exists(downloadFile))
          File.Delete(downloadFile);
        throw;
      }
    }