From nicolas at babelouest.org Sun Oct 7 14:18:10 2018 From: nicolas at babelouest.org (Nicolas Mora) Date: Sun, 7 Oct 2018 08:18:10 -0400 Subject: [gnutls-help] Problems with async read on a tls session Message-ID: <20cc771e-2686-167a-75c2-fb7b38d23758@babelouest.org> Hello, I'm implementing a websocket client library over https, so I need to run asynchronous read on the gnutls session to be able to send messages while I'm receiving them. I'm having trouble detecting if the socket has incoming activity, gnutls_record_check_pending, it always return 0. I'm based on the "Client example with X.509 certificate support" to make my http connection, so the tcp socket is basically initiated like that (pseudo-code): tcp_sock = socket(AF_INET, SOCK_STREAM, 0); connect(tcp_sock, (struct sockaddr *)&server , sizeof(server)); gnutls_transport_set_int(gnutls_session, tcp_sock); gnutls_handshake_set_timeout(gnutls_session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); What do I miss to have a working async connection? Thanks in advance /Nicolas From contact at simonbernard.eu Tue Oct 16 16:36:27 2018 From: contact at simonbernard.eu (Simon Bernard) Date: Tue, 16 Oct 2018 16:36:27 +0200 Subject: [gnutls-help] DTLS Role Exchange Message-ID: <7193c6eb-82b6-7f66-7f67-f4e4f7d58479@simonbernard.eu> Hi, I would like to know if this is possible to make gnuTLS works as a DTLS client and server on the same address/port? (using PSK, RPK and X509) Maybe this sounds a bit strange and I will give some context to understand. I?m working on LWM2M protocol which is based on CoAP and DTLS. LWM2M supports PSK, RPK and X509. I?m currently searching how to handle server failover in ?server initiated mode? . Here is a brief explanation of how it works. 1. The device has an static/fixed IP address/port. 2. The device establishes DTLS connection. 3. The device registers to the server (server has also a static/fixed IP address/port) 4. Later, server sends request to a registered client. If the server still have a DTLS connection to the device there is no issue ! Now imagine the DTLS connection is lost (e.g. crash/reboot), we still know the device address (registration is persisted) but we don?t have any DTLS connection to it. So a solution could be to make the LWM2M server act as a DTLS client and so the LWM2M device should act as a DTLS server. Just to let you know, the java scandium library from californium can act like this. Here a wireshark capture done using scandium at device(port 36038) and server(port 5684) side. (using PSK) |No. Time Source Destination SrcPort DesPort Protocol Length Info 1 0.000000000 127.0.0.1 127.0.0.1 36038 5684 DTLSv1.2 133 Client Hello 2 0.000359644 127.0.0.1 127.0.0.1 5684 36038 DTLSv1.2 102 Hello Verify Request 3 0.005001722 127.0.0.1 127.0.0.1 36038 5684 DTLSv1.2 165 Client Hello 4 0.005626495 127.0.0.1 127.0.0.1 5684 36038 DTLSv1.2 162 Server Hello, Server Hello Done 5 0.042162424 127.0.0.1 127.0.0.1 36038 5684 DTLSv1.2 147 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message 6 0.061195906 127.0.0.1 127.0.0.1 5684 36038 DTLSv1.2 109 Change Cipher Spec, Encrypted Handshake Message 7 0.062815631 127.0.0.1 127.0.0.1 36038 5684 DTLSv1.2 179 Application Data (LWM2M REGISTER request from device) 8 0.081334961 127.0.0.1 127.0.0.1 5684 36038 DTLSv1.2 97 Application Data (LWM2M REGISTER response from server) 9 8.483287786 127.0.0.1 127.0.0.1 5684 36038 DTLSv1.2 90 Application Data (LWM2M READ request from server) 10 8.496936449 127.0.0.1 127.0.0.1 36038 5684 DTLSv1.2 213 Application Data (LWM2M READ response from client) ### LWM2M Server (5684) Reboot and so lost its DTLS connection to LWM2M device (36038), ... ### ... LWM2M Server will establish a new connection and so act as a DTLS client. 11 24.079310967 127.0.0.1 127.0.0.1 5684 36038 DTLSv1.2 151 Client Hello 12 24.080362291 127.0.0.1 127.0.0.1 36038 5684 DTLSv1.2 102 Hello Verify Request 13 24.083452354 127.0.0.1 127.0.0.1 5684 36038 DTLSv1.2 183 Client Hello 14 24.085327257 127.0.0.1 127.0.0.1 36038 5684 DTLSv1.2 162 Server Hello, Server Hello Done 15 24.110637371 127.0.0.1 127.0.0.1 5684 36038 DTLSv1.2 147 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message 16 24.111419901 127.0.0.1 127.0.0.1 36038 5684 DTLSv1.2 109 Change Cipher Spec, Encrypted Handshake Message 17 24.113519322 127.0.0.1 127.0.0.1 5684 36038 DTLSv1.2 92 Application Data (LWM2M READ request from server) 18 24.114368265 127.0.0.1 127.0.0.1 36038 5684 DTLSv1.2 108 Application Data (LWM2M READ response from client) | Is mailing list the right way to ask this question ? or should I ask this kind of question on gitlab ? Simon -------------- next part -------------- An HTML attachment was scrubbed... URL: From nuncestbibendum at excite.com Tue Oct 23 21:59:02 2018 From: nuncestbibendum at excite.com (Full Name) Date: Tue, 23 Oct 2018 15:59:02 -0400 Subject: [gnutls-help] Supplying a PIN for an HSM with PKCS 11 Message-ID: <20181023155902.24377@web001.roc2.bluetie.com> I am trying to understand how to supply a PIN to generate a key pair in an HSM using the PKCS #11 interface in GnuTLS - and, so far, failing miserably. My function does (in essence) the following: 1) Initialize the PKCS #11 interface with gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL) 2) Add the provider with gnutls_pkcs11_add_provider("", NULL) ; where is the pathname of the shared library for the client component of the HSM. After the above, I tried to generate a keypair as follows: gnutls_pkcs11_privkey_generate3(, GNUTLS_PK_RSA, 2048, "First Key", &cid, 0, &pubKey, 0, GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE | GNUTLS_PKCS11_OBJ_FLAG_LOGIN) ; where is the URL for the HSM that I am using. The above doesn't work. Both the init and provider calls do work, but generate3 returns error -300 - PKCS11 error. This is not surprising, for one needs to supply credentials in order to access the HSM. The GnuTLS documentation says that, when a PIN is required for PKCS 11 operations, one should install a callback by means of gnutls_pkcs11_set_pin_function(). I added such a thing, but the callback does not get invoked. Even if it were, I am confused as to where the arguments for the callback are coming from. The callback has the prototype typedef int (*gnutls_pin_callback_t) (void *userdata, int attempt, const char *token_url, const char *token_label, unsigned int flags, char *pin, size_t pin_max); Who is supplying them? SInce they involve the PIN (among other things) I would have thought it is up to me. I don't know how. And, as I mentioned, the callback does not get invoked when I call the generate3 function. Any help to clarify these issues would be much appreciated. From nuncestbibendum at excite.com Fri Oct 26 22:11:44 2018 From: nuncestbibendum at excite.com (Full Name) Date: Fri, 26 Oct 2018 16:11:44 -0400 Subject: [gnutls-help] Supplying a PIN for an HSM with PKCS #11 Message-ID: <20181026161144.25887@web003.roc2.bluetie.com> In case anyone cares (which I doubt, bearing in mind the negligible volume of traffic in this forum): To answer my own question, the callback that I mentioned is expected to supply the PIN itself, be directly or by invoking some other function, to e.g. prompt a user at the command line for a PIN. The PIN must then be copied to the input pin buffer, with the length constraint specified by pin_max. It would be nice if the gnutls documentation were to include a description similar to this - it's just a couple of lines. From carlo at alinoe.com Sat Oct 27 00:20:13 2018 From: carlo at alinoe.com (Carlo Wood) Date: Sat, 27 Oct 2018 00:20:13 +0200 Subject: [gnutls-help] Asynchronous operation. Message-ID: <20181027002013.3e41da93@hikaru> Hello list, I wrote a library (GPL) that aims for not creating more threads than CPU cores. This library provides a thread pool and does all timer and socket/filedescriptor monitoring. At the moment I can create a TCP connection and read/write data in a 100% non-blocking way by means of callback functions (well, not really - but that would be the same); when it is possible to write data and I have data, a function is called that allows me to do that: write the data. When a socket has data then a function is called that allows me to read that data. I now wish to add TLS layer to this. In order to (still) never put a thread to sleep (except a specialized one that does the calls to epoll) I need this gnutls to provided the following interface: it should call a callback function (that I configured) to tell me that it is interested in reading and/or writing (not to get actual data or write it - just to tell me that it is ready to do so). When there is nothing to do for the library, it should return from whatever function I called (it should never go to sleep internally, or internally wait for anything (like sockets or a timer)). When the library indicates it is interested in reading or writing data, I will call functions of the library as soon as this is possible; ie, when the library wants to read I can provide it a non-blocking fd that it can read from, or I can do reading and buffering myself and call a function of the library providing a buffer pointer and the number of characters available in the buffer. [ Ideal would be when the gnutls also provided an end-of-message detection function that I could use to know when I have a complete message, so that my library can provide strictly contiguous messages, but this is not absolutely necessary (the result I'd expect is that the library will make a copy of the data that I provide; which is slower, but that is ok I suppose). If each message always starts with a header that contains the total length of that message then I provide the end-of-message decoder myself of course. ] Reading https://gnutls.org/manual/gnutls.html#Asynchronous-operation I'm a bit lost however... it seems kind of clear, but not entirely ;). Is there client example code available somewhere that shows how this can be done? Many thanks for your time, Carlo Wood PS In case anyone is interested; my library in question exists of many git submodules, each of which alone hardly ever make a whole; the only currently existing repository that brings it all together is https://github.com/CarloWood/ai-statefultask-testsuite and the submodule that I'd add the TLS to will be https://github.com/CarloWood/evio PS2 About the end-of-message detection: I don't want to ever copy data around in memory unless absolutely necessary: data is read from a socket into a buffer that is considerably larger than the average message size; whenever all data in the buffer is processed, it starts again at the beginning of the buffer. Only in the event that data comes in faster than it can be processed it might happen that a message wraps over the end into a newly allocated block. In that case (which should seldom happen) I prefer to make a copy into a new buffer to make the message contiguous because decoding contiguous messages is usually much faster and normally they are contiguous anyway. In order to know if a (new) message wraps over the end of the current buffer I simply look if 1) the current memory block is full, 2) there is no 'end-of-message' between where we are and the end of the current block. This can of course be done much much faster than decoding the message, especially for binary protocols that simply have the length of a message in the header of each message (or have fixed size messages, etc). -- Carlo Wood