#48798 Enable DS to offer weaker DH params in NSS
Closed: Fixed None Opened 3 years ago by firstyear.

Certain client applications, especially java may crash with the following:

javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair

This affects java 1.6.0 and 1.7.0.

When nss upgrades to 2.21, it enables DH in ciphers. By default the smallest DH param size is 2048 bits.

However, java 1.6.0 and 1.7.0 can only accept up to 1024 bit params.

DS should have the option, to set NSS to offer smaller (weaker) param sizes for compatibility with older clients.


typo about NSS version: this is about nss-3.2x

the DHE related changes appeared in nss-3.20 (logjam and other)
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_3.20_release_notes

the proposed draft to negotiate the DHE params applies by design to the larger primes after the logjam fix
https://tools.ietf.org/html/draft-ietf-tls-negotiated-ff-dhe-10

so the newer API from nss-3.20 with SSL_EnableWeakDHEPrimeGroup and a new config knob to wrongly and intentionally allow the pre-logjam DHE "weak" parameters to till connect with legacy clients may be a solution in desperate cases.

more references:
https://wiki.mozilla.org/Security/Server_Side_TLS#Pre-defined_DHE_groups
https://wiki.mozilla.org/Security/Server_Side_TLS#DHE_and_Java

example a failing connection in SSL/TLS handshake with "legacy" client and a RHEL 6.7 system updated from batch update 6 release of 2016-Mar-22, with nss-3.21.0-0.3.el6_7.x86_64 and nss-softokn-3.14.3-23.el6_7.x86_64

server Hello, 2K bits prime and public key size in DHE params, non negotiable in this TLS session:

{{{
Secure Sockets Layer
TLSv1 Record Layer: Handshake Protocol: Multiple Handshake Messages
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 4496
Handshake Protocol: Server Hello
Handshake Type: Server Hello (2)
Length: 77
Version: TLS 1.0 (0x0301)
Random
GMT Unix Time: Jun 25, 2094 06:05:36.000000000 PDT
Random Bytes: c260eba865775629d787f8908dcc5ba2e3b3ff1ce04c8a8d...
Session ID Length: 32
Session ID: 073b7ec00ed3e623be72b6ab2e9a953fb1b9e0751f343a7c...
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
...snip...
Handshake Protocol: Server Key Exchange
Handshake Type: Server Key Exchange (12)
Length: 777
Diffie-Hellman Server Params
p Length: 256
p: ffffffffffffffffadf85458a2bb4a9aafdc5620273d3cf1...
g Length: 1
g: 02
Pubkey Length: 256
Pubkey: 3611f282e80c549fd79e06fe433472abffe6a14ae5de9376...
Signature Length: 256
Signature: 37928112d513460e4980b88b429481b22784284b964ee79b...
}}}

client Hello, could only handle 1K max, unhappy:

{{{
Secure Sockets Layer
TLSv1 Record Layer: Alert (Level: Fatal, Description: Internal Error)
Content Type: Alert (21)
Version: TLS 1.0 (0x0301)
Length: 2
Alert Message
Level: Fatal (2)
Description: Internal Error (80)
}}}

msauton: I don't understand what you have done or are attempting to show with this trace. Can you please clarify?

I think the proper test is:

  • Java 1.6.0 or Java 1.7.0 to DS with NSS 2.19 or lower (Should work, and NO DH exchange)
  • Java 1.6.0 or Java 1.7.0 to DS with NSS 2.20 or higher (Will fail due to DH Params being larger than can be supported)
  • Java 1.6.0 or Java 1.7.0 to an openssl s_server that has a 1024 bit DH param (Should work, WITH DH exchange)

This will highlight that the correct fix is to make a tunable for DS, that will trigger a call to SSL_EnableWeakDHEPrimeGroup(). SSL_EnableWeakDHEPrimeGroup() allows NSS to use 1024 bit primes, rather than the default 2048 or higher.

Replying to [comment:4 firstyear]:

msauton: I don't understand what you have done or are attempting to show with this trace. Can you please clarify?

I think the proper test is:

  • Java 1.6.0 or Java 1.7.0 to DS with NSS 2.19 or lower (Should work, and NO DH exchange)
  • Java 1.6.0 or Java 1.7.0 to DS with NSS 2.20 or higher (Will fail due to DH Params being larger than can be supported)
  • Java 1.6.0 or Java 1.7.0 to an openssl s_server that has a 1024 bit DH param (Should work, WITH DH exchange)

This will highlight that the correct fix is to make a tunable for DS, that will trigger a call to SSL_EnableWeakDHEPrimeGroup(). SSL_EnableWeakDHEPrimeGroup() allows NSS to use 1024 bit primes, rather than the default 2048 or higher.

For 1.7.0, we could use this definition as proposed by German in https://bugzilla.redhat.com/show_bug.cgi?id=1327065#c18?

you could run java using:
-Djdk.tls.ephemeralDHKeySize=2048
but this has been tested in java 7 only.

Java 7 relnotes:
http://www.oracle.com/technetwork/java/javase/7u85-relnotes-2587591.html

I think there is a better way to detect the present of the SSL_EnableWeakDHEPrimeGroup() function, but I can't get AC_CHECK_FUNCs to work properly.

So, we are having another patch for this improvement (line 142, 143)? Luckily, since we have more and better workarounds for Java 1.6 and 1.7 (https://bugzilla.redhat.com/show_bug.cgi?id=1327065#c28), we don't have to rush. Please take your time to figure it out. If "AC_CHECK_FUNCS([SSL_DHEGroupPrefSet SSL_EnableWeakDHEPrimeGroup])" does not work to trigger to set HAVE_WEAKDHGROUP, the version number of NSS (e.g., #if NSS_VMAJOR * 100 + NSS_VMINOR >= 320) could be used alternatively.

142 /* This is temporary until we can work out the checks in nss.m4 */ 
143 #define HAVE_WEAKDHGROUP 1 
144  
145 #ifdef HAVE_WEAKDHGROUP 
146 static int allowweakdhparam = CIPHER_SET_DEFAULTWEAKDHPARAM; 
147 #endif

I guess these defines could be put in #ifdef HAVE_WEAKDHGROUP, as well.
107 #define CIPHER_SET_DEFAULTWEAKDHPARAM 0x100 / allowWeakDhParam is not set in cn=enryption /
108 #define CIPHER_SET_ALLOWWEAKDHPARAM 0x200 / allowWeakDhParam is on /
109 #define CIPHER_SET_DISALLOWWEAKDHPARAM 0x200 / allowWeakDhParam is off /
line 107 -- a typo in the comment... cn=encryption.
line 108, 109 -- why both share the same bit 0x200?

I think that I like your NSS_VMAJOR option better. I'll implement that.

No, I have them there because I leave the function def for get_allow_weak_dh_param as:

{{{
get_allow_weak_dh_param(Slapi_Entry *e){
int allow = CIPHER_SET_DEFAULTWEAKDHPARAM;

ifdef HAVE_WEAKDHGROUP

...
}
}}}

This way, if a mistake happens, the function is there and still works? Maybe this is unnecessary.

line 108, 109 -- why both share the same bit 0x200?

Because I made a mistake :)

commit 877ba5fe5da349557788b1e7897ea7bacb4666a5
Total 12 (delta 9), reused 0 (delta 0)
To ssh://git.fedorahosted.org/git/389/ds.git
6881e0a..b2022ca master -> master

commit 696d4321de0985ad28e747fb0c4a84697d995d31
commit 0289b4ac0a87e6c955e6821e6f9bc7ff162af0be
Writing objects: 100% (8/8), 3.96 KiB | 0 bytes/s, done.
Total 8 (delta 5), reused 0 (delta 0)
To ssh://git.fedorahosted.org/git/389/lib389.git
4255e0d..56eb259 master -> master

branch 389-ds-base-1.3.4

commit 2fe85773b3a53d524cb10453e0919e46226f270d
Writing objects: 100% (12/12), 3.78 KiB | 0 bytes/s, done.
Total 12 (delta 8), reused 0 (delta 0)
To ssh://git.fedorahosted.org/git/389/ds.git
af5c312..d8fefaa 389-ds-base-1.3.4 -> 389-ds-base-1.3.4

branch 389-ds-base-1.2.11

commit 50910ac
Writing objects: 100% (15/15), 4.26 KiB | 0 bytes/s, done.
Total 15 (delta 9), reused 0 (delta 0)
To ssh://git.fedorahosted.org/git/389/ds.git
a80b2d8..50910ac 389-ds-base-1.2.11 -> 389-ds-base-1.2.11

Metadata Update from @firstyear:
- Issue assigned to firstyear
- Issue set to the milestone: 1.2.11.33

2 years ago

Login to comment on this ticket.

Metadata