JKRhb / dtls2

A DTLS library for Dart based on OpenSSL.
MIT License
3 stars 0 forks source link

Fatal exception with no trace #88

Closed Ifilehk closed 3 months ago

Ifilehk commented 1 year ago

Digging is always good :-)

Was trying to understand the handshake and manipulated using `openssl s_client. Crashed my usecase server and the minimal server used yesterday too. Unfortunately no trace is available. Note that that if the server runs on my linux machine, there is no crash. But on my cloud server one can see the following trace. So I suspect different libssl version. ret = is a print inside _maintainOutgoing() in dtls_server.dart

If you have an idea will let you go for it otherwise will try to narrow it down ...

Oh yes her the crash trigger: openssl s_client -dtls -psk_identity "" -psk "" -connect XX.XX.XX.XX:PPPP

Server listening on port 8888

ret = 60
ret = -1
New connection

===== CRASH =====
si_signo=Segmentation fault(11), si_code=1, si_addr=0x110
JKRhb commented 1 year ago

Thank you for reporting this issue! I actually found the bug: The crash occurs when you send a PSK with zero length (using a zero-length identity works, however). Will try to provide a fix ASAP.

Ifilehk commented 1 year ago

Cannot confirm.

openssl s_client -dtls -psk_identity "ABCDE" -psk "AAAAAAAAAAAAAAAAAA" -connect XX.XX.XX.XX:PPPP

does the same.

Server listening on port 8888

ret = 60
ret = -1
New connection

===== CRASH =====
si_signo=Segmentation fault(11), si_code=1, si_addr=0x110
Ifilehk commented 1 year ago

As as stated before same command openssl s_client -dtls -psk_identity "ABCDE" -psk "AAAAAAAAAAAAAAAAAA" -connect localhost:8888, on my local server no crash. Just on the cloud server.

Server listening on port 8888

ret = 60
ret = -1
New connection
ret = 60
ret = 60
ret = 60
JKRhb commented 1 year ago

Hmm, okay, then the empty PSK is actually a different bug :D

Do you have any way of checking the OpenSSL version on the server?

Ifilehk commented 1 year ago

strings /usr/lib/x86_64-linux-gnu/libssl.so | grep "^OpenSSL" OpenSSL 1.1.1d 10 Sep 2019

Ifilehk commented 1 year ago

on my local machine

Package: libssl3                  
Version: 3.0.8-1ubuntu1.2
Ifilehk commented 1 year ago

What is making the server crash is when PSK is not multiple of 8bits. No crash: openssl s_client -dtls -psk_identity "R" -psk "1A" -cipher "PSK-AES128-CCM8" -connect <IP>:<PORT> Crash: openssl s_client -dtls -psk_identity "R" -psk "1AB" -cipher "PSK-AES128-CCM8" -connect <IP>:<PORT>

PSK for openssl s_client must be HEX. So may be there is a problem there reading the HEX like "1AB" that should be "01AB"

Ifilehk commented 1 year ago

And I can confirm PSK 01AB does not trigger a crash but 1AB does.

Seems to be that openssl 3 is more resilient to that then openssl 1

Ifilehk commented 1 year ago

Thank you for reporting this issue! I actually found the bug: The crash occurs when you send a PSK with zero length (using a zero-length identity works, however). Will try to provide a fix ASAP.

Please consider the client side too. Client crashing on empty PSK string too.

Unhandled exception:
SocketException: Send failed (OS Error: Message too long, errno = 90), address = 0.0.0.0, port = 0
#0      _NativeSocket.send (dart:io-patch/socket_patch.dart:1246:34)
#1      _RawDatagramSocket.send (dart:io-patch/socket_patch.dart:2516:15)
#2      _DtlsClientConnection._maintainOutgoing (package:dtls2/src/dtls_client.dart:565:31)
#3      _DtlsClientConnection._connectToPeer (package:dtls2/src/dtls_client.dart:498:21)
#4      _DtlsClientConnection._maintainState (package:dtls2/src/dtls_client.dart:596:7)
#5      _DtlsClientConnection._incoming (package:dtls2/src/dtls_client.dart:557:5)
#6      DtlsClient._startListening.<anonymous closure> (package:dtls2/src/dtls_client.dart:87:26)
#7      _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
JKRhb commented 1 year ago

Hmm, with the current state on the main branch, I cannot reproduce the errors anymore using OpenSSL 3. Can you try upgrading and testing again?

Ifilehk commented 1 year ago

OK. Results with main branch on my cloud server on OpenSSL 1.1.1d 10 Sep 2019: No crash: openssl s_client -dtls -psk_identity "R" -psk "1A" -cipher "PSK-AES128-CCM8" -connect IP:PORT Crash: openssl s_client -dtls -psk_identity "R" -psk "01A" -cipher "PSK-AES128-CCM8" -connect IP:PORT

With an uneven number of bytes in the parameter psk I can still observe the crash.

JKRhb commented 1 year ago

Hi @Ifilehk, sorry for the long silence on my part, I am trying to get back into the issue now. Have you had any new insight into the problem so far and have a proposal for a fix? And do you maybe have a minimal example for me to reproduce the problem?

Ifilehk commented 1 year ago

Hello. No problem for the delay.

The issue is related to the number of bytes of the PSK. It has to be even to avoid the crash. At the moment, I don't have enough insight of your code to tell you where to patch. But the fact is. Uneven number of bytes triggers a crash as stated above.

Example to reproduce is simple. Use the minimal server and try to connect to it using the command:

openssl s_client -dtls -psk_identity "R" -psk "01A" -cipher "PSK-AES128-CCM8" -connect IP:PORT

Let me know if you succeed to reproduce me it.

On Aug 28, 2023, 14:17, at 14:17, Jan Romann @.***> wrote:

Hi @Ifilehk, sorry for the long silence on my part, I am trying to get back into the issue now. Have you had any new insight into the problem so far and have a proposal for a fix? And do you maybe have a minimal example for me to reproduce the problem?

-- Reply to this email directly or view it on GitHub: https://github.com/JKRhb/dtls2/issues/88#issuecomment-1695594565 You are receiving this because you were mentioned.

Message ID: @.***>

JKRhb commented 1 year ago

Hi @Ifilehk, thank you, that helped me to get closer to reproducing the problem :)

However, it seems to me as if this is not an issue with this library but with OpenSSL itself. If I try to connect to the server with the s_client command and the parameters you provided, I get the following error message on the command line:

$ openssl s_client -dtls -psk_identity "R" -psk "01A" -cipher "PSK-AES128-CCM8" -connect 127.0.0.1:5684

CONNECTED(00000003)
Can't use SSL_get_servername
Could not convert PSK key '01A' to buffer
009E09DE01000000:error:07800067:common libcrypto routines:hexstr2buf_sep:odd number of digits:crypto/o_str.c:154:
009E09DE01000000:error:0A0000DF:SSL routines:tls_construct_cke_psk_preamble:psk identity not found:ssl/statem/statem_clnt.c:2780:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 216 bytes and written 466 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : DTLSv1.2
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    PSK identity: None
    PSK identity hint: This is the identity hint!
    SRP username: None
    Start Time: 1693497719
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---

I think this should be the intended behavior, though. Trying to replace the PSK in the Dart example with hex.decode("01A") did not cause a crash/segfault either, although the handshake fails to succeed when using this "variant" of hex encoding. Are you sure that the problem is still present? Or have you more hints on reproducing it?

Ifilehk commented 1 year ago

Morgen!

In fact on libssl3 and this is I suppose what you have on your local machine, there is no crash as stated here https://github.com/JKRhb/dtls2/issues/88#issuecomment-1632513769.

Crash is seen on my cloud server running on libssl1. So as you said it is obviously a libssl1 problem, but dtls2 has to catch this before it happens, otherwise all the app crashes.

Wouldn't be possible to dtlstimeout when the PSK is null or uneven in number of bytes ?

Ifilehk commented 11 months ago

Any news at this front ?

JKRhb commented 7 months ago

Hi @Ifilehk, sorry, I only found the time to deal with the issue again now. If you are active working in this area, please have a look at #97 as a potential fix for the problem.

I tested it locally against OpenSSL version 1.1.1d and the inputs provided by you above and the server was able to handle the incorrectly formatted inputs now. The tests are, for some reason, currently failing on Windows, but I hope to be able to resolve these problems shortly. On Linux, you should already be able to perform tests with the updates on that branch.