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:[email protected] 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.
![]() |
0 |
![]() |
> 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
![]() |
0 |
![]() |
> {quote:title=Roberto Franceschetti wrote:}{quote} > 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
![]() |
0 |
![]() |
> {quote:title=Roberto Franceschetti wrote:}{quote} > 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 {code} ........ {$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; ........ {code} Once that is done, this is how I enabled PFS: {code} 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; {code} 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: {code} 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; {code} Edited by: Roberto Franceschetti on May 6, 2015 7:58 PM
![]() |
0 |
![]() |
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)
![]() |
0 |
![]() |
> {quote:title=Remy Lebeau (TeamB) wrote:}{quote} > 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... {code} 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; {code} 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
![]() |
0 |
![]() |