Skip to content

Instantly share code, notes, and snippets.

@jwarwick-bry
Forked from IISResetMe/s_client.ps1
Last active June 14, 2024 20:33
Show Gist options
  • Save jwarwick-bry/ad6b60a0024ccafb74ccee9692a8399d to your computer and use it in GitHub Desktop.
Save jwarwick-bry/ad6b60a0024ccafb74ccee9692a8399d to your computer and use it in GitHub Desktop.
PowerShell semi-clone of openssl s_client tool
using namespace System.Net.Sockets
using namespace System.Net.Security
using namespace System.Security.Cryptography.X509Certificates
#based on https://blog.iisreset.me/openssl-s_client-but-in-powershell/
function ConvertFrom-X509Certificate {
param(
[Parameter(ValueFromPipeline)]
[X509Certificate2]$Certificate
)
process {
@(
'-----BEGIN CERTIFICATE-----'
[Convert]::ToBase64String(
$Certificate.Export([X509ContentType]::Cert),
[Base64FormattingOptions]::InsertLineBreaks
)
'-----END CERTIFICATE-----'
) -join [Environment]::NewLine
}
}
function Get-RemoteSSLCertificate {
param(
[Alias('CN')]
[Parameter(Mandatory = $true, Position = 0)]
[string]$ComputerName,
[Parameter(Position = 1)]
[UInt16]$Port = 443,
[switch]$Insecure = $false,
[string]$ClientCert,
[ValidateSet('Base64', 'X509Certificate')]
[string]$As = 'X509Certificate'
)
$tcpClient = [TcpClient]::new($ComputerName, $Port)
try {
$tlsClient = [SslStream]::new($tcpClient.GetStream(), $false, {$Insecure})
#annoyingly (and probably protocol-unnecessarily): Error retrieving property '$RemoteCertificate': $This operation is only allowed using a successfully authenticated context.
if ($ClientCert -AND $ClientCert.length -gt 5) {
$pfxPath = $ClientCert
$varCached = get-variable -scope script -name 'pfxPassword' -ErrorAction SilentlyContinue
if (-NOT $varCached) {
$script:pfxPassword = Read-Host -Prompt "Enter the password for the client SSL cert PFX file" -AsSecureString
}
$pfxCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($pfxPath, $pfxPassword)
$sslOptions = [System.Net.Security.SslClientAuthenticationOptions]::new()
$sslOptions.TargetHost = $ComputerName
$sslOptions.ClientCertificates = [System.Security.Cryptography.X509Certificates.X509CertificateCollection]::new()
$sslOptions.ClientCertificates.Add($pfxCert)
$sslOptions.EnabledSslProtocols = [System.Security.Authentication.SslProtocols]::Tls12
$tlsClient.AuthenticateAsClient($sslOptions)
}else {
$tlsClient.AuthenticateAsClient($ComputerName)
}
if ($As -eq 'Base64') {
return $tlsClient.RemoteCertificate |ConvertFrom-X509Certificate
}
return $tlsClient.RemoteCertificate -as [X509Certificate2]
}
finally {
if ($tlsClient -is [IDisposable]) {
$tlsClient.Dispose()
}
$tcpClient.Dispose()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment