[gnutls-devel] gnutls_record_send after incomplete gnutls_handshake sends data unencrypted
Nikos Mavrogiannopoulos
nmav at gnutls.org
Mon Jan 2 10:41:38 CET 2017
Thank you. That's certainly something to be addressed at least in the
new 3.6.x branch. I've created an issue on the gitlab interface:
https://gitlab.com/gnutls/gnutls/issues/158
I'm wondering however, whether this could have side-effects, i.e.,
whether some existing program relied on that behavior to send TLS
application data records prior to handshake being complete.
regards,
Nikos
On Sat, Dec 31, 2016 at 1:13 PM, Andreas Metzler <ametzler at bebt.de> wrote:
> Hello,
>
> find attached bug-report http://bugs.debian.org/849807 as reported by
> Bernhard R. Link. The related bug against sssd-ldap is
> <http://bugs.debian.org/849756>
>
> cu Andreas
>
> ----- Forwarded message from "Bernhard R. Link" <brlink at debian.org> -----
> Package: libgnutls30
> Version: 3.5.7-3
> Severity: normal
> Tags: security
>
> This bug report is not about wrong behavior if libgnutls is called
> correctly but rather about dangerous behaviour if the caller is using
> libgnutls incorrectly.
>
> If a handshake has not yet completed (the caller ignoring
> gnutls_handshake return code or the caller having a bug in the handling
> of GNUTLS_E_AGAIN) then telling libgnutls to send data causes it to send
> it unencrypted. Unless there are cases where might be useful, I think a
> security relevelant library like libgnutls should rather catch this
> mistake and avoid sending stuff unencrypted.
>
> Here's an example:
>
> cat <<'EOF' > example.c
> #define _GNU_SOURCE
> #include <stdbool.h>
> #include <stdio.h>
> #include <error.h>
> #include <errno.h>
> #include <string.h>
> #include <assert.h>
> #include <gnutls/gnutls.h>
>
> static ssize_t sim_write(gnutls_transport_ptr_t session, const void *data, size_t len) {
> bool found = memmem(data, len, "SECRET", 6) != NULL;
> printf("Would have written %d bytes%s.\n", (int)len, found?" containing unencrypted plain-text secret":"");
> fflush(stdout);
> return len;
> }
> static ssize_t sim_read(gnutls_transport_ptr_t session, void *data, size_t len) {
> /* simulate non-blocking io with no incoming data arrived yet */
> gnutls_transport_set_errno(session, EAGAIN);
> fflush(stdout);
> return -1;
> }
>
> int main() {
> gnutls_certificate_credentials_t xcred;
> gnutls_session_t session;
> int r;
>
> r = gnutls_global_init();
> assert (r == GNUTLS_E_SUCCESS);
> r = gnutls_certificate_allocate_credentials(&xcred);
> assert (r == GNUTLS_E_SUCCESS);
> r = gnutls_init(&session, GNUTLS_CLIENT);
> assert (r == GNUTLS_E_SUCCESS);
> r = gnutls_set_default_priority(session);
> assert (r == GNUTLS_E_SUCCESS);
> r = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
> assert (r == GNUTLS_E_SUCCESS);
> gnutls_session_set_verify_cert(session, "server", 0);
>
> gnutls_transport_set_ptr(session, session);
> gnutls_transport_set_push_function(session, sim_write);
> gnutls_transport_set_pull_function(session, sim_read);
>
> r = gnutls_handshake(session);
> assert (r == GNUTLS_E_AGAIN);
> /* ignoring the return code and doing the sending: */
> r = gnutls_record_send(session, "SECRET\n", 7);
> printf("gnutls_record_send returned %d\n", r);
>
> return 0;
> }
> EOF
> gcc -Wall -O2 -g example.c -lgnutls && ./a.out
>
> It outputs:
>
> Would have written 238 bytes.
> Would have written 12 bytes containing unencrypted plain-text secret.
> gnutls_record_send returned 7
>
> i.e. the data is send unencrypted (looking at the output one sees a
> CLIENT_HELO followed by an APPLICATION_DATA packet with unencrypted
> content).
>
> One example where this happens is libldap, which runs into this if
> gotten an non-blocking fd (as currently sssd does, see #849756),
> causing sssd-ldap to corrently sending passwords unencrypted.
>
> Bernhard R. Link
> --
> ----- End forwarded message -----
>
> _______________________________________________
> Gnutls-devel mailing list
> Gnutls-devel at lists.gnutls.org
> http://lists.gnupg.org/mailman/listinfo/gnutls-devel
More information about the Gnutls-devel
mailing list