diff --git a/.assets/scripts/modules_update.ps1 b/.assets/scripts/modules_update.ps1 index b04c87df..d02df262 100644 --- a/.assets/scripts/modules_update.ps1 +++ b/.assets/scripts/modules_update.ps1 @@ -40,6 +40,7 @@ begin { 'do-common' = @{ SetupUtils = @{ certs = @( + 'ConvertFrom-PEM' 'ConvertTo-PEM' 'Get-Certificate' ) diff --git a/modules/SetupUtils/Functions/certs.ps1 b/modules/SetupUtils/Functions/certs.ps1 index 905be7e4..c8fbbc66 100644 --- a/modules/SetupUtils/Functions/certs.ps1 +++ b/modules/SetupUtils/Functions/certs.ps1 @@ -1,3 +1,56 @@ +function ConvertFrom-PEM { + [CmdletBinding()] + [OutputType([System.Security.Cryptography.X509Certificates.X509Certificate2[]])] + param ( + [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'FromString')] + [string]$InputObject, + + [Parameter(Mandatory, Position = 0, ParameterSetName = 'FromPath')] + [ValidateScript({ Test-Path $_ -PathType 'Leaf' }, ErrorMessage = "'{0}' is not a valid file path.")] + [string]$Path + ) + + begin { + # list to store input certificate strings + $pemTxt = [System.Collections.Generic.List[string]]::new() + # hashset for storing parsed pem certificates + $pemSplit = [System.Collections.Generic.HashSet[string]]::new() + # list to store decoded certificates + $x509Certs = [System.Collections.Generic.List[Security.Cryptography.X509Certificates.X509Certificate2]]::new() + } + + process { + switch ($PsCmdlet.ParameterSetName) { + FromPath { + # read certificate file + Resolve-Path $Path | ForEach-Object { + $pemTxt.Add([IO.File]::ReadAllText($_)) + } + continue + } + FromString { + $InputObject.ForEach({ $pemTxt.Add($_) }) + continue + } + } + } + + end { + # parse certificate string + [regex]::Matches( + [string]::Join("`n", $pemTxt).Replace("`r`n", "`n"), + '(?<=-{5}BEGIN[\w ]+CERTIFICATE-{5}\n)[\S\n]+(?=\n-{5}END[\w ]+CERTIFICATE-{5})' + ).Value.ForEach({ $pemSplit.Add($_) | Out-Null }) + # convert PEM encoded certificates to X509 certificate objects + foreach ($pem in $pemSplit) { + $decCrt = [Security.Cryptography.X509Certificates.X509Certificate2]::new([Convert]::FromBase64String($pem)) + $x509Certs.Add($decCrt) + } + + return $x509Certs + } +} + function ConvertTo-PEM { [CmdletBinding()] [OutputType([System.Collections.Generic.List[string]])] diff --git a/modules/SetupUtils/SetupUtils.psd1 b/modules/SetupUtils/SetupUtils.psd1 index b8ce486b..9a2258a2 100644 --- a/modules/SetupUtils/SetupUtils.psd1 +++ b/modules/SetupUtils/SetupUtils.psd1 @@ -12,7 +12,7 @@ RootModule = 'SetupUtils.psm1' # Version number of this module. - ModuleVersion = '0.3.1' + ModuleVersion = '0.4.0' # Supported PSEditions CompatiblePSEditions = @('Core') @@ -71,6 +71,7 @@ # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. FunctionsToExport = @( # certs + 'ConvertFrom-PEM' 'ConvertTo-PEM' 'Get-Certificate' # common diff --git a/modules/SetupUtils/SetupUtils.psm1 b/modules/SetupUtils/SetupUtils.psm1 index bece98b6..3da63c1c 100644 --- a/modules/SetupUtils/SetupUtils.psm1 +++ b/modules/SetupUtils/SetupUtils.psm1 @@ -7,6 +7,7 @@ $ErrorActionPreference = 'Stop' $exportModuleMemberParams = @{ Function = @( # certs + 'ConvertFrom-PEM' 'ConvertTo-PEM' 'Get-Certificate' # common diff --git a/wsl/wsl_install.ps1 b/wsl/wsl_install.ps1 index b38ce2ec..149f2080 100644 --- a/wsl/wsl_install.ps1 +++ b/wsl/wsl_install.ps1 @@ -69,7 +69,7 @@ begin { # set location to workspace folder Push-Location "$PSScriptRoot/.." # import InstallUtils for the Update-SessionEnvironmentPath function - Import-Module (Resolve-Path './modules/InstallUtils') + Import-Module (Resolve-Path './modules/InstallUtils') -Force Write-Host 'checking if the repository is up to date...' -ForegroundColor Cyan if ((Update-GitRepository) -eq 2) { diff --git a/wsl/wsl_setup.ps1 b/wsl/wsl_setup.ps1 index 464b4e23..5c54a347 100644 --- a/wsl/wsl_setup.ps1 +++ b/wsl/wsl_setup.ps1 @@ -127,9 +127,9 @@ begin { # set location to workspace folder Push-Location "$PSScriptRoot/.." # import InstallUtils for the Invoke-GhRepoClone function - Import-Module (Convert-Path './modules/InstallUtils') + Import-Module (Convert-Path './modules/InstallUtils') -Force # import SetupUtils for the Set-WslConf function - Import-Module (Convert-Path './modules/SetupUtils') + Import-Module (Convert-Path './modules/SetupUtils') -Force if (-not $SkipRepoUpdate) { Write-Host "`nchecking if the repository is up to date..." -ForegroundColor Cyan