Open Bug 1472747 Opened 6 years ago Updated 2 years ago

Incorrect handling of too big and too small Finished messages

Categories

(NSS :: Libraries, defect, P2)

3.38

Tracking

(Not tracked)

People

(Reporter: hkario, Unassigned)

Details

(Whiteboard: [tls13])

Using NSS c84a61acb17d.

When NSS server receives a malformed Finished message (with payload that doesn't match the PRF used in connection), it aborts with illegal_parameter error instead of the TLS 1.3 mandated decode_error (as the message doesn't match the format specified in section 4.4.4 https://tools.ietf.org/html/draft-ietf-tls-tls13-28#page-75 )

Additionally, if the message is very long (>147000B), NSS will send a second alert: decode_error.

Reproducer:
openssl req -x509 -newkey rsa -keyout localhost.key \
-out localhost.crt -subj /CN=localhost -nodes -batch
mkdir /tmp/nssdb
certutil -N -d sql:/tmp/nssdb --empty-password
openssl pkcs12 -export -passout pass: -out /tmp/localhost.p12 \
-inkey /tmp/localhost.key -in /tmp/localhost.crt -name localhost
pk12util -i /tmp/localhost.p12 -d sql:/tmp/nssdb -W ''
selfserv -d sql:/tmp/nssdb -p 4433 -V tls1.0: -H 1 -n localhost 2> server.err > server.log &
nss_pid=$!
git clone https://github.com/tomato42/tlsfuzzer
pushd tlsfuzzer
git clone https://github.com/tomato42/tlslite-ng .tlslite-ng
ln -s .tlslite-ng/tlslite tlslite
git clone https://github.com/warner/python-ecdsa .python-ecdsa
ln -s .python-ecdsa/ecdsa ecdsa
# necessary to negotiate the currently supported draft in NSS
# works because draft-26 and draft-28 are binary compatible
sed -i 's/TLS_1_3_DRAFT = (127, 26)/TLS_1_3_DRAFT = (127, 28)/' tlslite/constants.py
PYTHONPATH=. python scripts/test-tls13-finished.py
popd
kill $nss_pi


tlsfuzzer output:
(snip)

padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 0, pad_right 16777183 ...
Error encountered while processing node <tlsfuzzer.expect.ExpectClose object at 0x7fa936b2b310> (child: None) with last message being: <tlslite.messages.Message object at 0x7fa93681b910>
Error while processing
Traceback (most recent call last):
  File "scripts/test-tls13-finished.py", line 421, in main
    runner.run()
  File "/home/hkario/dev/tlsfuzzer/tlsfuzzer/runner.py", line 210, in run
    RecordHeader2)))
AssertionError: Unexpected message from peer: Alert(fatal, decode_error)

padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 48, pad_right 0 ...
Error encountered while processing node <tlsfuzzer.expect.ExpectAlert object at 0x7fa936b39350> (child: <tlsfuzzer.expect.ExpectClose object at 0x7fa936b39590>) with last message being: <tlslite.messages.Message object at 0x7fa936814590>
Error while processing
Traceback (most recent call last):
  File "scripts/test-tls13-finished.py", line 421, in main
    runner.run()
  File "/home/hkario/dev/tlsfuzzer/tlsfuzzer/runner.py", line 212, in run
    node.process(self.state, msg)
  File "/home/hkario/dev/tlsfuzzer/tlsfuzzer/expect.py", line 1080, in process
    raise AssertionError(problem_desc)
AssertionError: Expected alert description "decode_error" does not match received "illegal_parameter"

sanity ...
OK

Fuzzing TLS 1.3 Finished messages
version: 1

Test end
successful: 642
failed: 68
  'empty - cipher TLS_AES_128_GCM_SHA256'
  'empty - cipher TLS_AES_256_GCM_SHA384'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 0, pad_right 1'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 0, pad_right 2'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 0, pad_right 4'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 0, pad_right 8'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 0, pad_right 16'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 0, pad_right 32'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 0, pad_right 48'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 0, pad_right 16348'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 0, pad_right 16777183'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 1, pad_right 0'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 1, pad_right 1'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 2, pad_right 0'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 4, pad_right 0'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 8, pad_right 0'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 8, pad_right 8'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 12, pad_right 0'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 16, pad_right 0'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 32, pad_right 0'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 48, pad_right 0'
  'padding - cipher TLS_AES_128_GCM_SHA256, pad_byte 0, pad_left 16348, pad_right 0'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 0, pad_right 1'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 0, pad_right 2'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 0, pad_right 4'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 0, pad_right 8'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 0, pad_right 12'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 0, pad_right 16'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 0, pad_right 32'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 0, pad_right 48'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 0, pad_right 16332'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 0, pad_right 16777167'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 1, pad_right 0'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 1, pad_right 1'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 2, pad_right 0'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 4, pad_right 0'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 8, pad_right 0'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 8, pad_right 8'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 16, pad_right 0'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 32, pad_right 0'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 48, pad_right 0'
  'padding - cipher TLS_AES_256_GCM_SHA384, pad_byte 0, pad_left 16332, pad_right 0'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 0, end 12'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 0, end -1'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 0, end -2'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 0, end -4'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 0, end -8'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 0, end -16'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 0, end -32'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 1, end None'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 2, end None'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 4, end None'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 8, end None'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 16, end None'
  'truncation - cipher TLS_AES_128_GCM_SHA256, start 32, end None'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 0, end 12'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 0, end -1'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 0, end -2'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 0, end -4'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 0, end -8'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 0, end -16'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 0, end -32'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 1, end None'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 2, end None'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 4, end None'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 8, end None'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 16, end None'
  'truncation - cipher TLS_AES_256_GCM_SHA384, start 32, end None'


NSS output:
Received incorrect handshakes hash values from peer.
selfserv: HDX PR_Read returned error -12252:
SSL received a malformed Finished handshake message.
selfserv: HDX PR_Read returned error -12252:
Priority: -- → P2
QA Contact: jjones
Whiteboard: [tls13]
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.