On shutdown, a previous iteration of dtsl_connection_process()
might be incomplete and leave a partial bio_buffer behind.
If the DTLS connection is already marked closed, drop out
of dtls_connection_process early without asserting.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1741>
keys_exported flag should be set only if keys are actually exported.
For that the next conditions are needed:
1 - SSL_export_keying_material on success
2 - SSL_get_selected_srtp_profile returns a valid profile
3 - The profile ID is SRTP_AES128_CM_SHA1_80 or SRTP_AES128_CM_SHA1_32
Also don't crash if NULL is returned as profile.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1156>
openssl 1.1.1e does some stricker EOF handling and will throw an error
if the EOF is unexpected (like in the middle of a record). As we are
streaming data into openssl here, it is entirely possible that we push
data from multiple buffers/packets into openssl separately.
From the openssl changelog:
Changes between 1.1.1d and 1.1.1e [17 Mar 2020]
*) Properly detect EOF while reading in libssl. Previously if we hit an EOF
while reading in libssl then we would report an error back to the
application (SSL_ERROR_SYSCALL) but errno would be 0. We now add
an error to the stack (which means we instead return SSL_ERROR_SSL) and
therefore give a hint as to what went wrong.
[Matt Caswell]
We can relax the EOF signalling to only return TRUE when we have stopped
for any reason (EOS, error).
Will also remove a spurious EOF error from previous openssl version.
Previously we simply logged errors but never reported them to elements
or even to the user. Fatal errors are now properly reported.
Additionally proper connection closing is implemented based on EOS:
- dtlsenc: EOS will cause close_notify to be sent to the peer and only
if the peer also sent back close_notify we will forward the
EOS event.
- dtlsdec: EOS will be forwarded normally, this only means that the
unterlying transport was closed. On receiving a DTLS packet
containing close_notify, return EOS and send EOS downstream.
By passing NULL to `g_signal_new` instead of a marshaller, GLib will
actually internally optimize the signal (if the marshaller is available
in GLib itself) by also setting the valist marshaller. This makes the
signal emission a bit more performant than the regular marshalling,
which still needs to box into `GValue` and call libffi in case of a
generic marshaller.
Note that for custom marshallers, one would use
`g_signal_set_va_marshaller()` with the valist marshaller instead.
The agent itself will take a ref on the property setter, so we'll be
left with two references to the certificate object, when actually there
should be only one
As suggested in [the SSL_get_error manpage][1]. Upgrade the message to a
warning if the errno isn't 0 (success). The latter apparently means the
transport encountered an EOF (shutdown) without the shut down handshake
on the (D)TLS level. This happens quite often for otherwise normal DTLS
connections.
[1]: https://www.openssl.org/docs/man1.1.1/man3/SSL_get_error.html
Print out all errors from the OpenSSL error queue instead of just
looking at the topmost error. Using the callback interface also removes
the need for formatting using a buffer on the stack.
By removing the indirection to the main loop completely when receiving
the peer certificate. For reference, the on-decoder-key signal does not
have a redirection.
For pre-1.1.x openssl, a callback to set the thread id needs to be
provided to openssl. In 0.9.x the thread id was an unsigned long. In
1.0.x it was expanded to be able to hold a void*. Here we change to use
the 1.0.x API so that the thread id can always hold a GThread*, even on
platforms like msvc x64 where unsigned long is only 32 bits.
All of this is still #ifdef'd out of existence when building with
openssl 1.1.x or later which changed the thread API again, and does not
need a thread id callback.
https://bugzilla.gnome.org/show_bug.cgi?id=775292
- DTLSv1_method() is deprecated, and since 1.0.2 replaced by
DTLS_method().
- CRYPTO_set_locking_callback() and CRYPTO_set_id_callback() are
no-ops (empty macros) since 1.1 and are not supposed to be used
anymore.
gstdtlsagent.c: In function ‘gst_dtls_agent_init’:
gstdtlsagent.c:173:3: error: ‘DTLSv1_method’ is deprecated [-Werror=deprecated-declarations]
priv->ssl_context = SSL_CTX_new (DTLSv1_method ());
^~~~
In file included from /usr/include/openssl/ct.h:13:0,
from /usr/include/openssl/ssl.h:61,
from gstdtlsagent.c:40:
/usr/include/openssl/ssl.h:1614:1: note: declared here
DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_method(void)) /* DTLSv1.0 */
^
At top level:
gstdtlsagent.c:103:1: error: ‘ssl_thread_id_function’ defined but not used [-Werror=unused-function]
ssl_thread_id_function (void)
^~~~~~~~~~~~~~~~~~~~~~
gstdtlsagent.c:73:1: error: ‘ssl_locking_function’ defined but not used [-Werror=unused-function]
ssl_locking_function (gint mode, gint lock_num, const gchar * file, gint line)
^~~~~~~~~~~~~~~~~~~~