markus / MarkusAutoUpdate / src / NetSparkle / Utilities.cs @ d8f5045e
이력 | 보기 | 이력해설 | 다운로드 (6.96 KB)
1 |
using NetSparkleUpdater.Enums; |
---|---|
2 |
using System; |
3 |
using System.Collections.Generic; |
4 |
using System.IO; |
5 |
using System.Net; |
6 |
using System.Runtime.InteropServices; |
7 |
using System.Security.Cryptography; |
8 |
|
9 |
namespace NetSparkleUpdater |
10 |
{ |
11 |
/// <summary> |
12 |
/// Provides commonly used utility functions. |
13 |
/// </summary> |
14 |
public class Utilities |
15 |
{ |
16 |
/// <summary> |
17 |
/// Removes trailing 0 components from the given version. |
18 |
/// </summary> |
19 |
/// <param name="version">Version object</param> |
20 |
/// <returns>Version string</returns> |
21 |
public static string GetVersionString(Version version) |
22 |
{ |
23 |
if (version.Revision != 0) |
24 |
{ |
25 |
return version.ToString(); |
26 |
} |
27 |
if (version.Build != 0) |
28 |
{ |
29 |
return version.ToString(3); |
30 |
} |
31 |
return version.ToString(2); |
32 |
} |
33 |
|
34 |
/// <summary> |
35 |
/// Gets the signature of a file with the given DSA private key. |
36 |
/// </summary> |
37 |
/// <param name="fileToSignPath">Path to the file you want to sign</param> |
38 |
/// <param name="privateKeyFilePath">Path to the private key file</param> |
39 |
/// <returns>DSA signature as base64 string</returns> |
40 |
public static string GetDSASignature(string fileToSignPath, string privateKeyFilePath) |
41 |
{ |
42 |
if (string.IsNullOrEmpty(fileToSignPath) || !File.Exists(fileToSignPath)) |
43 |
{ |
44 |
return null; |
45 |
} |
46 |
if (string.IsNullOrEmpty(privateKeyFilePath) || !File.Exists(privateKeyFilePath)) |
47 |
{ |
48 |
return null; |
49 |
} |
50 |
var privateKey = File.ReadAllText(privateKeyFilePath); |
51 |
if (!string.IsNullOrEmpty(privateKey)) |
52 |
{ |
53 |
DSACryptoServiceProvider cryptoProvider = new DSACryptoServiceProvider(); |
54 |
cryptoProvider.FromXmlString(privateKey); |
55 |
|
56 |
using (Stream inputStream = File.OpenRead(fileToSignPath)) |
57 |
{ |
58 |
byte[] hash = null; |
59 |
hash = cryptoProvider.SignData(inputStream); |
60 |
var dsaSignature = Convert.ToBase64String(hash); |
61 |
return dsaSignature; |
62 |
} |
63 |
} |
64 |
|
65 |
return null; |
66 |
} |
67 |
|
68 |
/// <summary> |
69 |
/// Creates a <see cref="Uri"/> from a URL string. If the URL is relative, converts it to an absolute URL based on the appcast URL. |
70 |
/// </summary> |
71 |
/// <param name="url">relative or absolute URL</param> |
72 |
/// <param name="appcastURL">URL to appcast</param> |
73 |
public static Uri GetAbsoluteURL(string url, string appcastURL) |
74 |
{ |
75 |
return new Uri(new Uri(appcastURL), url); |
76 |
} |
77 |
|
78 |
/// <summary> |
79 |
/// Convert a number of bytes to a user-readable string |
80 |
/// </summary> |
81 |
/// <param name="numBytes">Number of bytes to convert</param> |
82 |
/// <returns>A string that represents the number of bytes in KB, MB, or GB if numBytes > 1024. |
83 |
/// If numBytes is less than 1024, returns numBytes.</returns> |
84 |
public static string ConvertNumBytesToUserReadableString(long numBytes) |
85 |
{ |
86 |
if (numBytes > 1024) |
87 |
{ |
88 |
double numBytesDecimal = numBytes; |
89 |
// Put in KB |
90 |
numBytesDecimal /= 1024; |
91 |
if (numBytesDecimal > 1024) |
92 |
{ |
93 |
// Put in MB |
94 |
numBytesDecimal /= 1024; |
95 |
if (numBytesDecimal > 1024) |
96 |
{ |
97 |
// Put in GB |
98 |
numBytesDecimal /= 1024; |
99 |
return numBytesDecimal.ToString("F2") + " GB"; |
100 |
} |
101 |
return numBytesDecimal.ToString("F2") + " MB"; |
102 |
} |
103 |
return numBytesDecimal.ToString("F2") + " KB"; |
104 |
} |
105 |
return numBytes.ToString(); |
106 |
} |
107 |
|
108 |
/// <summary> |
109 |
/// Get the full base (running) directory for this application including a trailing slash. |
110 |
/// From WalletWasabi: |
111 |
/// https://github.com/zkSNACKs/WalletWasabi/blob/8d42bce976605cca3326ea6c998b2294494900e6/WalletWasabi/Helpers/EnvironmentHelpers.cs |
112 |
/// </summary> |
113 |
/// <returns>the full running directory path including trailing slash for this application</returns> |
114 |
public static string GetFullBaseDirectory() |
115 |
{ |
116 |
#if NETCORE |
117 |
var fullBaseDirectory = Path.GetFullPath(AppContext.BaseDirectory); |
118 |
|
119 |
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) |
120 |
{ |
121 |
if (!fullBaseDirectory.StartsWith("/")) |
122 |
{ |
123 |
fullBaseDirectory = fullBaseDirectory.Insert(0, "/"); |
124 |
} |
125 |
} |
126 |
|
127 |
return fullBaseDirectory; |
128 |
#else |
129 |
// https://stackoverflow.com/a/837501/3938401 |
130 |
return System.Reflection.Assembly.GetExecutingAssembly().CodeBase; |
131 |
#endif |
132 |
} |
133 |
|
134 |
/// <summary> |
135 |
/// Convert a given <see cref="Stream"/> to a byte array |
136 |
/// </summary> |
137 |
/// <param name="stream">the <see cref="Stream"/> to convert</param> |
138 |
/// <returns>a byte[] array of the data in the given stream</returns> |
139 |
public static byte[] ConvertStreamToByteArray(Stream stream) |
140 |
{ |
141 |
// read the data |
142 |
byte[] data = new byte[stream.Length]; |
143 |
stream.Read(data, 0, data.Length); |
144 |
return data; |
145 |
} |
146 |
|
147 |
/// <summary> |
148 |
/// Checks to see whether a signature is ncessary given the provided |
149 |
/// info on the <see cref="SecurityMode"/> and whether or not valid |
150 |
/// key information exists at the moment. |
151 |
/// </summary> |
152 |
/// <param name="securityMode">the <see cref="SecurityMode"/> for the signature check</param> |
153 |
/// <param name="doesKeyInfoExist">true if the application has appropriate key |
154 |
/// information in order to run signature checks; false otherwise</param> |
155 |
/// <param name="isCheckingSoftwareDownload">True if the caller is checking on the signature of a software |
156 |
/// download; false if the caller is checking on the signature of something else (e.g. release notes, |
157 |
/// app cast)</param> |
158 |
/// <returns>true if an item's signature needs to be checked; false otherwise</returns> |
159 |
public static bool IsSignatureNeeded(SecurityMode securityMode, bool doesKeyInfoExist, bool isCheckingSoftwareDownload = false) |
160 |
{ |
161 |
switch (securityMode) |
162 |
{ |
163 |
case SecurityMode.UseIfPossible: |
164 |
// if we have a public key, we need a signature |
165 |
return doesKeyInfoExist; |
166 |
case SecurityMode.Strict: |
167 |
// we always need a signature |
168 |
return true; |
169 |
case SecurityMode.Unsafe: |
170 |
return false; |
171 |
case SecurityMode.OnlyVerifySoftwareDownloads: |
172 |
return isCheckingSoftwareDownload; |
173 |
|
174 |
} |
175 |
return false; |
176 |
} |
177 |
} |
178 |
} |