Add SHA256 field to VelopackAsset

This commit is contained in:
Daniel Svensson
2024-06-20 10:01:50 +02:00
committed by Caelan Sayler
parent 1f4591a14f
commit 295eab4d63
5 changed files with 51 additions and 9 deletions

View File

@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
using System.Security.Cryptography;
using Microsoft.Extensions.Logging;
using Velopack.Packaging;
using Velopack.Packaging.Abstractions;
using Velopack.Sources;
@@ -80,8 +81,12 @@ public abstract class DownRepository<TDown> : IRepositoryCanDownload<TDown>
if (File.Exists(path)) {
Log.Warn($"File '{path}' already exists on disk. Verifying checksum...");
var hash = Utility.CalculateFileSHA1(path);
if (hash == latest.SHA1) {
bool hashMatch = (latest.SHA256 != null)
? latest.SHA256 == Utility.CalculateFileSHA256(path)
: latest.SHA1 == Utility.CalculateFileSHA1(path);
if (hashMatch) {
Log.Info("Checksum matches. Finished.");
return;
} else {
@@ -92,8 +97,14 @@ public abstract class DownRepository<TDown> : IRepositoryCanDownload<TDown>
await RetryAsync(() => SaveEntryToFileAsync(options, latest, incomplete), $"Downloading {latest.FileName}...");
Log.Info("Verifying checksum...");
var newHash = Utility.CalculateFileSHA1(incomplete);
if (newHash != latest.SHA1) {
string newHash;
if (!string.IsNullOrEmpty(latest.SHA256)) {
if (latest.SHA256 != (newHash = Utility.CalculateFileSHA256(incomplete))) {
Log.Error($"Checksum mismatch, expected {latest.SHA256}, got {newHash}");
return;
}
}
else if (latest.SHA1 != (newHash = Utility.CalculateFileSHA1(incomplete))) {
Log.Error($"Checksum mismatch, expected {latest.SHA1}, got {newHash}");
return;
}

View File

@@ -163,6 +163,25 @@ namespace Velopack
}
}
/// <inheritdoc cref="CalculateStreamSHA256"/>
public static string CalculateFileSHA256(string filePath)
{
var bufferSize = 1000000; // 1mb
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize)) {
return CalculateStreamSHA256(stream);
}
}
/// <summary>
/// Get SHA256 hash of the specified file and returns the result as a base64 encoded string (with length 44)
/// </summary>
public static string CalculateStreamSHA256(Stream file)
{
using (var sha256 = SHA256.Create()) {
return Convert.ToBase64String(sha256.ComputeHash(file));
}
}
public static Sources.IFileDownloader CreateDefaultDownloader()
{
return new Sources.HttpClientFileDownloader();

View File

@@ -125,6 +125,7 @@ namespace Velopack.Sources
Type = entry.Type;
FileName = entry.FileName;
SHA1 = entry.SHA1;
SHA256 = entry.SHA256;
Size = entry.Size;
NotesMarkdown = entry.NotesMarkdown;
NotesHTML = entry.NotesHTML;

View File

@@ -430,10 +430,17 @@ namespace Velopack
throw new ChecksumFailedException(targetPackage.FullName, $"Size doesn't match ({targetPackage.Length} != {release.Size}).");
}
var hash = Utility.CalculateFileSHA1(targetPackage.FullName);
if (!hash.Equals(release.SHA1, StringComparison.OrdinalIgnoreCase)) {
throw new ChecksumFailedException(targetPackage.FullName, $"SHA1 doesn't match ({release.SHA1} != {hash}).");
}
if (release.SHA256 is not null) {
var hash = Utility.CalculateFileSHA256(targetPackage.FullName);
if (!hash.Equals(release.SHA256, StringComparison.OrdinalIgnoreCase)) {
throw new ChecksumFailedException(targetPackage.FullName, $"SHA256 doesn't match ({release.SHA256} != {hash}).");
}
} else {
var hash = Utility.CalculateFileSHA1(targetPackage.FullName);
if (!hash.Equals(release.SHA1, StringComparison.OrdinalIgnoreCase)) {
throw new ChecksumFailedException(targetPackage.FullName, $"SHA1 doesn't match ({release.SHA1} != {hash}).");
}
}
}
/// <summary>

View File

@@ -57,6 +57,9 @@ namespace Velopack
/// <summary> The SHA1 checksum of the update package containing this release. </summary>
public string SHA1 { get; set; }
/// <summary> The SHA256 checksum (if availible) of the update package containing this release. </summary>
public string SHA256 { get; set; }
/// <summary> The size in bytes of the update package containing this release. </summary>
public long Size { get; set; }
@@ -79,6 +82,7 @@ namespace Velopack
NotesHTML = zip.ReleaseNotesHtml,
Size = new FileInfo(filePath).Length,
SHA1 = Utility.CalculateFileSHA1(filePath),
SHA256 = Utility.CalculateFileSHA256(filePath),
FileName = Path.GetFileName(filePath),
Type = IsDeltaFile(filePath) ? VelopackAssetType.Delta : VelopackAssetType.Full,
};