(D)TLS 1.2 Secure Renegotiation Application Data

One of the new features in wolfSSL 4.6.0 is the ability to process application data during a (D)TLS 1.2 secure renegotiation. The new functionality (added in commit 7c89d10e5362ec281ce61ff12f37a091aa124e98) allows users to send and receive their data during the re-handshake process. Sending data can be accomplished, when using non-blocking sockets, by calling the wolfSSL_write API during a secure renegotiation. To read data during a secure renegotiation, use the wolfSSL_read API.

The wolfSSL examples have been updated to test exchanging application data during a secure renegotiation. To enable and test this new feature, build wolfSSL 4.6.0 with the following commands:

./configure --enable-secure-renegotiation
make

Run the following TLS examples simultaneously in separate windows to demonstrate application data with secure renegotiation:

./examples/server/server -M -m -d -N
./examples/client/client -R -i scr-app-data -N

To run the same tests with DTLS add --enable-dtls to the configure parameters and add -u to both of the example parameters:

./configure --enable-secure-renegotiation --enable-dtls
make
./examples/server/server -M -m -d -N -u
./examples/client/client -R -i scr-app-data -N -u

Users who use secure renegotiation must also expect and handle a new error value. wolfSSL TLS API’s (wolfSSL_connect, wolfSSL_accept, wolfSSL_read, wolfSSL_write) may now return a failure and set the error code to APP_DATA_READY (retrievable by wolfSSL_get_error). This signals to the user that wolfSSL has received application data during a secure renegotiation. The user should immediately call wolfSSL_read to retrieve the received data. If wolfSSL_read is not called immediately after receiving the APP_DATA_READY error code then the data may be dropped if new application data is received. This applies to both TLS and DTLS.

An example connect loop using non-blocking sockets which processes application data during a secure renegotiation:

if ((ret = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS) {
    err = wolfSSL_get_error(ssl, 0);
    if (err == WOLFSSL_ERROR_WANT_READ ||
        err == WOLFSSL_ERROR_WANT_WRITE ||
        err == APP_DATA_READY) {
        do {
	    if (err == APP_DATA_READY) {
    	        if ((ret = wolfSSL_read(ssl, reply,
            	    sizeof(reply)-1)) < 0) {
        	    /* HANDLE ERROR */
    	        }
    	        printf("Received message during "
           	       "renegotiation: %s\n", reply);
	    }
	    err = 0;
	    if ((ret = wolfSSL_connect(ssl)) != WOLFSSL_SUCCESS) {
    	        err = wolfSSL_get_error(ssl, ret);
	    }
        } while (ret != WOLFSSL_SUCCESS &&
    	        (err == WOLFSSL_ERROR_WANT_READ ||
        	 err == WOLFSSL_ERROR_WANT_WRITE ||
        	 err == APP_DATA_READY));
	}
}

Please see the example/client/client.c and example/server/server.c files in the wolfSSL directory as a reference for how the APIs may be used. Contact wolfSSL at facts@wolfssl.com with any questions or comments!