OpenSSL s client-cert: potwierdzenie wysłania certyfikatu klienta na serwer

Tło

Utknąłem w meczu wskazującym palcem z dostawcą usług z API chronionym certyfikatami SSL server i client.

  • wygenerowałem CSR, uzyskałem certyfikat od publicznego urzędu certyfikacji (w tym przypadku GoDaddy) i dostarczyłem łańcuch certyfikatów i CA dostawcy usług.
  • podobno załadowali certyfikat CA i mojego klienta do swojej bramy.
  • pracuję z najbardziej podstawowymi testami na poziomie using openssl s_client -connect ... -cert ... -key ...
  • dostawca mówi mi, że ich dzienniki sugerują, że moje żądania nie zawierają certyfikatu SSL klienta w ogóle.
  • o dziwo, właściwy wystawca CA dla mojego certyfikatu pojawia się na liście "akceptowalnych nazw CA certyfikatu klienta" podanej podczas uścisku dłoni SSL.
  • dla odniesienia, własnoręcznie podpisany certyfikat, który stworzyłem i dostarczyłem im do testów, w rzeczywistości działa poprawnie.

Przykładowe (nieudane) żądanie

[shell ~]$ openssl s_client -connect host:443 -cert cert_and_key.pem -key cert_and_key.pem -state -quiet
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 **SNIP**
verify return:1
depth=1 **SNIP**
verify return:1
depth=0 **SNIP**
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write certificate verify A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL3 alert read:fatal:unknown CA
SSL_connect:failed in SSLv3 read finished A
140011313276744:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1197:SSL alert number 48
140011313276744:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:

Moje czytanie błąd SSL3 alert read:fatal:unknown CA polega na tym, że serwer nie rozpoznaje wystawcy certyfikatu, który (w rzeczywistości) dostarczam. Jednak dostawca "zapewnia" mnie, że certyfikaty CA są ładowane prawidłowo i nie byłem w stanie ich przekonać, że jest inaczej.

Pytanie

Tak więc, odkładając na bok inne (obszerne) kroki rozwiązywania problemów, naprawdę chciałbym wiedzieć:

Czy istnieje jakieś wyjście z openssl s_client, które jednoznacznie pokazuje, że certyfikat klienta nie był tylko żądany przez serwer, ale w rzeczywistości został przesłany do serwera podczas SSL handshake?

Eksperymentowałem z -state, -msg, -debug i opcje -trace, ale nie mają tła niezbędnego do interpretacji wyjścia.

Odpowiedź EJP sugeruje, że Przykładowe wyjście, które podałem, jest wystarczającym dowodem z write client certificate A, ale to wyjście pojawia się niezależnie od tego, czy opcje -cert zostały użyte w linii poleceń, czy nie, więc nie wskazuje, że certyfikat został wysłany .

Author: beporter, 2013-06-20

2 answers

Aby zweryfikować, czy certyfikat klienta jest wysyłany na serwer, należy przeanalizować wyjście z kombinacji znaczników -state i -debug.

Najpierw jako podstawa, spróbuj uruchomić

$ openssl s_client -connect host:443 -state -debug

Otrzymasz mnóstwo danych wyjściowych, ale linie, które nas interesują, wyglądają tak:

SSL_connect:SSLv3 read server done A
write to 0x211efb0 [0x21ced50] (12 bytes => 12 (0xC))
0000 - 16 03 01 00 07 0b 00 00-03                        .........
000c - <SPACES/NULS>
SSL_connect:SSLv3 write client certificate A

Co tu się dzieje:

  • Flaga -state odpowiada za wyświetlenie końca poprzedniej sekcji:

    SSL_connect:SSLv3 read server done A  
    

    To jest tylko ważne za pomoc w znalezieniu swojego miejsca w wyjściu.

  • Następnie znacznik -debug pokazuje wysłane surowe bajty w następnym kroku:

    write to 0x211efb0 [0x21ced50] (12 bytes => 12 (0xC))
    0000 - 16 03 01 00 07 0b 00 00-03                        .........
    000c - <SPACES/NULS>
    
  • Wreszcie flaga -state po raz kolejny informuje o wyniku kroku, który -debug właśnie odbił się echem:

    SSL_connect:SSLv3 write client certificate A
    

Innymi słowy: s_client zakończono odczyt danych wysłanych z serwera i wysłano 12 bajtów do serwera jako (co zakładam) "brak certyfikatu klienta" wiadomość.


Jeśli powtórzysz test, ale tym razem Dołącz -cert i -key flagi takie jak:

$ openssl s_client -connect host:443 \
   -cert cert_and_key.pem \
   -key cert_and_key.pem  \
   -state -debug

Twoje wyjście pomiędzy linią "read server done" i linią "write client certificate" będzie znacznie dłuższe, reprezentując binarną formę certyfikatu klienta:

SSL_connect:SSLv3 read server done A
write to 0x7bd970 [0x86d890] (1576 bytes => 1576 (0x628))
0000 - 16 03 01 06 23 0b 00 06-1f 00 06 1c 00 06 19 31   ....#..........1
(*SNIP*)
0620 - 95 ca 5e f4 2f 6c 43 11-                          ..^%/lC.
SSL_connect:SSLv3 write client certificate A

1576 bytes jest doskonałą wskazówką, że cert został przekazany, ale na dodatek, prawa kolumna pokaże części certyfikat czytelny dla człowieka: powinieneś być w stanie rozpoznać ciągi CN i emitenta twojego cert.

 57
Author: beporter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-17 13:57:09

Wiem, że to stare pytanie, ale wydaje się, że nie ma jeszcze odpowiedzi. Zdublowałem tę sytuację, ale piszę aplikację serwerową, więc udało mi się ustalić, co dzieje się również po stronie serwera. Klient wysyła certyfikat, gdy serwer o niego poprosi i jeśli ma odniesienie do prawdziwego certyfikatu w wierszu poleceń s_client. Moja aplikacja serwera jest skonfigurowana tak, aby prosić o certyfikat klienta i zawieść, jeśli nie zostanie on przedstawiony. Oto wiersz poleceń I wydanie:

Yourhostname here -vvvvvvvvvv s_client -connect <hostname>:443 -cert client.pem -key cckey.pem -CAfile rootcert.pem -cipher ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH -tls1 -state

Kiedy pomijam klienta " - cert.pem " część polecenia handshake nie powiedzie się po stronie serwera, a komenda s_client nie powiedzie się ze zgłoszonym błędem. Nadal otrzymuję raport "nie wysłano nazw CA certyfikatu klienta", ale myślę, że odpowiedziano tutaj powyżej.

Krótka odpowiedź jest taka, że serwer określa, czy certyfikat zostanie wysłany przez Klienta w normalnych warunkach pracy (s_client nie jest normalny), a awaria jest spowodowana serwer nie rozpoznaje CA w przedstawionym certyfikacie. Nie znam wielu sytuacji, w których odbywa się dwukierunkowe uwierzytelnianie, chociaż jest to wymagane w moim projekcie.

Wyraźnie wysyłasz certyfikat. Serwer wyraźnie go odrzuca.

Brakujące tutaj informacje to dokładny sposób, w jaki Cert zostały utworzone i sposób, w jaki dostawca załadował cert, ale to prawdopodobnie wszystko jest już zapakowane.

 6
Author: JSAnderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-04 14:26:31