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;
}
}