Search code examples
delphisslindy

Delphi 6 and Indy SSL connection not working


I need to consume a Web Service via SSL. In order to accomplish that I have built a web client in Delphi 6 that uses Indy to read the client certificates and write the soap request via https. The compilated version of the code is a DLL that runs in IIS 5.0. After tested the code in my local machine it works fine (I'm behind a proxy). But after the code is deployed to prod servers (not proxy) the SSL connection fails saying "Error connecting with SSL".

Here is my code:

var
  Response: TStringStream;
  IdHttp: TIdHTTP;
  IdCnxSLL: TIdConnectionInterceptOpenSSL;
  XmlSoapDoc: IXMLDocument;
begin
  Response := TStringStream.Create('');
  IdHttp := TIdHTTP.Create(nil);
  IdCnxSLL := TIdConnectionInterceptOpenSSL.Create(nil);
  XmlSoapDoc := TXMLDocument.Create(nil);
  with IdCnxSLL do
   begin
    IdCnxSLL.SSLOptions.Method := sslvSSLv23;
    IdCnxSLL.SSLOptions.RootCertFile := IniHttpConnectionData.Values['RootCertFile'];
    IdCnxSLL.SSLOptions.CertFile := IniHttpConnectionData.Values['CertFile'];
    IdCnxSLL.SSLOptions.KeyFile := IniHttpConnectionData.Values['KeyFile'];
    IdCnxSLL.OnGetPassword :=  IdConInterceptOpenSSLGetPassword;
  end;
  with IdHttp do
  begin
    if bUseProxy then
    begin
       Request.ProxyServer := IniHttpConnectionData.Values['ProxyServer'];
       Request.ProxyPort := StrToIntDef(IniHttpConnectionData.Values['ProxyPort'], 0);
    end
    else
    begin
       Host := IniHttpConnectionData.Values['HTTPHost'];
       Port := StrToIntDef(IniHttpConnectionData.Values['HTTPPort'], 443);
    end;
    Request.ContentType := 'text/xml';
    Intercept := IdCnxSLL;
    InterceptEnabled := True;
  end;

  try
    IdHttp.Post(ServiceURL, SoapEnv, Response);
  except
    on E:EIdOSSLConnectError do
       LogError('SSL Connect Error: ' + E.Message);
    on E:Exception do
      LogError('Error' + E.ClassName + ' - ' + E.Message);
  end;

I also try this code compiling into an exe program and it works. Is there something else I need to configure/add?

Thanks.


Solution

  • Finnally It worked. Although I strongly encourage you to use a newer version of Indy as Remy suggests. I will post the steps that did the trick for me since there should be other people with the same problem.

    The original code I posted is functional, it works when we need to post information via secured http (https) but the remote server requires prior authentification using a client certificate.

    In order to make it work, it is necessary to verify the following:

    1. TIdHttp and TIdConnectionInterceptOpenSSL configuration
    2. Certificates

    For the first 2 steps follow the steps mentioned here link text or (in case link is expired) Google "IndySSL - using certificate authentication". It worked for me.

    1. Indy SSL DLLs. (For D6/Indy 8 download indy_openssl096g.zip from Indy SSL or Intelicom) This DLLs where the only ones that worked for this version of Indy.

    Hope this will help.