handshake: do not negotiate TLS1.3 using the legacy version field
Previously we could end-up with a TLS1.3 connection if the TLS1.3
ID was seen on the wire. We now explicitly fallback to TLS1.2
when we see a protocol with TLS1.3 semantics in an SSL2.0 or
in the legacy version of the client hello.
Daiki Ueno [Fri, 10 Aug 2018 12:06:16 +0000 (14:06 +0200)]
ext/record_size_limit: new extension
This implements the record_size_limit extension as defined in RFC 8449.
Although it obsoletes the max_record_size extension, for compatibility
reasons GnuTLS still sends it on certain occasions. For example, when
the new size is representable as the codepoint defined for
max_record_size.
Daiki Ueno [Tue, 14 Aug 2018 14:46:12 +0000 (16:46 +0200)]
ext/max_record: remove use of extension private data
As the extension data is always stored in
session->security_parameters.max_record_send_size, it shouldn't be
necessary to track it with the private data.
Daiki Ueno [Tue, 7 Aug 2018 12:45:07 +0000 (14:45 +0200)]
ext/pre_shared_key: prevent crash if no server credentials are set
Previously, if server is configured without PSK credentials and the
client authenticated with PSK, the server crashed with:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b190ba in server_recv_params (session=0x636fc0, data=0x634e6e "",
len=46, pskcred=0x0) at pre_shared_key.c:523
523 prf = pskcred->binder_algo;
Daiki Ueno [Tue, 7 Aug 2018 10:32:56 +0000 (12:32 +0200)]
alert: map GNUTLS_E_NO_COMMON_KEY_SHARE to handshake_failure
Previously, when server received a ClientHello that does include only
groups from unassigned ranges in supported_groups, it aborted the
connection with an illegal_parameter.
This seems to be a regression since EdDSA support. The call to
_gnutls_x509_get_pk_algorithm() in public key import was unnecessary
and in fact it was overriding the available curve with a curve associated
with the OID. As the ECDSA OID doesn't include the curve, that had the
result of deleting the already read curve.
Ensure we are sending the right protocol version on second client hello
That is, when we respond to a Hello Retry Request as client, we put
the TLS1.2 version on the second client hello to send a hello that is
as close as possible to the original hello. That effectively separates
the handling of TLS1.2 rehandshake and TLS1.3 hello retry request
when sending a client hello.
gnutls-serv: re-introduce the session identifier message
The message "If your browser supports session resuming, then you should
see the same session ID, when you press the reload button", is now printed
again even under TLS1.3.
With the introduction of session ticket support (TLS1.2) and
TLS1.3, session identifiers have no persistency on server or
client side. Improve the situation by introducing persistent
session identifiers on server side in a backwards compatible
way.
buffers: handle very short fragmentation of handshake messages
If the received record doesn't even complete the handshake
header (i.e., the record size < 4), keep it in a temporary buffer and
let the caller receive more records. Once enough amount of data is
received, move the already received records back to record_buffer and
proceed to the normal processing.
buffers: avoid confusion in fragment length calculation
Previously, to calculate the fragment length, it added/subtracted one
to the ending offset back and forth; that was not easier to read and
couldn't handle empty payload messages in TLS.
As 0-RTT is still not implemented in GnuTLS, the server responds with
1-RTT, by skipping decryption failure up to max_early_data_size, as
suggested in 4.2.10 Early Data Detection.
tls1.3: server returns early on handshake when no cert is provided by client
Under TLS1.3 the server knows the negotiated keys early, if no client
certificate is sent. In that case, the server is not only able to
transmit the session ticket immediately after its finished message,
but is also able to transmit data, similarly to false start.
gnutls-serv: don't close connection properly when handshake is not yet complete
In the case handshake is not yet complete and we need
to terminate, it is because of an issue. As such prefer an
unclear termination at this stage. This addresses error detection
issues with tlsfuzzer.
ext/key_share: check the validity of server key shares
That is, when generating the public key based on the server's
key share, ensure that the algorithms match completely with
the key shares the client initially sent. This was detected
by the updated traces for TLS1.3 fuzzying.
That is, silence fields no longer applicable under TLS1.3
and make sure that newer functions like gnutls_session_get_desc()
get used when describing the session.
send_client_hello: don't override version after HRR is received
When a Hello Retry Request is received, do not set our (transient)
version to TLS1.2 on the second client hello. That's because both
peers have already negotiated TLS1.3.
This addresses issue with peers which may send a changecipherspec
message at this stage, which is now allowed when our version is
set to be TLS1.2. Introduced test suite using openssl and resumption
using HRR which reproduces the issue.
hello_ext_parse: apply the test for pre-shared key ext being last on client hello
We were incorrectly insisting on pre-shared key extension being last in
both client and server hello. That was incorrect, as only in client hello
it is required by TLS1.3 to be last.
Quoting:
The "pre_shared_key" extension MUST be the last extension in the
ClientHello (this facilitates implementation as described below).
Servers MUST check that it is the last extension and otherwise fail
the handshake with an "illegal_parameter" alert.
cert-cred: fix possible segfault when resetting cert retrieval function
Reset get_cert_callback3 callback to NULL if provided callback is NULL.
Otherwise after the certificate request call_legacy_cert_cb1 /
call_legacy_cert_cb2 will try to unconditionally call legacy_cert_cb1 /
legacy_cert_cb2 callback (set to NULL) leading to segfault.
constate: drop unused variable in _gnutls_set_keys
_gnutls_set_keys() creates rrnd as client random + server random, but
does not use it (it was used before for export key generation, but was
not removed when dropping support for export cipher suites).
gnutls_x509_privkey_import_ecc_raw: encode parameters on import
That makes the structure fully usable after import. In _encode_privkey()
use the lower-level _gnutls_x509_export_int2() for key encoding as the
call to higher gnutls_x509_privkey_export2() could result to an infinite
recursion when keys are incomplete.
Introduced additional tests for PKCS#8 key import and export.
The tests nature (waiting on a socket) didn't fit well with the virt-time
implementation. Reverted to original real-time wait and improved error
detection in child process.
gnutls_priority_init: fix err_pos on invalid strings
When the provided string would be resolved (e.g., due to a @ priority
being used), to a different string, then do not attempt to
detect the right location of the error. It will not be useful to the caller.
This addresses the issue of test suite failure when --with-system-priority-file
and --with-default-priority-string are provided. It also enhances the test suite
with these options being active.