a certificate. We were already enforcing the signature algorithm, but there
was a bug in parameter checking code.
+** libgnutls: no longer send downgrade sentinel in TLS 1.3.
+ Previously the sentinel value was embedded to early in version
+ negotiation and was sent even on TLS 1.3. It is now sent only when
+ TLS 1.2 or earlier is negotiated (#689).
+
** API and ABI modifications:
No changes since last version.
int ret;
if (session->security_parameters.entity == GNUTLS_SERVER) {
+ const version_entry_st *old_vers;
+
vers = _gnutls_version_max(session);
+ old_vers = get_version(session);
/* do not parse this extension when we haven't TLS1.3
* enabled. That is because we cannot handle earlier protocol
_gnutls_handshake_log("EXT[%p]: Negotiated version: %d.%d\n",
session, (int)major, (int)minor);
+
+ vers = get_version(session);
+ if (old_vers != vers) {
+ /* regenerate the random value to set
+ * downgrade sentinel if necessary
+ */
+ ret = _gnutls_gen_server_random(session,
+ vers->id);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ }
+
return 0;
}
}
gnutls_certificate_credentials_t x509_cred;
gnutls_session_t session;
gnutls_datum_t srandom;
+ unsigned try = 0;
+ gnutls_datum_t session_data = { NULL, 0 };
global_init();
&cli_ca3_key,
GNUTLS_X509_FMT_PEM);
+ retry:
/* Initialize TLS session
*/
gnutls_init(&session, GNUTLS_CLIENT);
if (ret < 0)
fail("cannot set TLS priorities\n");
+ if (try > 0)
+ gnutls_session_set_data(session, session_data.data, session_data.size);
+
/* put the anonymous credentials to the current session
*/
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
fail("error in handshake: %s\n", gnutls_strerror(ret));
}
+ if (try > 0)
+ assert(gnutls_session_is_resumed(session));
+
gnutls_session_get_random(session, NULL, &srandom);
if (srandom.size != 32)
fail("unexpected random data for %s\n", name);
}
- close(fd);
+ do {
+ ret = gnutls_record_send(session, "\x00", 1);
+ } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
+
+ if (try == 0) {
+ ret = gnutls_session_get_data2(session, &session_data);
+ if (ret < 0)
+ fail("couldn't retrieve session data: %s\n",
+ gnutls_strerror(ret));
+ }
gnutls_deinit(session);
+ if (try == 0) {
+ try++;
+ goto retry;
+ }
+
+ close(fd);
+
+ gnutls_free(session_data.data);
+
gnutls_certificate_free_credentials(x509_cred);
gnutls_global_deinit();
int ret;
gnutls_session_t session;
gnutls_certificate_credentials_t x509_cred;
+ gnutls_datum_t skey;
+ unsigned try = 0;
+ unsigned char buf[16];
/* this must be called once in the program
*/
&server_key,
GNUTLS_X509_FMT_PEM);
+ assert(gnutls_session_ticket_key_generate(&skey) >= 0);
+
+ retry:
gnutls_init(&session, GNUTLS_SERVER);
gnutls_handshake_set_timeout(session, 20 * 1000);
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
+ assert(gnutls_session_ticket_enable_server(session, &skey) >= 0);
+
gnutls_transport_set_int(session, fd);
do {
if (ret < 0)
fail("error in handshake: %s\n", gnutls_strerror(ret));
- close(fd);
+ if (try > 0)
+ assert(gnutls_session_is_resumed(session));
+
+ do {
+ ret = gnutls_record_recv(session, buf, sizeof(buf));
+ } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
+
+ if (ret < 0)
+ fail("server: recv did not succeed as expected: %s\n", gnutls_strerror(ret));
+
gnutls_deinit(session);
+ if (try == 0) {
+ try++;
+ goto retry;
+ }
+
+ close(fd);
+
+ gnutls_free(skey.data);
gnutls_certificate_free_credentials(x509_cred);
gnutls_global_deinit();