Dlaczego openssl s_client weryfikuje certyfikat przed niezgodnym plikiem CA?

10

Próbuję wygenerować błąd weryfikacji certyfikatu w openssl s_clientnastępujący sposób:

$ openssl s_client -crlf -verify 9 \
  -CAfile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.pem \
  -starttls smtp -host mx-ha03.web.de -port 25

Certyfikat serwera web.de jest certyfikowany przez Deutsche Telekom CA, a nie TURKTRUST, więc powyższe polecenie powinno zawieść, prawda?

Ale informuje:

    Verify return code: 0 (ok)

Dlaczego?

Mam na myśli, że analogiczne polecenie gnutls-cli kończy się niepowodzeniem zgodnie z oczekiwaniami:

$ { echo -e 'ehlo example.org\nstarttls' ; sleep 1 } | \
   gnutls-cli --starttls --crlf \
   --x509cafile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.pem \
   --port 25 mx-ha03.web.de
[..]
*** Verifying server certificate failed...

Robiąc crosscheck, tzn. Używając zamiast tego --x509cafile /etc/ssl/certs/ca-certificates.crtz gnutls-cli otrzymuję:

[..]
- The hostname in the certificate matches 'mx-ha03.web.de'.
- Peer's certificate is trusted

(co jest również oczekiwane)

Otwarcie s_client drukuje dla certyfikatów ca.crt:

    Verify return code: 0 (ok)

Taki sam wynik jak dla TURKTRUST ...

Najpierw podejrzewałem, że openssl używa domyślnego ustawienia dla -CApath(tj. / Etc / ssl / certs) - ale kiedy jestem stracew trakcie procesu, widzę tylko openwywołanie systemowe dla argumentu CAfile.

(wszystkie testy wykonane na serwerze Ubuntu 10.04)

Aktualizacja: Skopiowałem certyfikat TURKTRUST do systemu Fedora 20 i wykonałem pierwszą instrukcję openssl - tam otrzymuję inny wynik:

Verify return code: 19 (self signed certificate in certificate chain)
maxschlepzig
źródło

Odpowiedzi:

10

Okazuje się, że openssl s_clientna Ubuntu 10.04 nadal sprawdza domyślną lokalizację dla zainstalowanych certyfikatów systemowych, nawet jeśli -CApath i -CAfile są określone:

8466  open("/usr/lib/ssl/certs/4e18c148.0", O_RDONLY) = 4

(wyjście strace)

Gdzie:

$ ls -l /usr/lib/ssl/certs/4e18c148.0
lrwxrwxrwx 1 root root 30 2014-04-11 21:50 /usr/lib/ssl/certs/4e18c148.0 ->
    Deutsche_Telekom_Root_CA_2.pem

Katalog /usr/lib/ssl/certsjest dowiązaniem symbolicznym do /etc/ssl/certsUbuntu 10.04, dlatego openlinia z dziennika śledzenia nie jest wybierana podczas grepowania dla '/ etc / ssl' ...

Źródło

Patrząc na openssl-0.9.8k, źródłem tego problemu znajduje się w crypto/x509/by_dir.c, dir_ctrl():

dir=(char *)Getenv(X509_get_default_cert_dir_env());
if (dir)
    ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM);
else
    ret=add_cert_dir(ld,X509_get_default_cert_dir(),
                     X509_FILETYPE_PEM);

Gdzie X509_get_default_cert_dirzwraca /usr/lib/ssl/certsi X509_get_default_cert_dir_envwraca SSL_CERT_DIR.

Obejście

W związku z tym można zastosować następujące obejście w systemie Ubuntu 10.04 / openssl 0.9.8k, aby uzyskać oczekiwane zachowanie:

$ SSL_CERT_DIR="" openssl s_client -crlf -verify 9 \
    -CAfile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.crt \
    -starttls smtp -host mx-ha03.web.de -port 25

A weryfikacja kończy się niepowodzeniem:

Verify return code: 19 (self signed certificate in certificate chain)

Obecna sytuacja

To jest problem z Ubuntu. Na przykład w przypadku Fedory 20's openssl 1.0.1e lub Fedory 29's openssl 1.1.1 to obejście nie jest konieczne, ponieważ problemu nie można odtworzyć. Oznacza to, że przy określaniu opcji typu -CAfilelub -CApathdo listy wyszukiwania katalogów w systemach Fedora nie jest dodawany domyślny katalog systemu certyfikatów.

Na Ubuntu 16 z openssl 1.0.2g problem jest nadal obecny.

Jest także obecny w CentOS 7 z openssl-1.0.2k-16 - i niestety powyższe obejście tam nie pomaga, a gnutls-3.3.29-8 nie działa z powodu nieznanych / nieoczekiwanych typów pakietów TLS.

maxschlepzig
źródło
Mam wersję 1.0.2g i nadal ma ten błąd. Co gorsza, flaga -verify_return_error nie ma żadnego wpływu, a połączenie TLS jest kontynuowane, nawet jeśli certyfikat jest nieprawidłowy.
takumar
@ takumar, ponownie przetestowałem to pod Ubuntu 16 z openssl 1.0.2g-1ubuntu4.14 i mogę potwierdzić, bez obejścia ten test openssl nadal kończy się niepowodzeniem. Ale przynajmniej z obejściem pojawia się oczekiwany komunikat o błędzie - a z obejściem i -verify_return_errorpoleceniem kończy się status wyjścia 1. W Fedorze 29 i openssl-1.1.1-3.fc29.x86_64 wszystko nadal działa zgodnie z oczekiwaniami, tj. Obejście nie jest konieczne.
maxschlepzig
W 2019 r. Nadal tak jest w przypadku systemu macOS. Ponadto niektóre systemy mogą obsługiwać -no-CAfile( Nie ładuj zaufanych certyfikatów CA z domyślnej lokalizacji pliku ) i -no-CApath( Nie ładuj zaufanych certyfikatów CA z domyślnej lokalizacji katalogu ), ale mój system nie, więc ich nie testowałem.
Arjan