Search code examples
httpsopenssldelphi-2010tls1.2indy10

How to enable Perfect Forward Secrecy In Indy 10?


I'm using OpenSSL 1.0.2o with Indy 10.6.2 in Delphi 2010.

This is what I have done so far:

procedure TServerForm.FormCreate(Sender: TObject);
var
  LEcdh: PEC_KEY;
  FSslCtx: PSSL_CTX;
  SSL: PSSL;
  FSSLContext: TIdSSLContext;
begin
  //mServer.Active := True;
  FSingle:=TCriticalSection.Create;
  appdir := ExtractFilePath(ParamStr(0));
  IdServerIOHandlerSSLOpenSSL1.SSLOptions.RootCertFile := appdir + 'EccCA.pem';
  IdServerIOHandlerSSLOpenSSL1.SSLOptions.KeyFile := appdir + 'EccSite.key';
  IdServerIOHandlerSSLOpenSSL1.SSLOptions.CertFile := appdir + 'EccSite.pem';
  IdServerIOHandlerSSLOpenSSL1.SSLOptions.DHParamsFile := appdir + 'dhparam.pem';
  IdServerIOHandlerSSLOpenSSL1.SSLOptions.Method := sslvTLSv1_2;
  IdServerIOHandlerSSLOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_2];
  IdServerIOHandlerSSLOpenSSL1.SSLOptions.CipherList := 
    //'ECDHE-ECDSA-AES128-GCM-SHA256:' +
    'ECDHE-RSA-AES128-GCM-SHA256:' +
    //'ECDHE-RSA-AES256-GCM-SHA384:' +
    //'ECDHE-ECDSA-AES256-GCM-SHA384:' +
    //'DHE-RSA-AES128-GCM-SHA256:' +
    //'ECDHE-RSA-AES128-SHA256:' +
    //'DHE-RSA-AES128-SHA256:' +
    //'ECDHE-RSA-AES256-SHA384:' +
    //'DHE-RSA-AES256-SHA384:' +
    //'ECDHE-RSA-AES256-SHA256:' +
    //'DHE-RSA-AES256-SHA256:' +
    'HIGH:' +
    '!aNULL:' +
    '!eNULL:' +
    '!EXPORT:' +
    '!DES:' +
    '!RC4:' +
    '!MD5:' +
    '!PSK:' +
    '!SRP:' +
    '!CAMELLIA';

  MServer.IndyServer.IOHandler := IdServerIOHandlerSSLOpenSSL1;
  mServer.Active := True;
  //FSSLContext := TIdSSLContext(IdServerIOHandlerSSLOpenSSL1.SSLContext);
end;

This does not work.

Failure

Does anyone have good suggestions?


Solution

  • First off, make sure that you update your version of Indy to the latest SVN snapshot. After the previous discussion I had with Roberto Frances on the Embarcadero forums, I added SSL_CTRL_SET_ECDH_AUTO and SSL_CTX_set_ecdh_auto() to Indy's IdSSLOpenSSLHeaders unit.

    So, the only piece missing from the code in that other discussion is the definition of TMyIdSSLContext, which I assume is simply this:

    type
      TMyIdSSLContext = class(TIdSSLContext)
      end;
    

    Since the TIdSSLContext.fContext member is declared as protected, the unit that declares TMyIdSSLContext gains access to TIdSSLContext's protected members. Thus, your code can then look like this:

    type
      TMyIdSSLContext = class(TIdSSLContext)
      end;
    
    procedure TServerForm.FormCreate(Sender: TObject);
    var
      FSSLContext: TMyIdSSLContext;
    begin
      FSingle := TCriticalSection.Create;
      appdir := ExtractFilePath(ParamStr(0));
      IdServerIOHandlerSSLOpenSSL1.SSLOptions.RootCertFile := appdir + 'EccCA.pem';
      IdServerIOHandlerSSLOpenSSL1.SSLOptions.KeyFile := appdir + 'EccSite.key';
      IdServerIOHandlerSSLOpenSSL1.SSLOptions.CertFile := appdir + 'EccSite.pem';
      IdServerIOHandlerSSLOpenSSL1.SSLOptions.DHParamsFile := appdir + 'dhparam.pem';
      IdServerIOHandlerSSLOpenSSL1.SSLOptions.Method := sslvTLSv1_2;
      IdServerIOHandlerSSLOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_2];
      IdServerIOHandlerSSLOpenSSL1.SSLOptions.CipherList := 
        //'ECDHE-ECDSA-AES128-GCM-SHA256:' +
        'ECDHE-RSA-AES128-GCM-SHA256:' +
        //'ECDHE-RSA-AES256-GCM-SHA384:' +
        //'ECDHE-ECDSA-AES256-GCM-SHA384:' +
        //'DHE-RSA-AES128-GCM-SHA256:' +
        //'ECDHE-RSA-AES128-SHA256:' +
        //'DHE-RSA-AES128-SHA256:' +
        //'ECDHE-RSA-AES256-SHA384:' +
        //'DHE-RSA-AES256-SHA384:' +
        //'ECDHE-RSA-AES256-SHA256:' +
        //'DHE-RSA-AES256-SHA256:' +
        'HIGH:' +
        '!aNULL:' +
        '!eNULL:' +
        '!EXPORT:' +
        '!DES:' +
        '!RC4:' +
        '!MD5:' +
        '!PSK:' +
        '!SRP:' +
        '!CAMELLIA';
    
      MServer.IndyServer.IOHandler := IdServerIOHandlerSSLOpenSSL1;
      mServer.Active := True;
    
      FSSLContext := TMyIdSSLContext(IdServerIOHandlerSSLOpenSSL1.SSLContext);
      SSL_CTX_set_ecdh_auto(FSSLContext.fContext, 1);
    end;