Resumption and renegotiation with extended master secret is not RFC compliant
I'm using gnutls-3.4.8-1.fc23.x86_64 and testing it with tlsfuzzer.
Whith resumption, if the original session was negotiated without EMS but is now being resumed with EMS extension GnuTLS will send a ServerHello with matching session_id - that is, it will resume instead of negotiating a new session or aborting the handshake. That is in violation of MUST NOT from RFC 7627 section 5.3:
o If the original session did not use the "extended_master_secret"
extension but the new ClientHello contains the extension, then the
server MUST NOT perform the abbreviated handshake. Instead, it
SHOULD continue with a full handshake (as described in
Section 5.2) to negotiate a new session.
(test case "resume non-EMS session with EMS extension" inside the test script below)
If I perform resumption of a session that originally negotiated EMS, but current Client Hello doesn't contain the extension, the server continues the negotiation instead of aborting the connection with an alert. This is in violation of MUST from RFC 7627 section 5.3:
o If the original session used the "extended_master_secret"
extension but the new ClientHello does not contain it, the server
MUST abort the abbreviated handshake.
(test case "EMS with session resume without extension" inside the test script below)
Finally, if I perform renegotiation inside of session with EMS, but the renegotiated session does not advertise EMS, the server rejects my Finished message with fatal bad_record_mac alert. This is in violation of MUST clause from RFC 7627 section 5.2:
If the client and server choose to continue a full handshake without
the extension, they MUST use the standard master secret derivation
for the new session.
(test case "renegotiate without EMS in session with EMS" in test script below)
Reproducer:
openssl req -x509 -newkey rsa -keyout localhost.key -out localhost.crt -nodes -batch -subj /CN=localhost
gnutls-serv --x509keyfile localhost.key --x509certfile localhost.crt --port 4433 --disable-client-cert
pip install --pre tlslite-ng
git clone https://github.com/tomato42/tlsfuzzer.git
cd tlsfuzzer
git checkout extended-master # later on unnecessary as this will soon be merged
PYTHONPATH=. python scripts/test-extended-master-secret-extension.py