-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
216 changed files
with
53,390 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.5" /> | ||
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="7.0.0" /> | ||
<PackageReference Include="System.Drawing.Common" Version="7.0.0" /> | ||
<PackageReference Include="System.Management" Version="7.0.2" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.Net; | ||
using System.Security.Cryptography; | ||
using System.Security.Cryptography.X509Certificates; | ||
|
||
#nullable enable | ||
namespace MsmhToolsClass | ||
{ | ||
public class CertificateTool | ||
{ | ||
public static void GenerateCertificate(string folderPath, IPAddress gateway, string issuerSubjectName = "CN=MSasanMH Authority", string subjectName = "CN=MSasanMH") | ||
{ | ||
const string CRT_HEADER = "-----BEGIN CERTIFICATE-----\n"; | ||
const string CRT_FOOTER = "\n-----END CERTIFICATE-----"; | ||
|
||
const string KEY_HEADER = "-----BEGIN RSA PRIVATE KEY-----\n"; | ||
const string KEY_FOOTER = "\n-----END RSA PRIVATE KEY-----"; | ||
|
||
// Create X509KeyUsageFlags | ||
const X509KeyUsageFlags x509KeyUsageFlags = X509KeyUsageFlags.CrlSign | | ||
X509KeyUsageFlags.DataEncipherment | | ||
X509KeyUsageFlags.DigitalSignature | | ||
X509KeyUsageFlags.KeyAgreement | | ||
X509KeyUsageFlags.KeyCertSign | | ||
X509KeyUsageFlags.KeyEncipherment | | ||
X509KeyUsageFlags.NonRepudiation; | ||
|
||
// Create SubjectAlternativeNameBuilder | ||
SubjectAlternativeNameBuilder sanBuilder = new(); | ||
sanBuilder.AddDnsName("localhost"); // Add Localhost | ||
sanBuilder.AddDnsName(Environment.UserName); // Add Current User | ||
sanBuilder.AddUserPrincipalName(System.Security.Principal.WindowsIdentity.GetCurrent().Name); // Add User Principal Name | ||
sanBuilder.AddIpAddress(IPAddress.Loopback); | ||
sanBuilder.AddIpAddress(IPAddress.IPv6Loopback); | ||
sanBuilder.AddIpAddress(IPAddress.Any); | ||
sanBuilder.AddIpAddress(IPAddress.IPv6Any); | ||
|
||
// Generate IP range for gateway | ||
if (NetworkTool.IsIPv4(gateway)) | ||
{ | ||
string ipString = gateway.ToString(); | ||
string[] ipSplit = ipString.Split('.'); | ||
string ip1 = ipSplit[0] + "." + ipSplit[1] + "." + ipSplit[2] + "."; | ||
for (int n = 0; n <= 255; n++) | ||
{ | ||
string ip2 = ip1 + n.ToString(); | ||
sanBuilder.AddIpAddress(IPAddress.Parse(ip2)); | ||
sanBuilder.AddUri(new Uri($"https://{ip2}")); | ||
} | ||
// Generate local IP range in case a VPN is active. | ||
if (!ip1.Equals("192.168.1.")) | ||
{ | ||
string ipLocal1 = "192.168.1."; | ||
for (int n = 0; n <= 255; n++) | ||
{ | ||
string ipLocal2 = ipLocal1 + n.ToString(); | ||
sanBuilder.AddIpAddress(IPAddress.Parse(ipLocal2)); | ||
sanBuilder.AddUri(new Uri($"https://{ipLocal2}")); | ||
} | ||
} | ||
} | ||
|
||
sanBuilder.Build(); | ||
|
||
// Create Oid Collection | ||
OidCollection oidCollection = new(); | ||
oidCollection.Add(new Oid("2.5.29.37.0")); // Any Purpose | ||
oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.1")); // Server Authentication | ||
oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.2")); // Client Authentication | ||
oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.3")); // Code Signing | ||
oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.4")); // Email Protection | ||
oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.5")); // IPSEC End System Certificate | ||
oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.6")); // IPSEC Tunnel | ||
oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.7")); // IPSEC User Certificate | ||
oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.8")); // Time Stamping | ||
oidCollection.Add(new Oid("1.3.6.1.4.1.311.10.3.2")); // Microsoft Time Stamping | ||
oidCollection.Add(new Oid("1.3.6.1.4.1.311.10.5.1")); // Digital Rights | ||
oidCollection.Add(new Oid("1.3.6.1.4.1.311.64.1.1")); // Domain Name System (DNS) Server Trust | ||
|
||
// Create Issuer RSA Private Key | ||
using RSA issuerRsaKey = RSA.Create(4096); | ||
|
||
// Create Issuer Request | ||
CertificateRequest issuerReq = new(issuerSubjectName, issuerRsaKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); | ||
issuerReq.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true)); | ||
issuerReq.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(issuerReq.PublicKey, false)); | ||
issuerReq.CertificateExtensions.Add(new X509KeyUsageExtension(x509KeyUsageFlags, false)); | ||
issuerReq.CertificateExtensions.Add(sanBuilder.Build()); | ||
issuerReq.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(oidCollection, true)); | ||
|
||
// Create Issuer Certificate | ||
using X509Certificate2 issuerCert = issuerReq.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(10)); | ||
|
||
// Create RSA Private Key | ||
using RSA rsaKey = RSA.Create(2048); | ||
|
||
// Create Request | ||
CertificateRequest req = new(subjectName, rsaKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); | ||
req.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false)); | ||
req.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(req.PublicKey, false)); | ||
req.CertificateExtensions.Add(new X509KeyUsageExtension(x509KeyUsageFlags, false)); | ||
req.CertificateExtensions.Add(sanBuilder.Build()); | ||
req.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(oidCollection, true)); | ||
|
||
// Create Certificate | ||
using X509Certificate2 cert = req.Create(issuerCert, DateTimeOffset.Now, DateTimeOffset.Now.AddYears(9), new byte[] { 1, 2, 3, 4 }); | ||
|
||
// Export | ||
// Export Issuer Private Key | ||
var issuerPrivateKeyExport = issuerRsaKey.ExportRSAPrivateKey(); | ||
var issuerPrivateKeyData = Convert.ToBase64String(issuerPrivateKeyExport, Base64FormattingOptions.InsertLineBreaks); | ||
File.WriteAllText(Path.Combine(folderPath, "rootCA.key"), KEY_HEADER + issuerPrivateKeyData + KEY_FOOTER); | ||
|
||
// Export Issuer Certificate | ||
var issuerCertExport = issuerCert.Export(X509ContentType.Cert); | ||
var issuerCertData = Convert.ToBase64String(issuerCertExport, Base64FormattingOptions.InsertLineBreaks); | ||
File.WriteAllText(Path.Combine(folderPath, "rootCA.crt"), CRT_HEADER + issuerCertData + CRT_FOOTER); | ||
|
||
// Export Private Key | ||
var privateKeyExport = rsaKey.ExportRSAPrivateKey(); | ||
var privateKeyData = Convert.ToBase64String(privateKeyExport, Base64FormattingOptions.InsertLineBreaks); | ||
File.WriteAllText(Path.Combine(folderPath, "localhost.key"), KEY_HEADER + privateKeyData + KEY_FOOTER); | ||
|
||
// Export Certificate | ||
var certExport = cert.Export(X509ContentType.Cert); | ||
var certData = Convert.ToBase64String(certExport, Base64FormattingOptions.InsertLineBreaks); | ||
File.WriteAllText(Path.Combine(folderPath, "localhost.crt"), CRT_HEADER + certData + CRT_FOOTER); | ||
|
||
} | ||
|
||
public static void CreateP12(string certPath, string keyPath, string password = "") | ||
{ | ||
string? folderPath = Path.GetDirectoryName(certPath); | ||
string fileName = Path.GetFileNameWithoutExtension(certPath); | ||
using X509Certificate2 certWithKey = X509Certificate2.CreateFromPemFile(certPath, keyPath); | ||
var certWithKeyExport = certWithKey.Export(X509ContentType.Pfx, password); | ||
if (!string.IsNullOrEmpty(folderPath)) | ||
File.WriteAllBytes(Path.Combine(folderPath, fileName + ".p12"), certWithKeyExport); | ||
} | ||
|
||
/// <summary> | ||
/// Returns false if user don't install certificate, otherwise true. | ||
/// </summary> | ||
public static bool InstallCertificate(string certPath, StoreName storeName, StoreLocation storeLocation) | ||
{ | ||
try | ||
{ | ||
X509Certificate2 certificate = new(certPath, "", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); | ||
X509Store store = new(storeName, storeLocation); | ||
store.Open(OpenFlags.ReadWrite); | ||
store.Add(certificate); | ||
store.Close(); | ||
return true; | ||
} | ||
catch (Exception ex) // Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException | ||
{ | ||
Debug.WriteLine(ex.Message); | ||
// If ex.Message: (The operation was canceled by the user.) | ||
return false; | ||
} | ||
} | ||
|
||
public static bool IsCertificateInstalled(string subjectName, StoreName storeName, StoreLocation storeLocation) | ||
{ | ||
X509Store store = new(storeName, storeLocation); | ||
store.Open(OpenFlags.ReadOnly); | ||
|
||
X509Certificate2Collection certificates = store.Certificates.Find(X509FindType.FindBySubjectName, subjectName, false); | ||
|
||
if (certificates != null && certificates.Count > 0) | ||
{ | ||
Debug.WriteLine("Certificate is already installed."); | ||
return true; | ||
} | ||
else | ||
return false; | ||
} | ||
|
||
public static void UninstallCertificate(string subjectName, StoreName storeName, StoreLocation storeLocation) | ||
{ | ||
X509Store store = new(storeName, storeLocation); | ||
store.Open(OpenFlags.ReadWrite | OpenFlags.IncludeArchived); | ||
|
||
// You could also use a more specific find type such as X509FindType.FindByThumbprint | ||
X509Certificate2Collection certificates = store.Certificates.Find(X509FindType.FindBySubjectName, subjectName, false); | ||
Debug.WriteLine($"Cert Count: {certificates.Count}"); | ||
|
||
for (int i = 0; i < certificates.Count; i++) | ||
{ | ||
X509Certificate2 cert = certificates[i]; | ||
Debug.WriteLine($"Cert SubjectName: {cert.SubjectName.Name}"); | ||
|
||
X509Chain chain = new(); | ||
chain.Build(cert); | ||
X509Certificate2Collection allCertsInChain = new(); | ||
Debug.WriteLine($"Cert Chain Count: {chain.ChainElements.Count}"); | ||
|
||
for (int j = 0; j < chain.ChainElements.Count; j++) | ||
{ | ||
X509ChainElement chainElement = chain.ChainElements[j]; | ||
allCertsInChain.Add(chainElement.Certificate); | ||
|
||
Debug.WriteLine($"Cert Chain SubjectName: {chainElement.Certificate.SubjectName.Name}"); | ||
} | ||
|
||
store.RemoveRange(allCertsInChain); | ||
store.Remove(cert); | ||
} | ||
store.Close(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
using System; | ||
using System.Drawing; | ||
|
||
#nullable enable | ||
namespace MsmhToolsClass | ||
{ | ||
public static class ColorsTool | ||
{ | ||
//----------------------------------------------------------------------------------- | ||
/// <summary> | ||
/// Converts the HSL values to a Color. | ||
/// </summary> | ||
/// <param name="alpha">The alpha. (0 - 255)</param> | ||
/// <param name="hue">The hue. (0f - 360f)</param> | ||
/// <param name="saturation">The saturation. (0f - 1f)</param> | ||
/// <param name="lighting">The lighting. (0f - 1f)</param> | ||
/// <returns></returns> | ||
public static Color FromHsl(int alpha, float hue, float saturation, float lighting) | ||
{ | ||
if (0 > alpha || 255 < alpha) | ||
{ | ||
throw new ArgumentOutOfRangeException(nameof(alpha)); | ||
} | ||
if (0f > hue || 360f < hue) | ||
{ | ||
throw new ArgumentOutOfRangeException(nameof(hue)); | ||
} | ||
if (0f > saturation || 1f < saturation) | ||
{ | ||
throw new ArgumentOutOfRangeException(nameof(saturation)); | ||
} | ||
if (0f > lighting || 1f < lighting) | ||
{ | ||
throw new ArgumentOutOfRangeException(nameof(lighting)); | ||
} | ||
|
||
if (0 == saturation) | ||
{ | ||
return Color.FromArgb(alpha, Convert.ToInt32(lighting * 255), Convert.ToInt32(lighting * 255), Convert.ToInt32(lighting * 255)); | ||
} | ||
|
||
float fMax, fMid, fMin; | ||
int iSextant, iMax, iMid, iMin; | ||
|
||
if (0.5 < lighting) | ||
{ | ||
fMax = lighting - (lighting * saturation) + saturation; | ||
fMin = lighting + (lighting * saturation) - saturation; | ||
} | ||
else | ||
{ | ||
fMax = lighting + (lighting * saturation); | ||
fMin = lighting - (lighting * saturation); | ||
} | ||
|
||
iSextant = (int)Math.Floor(hue / 60f); | ||
if (300f <= hue) | ||
{ | ||
hue -= 360f; | ||
} | ||
hue /= 60f; | ||
hue -= 2f * (float)Math.Floor(((iSextant + 1f) % 6f) / 2f); | ||
if (0 == iSextant % 2) | ||
{ | ||
fMid = hue * (fMax - fMin) + fMin; | ||
} | ||
else | ||
{ | ||
fMid = fMin - hue * (fMax - fMin); | ||
} | ||
|
||
iMax = Convert.ToInt32(fMax * 255); | ||
iMid = Convert.ToInt32(fMid * 255); | ||
iMin = Convert.ToInt32(fMin * 255); | ||
|
||
switch (iSextant) | ||
{ | ||
case 1: | ||
return Color.FromArgb(alpha, iMid, iMax, iMin); | ||
case 2: | ||
return Color.FromArgb(alpha, iMin, iMax, iMid); | ||
case 3: | ||
return Color.FromArgb(alpha, iMin, iMid, iMax); | ||
case 4: | ||
return Color.FromArgb(alpha, iMid, iMin, iMax); | ||
case 5: | ||
return Color.FromArgb(alpha, iMax, iMin, iMid); | ||
default: | ||
return Color.FromArgb(alpha, iMax, iMid, iMin); | ||
} | ||
} | ||
//----------------------------------------------------------------------------------- | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using System; | ||
using System.Diagnostics; | ||
|
||
#nullable enable | ||
namespace MsmhToolsClass | ||
{ | ||
public class ConvertTool | ||
{ | ||
public enum SizeUnits | ||
{ | ||
Byte, KB, MB, GB, TB, PB, EB, ZB, YB, RB, QB | ||
} | ||
|
||
public static string ConvertByteToHumanRead(double bytes) | ||
{ | ||
string result = $"{bytes} {SizeUnits.Byte}"; | ||
double calc = bytes; | ||
if (calc > 1000) calc = ConvertSize(calc, SizeUnits.Byte, SizeUnits.KB, out result); | ||
if (calc > 1000) calc = ConvertSize(calc, SizeUnits.KB, SizeUnits.MB, out result); | ||
if (calc > 1000) calc = ConvertSize(calc, SizeUnits.MB, SizeUnits.GB, out result); | ||
if (calc > 1000) calc = ConvertSize(calc, SizeUnits.GB, SizeUnits.TB, out result); | ||
if (calc > 1000) calc = ConvertSize(calc, SizeUnits.TB, SizeUnits.PB, out result); | ||
if (calc > 1000) calc = ConvertSize(calc, SizeUnits.PB, SizeUnits.EB, out result); | ||
if (calc > 1000) calc = ConvertSize(calc, SizeUnits.EB, SizeUnits.ZB, out result); | ||
if (calc > 1000) calc = ConvertSize(calc, SizeUnits.ZB, SizeUnits.YB, out result); | ||
if (calc > 1000) calc = ConvertSize(calc, SizeUnits.YB, SizeUnits.RB, out result); | ||
if (calc > 1000) ConvertSize(calc, SizeUnits.RB, SizeUnits.QB, out result); | ||
return result; | ||
} | ||
|
||
public static double ConvertSize(double value, SizeUnits fromUnit, SizeUnits toUnit, out string humanRead) | ||
{ | ||
try | ||
{ | ||
double unit = 1000; // In decimal it's 1000 not 1024. ref:https://en.wikipedia.org/wiki/Byte#Multiple-byte_units | ||
double valueByte = value * (double)Math.Pow(unit, (long)fromUnit); | ||
double outValue = valueByte / (double)Math.Pow(unit, (long)toUnit); | ||
string outString = outValue.ToString(); | ||
if (outString.Contains('.') && outString.EndsWith('0')) | ||
{ | ||
while (outString.EndsWith('0')) | ||
{ | ||
outString = outString.TrimEnd('0'); | ||
} | ||
outString = outString.TrimEnd('.'); | ||
double result = double.TryParse(outString, out double outValueNoZero) ? outValueNoZero : outValue; | ||
humanRead = $"{Math.Round(result, 2)} {toUnit}"; | ||
return result; | ||
} | ||
else | ||
{ | ||
humanRead = $"{Math.Round(outValue, 2)} {toUnit}"; | ||
return outValue; | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
Debug.WriteLine($"ConvertSize: {ex.Message}"); | ||
humanRead = $"-1 {toUnit}"; | ||
return -1; | ||
} | ||
} | ||
//----------------------------------------------------------------------------------- | ||
} | ||
} |
Oops, something went wrong.