What are your configure options?

Sometimes when using TLSv1.3 a server might still be using an older draft of TLSv1.3, and we'll get a version mismatch error.

That's good to hear you figured it out.

Are you using TLSv1.3 on your client?

29

(6 replies, posted in wolfSSL)

KamKon:

The set-non-blocking function is a do-nothing for TLS sessions, it is meant to be used for DTLS. (We have recently renamed it to reflect this.) For TLS connections, you just need to set the socket to be non-blocking. If the socket would block, wolfSSL_read() will return a WANT_READ error.

--John

I think it might be the root of it. If it cannot use the big integer math it cannot check the signatures on the certificates. Unfortunately, public key crypto is a memory hog.

Have you tried connecting to your server with our command line client from Windows, Linux, or macOS? Sometimes I find that web servers will return different certificate chains between connecting with a browser and from the command line tool. I believe that the web servers return a redirect or a JS that triggers a new connection from a CDN that is using a slightly different certificate chain with a different root CA certificate.

/* serialNumber Attribute*/
    NameAttrib* n;

        n = &myCertName.name[0];
        n->id   = ASN_SERIAL_NUMBER;
        n->type = CTC_PRINTABLE;
        n->sz   = sizeof("1801908070");
        XMEMCPY(n->value, "1801908070", sizeof("1801908070"));
/* serialNumber Attribute*/

Change both sizeof to strlen. sizeof a string includes the null terminator. The null terminator on the string is getting included in your name's serial number attribute. The name building function uses memcpy() not strcpy().

David is correct that CSRs do not have a Serial Number and they are added by the CA, there is a "serialnumber" name attribute for your use.

And the "sn" attribute is the surname of the owner of the certificate, I believe it is used when you have a certificate for email signing purposes.

Kaleb is out of the office right now. I'll try to help you in his place.

Are you using normal math or fast math? Does your build environment have a realloc() function set up? If you are setting USE_FAST_MATH, you won't need a realloc. Fast math puts preallocated large integers on the stack rather than allocating and reallocating memory to store the large integer.

--John

33

(4 replies, posted in wolfSSL)

We do have some pre-made support for MQX 4. The memory and network abstraction layers exist.

You add the CA certs and keys to the WOLFSSL_CTX you create. All WOLFSSL sessions created with that CTX will have access to the CA certs and keys.

What are you using to build the project? Are you using an IDE or just building from the command line using configure to set up the build?

You are loading the domain parameters dh_p and dh_g into keyA and then making the keypair {pubA,privA}. Then you load dh_key_der_1024 into keyB and using that as the domain parameters for making the keypair {pubB,privB}. For key agreement, both A and B need to be using the same domain parameters.

35

(4 replies, posted in wolfSSL)

Yes. You set up the wolfSSL context and it acts like a factory for making the wolfSSL session objects. If your device is being a client or server, you first establish the TCP connection with the peer, then assign your socket to the session. The I/O callback functions will use the socket to send and receive data. Depending on the RTOS, this may be a little more complicated than using the UNIX-style socket interface. We do have some code showing how to do an I/O callback in ThreadX/NetX. Then you'll need to monitor multiple sockets and call wolfSSL_read() if there is data waiting and wolfSSL_write() to send data.

Which RTOS are you using on your embedded device?

--John

36

(6 replies, posted in wolfSSL)

Did you come to a solution?

37

(6 replies, posted in wolfSSL)

Martin:

I do think that the external cache is what you are looking for. It allocates the space needed to store the WOLFSSL_SESSION, copies the session information from the SSL session in process, not the old cache copy that might get written over. And then calls your own new_sess_cb with a pointer to the SESSION to put the pointer wherever you want. That data will not be overwritten by any new connections.

If you pass the pointer to the WOLFSSL_SESSION record from the external cache callback to wolfSSL_i2d_SSL_SESSION() there won't be a race condition issue.

--John

38

(6 replies, posted in wolfSSL)

Martin:

You aren't missing anything. The session cache is mutex protected for reads and writes. The contents of the session cache may change. We implement the cache as a statically allocated hash table and we recommend setting the length and width to minimize collisions in the hashing. The protocol is tolerant of having a hash table miss or an outdated cache entry as the session ID will not match, the server will perform a full handshake instead. The cache data also has an expiration date (about 5 minutes).

This was a trade off for avoiding memory allocations and speed. A general purpose server should have the memory for a large cache for many inbound connections; and embedded server probably won't be able to handle many inbound connections so can get away with a much smaller cache.

As for the 5 minute expiration time, we designed around having a client connect to the server many times in a short period. This saves time on doing only one public key operation for a bunch of connections over a short period of time. The trade off is that the public key operation will have to happen, each time, for new connections over long periods of time.

--John

I was able to recreate some of your symptoms locally. We discovered some bugs in setting up the I/O callbacks in our example server and client.

The symptom I recreated was with the error -308 happening in the wolfSSL JNI client. The I/O callback sets the timeout on socket reads, initially, to 1 second. After the handshake finishes, the client is sending "Hello wolfssl" to the server. If you have the OpenSSL server running, it should display that string. When you finally get around to typing the response to the client, the client has timed out. On a timeout, you end up with the socket error you are seeing. (Internally the handshake is complete, so the read isn't retried.)

From what I could find about the socket library, you don't actually get non-blocking sockets in Java. You can set the timeout to a very small value.

In the MyRecvCallback (or what you are using), if the Timeout exception is caught, try returning WolfSSL.WOLFSSL_CBIO_ERR_WANT_READ. Then the read should return a WANT_READ error, which will let you try the read again until something is read.

Olle:

I'm sorry for the delay in replying.

I disagree that this is an interoperation issue between OpenSSL and wolfSSL. Our C based client is communicating with the OpenSSL server. I also tried the wolfSSL client with non-blocking sockets, and that worked. (It does print out a lot of WANT_READ errors, but it prints the server's response when I put one in.)

I am trying to run the JNI client now, and I'm having a different problem than you are reporting. I'm going to have to pull in my coworker who wrote the JNI code and see if we can figure this out.

And to commiserate with you, I am no expert at Java/JNI.

--John

And to expand on non-blocking sockets, our example client and server know how to deal with them. For DTLS, we use blocking sockets with timeouts, or optionally non-blocking sockets with some additional work. For the handshake in DTLS, you have to do timing for waiting for the peer to reply and to trigger retries. With blocking sockets the library takes care of that automatically. With non-blocking sockets, it is fairly application specific. So, if the functions wolfSSL_negotiate(), wolfSSL_accept(), wolfSSL_connect(), wolfSSL_read(), or wolfSSL_write() return and error, you need to check it with wolfSSL_get_error(). If it is WANT_READ or WANT_WRITE, you need to call the function again, and again, until it is successful or you get a different error. Those two are special error codes meaning the socket would block normally. You also need to tell the DTLS session it is non-blocking because the usual network stacks treat a WANT_READ the same way as a timeout; wolfSSL needs a hint as to what the socket error code meant.

What I think your JNI application is doing is sending client hello, and then waits on the socket, which is non-blocking, and you get a WANT_READ immediately. Since you didn't tell the wolfSSL session it was non-blocking, it immediately retried the client hello, and the WANT_READ error code was returned.

(David isn't working on this issue, I am. Don't wait for him.)

olle wrote:

I found out how to make the example client accept ipv6 addresses. I Just added the TEST_IPV6 flag to C_EXTRA_FLAGS, instead of CFLAGS.

C_EXTRA_FLAGS="-DTEST_IPV6"

Hope it helps someone else.

Adding --enable-ipv6 to the configure command line should have enabled the IPv6 support in the example client and server. Where did you add the line that prints out "Not defined [TEST_IPV6]"? When you use the configure option, it adds -DTEST_IPV6 to the CFLAGS option passed to GCC on compile. When you put it in C_EXTRA_FLAGS, it is added as a #define in options.h.


Are you using non-blocking sockets on your JNI client?

Remove "--enable-sniffer" from your configure and this command line test should work. (Also remove "--enable-sctp", it is only needed if you are using DTLS over SCTP.) The sniffer allows you to build an application that provides packet decoding in a fashion similar to Wireshark. It only works if you are using RSA key exchange.

Can you connect to the server using the wolfSSL example client? What I usually do for interop testing is:

Shell 1:
 

~/Code/wolfssl$ openssl s_server -accept 11111 -cert ./certs/server-ecc.pem -key ./certs/ecc-key.pem -dtls1

Shell 2:
 

~/Code/wolfssl$ ./examples/client/client -u -A ./certs/ca-ecc-cert.pem -v2

The server will show "hello wolfssl!" in shell 1. If you type something and press enter that text will show up on the client in shell 2.

There is an issue with time on platforms without 64-bit values. We added the guard TIME_T_NOT_LONG to work around that. On the configure command line add CPPFLAGS=-DTIME_T_NOT_LONG or #define it in your settings file.

The testsuite.test works on your Mac (along with the other test utilities). That's good to hear. I'm using a Mac as well.

You say the testsuite.test fails on your Arm board. I looked at the log you attached and there is an failure where we generate a date, covert it to a string, and compare it to an expected value. In file tests/api.c line 10685, could you output the value of the string "date_str"?

In your first post you listed your wolfSSL configure command. Is that what you are using on the ARM board or on your Mac? Is the ARM you are using 32-bit or 64-bit?

Olle:

Which version of wolfSSL are you using? Is it v3.13.0?

Digging into your capture files a couple things catch my interest. In dump.pcap, you have two client hello messages. The second one isn't a retransmission. It is the second client hello. It should only come in response to a hello verify request from the server, which your server doesn't send, and should be longer than the initial hello. I'd like to know why the client is doing that. I'm going to look at that some more. But, I'm not quite seeing that behavior here. My second client hello comes through as expected.

In your case, the client should NOT send a second hello message as your server isn't sending the hello verify request message. The server alert is due to it receiving two separate client hello messages with separate handshake message sequence numbers, and not expecting the second one because it didn't send the hello verify request.

Do you know why the server isn't sending the hello verify request? Is that an option you disabled? I'm going to try to hack my server so it doesn't send the hello verify request message. The client should be able to handle not getting it. (The client is required to respond to the message, but the server is not required to send it.)

--John

48

(12 replies, posted in wolfSSL)

Marco Wenzel wrote:

That is right. The server calls wolfSSH_stram_send() many times in order to send a huge amount of data, but without calling wolfSSH_stream_read() in between. But the fact is, that when it calls wolfSSH_stream_read() between all these send calls, it expects some data from the client. When the client is not sending any data except the window adjustment message, wolfSSH_stream_read() does not return and any following operation is blocked.

So what do you suggest to do in this case?

Are you using blocking or non-blocking sockets?

The example echoserver is using blocking sockets. The client drives the echoserver's behavior. You should use non-blocking sockets. The call to wolfSSH_stream_read() should return a WS_WANT_READ error if there isn't data available on the socket.


As far as the DoChannelRequest() issue, I agree with you on the solution to the problem. I'm adding this to my list.

49

(12 replies, posted in wolfSSL)

It looks like your server is sending data to the client and never stopping to receive messages from the client. You need to call wolfSSH_stream_read() once in a while as it processes the background bookkeeping messages like Channel Adjust Window.

50

(12 replies, posted in wolfSSL)

Could you enable debugging and see if DoChannelWindowAdjust() is called? It should report what the peer wants to add back to the window, the current peerWindowSz and the updated peerWindowSz.

The logging will produce a lot of noisy output. Could you send the log to me directly?