Last active
August 9, 2017 18:36
-
-
Save joshcooper/9d6b4c7ebbd71347769d to your computer and use it in GitHub Desktop.
This file contains hidden or 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
$verifyCallback = { | |
param( | |
$sender, $certificate, $chain, $policyErrors | |
) | |
$verified = $true | |
switch($policyErrors) { | |
None { | |
Write-Host "Verified Cert:" $certificate.SubjectName.Name | |
} | |
RemoteCertificateChainErrors { | |
foreach ($status in $chain.ChainStatus) { | |
switch ($status.Status) { | |
NoError { | |
Write-Host "Verified Cert Chain" | |
} | |
UntrustedRoot { | |
Write-Host "Verifying Cert Chain:" | |
foreach ($element in $chain.ChainElements) { | |
$cert = $element.Certificate | |
Write-Host " " $cert.SubjectName.Name "[" $cert.Thumbprint "]" | |
} | |
$idx = $chain.ChainElements.Count - 1 | |
$root = $chain.ChainElements[$idx].Certificate | |
if ($root.Equals($cacert)) { | |
Write-Host "Root is trusted:" $root.SubjectName.Name | |
} | |
else | |
{ | |
Write-Host "Root is not trusted:" $root.SubjectName.Name | |
$verified = $false | |
} | |
} | |
default { | |
Write-Host "Problem with cert chain [" $status.Status "] " $status.StatusInformation | |
$verified = $false | |
} | |
} | |
} | |
} | |
default { | |
Write-Host "Verification failed " $sslPolicyError | |
$verified = $false | |
} | |
} | |
return $verified | |
} | |
Function Download-File { | |
Param() | |
# using endpoint because it doesn't require client certs | |
$url = 'https://arcturus.corp.puppetlabs.net:8140/puppet-ca/v1/certificate/ca' | |
$file = '.\index.html' | |
$cacert_file = ".\ca.pem" | |
$cacert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($cacert_file) | |
Write-Host "Downloading" $url | |
[Net.ServicePointManager]::ServerCertificateValidationCallback = $verifyCallback | |
$webclient = New-Object system.net.webclient | |
$webclient.DownloadFile($url, $file) | |
} | |
Download-File |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Defaulting to false sounds good.
About the other part, I would expect
$certificate
to be the server's certificate, which I wouldn't expect to ever match thecacert
. I think you need to always compare the root of the chain ($root = $chain.ChainElements[$idx].Certificate
) with the$cacert
.Also there can be other errors associated with the chain, e.g. expired ca, intermediate, or server cert, revoked certs (not sure if powershell automatically checks those against a system-wide CRL), the root cert may not actually be trusted to be used as a CA, e.g.
basicConstraints=CA:false
, etc. I'm not entirely sure which are reported as$policyErrors
, and which are reported when walking the$chain.ChainStatus
. So that's why I was handling both, and making sure we only verify the connection if there are nopolicyErrors
, or we get aRemoteCertificateChainErrors
policy error, and there is only a singleUntrustedRoot
status and the root cert matches.