diff options
author | sr55 <[email protected]> | 2016-04-29 21:10:35 +0100 |
---|---|---|
committer | sr55 <[email protected]> | 2016-04-29 21:10:35 +0100 |
commit | 0d83d0eed2d26869c9f557639593c1a4d5ad4710 (patch) | |
tree | 74adb28a3cd8a823162a713990b60dc8603d9a3e /win | |
parent | 7060facdeb480326fc3a488c720a3abf0d84696a (diff) |
WinGui: Improve the security of the update checker on windows. This download is now verified against a signed RSA-SHA256 hash verifying both file integrity and origin.
Diffstat (limited to 'win')
-rw-r--r-- | win/CS/HandBrakeWPF/HandBrakeWPF.csproj | 1 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs | 4 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Services/UpdateService.cs | 79 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs | 2 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/public.key | 1 |
5 files changed, 59 insertions, 28 deletions
diff --git a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj index 3a89ceda1..cfb5e8596 100644 --- a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj +++ b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj @@ -471,6 +471,7 @@ <None Include="Properties\AssemblyInfo.cs.Nightly.tmpl" />
<None Include="Properties\AssemblyInfo.cs.tmpl" />
<AppDesigner Include="Properties\" />
+ <EmbeddedResource Include="public.key" />
</ItemGroup>
<ItemGroup>
<Page Include="Controls\AlertPanel.xaml">
diff --git a/win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs b/win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs index 61c2bd36e..3ac3fb620 100644 --- a/win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs +++ b/win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs @@ -55,8 +55,8 @@ namespace HandBrakeWPF.Model public Exception Error { get; set; }
/// <summary>
- /// Gets or sets the expected sh a 1 hash.
+ /// Gets or sets the expected DSA SHA256 Signature
/// </summary>
- public string ExpectedSHA1Hash { get; set; }
+ public string Signature { get; set; }
}
}
diff --git a/win/CS/HandBrakeWPF/Services/UpdateService.cs b/win/CS/HandBrakeWPF/Services/UpdateService.cs index 732193ac4..e5c97126f 100644 --- a/win/CS/HandBrakeWPF/Services/UpdateService.cs +++ b/win/CS/HandBrakeWPF/Services/UpdateService.cs @@ -10,8 +10,10 @@ namespace HandBrakeWPF.Services
{
using System;
+ using System.Diagnostics;
using System.IO;
using System.Net;
+ using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
@@ -127,7 +129,7 @@ namespace HandBrakeWPF.Services DownloadFile = reader.DownloadFile,
Build = reader.Build,
Version = reader.Version,
- ExpectedSHA1Hash = reader.Hash
+ Signature = reader.Hash
};
callback(info2);
@@ -145,8 +147,8 @@ namespace HandBrakeWPF.Services /// <param name="url">
/// The url.
/// </param>
- /// <param name="expectedSha1Hash">
- /// The expected Sha 1 Hash.
+ /// <param name="expectedSignature">
+ /// The expected DSA SHA265 Signature
/// </param>
/// <param name="completed">
/// The complete.
@@ -154,7 +156,7 @@ namespace HandBrakeWPF.Services /// <param name="progress">
/// The progress.
/// </param>
- public void DownloadFile(string url, string expectedSha1Hash, Action<DownloadStatus> completed, Action<DownloadStatus> progress)
+ public void DownloadFile(string url, string expectedSignature, Action<DownloadStatus> completed, Action<DownloadStatus> progress)
{
ThreadPool.QueueUserWorkItem(
delegate
@@ -188,13 +190,13 @@ namespace HandBrakeWPF.Services localStream.Close();
completed(
- GetSHA1(tempPath) != expectedSha1Hash
- ? new DownloadStatus
+ this.VerifyDownload(expectedSignature, tempPath)
+ ? new DownloadStatus { WasSuccessful = true, Message = "Download Complete." } :
+ new DownloadStatus
{
WasSuccessful = false,
- Message = "Download Failed. SHA1 Checksum Failed. Please visit the website to download this update."
- }
- : new DownloadStatus { WasSuccessful = true, Message = "Download Complete." });
+ Message = "Download Failed. Checksum Failed. Please visit the website to download this update."
+ });
}
catch (Exception exc)
{
@@ -204,27 +206,54 @@ namespace HandBrakeWPF.Services }
/// <summary>
- /// The get sh a 1.
+ /// Verify the HandBrake download is Valid.
/// </summary>
- /// <param name="fileName">
- /// The file name.
- /// </param>
- /// <returns>
- /// The <see cref="string"/>.
- /// </returns>
- public static String GetSHA1(String fileName)
+ /// <param name="signature">The DSA SHA256 Signature from the appcast</param>
+ /// <param name="updateFile">Path to the downloaded update file</param>
+ /// <returns>True if the file is valid, false otherwise.</returns>
+ public bool VerifyDownload(string signature, string updateFile)
{
- FileStream file = new FileStream(fileName, FileMode.Open);
- SHA1 sha1 = new SHA1CryptoServiceProvider();
- byte[] retVal = sha1.ComputeHash(file);
- file.Close();
+ // Sanity Checks
+ if (!File.Exists(updateFile))
+ {
+ return false;
+ }
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < retVal.Length; i++)
+ if (string.IsNullOrEmpty(signature))
+ {
+ return false;
+ }
+
+ // Fetch our Public Key
+ string publicKey;
+ using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("HandBrakeWPF.public.key"))
+ {
+ if (stream == null)
+ {
+ return false;
+ }
+
+ using (StreamReader reader = new StreamReader(stream))
+ {
+ publicKey = reader.ReadToEnd();
+ }
+ }
+
+ // Verify the file against the Signature.
+ try
+ {
+ byte[] file = File.ReadAllBytes(updateFile);
+ using (RSACryptoServiceProvider verifyProfider = new RSACryptoServiceProvider())
+ {
+ verifyProfider.FromXmlString(publicKey);
+ return verifyProfider.VerifyData(file, "SHA256", Convert.FromBase64String(signature));
+ }
+ }
+ catch (Exception e)
{
- sb.Append(retVal[i].ToString("x2"));
+ Debug.WriteLine(e);
+ return false;
}
- return sb.ToString();
}
#endregion
diff --git a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs index a60be1aef..0b1b16df3 100644 --- a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs @@ -1104,7 +1104,7 @@ namespace HandBrakeWPF.ViewModels public void DownloadUpdate()
{
this.UpdateMessage = "Preparing for Update ...";
- this.updateService.DownloadFile(this.updateInfo.DownloadFile, this.updateInfo.ExpectedSHA1Hash, this.DownloadComplete, this.DownloadProgress);
+ this.updateService.DownloadFile(this.updateInfo.DownloadFile, this.updateInfo.Signature, this.DownloadComplete, this.DownloadProgress);
}
/// <summary>
diff --git a/win/CS/HandBrakeWPF/public.key b/win/CS/HandBrakeWPF/public.key new file mode 100644 index 000000000..6f242c85e --- /dev/null +++ b/win/CS/HandBrakeWPF/public.key @@ -0,0 +1 @@ +<RSAKeyValue><Modulus>muy8LsVQC6ZEAlK+3G4GuntE6OLdM1maplxkh2iJw38P/l+GY+IE+aWU9qTA08XXeieRdc32iZKlgmem81zkOXRZieYBKodHbLpsBHM9EQ4OKjiMheyMGlTYvmm2ct/2nr1tml0bpJ+LZdqDjLT4O3oG4j4vdCe5UxMfdAEGDss=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
\ No newline at end of file |