Q:

Delphi - SSL TCP communication with Indy components

I'm using the TIdSSLIOHandlerSocketOpenSSL Indy component in Delphi XE2 to send data to an SSL server (Apple Push Notification Service) over TCP.  I've got it working to a degree but not sure if I'm going about it the best way.  I'm doing the following :

Set the SSL properties inc. path to certificates
Call the .Open method to open the connection 
Check the AType parameter in the OnStatusInfoEx event until I get a 'Handshake Done'
Send the data using .WriteDirect
Close the connection with .Close

Is there a better way to know when the connection is ready to send data?  Does anybody have sample code using the TIdSSLIOHandlerSocketOpenSSL component directly over TCP?  The samples I've found are mainly for HTTP calls where the TIdSSLIOHandlerSocketOpenSSL component is just attached to secure the connection.

A:

Since you are using the client component, you only need to setup the certificates on the client if the server is going to authenticate the client's certificate.
Otherwise, set the TIdSSLIOHandlerSocketOpenSSL's SSLOptions.Mode to sslmClient, and you should be able to connect.
It's a good idea to enable the VerifyMode and use the OnVerifyPeer event on the socket component to verify the fingerprint on the server certificate in order to avoid man in the middle attacks.
Depending on your version of Indy, you may need to set the SSLOptions Method to sslvTLSv1. Some web servers no longer support SSLv2, which Indy 9 defaults to.
Here's some sample code that demonstrates retrieving a web page over SSL using the TCP component:
procedure TForm1.Button1Click(Sender: TObject);
var
  s: String;
begin
  IdTCPClient1.Host := 'example.com';
  IdTCPClient1.Port := 443;
  IdTCPClient1.Connect;
  IdTCPClient1.WriteLn('GET / HTTP/1.1');
  IdTCPClient1.WriteLn('Host: example.com');
  IdTCPClient1.WriteLn('');
  // Retrieve all the data until the server closes the connection
  s := IdTCPClient1.AllData;
  Memo1.Lines.Add(s);
end;

Don't forget to include the OpenSSL libraries libeay32.sll and ssleay32.dll in the same folder as your EXE on Windows. Use the standard (latest) binaries for Indy 10.

