Issue 7506 - Diffie-Hellman parameters (DHParamFile) are improperly handled
Summary: Diffie-Hellman parameters (DHParamFile) are improperly handled
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: slapd (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-01-28 00:13 UTC by ben@bjencks.net
Modified: 2016-02-29 20:44 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description ben@bjencks.net 2013-01-28 00:13:04 UTC
Full_Name: Ben Jencks
Version: git master
OS: Linux
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (2601:8:580:1d:5e6:2c43:96d0:4503)


Both tls_g.c for GnuTLS and tls_o.c for OpenSSL have major problems in their
handling of DHParamFile. Additionally, the documentation is not entirely
accurate.

For GnuTLS, DH parameters are entirely unimplemented. There appears to be an
attempt at generating them in tlsg_ctx_init, but they're never attached to
ctx->cred, so they're unused. Additionally, the size is hardcoded.

For OpenSSL, there's an attempt to support multiple sizes, but unfortunately
it's misusing the OpenSSL API and only 512 or 1024 bit parameters will ever be
used. The callback with specified size is only useful for export ciphers: the
size isn't negotiated, it's only specified as a maximum when the export flag is
set [1]. You want to specify exactly one size and parameter set.

The documentation refers to a non-existent TLSEphemeralDHParamFile option.

Patches are available below:
http://www.bjencks.net/openldap/0001-tls_g.c-Properly-support-DHParamFile.patch
http://www.bjencks.net/openldap/0002-tls_o.c-Fix-Diffie-Hellman-parameter-usage.patch
http://www.bjencks.net/openldap/0003-DHParamFile-Update-docs.patch

I'm a little uncomfortable with leaving a hardcoded parameter set in the OpenSSL
code, but I figured it would break compatibility to remove it. A better solution
(and the one recommended by OpenSSL) is to add parameter generation to the
install scripts. If you'd prefer that, I can modify the patch to get rid of the
hardcoded parameter and just not set a DH on the SSL_CTX without a file
specified.

The attached file is derived from OpenLDAP Software. All of the modifications to
OpenLDAP Software represented in the following patch(es) were developed by
Meddius. Meddius has not assigned rights and/or interest in this work to any
party. I, Ben Jencks am authorized by Meddius, my employer, to release this work
under the following terms.

Meddius hereby places the attached modifications to OpenLDAP Software (and only
these modifications) into the public domain. Hence, these modifications may be
freely used and/or redistributed for any purpose with or without attribution
and/or other notice.

[1] http://permalink.gmane.org/gmane.comp.encryption.openssl.user/45805
Comment 1 ben@bjencks.net 2013-01-28 00:28:17 UTC
I suppose I should attach a test case:

cd $WORKDIR
openssl dhparam 1536 > dh1536.pem
openssl req -new -newkey rsa:2048 -keyout server.key \
  -out server.crt -sha256 -nodes -subj '/CN=localhost/' -x509

For GnuTLS, load the following config:
dn: cn=config
objectClass: olcGlobal
cn: config
olcTLSCertificateFile: $WORKDIR/server.crt
olcTLSCertificateKeyFile: $WORKDIR/server.key
olcTLSCipherSuite: NONE:+VERS-TLS1.1:+VERS-TLS1.0:+AES-128-CBC:
 +DHE-RSA:+SHA1:+COMP-NULL
olcTLSDHParamFile: $WORKDIR/dh1536.pem

dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config

For Openssl, change olcTLSCipherSuite to:
olcTLSCipherSuite: aRSA+AES128+kEDH

Start up slapd with the config, listening on ldaps://localhost:6636.

openssl s_client -connect localhost:6636

With GnuTLS this will fail negotiation; with OpenSSL it will use 1024
bit parameters rather than the 1536 bits params we specified.

The only way I've found to find the actual parameter size is to tcpdump
the negotiation. First, verify that the negotiated cipher suite is
DHE-RSA-AES128-SHA according to s_client, then:

tcpdump -i lo -wldap.pcap port 6636
wireshark ldap.pcap
Apply the SSL decode to the traffic (right click on packet, Decode As,
Transport tab, SSL), find the Server Key Exchange packet, select the
Server Key Exchange portion of the handshake message, and look at the
hex dump.

It should start with 0c, followed by a three byte size, then the next
two bytes are the length of the DH parameters: 0080 for 1024 bits, 00c0
for 1536 bits.

On 01/27/2013 07:13 PM, openldap-its@OpenLDAP.org wrote:
> *** THIS IS AN AUTOMATICALLY GENERATED REPLY ***
> 
> Thanks for your report to the OpenLDAP Issue Tracking System.  Your
> report has been assigned the tracking number ITS#7506.
> 
> One of our support engineers will look at your report in due course.
> Note that this may take some time because our support engineers
> are volunteers.  They only work on OpenLDAP when they have spare
> time.
> 
> If you need to provide additional information in regards to your
> issue report, you may do so by replying to this message.  Note that
> any mail sent to openldap-its@openldap.org with (ITS#7506)
> in the subject will automatically be attached to the issue report.
> 
> 	mailto:openldap-its@openldap.org?subject=(ITS#7506)
> 
> You may follow the progress of this report by loading the following
> URL in a web browser:
>     http://www.OpenLDAP.org/its/index.cgi?findid=7506
> 
> Please remember to retain your issue tracking number (ITS#7506)
> on any further messages you send to us regarding this report.  If
> you don't then you'll just waste our time and yours because we
> won't be able to properly track the report.
> 
> Please note that the Issue Tracking System is not intended to
> be used to seek help in the proper use of OpenLDAP Software.
> Such requests will be closed.
> 
> OpenLDAP Software is user supported.
> 	http://www.OpenLDAP.org/support/
> 
> --------------
> Copyright 1998-2007 The OpenLDAP Foundation, All Rights Reserved.
> 

Comment 2 Howard Chu 2013-09-07 14:11:34 UTC
ben@bjencks.net wrote:
> I suppose I should attach a test case:

Thanks, patches applied to master (with some tweaks).
>
> cd $WORKDIR
> openssl dhparam 1536 > dh1536.pem
> openssl req -new -newkey rsa:2048 -keyout server.key \
>    -out server.crt -sha256 -nodes -subj '/CN=localhost/' -x509
>
> For GnuTLS, load the following config:
> dn: cn=config
> objectClass: olcGlobal
> cn: config
> olcTLSCertificateFile: $WORKDIR/server.crt
> olcTLSCertificateKeyFile: $WORKDIR/server.key
> olcTLSCipherSuite: NONE:+VERS-TLS1.1:+VERS-TLS1.0:+AES-128-CBC:
>   +DHE-RSA:+SHA1:+COMP-NULL
> olcTLSDHParamFile: $WORKDIR/dh1536.pem
>
> dn: olcDatabase={0}config,cn=config
> objectClass: olcDatabaseConfig
> olcDatabase: {0}config
>
> For Openssl, change olcTLSCipherSuite to:
> olcTLSCipherSuite: aRSA+AES128+kEDH
>
> Start up slapd with the config, listening on ldaps://localhost:6636.
>
> openssl s_client -connect localhost:6636
>
> With GnuTLS this will fail negotiation; with OpenSSL it will use 1024
> bit parameters rather than the 1536 bits params we specified.
>
> The only way I've found to find the actual parameter size is to tcpdump
> the negotiation. First, verify that the negotiated cipher suite is
> DHE-RSA-AES128-SHA according to s_client, then:
>
> tcpdump -i lo -wldap.pcap port 6636
> wireshark ldap.pcap
> Apply the SSL decode to the traffic (right click on packet, Decode As,
> Transport tab, SSL), find the Server Key Exchange packet, select the
> Server Key Exchange portion of the handshake message, and look at the
> hex dump.
>
> It should start with 0c, followed by a three byte size, then the next
> two bytes are the length of the DH parameters: 0080 for 1024 bits, 00c0
> for 1536 bits.



-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

Comment 3 Howard Chu 2013-09-07 14:12:10 UTC
changed notes
changed state Open to Test
moved from Incoming to Software Bugs
Comment 4 Howard Chu 2013-09-07 14:29:49 UTC
Howard Chu wrote:
> ben@bjencks.net wrote:
>> I suppose I should attach a test case:
>
> Thanks, patches applied to master (with some tweaks).
>>
>> cd $WORKDIR
>> openssl dhparam 1536 > dh1536.pem
>> openssl req -new -newkey rsa:2048 -keyout server.key \
>>     -out server.crt -sha256 -nodes -subj '/CN=localhost/' -x509
>>
>> For GnuTLS, load the following config:
>> dn: cn=config
>> objectClass: olcGlobal
>> cn: config
>> olcTLSCertificateFile: $WORKDIR/server.crt
>> olcTLSCertificateKeyFile: $WORKDIR/server.key
>> olcTLSCipherSuite: NONE:+VERS-TLS1.1:+VERS-TLS1.0:+AES-128-CBC:
>>    +DHE-RSA:+SHA1:+COMP-NULL
>> olcTLSDHParamFile: $WORKDIR/dh1536.pem
>>
>> dn: olcDatabase={0}config,cn=config
>> objectClass: olcDatabaseConfig
>> olcDatabase: {0}config
>>
>> For Openssl, change olcTLSCipherSuite to:
>> olcTLSCipherSuite: aRSA+AES128+kEDH
>>
>> Start up slapd with the config, listening on ldaps://localhost:6636.
>>
>> openssl s_client -connect localhost:6636
>>
>> With GnuTLS this will fail negotiation; with OpenSSL it will use 1024
>> bit parameters rather than the 1536 bits params we specified.
>>
>> The only way I've found to find the actual parameter size is to tcpdump
>> the negotiation. First, verify that the negotiated cipher suite is
>> DHE-RSA-AES128-SHA according to s_client, then:
>>
>> tcpdump -i lo -wldap.pcap port 6636
>> wireshark ldap.pcap
>> Apply the SSL decode to the traffic (right click on packet, Decode As,
>> Transport tab, SSL), find the Server Key Exchange packet, select the
>> Server Key Exchange portion of the handshake message, and look at the
>> hex dump.
>>
>> It should start with 0c, followed by a three byte size, then the next
>> two bytes are the length of the DH parameters: 0080 for 1024 bits, 00c0
>> for 1536 bits.

For future reference, you can check this just using
openssl s_client -connect localhost:6636 -debug -state

SSL_connect:SSLv3 read server certificate A
read from 0x16b0c20 [0x16b6cf3] (5 bytes => 5 (0x5))
0000 - 16 03 02 03 0d                                    .....
read from 0x16b0c20 [0x16b6cf8] (781 bytes => 781 (0x30D))
0000 - 0c 00 03 09 01 00 a8 e0-4a 3d d1 d2 73 a8 bd 2e   ........J=..s...

In this case 0c 00 03 09 marks the Server Key Exchange and length, and 01 00 
indicates 2048 bits (which matches the dhparams I used).

-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

Comment 5 Quanah Gibson-Mount 2014-12-11 01:11:20 UTC
changed notes
changed state Test to Closed
Comment 6 OpenLDAP project 2016-02-29 20:44:46 UTC
fixed in master
fixed in RE25
fixed in RE24 (2.4.45)
Comment 7 Quanah Gibson-Mount 2016-02-29 20:44:46 UTC
changed notes