Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Support for Perfect Forward Secrecy in SSL with indy 10


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 5 - Last Post: Oct 6, 2016 6:00 PM Last Post By: Alan Sisson
Roberto Frances...

Posts: 6
Registered: 5/14/02
Support for Perfect Forward Secrecy in SSL with indy 10  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 1, 2015 6:19 AM
Has anyone had any luck in adding support for Perfect Forward Secrecy (the ECDHE ciphers) in the Indy server-side components - I've been focusing on the TIdSMTPServer in particular?

I've been trying with both the 10.6.1.5210 and the 10.6.2.5270 Indy libraries with Delphi XE6, using the latest OpenSSL libraries v1.0.2a from http://indy.fulgan.com/SSL.

In addition to the default CipherList that is used in Indy, I've tried several alternate lists that have ECDHE ciphers, for example:
AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:HIGH:!MD5:!aNULL:!EDH
and
ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DES-CBC3-SHA:!ADH:!EXP:!RC4:!eNULL@STRENGTH

But when I test with the TestSSL tool (https://testssl.sh) or when I try to tests manually with OpenSSL and force the use of specific ECDHE ciphers, it seems none are supported and no PFS support is found.

To make things simple for my tests I've been using a slightly modified Indy sample - the "Indy 10 SMTPServer" from http://www.indyproject.org/Sockets/Demos/index.EN.aspx.

I've placed at https://cloud.logsat.com/index.php/s/VKvZGXxX2pLlEig a copy of the modified code that compiles with Delphi XE6, adding support for STARTTLS on port 25, and with an additional TIdSMTPServer listening on port 465 for SSL connections with TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough:=false.
This lets me test both TLS and SSL.

Is there anyone who either succeeded in adding support for PFS, or has suggestions on how to proceed?

PS - I've asked this question without luck on the Indy atozed.com forums, so I'm trying here now.

Angus Robertson

Posts: 205
Registered: 3/17/00
Re: Support for Perfect Forward Secrecy in SSL with indy 10  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 4, 2015 10:00 AM   in response to: Roberto Frances... in response to: Roberto Frances...
Has anyone had any luck in adding support for Perfect Forward
Secrecy (the ECDHE ciphers) in the Indy server-side components -
In addition to the default CipherList that is used in Indy, I've
tried several alternate lists that have ECDHE ciphers

Never used Indy, but I had a similar problem with ICS. Allowing the ECHDE
ciphers to be used needs two things.

1 - Support for DHParams, at least 512-bit, ideally several better versions.
Your server should have unique DHParams keys, which can be generated with
Openssl.exe, the better keys take several minutes. This is the DH and DHE
part of the cipher.

2 - Support for Elliptic Curves, which adds EC to the cipher, using the
function f_SSL_CTX_set_ecdh_auto (1.0.2) or f_SSL_CTX_set_tmp_ecdh for
older versions with NID_X9_62_prime256v1,
NID_secp384r1 or NID_secp521r1 as a parameter.

Also set SSL Options for SSL_OP_SINGLE_DH_USE so a new key is generated for
each session.

Angus
Roberto Frances...

Posts: 6
Registered: 5/14/02
Re: Support for Perfect Forward Secrecy in SSL with indy 10  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 6, 2015 7:58 PM   in response to: Roberto Frances... in response to: Roberto Frances...
Roberto Franceschetti wrote:
Has anyone had any luck in adding support for Perfect Forward Secrecy (the ECDHE ciphers) in the Indy server-side components - I've been focusing on the TIdSMTPServer in particular?

SUCCESS. Here what was needed.

To make it easier for myself right now I modified the IdOpenSSLHeaders to add support for the function SSL_CTX_set_ecdh_auto since it's not available in the Indy OpenSSL headers right now. These are the sections I added - to see where to add them just look for the references for the existing ones relative to SSL_CTX_set_tmp_ecdh and SSL_CTRL_SET_TMP_ECDH

.......
 
{$EXTERNALSYM SSL_CTRL_SET_ECDH_AUTO}
SSL_CTRL_SET_ECDH_AUTO = 94;
.......
 
{$EXTERNALSYM SSL_CTX_set_ecdh_auto}
function SSL_CTX_set_ecdh_auto(ctx : PSSL_CTX; m : TIdC_LONG) : TIdC_LONG;
........
 
function SSL_CTX_set_ecdh_auto(ctx : PSSL_CTX; m : TIdC_LONG) : TIdC_LONG;
 {$IFDEF USE_INLINE} inline; {$ENDIF}
begin
	Result := SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,m,nil);
end;
.......

Once that is done, this is how I enabled PFS:

procedure TForm1.btnServerOnClick(Sender: TObject);
var
  FSSLContext:TMyIdSSLContext;
const
  SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = $00040000;
  SSL_OP_LEGACY_SERVER_CONNECT             = $00000004;
  SSL_CTRL_OPTIONS                         = 32;
  SSL_CTRL_CLEAR_OPTIONS                   = 77;
  SSLContextOptions                        = $00000FFF {SSL_OP_ALL}                                    or
                                             $00020000 {SSL_OP_NO_COMPRESSION}                         or
                                             $00400000 {SSL_OP_CIPHER_SERVER_PREFERENCE}               or
                                             $00100000 {SSL_OP_SINGLE_DH_USE}                          or
                                             $00080000 {SSL_OP_SINGLE_ECDH_USE}                        or
                                             $00010000 {SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION} or
                                             $02000000 {SSL_OP_NO_SSLv3}                               or
                                             $01000000 {SSL_OP_NO_SSLv2}                               ;
 
begin
 IdServerIOHandlerSSLOpenSSL1.SSLOptions.CipherList:='AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:HIGH:!MD5:!aNULL:!EDH';
 IdSMTPServer1.active := true;
 
  FSSLContext := TMyIdSSLContext(IdServerIOHandlerSSLOpenSSL1.SSLContext);
  SSL_CTX_set_ecdh_auto(FSSLContext.fContext,1);
 
end;


That was all I needed to have the PFS ciphers enabled.

FYI in addition to the above changes I had also tried adding the following before calling SSL_CTX_set_ecdh_auto, but with my limited knowledge of OpenSSL right now I have no idea if it was needed or not:

 const
  NID_X9_62_prime256v1:integer       = 415;
 
  var
    ecdh : PEC_KEY;
  begin
    try
      ecdh := EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
      SSL_CTX_set_tmp_ecdh(ctx,ecdh);
    except
      ecdh := nil;
    end;
    if Assigned(ecdh) then
      EC_KEY_free(ecdh);
//    FSSLContext.DHParamsFile:='DH.pem';   //I also tried using a DH file I created with OpenSSL but did not see differences...
    FSSLContext.LoadDHParams;


Edited by: Roberto Franceschetti on May 6, 2015 7:58 PM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Support for Perfect Forward Secrecy in SSL with indy 10 [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 7, 2015 9:41 AM   in response to: Roberto Frances... in response to: Roberto Frances...
Roberto wrote:

const
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = $00040000;
SSL_OP_LEGACY_SERVER_CONNECT = $00000004;
SSL_CTRL_OPTIONS = 32;
SSL_CTRL_CLEAR_OPTIONS = 77;
SSLContextOptions = $00000FFF {SSL_OP_ALL}
<snip>

What is the point in defining all of those constants if you are not actually
using them?

--
Remy Lebeau (TeamB)
Roberto Frances...

Posts: 6
Registered: 5/14/02
Re: Support for Perfect Forward Secrecy in SSL with indy 10 [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 7, 2015 9:50 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Roberto wrote:

const
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = $00040000;
SSL_OP_LEGACY_SERVER_CONNECT = $00000004;
SSL_CTRL_OPTIONS = 32;
SSL_CTRL_CLEAR_OPTIONS = 77;
SSLContextOptions = $00000FFF {SSL_OP_ALL}
<snip>

What is the point in defining all of those constants if you are not actually
using them?

--
Remy Lebeau (TeamB)

None at all :-) I've been fighting with this for the past two weeks, testing so many different options that in the excitement of finally finding a solution and posting it here and in the Atozed forums that I forgot to cleanup useless code. At one point I was trying to call SSL_Set_Options(ctx,SSLContextOptions) but without success. Deleted the code but not the constants...

    try
      ecdh := EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
      SSL_CTX_set_tmp_ecdh(ctx,ecdh);
    except
      ecdh := nil;
    end;
    if Assigned(ecdh) then
      EC_KEY_free(ecdh);
    SSL_Set_Options(ctx,SSLContextOptions);
//    FSSLContext.DHParamsFile:='DH.pem';
    FSSLContext.LoadDHParams;


and forgot to remove the constants in addition to removing the bock of code above...

Edited by: Roberto Franceschetti on May 7, 2015 9:52 AM
Alan Sisson

Posts: 3
Registered: 1/26/98
Re: Support for Perfect Forward Secrecy in SSL with indy 10  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 6, 2016 5:59 PM   in response to: Roberto Frances... in response to: Roberto Frances...
Hi, reviewing your code you are missing the definition for TMyIDSSLContext. Can you provide that?

Thanks.

Once that is done, this is how I enabled PFS:

procedure TForm1.btnServerOnClick(Sender: TObject);
var
  FSSLContext:TMyIdSSLContext;
const
  SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = $00040000;
  SSL_OP_LEGACY_SERVER_CONNECT             = $00000004;
  SSL_CTRL_OPTIONS                         = 32;
  SSL_CTRL_CLEAR_OPTIONS                   = 77;
  SSLContextOptions                        = $00000FFF {SSL_OP_ALL}                                    or
                                             $00020000 {SSL_OP_NO_COMPRESSION}                         or
                                             $00400000 {SSL_OP_CIPHER_SERVER_PREFERENCE}               or
                                             $00100000 {SSL_OP_SINGLE_DH_USE}                          or
                                             $00080000 {SSL_OP_SINGLE_ECDH_USE}                        or
                                             $00010000 {SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION} or
                                             $02000000 {SSL_OP_NO_SSLv3}                               or
                                             $01000000 {SSL_OP_NO_SSLv2}                               ;
 
begin
 IdServerIOHandlerSSLOpenSSL1.SSLOptions.CipherList:='AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:HIGH:!MD5:!aNULL:!EDH';
 IdSMTPServer1.active := true;
 
  FSSLContext := TMyIdSSLContext(IdServerIOHandlerSSLOpenSSL1.SSLContext);
  SSL_CTX_set_ecdh_auto(FSSLContext.fContext,1);
 
end;


That was all I needed to have the PFS ciphers enabled.


Edited by: Alan Sisson on Oct 6, 2016 6:00 PM
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02