[Help-gnutls] Re: Handling "normal" peer errors on invalid certs

Philip Kovacs kovacsp3 at comcast.net
Tue Jun 12 22:20:44 CEST 2007


> Simon Josefsson <simon at josefsson.org> wrote:

>I suspect the error handling here is simply sub-optimal, and that you
>aren't doing anything wrong.

>Creating a self-test inside GnuTLS tests/ that trigger this situation
>would help.  Having that self-test would help us test what kind of
>errors really should be returned in this situation, and how to return
>them.  I can't commit to work on this now, so I added the following to
>doc/TODO:

>- Investigate why failed client authentication results in weird error
>  messages.  See http://permalink.gmane.org/gmane.network.gnutls.general/875

>If you or others wants to work on it, you are very welcome to do so.

>/Simon

Hi.  I did some investigating and can report a little more detail.

I began with replacing the underlying push function, send(), with
a variant, send_msg_nosignal(), in order to avoid the nagging
SIGPIPE that is being thrown when send() is called against a broken
connection.  Unless you catch SIGPIPE (or ignore it), the app. just
exits with -141 (Unknown error) when gnutls pushes against a broken
connection.

#ifdef HAVE_MSG_NOSIGNAL
static ssize_t
_send_msg_nosignal (gnutls_transport_ptr_t  ptr,
                    const void             *buf,
                    size_t                  buflen)
{
  ssize_t ret = send ( (int)ptr, buf, buflen, MSG_NOSIGNAL);

  /* Here I can look at the actual error.  On Linux I am seeing
     EPIPE.  Other unices probably return ENOTCONN.   */
  ...

  return ret;
}
#endif

and elsewhere in my code I issue this statement as I am setting up
the tls session:

#ifdef HAVE_MSG_NOSIGNAL
  gnutls_transport_set_push_function (tls->session, _send_msg_nosignal);
#endif

The error that is causing gnutls to issue GNUTLS_E_PUSH_ERROR in my
variant above is that send() is returning EPIPE.   I tried replacing
the EPIPE with ENOTCONN, just to see if gnutls "behaved better" on this
error.  I still get GNUTLS_E_PUSH_ERROR.

That seems to explain the reason for the GNUTLS_E_PUSH_ERROR client-side
errors when the server breaks off, and vice versa.  Perhaps the other
error I see, GNUTLS_E_UNEXPECTED_PACKET_LENGTH, when a peer breaks off
may be due to some unread TLS bytes in the tcp buffers?

I suppose, for now, the way to proceed is simply to treat

GNUTLS_E_PUSH_ERROR
GNUTLS_E_UNEXPECTED_PACKET_LENGTH

as "acceptable" errors that may occur during the handshake, indicating
that the peer broke off because it doesn't like our certificate, or that
we failed to send one when required to do so.

Phil

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: </pipermail/attachments/20070612/3b267bb0/attachment.pgp>


More information about the Gnutls-help mailing list