some strange decryption errors + one enhancement notice

View: New views
4 Messages — Rating Filter:   Alert me  

some strange decryption errors + one enhancement notice

by Miroslav Kratochvil :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I'm using GnuTLS library to develop a small and secure networking
tool, see [1]. Recently I came to a very strange problem:

My application is used for data transfer, and all sockets used are
non-blocking. When there's too much of data to send, it usually comes
to the state that the application needs to write, but socket is full
(resulting in returning a 'would block' from gnutls_record_send() and
waiting for a writeable socket). In these cases, the application
usually starts to randomly fail in this way:

1] the second peer (the one that didn't fill up the send queue)
reports gnutls error "Decryption failed" thrown by a call to
gnutls_record_recv()
2] the first peer then (as usual) fails with "TLS packet with
unexpected length was received", which is most probably a result of
having the other connection endpoint closed.

My little debugging search led to gnutls_cipher.c, where the
"decryption failed" error seems to originate. It is detected in line
535 (below the comment "Check padding bytes, TLS 1.x") and returned
after 'if (pad_failed!=0)' on line 572  (please note that this return
probably misses gnutls_assert() call, it can be helpful on debugging..
or at least it helped me after i added it;) )

Now about my question: As a reliable transport (TCP) is used to
transfer the packets, how is it possible that receiving end detects
corrupted data?

I guess the possible causes can be those:

a] I'm somehow using gnutls_record_send in a very bad manner,
especially when it returns after non-successful nonblocking write;
which causes some data corruption of outgoing data, which is then
detected by the other communication peer. Is it possible?

b] Improbable bug in GnuTLS padding-creating function.

c] Very improbable bug in GnuTLS padding-checking function.

d] Extremely improbable: TCP stack somehow fails, or "Decryption
failed" error is caused by connection problem.

I expect that it's a]. Could someone comment on correct send retrying
(gnutls manual isn't very talkative at that section)? If I'm somehow
wrong, please correct me. If you want to see my source, please see
[2].

Thanks in advance,
Mirek Kratochvil

[1] http://e-x-a.org/?view=cloudvpn
[2] http://e-x-a.org/repos/view.cgi/cloudvpn/tree/src/cloud/comm.cpp#n683


_______________________________________________
Help-gnutls mailing list
Help-gnutls@...
http://lists.gnu.org/mailman/listinfo/help-gnutls

Re: some strange decryption errors + one enhancement notice

by Simon Josefsson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Miroslav Kratochvil <exa.exa@...> writes:

> Hi,
>
> I'm using GnuTLS library to develop a small and secure networking
> tool, see [1]. Recently I came to a very strange problem:
>
> My application is used for data transfer, and all sockets used are
> non-blocking. When there's too much of data to send, it usually comes
> to the state that the application needs to write, but socket is full
> (resulting in returning a 'would block' from gnutls_record_send() and
> waiting for a writeable socket). In these cases, the application
> usually starts to randomly fail in this way:

Which version?  2.8.2 fixed a bug for non-blocking use:

** libgnutls: Avoid internal error when invoked after GNUTLS_E_AGAIN.
Report and patch by Tim Kosse <tim.kosse@...> in
<http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3671>
and
<http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3670>.

I'm not sure it is the same as you are seeing though...

/Simon


_______________________________________________
Help-gnutls mailing list
Help-gnutls@...
http://lists.gnu.org/mailman/listinfo/help-gnutls

Re: some strange decryption errors + one enhancement notice

by Miroslav Kratochvil :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Well,
I probably solved it - seems it was roughly the error from a] that I
described in last post (my error was that I was calling
gnutls_record_send for the same data, but with different (larger)
buffer size), sometimes combined with this bug. GnuTLS 2.8.3 with my
fixed version works perfectly now.

I'm not sure whether there shouldn't be some kind of input checking in
gnutls_record_send - if calling a retry with larger buffer size
results in output data corruption, I guess it should be avoided.

Anyway, this is the diff for that one assert I was missing when
searching for the problem, I guess it could get helpful sometime:

--- lib/gnutls_cipher.c.old 2009-09-11 17:43:18.000000000 +0200
+++ lib/gnutls_cipher.c 2009-09-11 17:43:38.000000000 +0200
@@ -571,7 +571,10 @@
    * 1.0 protocol.
    */
   if (pad_failed != 0)
+  {
+    gnutls_assert ();
     return pad_failed;
+  }

   /* HMAC was not the same.
    */


Thanks for help,
Mirek Kratochvil



On Fri, Sep 11, 2009 at 4:28 PM, Simon Josefsson <simon@...> wrote:

> Miroslav Kratochvil <exa.exa@...> writes:
>
>> Hi,
>>
>> I'm using GnuTLS library to develop a small and secure networking
>> tool, see [1]. Recently I came to a very strange problem:
>>
>> My application is used for data transfer, and all sockets used are
>> non-blocking. When there's too much of data to send, it usually comes
>> to the state that the application needs to write, but socket is full
>> (resulting in returning a 'would block' from gnutls_record_send() and
>> waiting for a writeable socket). In these cases, the application
>> usually starts to randomly fail in this way:
>
> Which version?  2.8.2 fixed a bug for non-blocking use:
>
> ** libgnutls: Avoid internal error when invoked after GNUTLS_E_AGAIN.
> Report and patch by Tim Kosse <tim.kosse@...> in
> <http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3671>
> and
> <http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3670>.
>
> I'm not sure it is the same as you are seeing though...
>
> /Simon
>


_______________________________________________
Help-gnutls mailing list
Help-gnutls@...
http://lists.gnu.org/mailman/listinfo/help-gnutls

Re: some strange decryption errors + one enhancement notice

by Simon Josefsson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Miroslav Kratochvil <exa.exa@...> writes:

> Well,
> I probably solved it - seems it was roughly the error from a] that I
> described in last post (my error was that I was calling
> gnutls_record_send for the same data, but with different (larger)
> buffer size), sometimes combined with this bug. GnuTLS 2.8.3 with my
> fixed version works perfectly now.

Great!

> I'm not sure whether there shouldn't be some kind of input checking in
> gnutls_record_send - if calling a retry with larger buffer size
> results in output data corruption, I guess it should be avoided.

Yes... although the documentation says to call it again using same
parameters.

> Anyway, this is the diff for that one assert I was missing when
> searching for the problem, I guess it could get helpful sometime:

Indeed, I have added it.

/Simon

> --- lib/gnutls_cipher.c.old 2009-09-11 17:43:18.000000000 +0200
> +++ lib/gnutls_cipher.c 2009-09-11 17:43:38.000000000 +0200
> @@ -571,7 +571,10 @@
>     * 1.0 protocol.
>     */
>    if (pad_failed != 0)
> +  {
> +    gnutls_assert ();
>      return pad_failed;
> +  }
>
>    /* HMAC was not the same.
>     */
>
>
> Thanks for help,
> Mirek Kratochvil
>
>
>
> On Fri, Sep 11, 2009 at 4:28 PM, Simon Josefsson <simon@...> wrote:
>> Miroslav Kratochvil <exa.exa@...> writes:
>>
>>> Hi,
>>>
>>> I'm using GnuTLS library to develop a small and secure networking
>>> tool, see [1]. Recently I came to a very strange problem:
>>>
>>> My application is used for data transfer, and all sockets used are
>>> non-blocking. When there's too much of data to send, it usually comes
>>> to the state that the application needs to write, but socket is full
>>> (resulting in returning a 'would block' from gnutls_record_send() and
>>> waiting for a writeable socket). In these cases, the application
>>> usually starts to randomly fail in this way:
>>
>> Which version?  2.8.2 fixed a bug for non-blocking use:
>>
>> ** libgnutls: Avoid internal error when invoked after GNUTLS_E_AGAIN.
>> Report and patch by Tim Kosse <tim.kosse@...> in
>> <http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3671>
>> and
>> <http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3670>.
>>
>> I'm not sure it is the same as you are seeing though...
>>
>> /Simon
>>


_______________________________________________
Help-gnutls mailing list
Help-gnutls@...
http://lists.gnu.org/mailman/listinfo/help-gnutls