I've got an issue with implementing SSL Certificate Pinning with TIdHTTP
.
So, here are the steps:
- Drop TIdHTTP, TIdSSLIOHandlerSocketOpenSSL and TIdCompressorZLib on the form.
- Assign TIdSSLIOHandlerSocketOpenSSL and TIdCompressorZLib to IOHandler and Compressor properties of TIdHTTP.
Setup TIdSSLIOHandlerSocketOpenSSL:
Port = 0 DefaultPort = 0 SSLOptions.Method = sslvTLSv1_2 SSLOptions.SSLVersions = [sslvTLSv1_2] SSLOptions.Mode = sslmClient SSLOptions.VerifyMode = [sslvrfPeer] SSLOptions.VerifyDepth = 0 OnVerifyPeer = SSLIOHandlerVerifyPeer
Code for SSLIOHandlerVerifyPeer:
function TForm2.SSLIOHandlerVerifyPeer(Certificate: TIdX509; AOk: Boolean; ADepth, AError: Integer): Boolean; const LCGoogleCert = '98:1D:34:C4:F8:4A:F2:B7:C7:AB:77:AD:51:1C:51:4C:AD:76:ED:0D:0E:FA:C9:63:68:AF:28:69:94:60:BF:7A'; begin Result := Certificate.Fingerprints.SHA256AsString.Equals(LCGoogleCert); end;
Drop a button on a form:
procedure TForm2.Button1Click(Sender: TObject); const LCGoogleURL = 'https://www.google.com/'; var s: UnicodeString; begin s := HTTPSender.Get(LCGoogleURL); end;
Install Fiddler
In Fiddler: Tools - Options - check "Capture HTTPS Connects" and uncheck "Decrypt HTTPS traffic". Generate and install certificate to system.
Set Fiddler's proxy address and port to TIdHTTP.
Run program and click the button. First click - you get the exception about the incorrect certificate. But if you click the second time - you won't get any exceptions, but you'll get the full response and you'll see the unencrypted traffic in Fiddler as if you sent the request via HTTP and not HTTPS.
You can see the result of the first and the second request on the picture below. So is this a bug in Indy component, or I'm trying to implement SSL Pinning incorrectly?