I'm dealing with a protocol that needs to start TLS after connected and handshaked, something like this:
procedure TForm1.Button1Click(Sender: TObject);
var
SSL: TIdSSLIOHandlerSocketOpenSSL;
begin
SSL:= TIdSSLIOHandlerSocketOpenSSL.Create;
SSL.SSLOptions.Method:= sslvTLSv1_2;
IdTCPClient1.Connect;
if IdTCPClient1.Connected then
begin
//plain-text operations
HandShake;
CheckAnswer;
//finish plain-text start TLS
IdTCPClient1.IOHandler:= SSL;
SendTLSSecureBytes;
end;
end;
Once I get inside SendTLSSecureBytes procedure, and send something over the connection, I get the exception: "Connection closed gracefully"
Something missing to do this work?
You need to assign the SSLIOHandler
object to the TIdTCPClient.IOHandler
property before you call TIdTCPClient.Connect()
. If you do not assign an IOHandler
object, Connect()
will create a default TCP-only object, and you can't assign a new IOHandler
object once the socket connection has been opened.
Then, set the SSLIOHandler.PassThrough
property to False when you are ready to invoke the TLS handshake:
procedure TForm1.Button1Click(Sender: TObject);
var
SSL: TIdSSLIOHandlerSocketOpenSSL;
begin
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdTCPClient1);
SSL.SSLOptions.Method := sslvTLSv1_2;
IdTCPClient1.Connect; // raises exception if failed
// do plain-text operations, then...
SSL.PassThrough := False // do TLS handshake
SendTLSSecureBytes; // will be encrypted by TLS
end;
Note, for future reference (not applicable to this situation), if you need the TLS handshake to be performed immediately upon establishing the socket connection, you can set the SSLIOHandler.PassThrough
property to False before calling TIdTCPClient.Connect()
, and the handshake will be completed before Connect()
exits:
procedure TForm1.Button1Click(Sender: TObject);
var
SSL: TIdSSLIOHandlerSocketOpenSSL;
begin
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdTCPClient1);
SSL.SSLOptions.Method := sslvTLSv1_2;
SSL.PassThrough := False // do TLS handshake upon connect
IdTCPClient1.Connect; // raises exception if failed
SendTLSSecureBytes; // will be encrypted by TLS
end;