diff --git a/Invoke-OpenSSHConfiguration.ps1 b/Invoke-OpenSSHConfiguration.ps1 index ddfa390..86b1f73 100644 --- a/Invoke-OpenSSHConfiguration.ps1 +++ b/Invoke-OpenSSHConfiguration.ps1 @@ -477,14 +477,98 @@ Switch (Test-ProcessElevationStatus) $CertificateExpirationThreshold = Get-Date - #Include both LocalMachine and CurrentUser CA stores + #Include LocalMachine CA stores $CertificateStorePathList = New-Object -TypeName 'System.Collections.Generic.List[System.String]' $CertificateStorePathList.Add('Cert:\LocalMachine\Root') $CertificateStorePathList.Add('Cert:\LocalMachine\CA') - $CertificateStorePathList.Add('Cert:\CurrentUser\Root') - $CertificateStorePathList.Add('Cert:\CurrentUser\CA') - $CACertificates = Get-ChildItem -Path $CertificateStorePathList -ErrorAction SilentlyContinue | Where-Object {($_.NotAfter -gt $CertificateExpirationThreshold) -and ($_.Extensions | Where-Object {($_.Oid.FriendlyName -iin @('Basic Constraints')) -and ($_.CertificateAuthority -eq $True)})} | Sort-Object -Property @('Thumbprint') -Unique + #Include CurrentUser CA stores (use logged-in user's store if running as SYSTEM) + $UserCertificates = New-Object -TypeName 'System.Collections.Generic.List[System.Security.Cryptography.X509Certificates.X509Certificate2]' + + Switch (($Null -ine $CurrentUserSession) -and ([System.String]::IsNullOrEmpty($CurrentUserSession.SID) -eq $False)) + { + {($_ -eq $True)} + { + #Check if user's registry hive is loaded under HKEY_USERS + $UserRegistryPath = "Registry::HKEY_USERS\$($CurrentUserSession.SID)" + + Switch (Test-Path -Path $UserRegistryPath -ErrorAction SilentlyContinue) + { + {($_ -eq $True)} + { + $WriteLogMessage.Invoke(0, @("Accessing certificate store for user: $($CurrentUserSession.NTAccount) [SID: $($CurrentUserSession.SID)]")) + + #Open user's Root and CA stores via X509Store + $UserStoreLocations = @( + @{Name = 'Root'; Location = [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser} + @{Name = 'CA'; Location = [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser} + ) + + ForEach ($StoreInfo In $UserStoreLocations) + { + Try + { + $UserCertStore = New-Object -TypeName 'System.Security.Cryptography.X509Certificates.X509Store' -ArgumentList @($StoreInfo.Name, $StoreInfo.Location) + $UserCertStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly -bor [System.Security.Cryptography.X509Certificates.OpenFlags]::OpenExistingOnly) + $UserCertificates.AddRange($UserCertStore.Certificates) + $UserCertStore.Close() + } + Catch + { + $WriteLogMessage.Invoke(1, @("Unable to access user certificate store `"$($StoreInfo.Name)`": $($_.Exception.Message)")) + } + } + } + + Default + { + $WriteLogMessage.Invoke(1, @("User registry hive not loaded for SID: $($CurrentUserSession.SID). Using current process identity certificates.")) + $CertificateStorePathList.Add('Cert:\CurrentUser\Root') + $CertificateStorePathList.Add('Cert:\CurrentUser\CA') + } + } + } + + Default + { + #No user session info available, use current process identity + $CertificateStorePathList.Add('Cert:\CurrentUser\Root') + $CertificateStorePathList.Add('Cert:\CurrentUser\CA') + } + } + + $CACertificates = New-Object -TypeName 'System.Collections.Generic.List[System.Security.Cryptography.X509Certificates.X509Certificate2]' + + #Add certificates from LocalMachine stores + $LocalMachineCerts = Get-ChildItem -Path $CertificateStorePathList -ErrorAction SilentlyContinue | Where-Object {($_.NotAfter -gt $CertificateExpirationThreshold) -and ($_.Extensions | Where-Object {($_.Oid.FriendlyName -iin @('Basic Constraints')) -and ($_.CertificateAuthority -eq $True)})} + + Switch ($Null -ine $LocalMachineCerts) + { + {($_ -eq $True)} + { + $CACertificates.AddRange([System.Security.Cryptography.X509Certificates.X509Certificate2[]]$LocalMachineCerts) + } + } + + #Add user certificates (already filtered by store type) + Switch ($UserCertificates.Count -gt 0) + { + {($_ -eq $True)} + { + $FilteredUserCerts = $UserCertificates | Where-Object {($_.NotAfter -gt $CertificateExpirationThreshold) -and ($_.Extensions | Where-Object {($_.Oid.FriendlyName -iin @('Basic Constraints')) -and ($_.CertificateAuthority -eq $True)})} + + Switch ($Null -ine $FilteredUserCerts) + { + {($_ -eq $True)} + { + $CACertificates.AddRange([System.Security.Cryptography.X509Certificates.X509Certificate2[]]$FilteredUserCerts) + } + } + } + } + + #Dedupe by thumbprint + $CACertificates = $CACertificates | Sort-Object -Property @('Thumbprint') -Unique #region Apply CA Inclusion Filter Switch (([System.String]::IsNullOrEmpty($CAInclusionExpression) -eq $False) -and ([System.String]::IsNullOrWhiteSpace($CAInclusionExpression) -eq $False))