malformed key shares cause incorrect alert messages

Assigned to


10 months ago
3 months ago


(Reporter: Hubert Kario, Assigned: fkiefer)



Firefox Tracking Flags

(Not tracked)




10 months ago
When a client sends invalid x25519 key share to the server, the server replies with incorrect alert messages.

When the key share is longer or shorter than 32 bytes, the server replies with handshake_failure instead of illegal_parameter.

When the key share has invalid x25519 key share (the highest bit of the most significant byte is set) the server continues the connection and in the end replies with bad_record_mac instead of illegal_parameter.

git clone
pushd tlsfuzzer
git checkout basic-x25519
git clone .python-ecdsa
ln -s .python-ecdsa/ecdsa ecdsa
git clone .tlslite-ng
pushd .tlslite-ng
git checkout rfc7748
ln -s .tlslite-ng/tlslite tlslite
openssl req -x509 -newkey rsa -keyout localhost.key -out localhost.crt -nodes -batch -subj /CN=localhost
openssl pkcs12 -export -passout pass:  -out localhost.p12 -inkey localhost.key -in localhost.crt
mkdir nssdb
certutil -N -d sql:nssdb --empty-password
pk12util -i localhost.p12 -d sql:nssdb -W ''
selfserv -n localhost -p 4433 -d sql:./nssdb -V tls1.0: -H 1 -U 0 -G

# in another terminal, same directory
PYTHONPATH=tlsfuzzer python tlsfuzzer/scripts/ 'too big x25519 key share' 'too small x25519 key share' 'x25519 key share with high bit set' 'sanity - negotiate x25519'

Additional info:
   Since there are some implementation of the X25519 function that
   impose this restriction on their input and others that don't,
   implementations of X25519 in TLS SHOULD reject public keys when the
   high-order bit of the final byte is set (in other words, when the
   value of the rightmost byte is greater than 0x7F) in order to prevent
   implementation fingerprinting.

RFC 5246:
      A field in the handshake was out of range or inconsistent with
      other fields.  This message is always fatal.


10 months ago
Ever confirmed: true
We send handshake_failure for all malformed client key exchange messages.
Assignee: nobody → franziskuskiefer
Summary: malformed x25519 key shares cause incorrect alert messages → malformed key shares cause incorrect alert messages
The high-bit check was removed from rfc4492bis [1]. But the other issue is still valid.


Comment 3

9 months ago
Empty key share is also a problem:

$ python 'empty x25519 key share'
Error encountered while processing node <tlsfuzzer.expect.ExpectAlert object at 0x1df1790> (child: <tlsfuzzer.expect.ExpectClose object at 0x1df17d0>) with last message being: <tlslite.messages.Message object at 0x1df4090>
Error while processing
Traceback (most recent call last):
  File "", line 673, in main
  File "/tmp/tmp.Euj5MSlvEv/tlsfuzzer/tlsfuzzer/", line 168, in run
    node.process(self.state, msg)
  File "/tmp/tmp.Euj5MSlvEv/tlsfuzzer/tlsfuzzer/", line 543, in process
    raise AssertionError(problem_desc)
AssertionError: Alert description 47 != 50

Since the RFC specifies the minimal size of the key share to be 1 byte, an empty one is a malformed message, so it needs to be rejected with decode_error alert (50).

Comment 4

5 months ago
Script updated to remove the high-bit check.
I also added test cases with key shares that should result in all-zero shared secret.
(Also, use of rfc7748 branch in tlslite-ng is no longer necessary).


3 months ago
Priority: -- → P3
You need to log in before you can comment on or make changes to this bug.