Skip to content

Commit

Permalink
Updated some error messages and added new unit tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Bob Pokorny committed Sep 12, 2024
1 parent c8035c3 commit 118c583
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 31 deletions.
30 changes: 18 additions & 12 deletions IISU/ClientPSIIManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -488,9 +488,9 @@ private object PerformIISBinding(string webSiteName, string protocol, string ipA
# Check if the IISAdministration module is available
$module = Get-Module -Name IISAdministration -ListAvailable
if (-not $module) {
throw ""The IISAdministration module is not installed on this system.""
}
#if (-not $module) {
#throw ""The IISAdministration module is not installed on this system.""
#}
# Check if the IISAdministration module is already loaded
if (-not (Get-Module -Name IISAdministration)) {
Expand Down Expand Up @@ -522,14 +522,20 @@ private object PerformIISBinding(string webSiteName, string protocol, string ipA
# Create the new binding with modified properties
$newBindingInfo = ""${IPAddress}:${Port}:${Hostname}""
New-IISSiteBinding -Name $SiteName `
-BindingInformation $newBindingInfo `
-Protocol $Protocol `
-CertificateThumbprint $Thumbprint `
-CertStoreLocation $StoreName `
-SslFlag $SslFlags
Write-Host ""New binding added: $newBindingInfo""
try
{
New-IISSiteBinding -Name $SiteName `
-BindingInformation $newBindingInfo `
-Protocol $Protocol `
-CertificateThumbprint $Thumbprint `
-CertStoreLocation $StoreName `
-SslFlag $SslFlags
Write-Host ""New binding added: $newBindingInfo""
}
catch {
throw $_
}
";

ps.AddScript(funcScript);
Expand Down Expand Up @@ -569,7 +575,7 @@ public static string MigrateSNIFlag(string input)
case "3 - sni binding":
return "3";
default:
throw new Exception($"Received an invalid value '{input}' for sni/ssl Flag value");
throw new ArgumentOutOfRangeException($"Received an invalid value '{input}' for sni/ssl Flag value");
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions IISU/WindowsCertStore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,10 @@
</None>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="System.Management.Automation">
<Version>7.4.5</Version>
</PackageReference>
</ItemGroup>

</Project>
52 changes: 52 additions & 0 deletions WinCertUnitTests/CertificateHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace WinCertUnitTests
{
internal class CertificateHelper
{
public static void CreateSelfSignedCertificate(string certName, string password, string pfxPath)
{
// Set certificate subject and other properties
var distinguishedName = new X500DistinguishedName($"CN={certName}");

using (RSA rsa = RSA.Create(2048))
{
// Define the certificate request
var certificateRequest = new CertificateRequest(
distinguishedName,
rsa,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);

// Add key usage and enhanced key usage (EKU) extensions
certificateRequest.CertificateExtensions.Add(
new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, true));

certificateRequest.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.1") // OID for Server Authentication
}, true));

// Create the self-signed certificate
var startDate = DateTimeOffset.Now;
var endDate = startDate.AddYears(1);

using (X509Certificate2 certificate = certificateRequest.CreateSelfSigned(startDate, endDate))
{
// Export the certificate with a password to a PFX file
byte[] pfxBytes = certificate.Export(X509ContentType.Pfx, password);

// Save to a file
File.WriteAllBytes(pfxPath, pfxBytes);

Console.WriteLine($"Certificate created and saved at {pfxPath}");
}
}
}
}
}
77 changes: 66 additions & 11 deletions WinCertUnitTests/UnitTestIISBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,39 @@
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting.Logging;
using System.Net;
using System.Web.Services.Description;
//using System.Web.Services.Description;
using System.Management.Automation;
using Keyfactor.Orchestrators.Common.Enums;
using System.Security.Policy;
using Microsoft.Web.Administration;
namespace WinCertUnitTests
{
[TestClass]
public class UnitTestIISBinding
{
private string certName = "";
private string certPassword = "";
private string pfxPath = "";

public UnitTestIISBinding()
{
certName = "UnitTestCertificate";
certPassword = "lkjglj655asd";
pfxPath = Path.Combine(Directory.GetCurrentDirectory(), "TestCertificate.pfx");

if (!File.Exists(pfxPath))
{
CertificateHelper.CreateSelfSignedCertificate(certName, certPassword, pfxPath);
}
}


[TestMethod]
public void RenewBindingCertificate()
{
string certPath = @"Assets\ManualCert_8zWwF36N6cNu.pfx";

Check warning on line 39 in WinCertUnitTests/UnitTestIISBinding.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

The variable 'certPath' is assigned but its value is never used
string password = "8zWwF36N6cNu";

Check warning on line 40 in WinCertUnitTests/UnitTestIISBinding.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

The variable 'password' is assigned but its value is never used
X509Certificate2 cert = new X509Certificate2(certPath, password);
X509Certificate2 cert = new X509Certificate2(pfxPath, certPassword);

Runspace rs = PsHelper.GetClientPsRunspace("", "localhost", "", false, "", "");

Expand All @@ -33,11 +52,13 @@ public void BindingNewCertificate()
{
string certPath = @"Assets\ManualCert_8zWwF36N6cNu.pfx";

Check warning on line 53 in WinCertUnitTests/UnitTestIISBinding.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

The variable 'certPath' is assigned but its value is never used
string password = "8zWwF36N6cNu";

Check warning on line 54 in WinCertUnitTests/UnitTestIISBinding.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

The variable 'password' is assigned but its value is never used
X509Certificate2 cert = new X509Certificate2(certPath, password);
X509Certificate2 cert = new X509Certificate2(pfxPath, certPassword);

Runspace rs = PsHelper.GetClientPsRunspace("", "localhost", "", false, "", "");

ClientPSIIManager IIS = new ClientPSIIManager(rs, "Default Web Site", "https", "*", "443", "", "", "My", "3");
string sslFlag = "32";

ClientPSIIManager IIS = new ClientPSIIManager(rs, "Default Web Site", "https", "*", "443", "", "", "My", sslFlag);
JobResult result = IIS.BindCertificate(cert);

Assert.AreEqual("Success", result.Result.ToString());
Expand All @@ -47,14 +68,14 @@ public void BindingNewCertificate()
public void AddCertificate()
{

string certPath = @"Assets\ManualCert_8zWwF36N6cNu.pfx";
string password = "8zWwF36N6cNu";
//string certPath = @"Assets\ManualCert_8zWwF36N6cNu.pfx";
//string password = "8zWwF36N6cNu";

Runspace rs = PsHelper.GetClientPsRunspace("", "localhost", "", false, "", "");
rs.Open();

ClientPSCertStoreManager certStoreManager = new ClientPSCertStoreManager(rs);
JobResult result = certStoreManager.ImportPFXFile(certPath, password, "", "My");
JobResult result = certStoreManager.ImportPFXFile(pfxPath, certPassword, "", "My");
rs.Close();

Assert.AreEqual("Success", result.Result.ToString());
Expand Down Expand Up @@ -83,12 +104,46 @@ public void OrigSNIFlagZeroReturnsZero()
}

[TestMethod]
public void InvalidSNIFlagZeroThrowException()
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void InvalidSNIFlagThrowException()
{
string expectedResult = "32";
string result = ClientPSIIManager.MigrateSNIFlag("32");
Assert.AreEqual(expectedResult, result);
string result = ClientPSIIManager.MigrateSNIFlag("Bad value");
}

static bool TestValidSslFlag(int sslFlag)
{
try
{
using (ServerManager serverManager = new ServerManager())
{
// Loop through all sites in IIS
foreach (Microsoft.Web.Administration.Site site in serverManager.Sites)
{
// Loop through all bindings for each site
foreach (Binding binding in site.Bindings)
{
// Check if the binding uses the HTTPS protocol
if (binding.Protocol == "https")
{
// Get the SslFlags value (stored in binding.Attributes)
int currentSslFlags = (int)binding.Attributes["sslFlags"].Value;

// Check if the SslFlag value matches the provided one
if (currentSslFlags == sslFlag)
{
return true; // Valid SslFlag found
}
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}

return false; // No matching SslFlag found
}
}
}
11 changes: 3 additions & 8 deletions WinCertUnitTests/WinCertUnitTests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -13,6 +13,7 @@
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Keyfactor.Orchestrators.Common" Version="3.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Microsoft.Web.Administration" Version="11.1.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
</ItemGroup>
Expand All @@ -25,10 +26,4 @@
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
</ItemGroup>

<ItemGroup>
<None Update="Assets\ManualCert_8zWwF36N6cNu.pfx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

0 comments on commit 118c583

Please sign in to comment.