Определение количества сертификатов, возвращаемых сервером SSL (TLS) при использовании System.Net.Security.SSLStream - PullRequest
0 голосов
/ 27 сентября 2019

в openssl вы можете увидеть, сколько сертификатов предоставляется во время рукопожатия ssl.Например, если есть сертификат службы, два промежуточных центра сертификации и корневой центр сертификации, ожидаемое рукопожатие будет иметь 3 сертификата."все минус корень"

Я пишу код, который использует System.Net.Security.SSLStream.Легко получить сертификат сервера (свойство RemoteCertificate после AuthenticateAsClient ()) и легко получить цепочку (в объекте X509Chain есть метод, который принимает x509v2 и «строит» цепочку)

Что яменя интересует получение сертификатов, представленных сервером SSL во время рукопожатия SSl / TLS ... в основном, я хочу знать, отправил ли сервер правильный набор сертификатов (все без корня) или неполный набор (сертификат сервера,но не хватает некоторых или всех промежуточных звеньев .. надеюсь, что клиент их уже знает), или неуместный набор (все, включая root ... не говорите клиентам, кому доверять, это не ваше дело)

inopenssl (бесполезно для моих обстоятельств, но в качестве примера) вы можете получить точный список сертификатов, предоставленных сервером

C:\Program Files\openssl>openssl s_client -connect xxxxxx:443
WARNING: can't open config file: /usr/local/ssl/openssl.cnf
CONNECTED(00000214)
depth=1 DC = loc, DC = xxxxx, DC = xxxx, CN = prod-xxxxxxx-CA
verify error:num=20:unable to get local issuer certificate
---
Certificate chain
 0 s:/C=US/ST=xxx/L=xxxx/O=xxxxxx/OU=IT Infrastructure Services/CN=xxxx.xxxxx.xxxxxx.loc/emailAddress=xxxxx.xxxxx@xxxxxx.com
   i:/DC=loc/DC=xxxxx/DC=xxxx/CN=prod-xxxxxxx-CA
 1 s:/DC=loc/DC=xxxxx/DC=xxxx/CN=prod-xxxxxxx-CA
   i:/C=US/ST=xxx/L=xxxx/O=xxxxxx/OU=IT Infrastructure Services/CN=XXXX XXXX XXXX Root CA 2016
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIH+zCCBeOgAwIBAgITFAAEIo5+ju3K+O0+1AAAAAQijjANBgkqhkiG9w0BAQ0F
ADBhMRMwEQYKCZImiZPyLGQBGRYDbG9

Мы можем видеть, что это рукопожатие SSL отправило сертификат сервера, а также сертификатCA, который выдал сертификат сервера, который был подписан эмитентом (мы можем предположить, что это будет корневой CA, то есть 3-й сертификат, не представленный, будет иметьон был самоподписан)

Помимо отображения сертификатов в представленном виде, openssl также показывает глубину 1 (что на один больше, чем сертификат сервера) .. что, хотя это и не так функционально, как на самом деле описание цепочки, будетдостаточно информации для моих целей (я мог бы сделать обоснованное предположение о сертификатах, которые были отправлены во время рукопожатия, если бы я знал глубину, даже если у меня не было объектов x509v2 для каждого).

Я, конечно, могу спроситьSCHANNEL (туннели SSL / TLS операционной системы Windows), чтобы получить цепочку объектов x509v2.

$chain = [Security.Cryptography.X509Certificates.X509Chain]::create()
$isValid = $chain.Build($certificate)

, но это, кажется, создает цепочку за кулисами с тем, как хочет dll schannel, и технически, кажется, это делаетфактически получая файлы crt каждого CA в цепочке из url (s), встроенных в записи AIA cert (s).Но независимо от того, как это делается, я не могу найти какой-либо маркер, который позволил бы мне узнать, какие сертификаты были в рукопожатии, какие сертификаты были найдены в хранилище (ах) клиентских сертификатов, и какие сертификаты были получены из Интернета ... для того, чтобы"построить" исправную цепь X509.

Итак, вот небольшой код PowerShell (где $ target = fqdn или ip ресурса, на котором есть сервер SSL, а $ port - порт указанной службы), этот упрощенный кодне может обрабатывать STARTTLS (поэтому нет SMTP, LDAP, FTP через STARTTLS).Проще всего протестировать его на веб-сервере https, но объект SSLStream не заботится о внутреннем протоколе.

############ DO NOT USE THIS CODE IN PRODUCTION, 
############ IT HAS BEEN STRIPPED OF ITS ERROR CHECKING

$TcpSocket = New-Object Net.Sockets.TcpClient
$TcpSocket.ReceiveTimeout = 2000
$TcpSocket.SendTimeout = 2000
$TimeOut = 2000
$connect = $TcpSocket.BeginConnect($target,$port,$null,$null)
$wait = $connect.AsyncWaitHandle.WaitOne($timeout,$false) 
$tcpstream = $TcpSocket.GetStream()

#ClearStreams only needed if your going to emulate STARTTLS      
$clearTextReader = [System.IO.StreamReader]($tcpstream)
$clearTextReader.BaseStream.ReadTimeout = $TimeOut
$clearTextWriter = [System.IO.StreamWriter]($tcpstream)
$clearTextWriter.AutoFlush = $true

#ignore cert error (we are here for the cert no matter what it's state is. If we dont 
#do this the SSLStream will error on validity and not capture a cert if it is bad)
$Callback = {param($sender,$cert,$chain,$errors) return $true}

$SSLStream = New-Object -TypeName System.Net.Security.SSLStream -ArgumentList @($tcpstream, $True, $Callback) 
$SSLStream.AuthenticateAsClient($target)
$Certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($SSLStream.RemoteCertificate)
############################# !!!!!!!!!!!! ######################################
# we now have a x509v2 object,
# but how would I get an x509v2 for EACH cert available in the handshake
#################################################################################

$SSLStream.Dispose()
[void]$tcpobject.EndConnect($connect)
$TCPSocket.Dispose()

#build our certificate chain object
$chain = [Security.Cryptography.X509Certificates.X509Chain]::create()
$isValid = $chain.Build($certificate)

############################# !!!!!!!!!!!! ######################################
# we now have a complete chain, _if_ SCHANNEL could figure it out,
# but this doesnt tell me how much was provided during the handshake??
#################################################################################

Опять же, мой вопрос ... Кто-нибудь знает, как получить два сертификата?Я знаю, что существует в моем сценарии рукопожатия SSL выше (я знаю, потому что openssl показывает меня) в .NET (мой пример в .PS, но я могу перевести с C #, VB и т. Д ...)

Я непротив использования чего-то, кроме SSLStream, но до сих пор этот класс был более чем способен для всех остальных критериев для этого кода.

...