[gnutls-dev] [Help-gnutls] push/pull functions

Nikos Mavrogiannopoulos n.mavrogiannopoulos at gmail.com
Wed Sep 26 09:56:18 CEST 2007


On Wednesday 26 September 2007, Robin Redeker wrote:
> Hi!

> I have a (maybe not so?) simple question:
> Can I call gnutls_record_recv/gnutls_record_send safely while I'm in a
> push/pull callback?

As long as you don't use the same session, it should be safe.

> The reason I'm asking is that I want to make bindings for GNU Smalltalk,
> which has support for non-preemtive multiple threads of execution.

gnutls can be used with multiple threads, as long as the gcrypt callbacks are 
set and the same session is not accessed by multiple threads.

> What if some kind of re-handshake happens while I call
> gnutls_record_recv? Will GnuTLS detect that it is still waiting for the
> callback to read to return?

A rehandshake will be detected by the return value of gnutls_record_recv(). It 
is in-band data so it should procceed normally.

> And there is also another issue I stepped over while testing. I somehow
> could't get the anonymous client example to work with gnutls-serv.
> I've tried running the server with:
>    gnutls-serv -p 12331 --kx "Anon DH"
>    gnutls-serv -p 12331 --kx "Anon DH" -g
>    gnutls-serv -p 12331 --kx "Anon DH" --dhparams /tmp/dh.pem (with a
>    properly initialized dh.pem)

Thank you for reporting this. It seems that it was a bug in the handshake 
function and couldn't negotiate anonymous DH if a certificate wasn't set. It 
must be corrected in the git repository (and attached patch).


regards,
Nikos
-------------- next part --------------
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index f8d2724..3787796 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -2801,11 +2801,11 @@ _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session,
   int ret = 0;
   cipher_suite_st *newSuite, cs;
   int newSuiteSize = 0, i;
-  gnutls_certificate_credentials_t x509_cred;
+  gnutls_certificate_credentials_t cert_cred;
   gnutls_kx_algorithm_t kx;
   int server = session->security_parameters.entity == GNUTLS_SERVER ? 1 : 0;
-  gnutls_kx_algorithm_t *alg;
-  int alg_size;
+  gnutls_kx_algorithm_t *alg = NULL;
+  int alg_size = 0;
 
   /* if we should use a specific certificate, 
    * we should remove all algorithms that are not supported
@@ -2813,29 +2813,30 @@ _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session,
    * method (CERTIFICATE).
    */
 
-  x509_cred =
+  cert_cred =
     (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
 							 GNUTLS_CRD_CERTIFICATE,
 							 NULL);
 
-  /* if x509_cred==NULL we should remove all X509 ciphersuites
+  /* If there are certificate credentials, find an appropriate certificate
+   * or disable them;
    */
-
   if (session->security_parameters.entity == GNUTLS_SERVER
-      && x509_cred != NULL)
+      && cert_cred != NULL)
     {
       ret = _gnutls_server_select_cert (session, requested_pk_algo);
       if (ret < 0)
 	{
 	  gnutls_assert ();
-	  return ret;
+	  _gnutls_x509_log("Could not find an appropriate certificate: %s\n", gnutls_strerror(ret));
+	  cert_cred = NULL;
 	}
     }
 
   /* get all the key exchange algorithms that are 
    * supported by the X509 certificate parameters.
    */
-  if ((ret =
+  if (cert_cred != NULL && (ret =
        _gnutls_selected_cert_supported_kx (session, &alg, &alg_size)) < 0)
     {
       gnutls_assert ();


More information about the Gnutls-dev mailing list