2012-11-27 14 views
5

Przeszukałem Internet i nie znalazłem rozwiązania ani metody sprawdzania certyfikatu podczas łączenia się przez HTTPS przy użyciu TIdHTTP.Delphi Indy zweryfikuj certyfikat serwera SSL

Podłączyłem komponent IdSSLIOHandlerSocketOpenSSL jako IOHandler, ustawiłem SSLModes itp., Ale kiedy przeglądam do https://s3.amazonaws.com, nie mogę zweryfikować certyfikatu.

OpenSSL (Indy) daje

"Błąd połączenia z SSL SSL3_GET_SERVER_CERTIFICATE. Certyfikat zweryfikować failed"

Biblioteki OpenSSL pomyślnie załadowany (sprawdzone z WhichFailedToLoad). Impreza OnStatusInfo pisze następujące:

stan SSL: "przed/połączyć inicjalizacji" status

SSL: "przed/połączyć inicjalizacji" status

SSL: "SSLv2/v3 zapisu klienta powitania A"

stan SSL: "SSLv3 serwer czytać komentarzy A"

stan SSL: "SSLv3 czytać certyfikat serwera B"

SSL s tatus "SSLv3 czytać certyfikat serwera B"

stan SSL: "SSLv3 czytać certyfikat serwera B"

And OnVerifyPeer, AOK = False.

Jak mogę go uzyskać, aby zweryfikować poprawnie. Co się dzieje?

Dzięki za czytanie, Adrian

Odpowiedz

7

Trzeba zaimplementować obsługi zdarzeń dla zdarzenia OnVerifyPeer swojego komponentu TIdSSLIOHandlerSocketOpenSSL.

Od IdSSLOpenSSL.pas:

pamiętać, że naprawdę powinien zawsze wdrażają OnVerifyPeer, inaczej świadectwa peer jesteś łączenia, nie jest sprawdzane, aby upewnić się, że jest ważny.

Jeśli chcesz po prostu uważać za ważne te same certyfikaty Biblioteka uważa również ważne, po prostu trzeba zaimplementować to w ten sposób:

function TForm1.IdSSLIOHandlerSocketOpenSSL1VerifyPeer(Certificate: TIdX509; 
    AOk: Boolean; ADepth, AError: Integer): Boolean; 
begin 
    Result := AOk; 
end; 

As Indy najpierw sprawdza ważność certyfikatu i przekazać jeśli jest OK lub nie ma go w parametrze AOk. Ostatnie słowo znajduje się w kodzie, ponieważ możesz przekazać niektóre drobne błędy sprawdzania poprawności , takie jak bycie nieaktualnym, lub nawet zapytać użytkownika, czy certyfikat jest akceptowany, czy też nie, w przypadku błędu (pomniejszego lub nie).

Aby zrozumieć, dlaczego działa w ten sposób, możesz również przeczytać wszystkie komentarze u góry IdSSLOpenSSL.pas file:

{

Ważne informacje dotyczące OnVerifyPeer: Rev 1.39 lutego 2005 celowo złamał interfejs OnVerifyPeer, który (oczywiście?) wpływa tylko programy, które wdrożone że zwrotnego jako część SSL negocjacja. Zauważ, że naprawdę powinieneś zawsze zaimplementować OnVerifyPeer, w przeciwnym razie połączenie z peerem, z którym jesteś , nie jest sprawdzane, aby upewnić się, że jest prawidłowe.

Wcześniej, jeśli biblioteka SSL wykrył problem z certyfikatem lub Głębokość była niewystarczająca (czyli „Ok” parametr w VerifyCallback jest 0/FAŁSZ), to niezależnie od tego, czy OnVerifyPeer powrócił prawda lub Fałsz, połączenie SSL byłoby celowo nieudane.

To stworzyło problem, że nawet jeśli nie było tylko bardzo drobne problem z jednym z certyfikatów w łańcuchu (OnVerifyPeer nazywa raz dla każdego certyfikatu w łańcuchu certyfikatów), które użytkownik może zostały z przyjemnością zaakceptować, negocjacja SSL zakończy się niepowodzeniem. Jednak zmiana kodu zezwalającego na połączenie SSL w przypadku, gdy użytkownik zwrócił True dla OnVerifyPeer, oznaczałaby, że istniejący kod, który był zależny od automatycznego odrzucenia nieważnych certyfikatów , byłby wówczas akceptowany jako nieakceptowane zabezpieczenie zmiana.

W konsekwencji zmieniono ustawienie OnVerifyPeer, aby rozmyślnie złamać istniejący kod , dodając parametr AOk. Aby zachować poprzednią funkcjonalność, zdarzenie OnVerifyPeer powinno wykonać "Wynik: = AOk;". Jeśli chcesz wziąć pod uwagę akceptowanie certyfikatów uznanych przez bibliotekę SSL za nieprawidłowe, następnie w urządzeniu OnVerifyPeer, upewnij się, że certyfikat rzeczywiście jest prawidłowy, a następnie ustaw wartość Wynik na True. W rzeczywistości, oprócz sprawdzania AOk pod numerem , zawsze powinieneś zaimplementować kod, który gwarantuje, że tylko akceptuje certyfikaty, które są ważne (przynajmniej z twojego punktu widzenia).

Ciaran Costelloe, ccostelloe [_a_t_] flogas.ie

}

{

RLebeau 12.01.2011 Event niszczące OnVerifyPeer ponownie, tym razem z dodatkową parametr AError (łatka dzięki uprzejmości "jvlad", [email protected]). Ten numer pomaga kodowi użytkownika odróżnić certyfikaty z podpisem własnym od nieważnych .

}

1

Jeśli pojawi się błąd jak SSL3_GET_SERVER_CERTIFICATE:certificate verify failed, a następnie zachować czytania:

Wydaje się w Indy 10, że jeśli ustawić VerifyDepth z 0 The 0 faktycznie oznacza all.Niestety, Indy tylko wydaje się wiedzieć o głównych urzędów certyfikacji, tak aby zweryfikować tylko korzenie, spróbuj następujące OnVerify metody:

function TForm1.IdSSLIOHandlerSocketOpenSSL1VerifyPeer(Certificate: TIdX509; 
    AOk: Boolean; ADepth, AError: Integer): Boolean; 
begin 
    if ADepth = 0 then 
    begin 
    Result := AOk; 
    end 
    else 
    begin 
    Result := True; 
    end; 
end; 
+1

To jest złe. Indy domyślnie nie zna żadnych certyfikatów głównych. To sprawia, że ​​jesteś podatny na ataki MitM. Musisz ustawić co najmniej 'VerifyMode',' VerifyDepth' i 'RootCertFile', aby mieć bezpieczne połączenie. Po tym możesz po prostu zwrócić 'AOk' na dowolną głębokość, ponieważ OpenSSL robi to, co właściwe dla ciebie. – TobiX

1

wiem, że to starożytne stanowisko, ale to wszystko udało mi się znaleźć na Rozwiąż problem. Chciałbym więc dodać odpowiedź Marcusa dla innych z tym samym problemem: Gdy OpenSSL nie może znaleźć certyfikatu głównego na komputerze, AError zwróci numer 19 (X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN), a AOK będzie fałszywy dla certyfikatu głównego. Gdy ręcznie załadować certyfikat główny z pliku, należy zawsze zwrócić AOK prawdą (i trzeba osiągnąć przypinania świadectwo jakiegoś zbyt):

FSSLIOHandlerSocketOpenSSL.SSLOptions.RootCertFile: „MyRoot.cer” =;