wolfSSL / wolfssl

The wolfSSL library is a small, fast, portable implementation of TLS/SSL for embedded devices to the cloud. wolfSSL supports up to TLS 1.3 and DTLS 1.3!
https://www.wolfssl.com
GNU General Public License v2.0
2.34k stars 830 forks source link

Link error when using user I/O #1536

Closed denravonska closed 6 years ago

denravonska commented 6 years ago

I have an AVR32 platform where I want to enable user I/O in wolfSSL to use in combination with wolfMQTT. When looking at the configure script it seems like the only way to get to the WOLFSSL_USER_IO define is to enable leanpsk which I've done. wolfSSL builds but linking the final binary fails with:

mqtt_socket.c:(.text+0x317): undefined reference to `wolfSSL_CTX_SetIORecv'
mqtt_socket.c:(.text+0x327): undefined reference to `wolfSSL_CTX_SetIOSend'
mqtt_socket.c:(.text+0x425): undefined reference to `wolfSSL_SetIOReadCtx'
mqtt_socket.c:(.text+0x431): undefined reference to `wolfSSL_SetIOWriteCtx'
mqtt_socket.c:(.text+0x43f): undefined reference to `wolfSSL_set_using_nonblock'
mqtt_socket.c:(.text+0x498): undefined reference to `wolfSSL_CTX_set_verify'

where mqtt_socket.c comes from wolfMQTT. Is there a better/proper way of enabling user I/O functions that I should be using?

dgarske commented 6 years ago

Hi denravonska,

Thanks for the question and interest in wolfSSL/wolfMQTT!

You do need those API's and they should be available by default if building wolfSSL correctly. In fact WOLFSSL_LEANPSK will remove wolfSSL_set_using_nonblock. Are you including src/*.c files in your build?

If you are building these sources yourself and not using the autoconf ./configure then you should make sure and define the pre-processor macro WOLFSSL_USER_SETTINGS and include a user_settings.h file. This file allows you to setup your library configuration in a single place. We have templates such as this one you can use: https://github.com/wolfSSL/wolfssl/blob/master/IDE/GCC-ARM/Header/user_settings.h

Another possibility is the wolfssl/wolfcrypt/visibility.h section, which sets the API's that are made visible and hidden. You might try adding the preprocessor macro BUILDING_WOLFSSL.

If you are building with ./configure and cross-compiling please let me know the command you are using, so we can look into it.

Thanks, David Garske, wolfSSL

denravonska commented 6 years ago

I wanted to avoid user_settings.h when possible, so I am using currently using configure using the following options:

OPTS = \
   --prefix=$${DESTDIR} \
   --enable-static \
   --enable-leanpsk \
   --enable-smallstack \
   --enable-ecc \
   --disable-shared \
   --disable-examples \
   --disable-fips \
   --disable-selftest \
   --disable-dh \
   --disable-harden \
   --enable-tlsv10 \
   CFLAGS="\"$${QMAKE_CFLAGS}\""

I build it the same way for PC and AVR32, so on the PC where I'm currently able to test the CFLAGS variable is just "-pipe -std=gnu99".

I'm wondering if it's just a matter of link order though as libwolfssl.a is linked before libwolfmqtt.a in the Makefile qmake generates.

dgarske commented 6 years ago

Hi denravonska,

I can reproduce. The issue is leanpsk is defining NO_CERTS which is disabling required functionality.

WOLFSSL:

./configure --enable-leanpsk --enable-smallstack --enable-ecc --disable-examples --disable-fips --disable-selftest --disable-dh --disable-harden --enable-tlsv10 && make
sudo make install

cat ./wolfssl/options.h | grep NO_CERTS
#undef  NO_CERTS
#define NO_CERTS

WOLFMQTT:

examples/aws/awsiot.c:206:14: error: implicit declaration of function 'wolfSSL_CTX_load_verify_buffer' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        rc = wolfSSL_CTX_load_verify_buffer(client->tls.ctx,
             ^
  CC       examples/examples_aws_awsiot-mqttexample.o
examples/aws/awsiot.c:206:14: error: this function declaration is not a prototype [-Werror,-Wstrict-prototypes]
examples/aws/awsiot.c:211:18: error: implicit declaration of function 'wolfSSL_CTX_use_certificate_buffer' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
            rc = wolfSSL_CTX_use_certificate_buffer(client->tls.ctx,
                 ^
examples/aws/awsiot.c:211:18: note: did you mean 'wolfSSL_X509_load_certificate_buffer'?
/usr/local/include/wolfssl/ssl.h:1514:27: note: 'wolfSSL_X509_load_certificate_buffer' declared here
WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer(
                          ^
examples/aws/awsiot.c:211:18: error: this function declaration is not a prototype [-Werror,-Wstrict-prototypes]
            rc = wolfSSL_CTX_use_certificate_buffer(client->tls.ctx,
                 ^
examples/aws/awsiot.c:217:18: error: implicit declaration of function 'wolfSSL_CTX_use_PrivateKey_buffer' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
            rc = wolfSSL_CTX_use_PrivateKey_buffer(client->tls.ctx,
                 ^
examples/aws/awsiot.c:217:18: note: did you mean 'wolfSSL_CTX_use_certificate_buffer'?
examples/aws/awsiot.c:211:18: note: 'wolfSSL_CTX_use_certificate_buffer' declared here
            rc = wolfSSL_CTX_use_certificate_buffer(client->tls.ctx,
                 ^
examples/aws/awsiot.c:217:18: error: this function declaration is not a prototype [-Werror,-Wstrict-prototypes]
            rc = wolfSSL_CTX_use_PrivateKey_buffer(client->tls.ctx,

You can build using this to achieve the same settings, minus the NO_CERTS:

./configure --enable-nullcipher --enable-singlethreaded --disable-aes --disable-aesgcm --disable-filesystem --disable-rsa --disable-dh --disable-md5 --disable-sha --disable-errorstrings --enable-smallstack --enable-ecc --enable-lowresource --disable-examples --disable-fips --disable-selftest --disable-harden --enable-tlsv10 CFLAGS="-DWOLFSSL_STATIC_PSK -DNO_WRITEV -DWOLFSSL_USER_IO -DALT_ECC_SIZE" && make

Thanks, David Garske, wolfSSL

denravonska commented 6 years ago

That solved some of the issues:

mqtt_socket.c:(.text+0x317): undefined reference to `wolfSSL_CTX_SetIORecv'
mqtt_socket.c:(.text+0x327): undefined reference to `wolfSSL_CTX_SetIOSend'
mqtt_socket.c:(.text+0x425): undefined reference to `wolfSSL_SetIOReadCtx'
mqtt_socket.c:(.text+0x431): undefined reference to `wolfSSL_SetIOWriteCtx'

It looks like the symbol is in the libwolfssl.a library:

objdump -S SetIORecv bin/unix/debug/stub/lib/libwolfssl.a  | less

0000000000000020 <wolfSSL_SetIOReadCtx>:
  20:   48 89 77 20             mov    %rsi,0x20(%rdi)
  24:   c3                      retq   
  25:   90                      nop
  26:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  2d:   00 00 00 
dgarske commented 6 years ago

Hi denravonska,

That sounds like an issue with the rename we did in this commit: https://github.com/wolfSSL/wolfssl/commit/040e0ab752fc080ca9408f5d1d570736acc43b02

The correct function name is wolfSSL_CTX_SetIORecv, but we have a define to map the old name as #define wolfSSL_SetIOSend wolfSSL_CTX_SetIOSend.

Are you using an older version of wolfSSL that still has the name as wolfSSL_SetIOSend? If so you'll need to remap those manually to accommodate the older wolfSSL with the newer wolfMQTT.

David

denravonska commented 6 years ago

I was missing some commits but the problem was the good old library link order issue. It links properly now, thanks!