Wolfssl [version 0.0.2; documenting]

So the define didn’t help, but changing printf to sprintf did the trick! Now it compiles and runs, but it does not connect. That’s quite a big jump forward! Will keep working on this later tonight. Thanks Rob! :slight_smile:

Those symbol errors are nefarious. Not a lot of information on where they might be originating. I am thinking if we got an object/symbol dump for each object file, these could be found more easily. I may send a feature request later.

I’ll have a chance in the next day or so to take a look. I’ll merge the PR and try.

So, I merged the PR. I had to move some files around to actually compile the mqtt library with the ssl library. There is a build script in the example directory. You will need to edit it a bit to match what your compiling for.

mkbin:
  -b compile the binary in the cloud
  -f if compile is successful, flash via DFU-UTIL
  -s if compile successful, flash via serial if used with -f
  -m if compile successful, after attempting to flash, will
       automatically drop you into serial monitor mode with --follow

If compile fails, errors are stashed to err.txt.

So, I don’t think you were pulling in all the code which is why it looks like it succeeded and did not connect. There are more symbol errors to navigate unfortunately.

/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
collect2: error: ld returned 1 exit status
../../../build/module.mk:222: recipe for target 'target/workspace.elf' failed
make[1]: *** [target/workspace.elf] Error 1
make[1]: Leaving directory '/firmware/modules/photon/user-part'
../build/recurse.mk:11: recipe for target 'modules/photon/user-part' failed
make: *** [modules/photon/user-part] Error 2
Compile failed.  Errors captured in err.txt.

More later…

Finally got a little bit of time to move a little further on this. I finally have a working example of AWS IoT to verify that when we get the wolfmqtt working that things are really working. Not only do we have to get the client working, we have to encode the client certificates.

wolfmqtt

  • Create a SSL context with RootCA, Client Cert & Priv Cert from AWS IoT
  • Use the SSL context to connect to AWS IoT and perform the requested work

I am using a combination of python from a hackster.io project and curl so I can get a handle on what wolfssl/wolfmqtt need to do to initiate a payload to AWS IoT.

Here is the hackster link. This uses “Python and Paho for MQTT with AWS IoT”.

Now on to completing the wolfmqtt port and seeing if we can get data back.

The payload can be anything, but I used an example from the AWS documentation. I am using a different thingy. The naming is up to you.

curl --tlsv1.2 --cacert ./aws-iot-rootCA.crt --cert ./cert.pem --key ./privkey.pem\
  -X POST -d "{ \"serialNumber\": \"G030JF053216F1BS\", \"clickType\": \"SINGLE\", \"batteryVoltage\": \"2000mV\" }" "https://data.iot.us-west-2.amazonaws.com:8443/topics/temperatureA?qos=1"

If all goes well, the receiver gets a payload:

[cermak@localhost python-paho-mqtt-for-aws-iot]$ python awsiotsub.py 
Connection returned result: 0
topic: temperatureA
payload: { "serialNumber": "G030JF053216F1BS", "clickType": "SINGLE", "batteryVoltage": "2000mV" }

I haven’t figure out how to view this payload on AWS IoT, but I can at least see the packet via CloudWatch.

2017-07-15 02:06:30.857 TRACEID:8afa0c4b-6390-cdee-1002-c90d55a4d09d PRINCIPALID:752497542b54204429ce0b82a081b83e8603828e44689547ab73ceef3a0a83f7 [INFO] EVENT:PublishEvent TOPICNAME:temperatureA MESSAGE:PublishIn Status: SUCCESS
2017-07-15 02:06:30.857 TRACEID:8afa0c4b-6390-cdee-1002-c90d55a4d09d PRINCIPALID:752497542b54204429ce0b82a081b83e8603828e44689547ab73ceef3a0a83f7 [INFO] EVENT:PublishEvent MESSAGE: IpAddress: 216.115.122.132 SourcePort: 39856
1 Like

I am in a compiler bind. Any helpful hints? Any way out? I have also switched to performing a local build on the mac.

The offending header file is ssl.h via the wolfssl library. Using the wolfssl library on its own works with the “application.h” in ssl.h, but not when both libraries are built together. My last resort is just to manually define it in the header file. I don’t like stubbing things like that.

If I do not include an #include "application.h", I see this error:

mkdir -p ../build/target/user/platform-6-m/wolfmqtt/src/
arm-none-eabi-gcc -DSTM32_DEVICE -DSTM32F2XX -DPLATFORM_THREADING=1 -DPLATFORM_ID=6 -DPLATFORM_NAME=photon -DUSBD_VID_SPARK=0x2B04 -DUSBD_PID_DFU=0xD006 -DUSBD_PID_CDC=0xC006 -DSPARK_PLATFORM -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb -DINCLUDE_PLATFORM=1 -DPRODUCT_ID=6 -DPRODUCT_FIRMWARE_VERSION=65535 -DUSE_STDPERIPH_DRIVER -DDFU_BUILD_ENABLE -DSYSTEM_VERSION_STRING=0.6.2 -DRELEASE_BUILD -I./inc -I../wiring/inc -I../system/inc -I../services/inc -I../communication/src -I../hal/inc -I../hal/shared -I../hal/src/photon -I../hal/src/stm32f2xx -I../hal/src/stm32 -I../hal/src/photon/api -I../platform/shared/inc -I../platform/MCU/STM32F2xx/CMSIS/Include -I../platform/MCU/STM32F2xx/CMSIS/Device/ST/Include -I../platform/MCU/STM32F2xx/SPARK_Firmware_Driver/inc -I../platform/MCU/shared/STM32/inc -I../platform/MCU/STM32F2xx/STM32_StdPeriph_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_Device_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_Host_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc -I../dynalib/inc -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/inc -I./libraries -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I. -MD -MP -MF ../build/target/user/platform-6-m/wolfmqtt/src/mqttclient.o.d -ffunction-sections -fdata-sections -Wall -Wno-switch -Wno-error=deprecated-declarations -fmessage-length=0 -fno-strict-aliasing -DSPARK=1 -DPARTICLE=1 -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 -DSTART_YMODEM_FLASHER_SERIAL_SPEED=28800 -DSPARK_PLATFORM_NET=BCM9WCDUSI09 -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc  -DLOG_INCLUDE_SOURCE_INFO=1 -DPARTICLE_USER_MODULE -DUSE_THREADING=0 -DUSE_THREADING=0 -DUSE_SPI=SPI -DUSE_CS=A2 -DUSE_SPI=SPI -DUSE_CS=A2 -DUSER_FIRMWARE_IMAGE_SIZE=0x20000 -DUSER_FIRMWARE_IMAGE_LOCATION=0x80A0000 -DMODULAR_FIRMWARE=1 -DMODULE_VERSION=4 -DMODULE_FUNCTION=5 -DMODULE_INDEX=1 -DMODULE_DEPENDENCY=4,2,108 -D_WINSOCK_H -D_GNU_SOURCE -DLOG_MODULE_CATEGORY="\"app\""  -fno-exceptions -fno-rtti -fcheck-new -std=gnu++11 -c -o ../build/target/user/platform-6-m/wolfmqtt/src/mqttclient.o /Users/cermak/Documents/src/wolfmqtt/src/mqttclient.cpp
In file included from /Users/cermak/Documents/src/wolfmqtt/src/mqttclient.cpp:7:0:
/Users/cermak/Documents/src/wolfmqtt/inc/wolfssl/ssl.h:2329:13: error: 'size_t' does not name a type
 WOLFSSL_API size_t SSL_get_finished(const WOLFSSL *s, void *buf, size_t count);
             ^
/Users/cermak/Documents/src/wolfmqtt/inc/wolfssl/ssl.h:2330:13: error: 'size_t' does not name a type
 WOLFSSL_API size_t SSL_get_peer_finished(const WOLFSSL *s, void *buf, size_t count);
             ^

If I include the #include "application.h", I see this error:

mkdir -p ../build/target/user/platform-6-m/wolfmqtt/src/
arm-none-eabi-gcc -DSTM32_DEVICE -DSTM32F2XX -DPLATFORM_THREADING=1 -DPLATFORM_ID=6 -DPLATFORM_NAME=photon -DUSBD_VID_SPARK=0x2B04 -DUSBD_PID_DFU=0xD006 -DUSBD_PID_
CDC=0xC006 -DSPARK_PLATFORM -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb -DINCLUDE_PLATFORM=1 -DPRODUCT_ID=6 -DPRODUCT_FIRMWARE_VERSION=65535 -DUSE_STDPERIPH_DRIVER -D
DFU_BUILD_ENABLE -DSYSTEM_VERSION_STRING=0.6.2 -DRELEASE_BUILD -I./inc -I../wiring/inc -I../system/inc -I../services/inc -I../communication/src -I../hal/inc -I../hal/shared -I../hal/src/photon -I../hal/src/stm32f2xx -I../hal/src/stm32 -I../hal/src/photon/api -I../platform/shared/inc -I../platform/MCU/STM32F2xx/CMSIS/Include -I../platform/MCU/STM32F2xx/CMSIS/Device/ST/Include -I../platform/MCU/STM32F2xx/SPARK_Firmware_Driver/inc -I../platform/MCU/shared/STM32/inc -I../platform/MCU/STM32F2xx/STM32_StdPeriph_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_Device_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_Host_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc -I../dynalib/inc -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/inc -I./libraries -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I. -MD -MP -MF ../build/target/user/platform-6-m/wolfmqtt/src/internal.o.d -ffunction-sections -fdata-sections -Wall -Wno-switch -Wno-error=deprecated-declarations -fmessage-length=0 -fno-strict-aliasing -DSPARK=1 -DPARTICLE=1 -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 -DSTART_YMODEM_FLASHER_SERIAL_SPEED=28800 -DSPARK_PLATFORM_NET=BCM9WCDUSI09 -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc  -DLOG_INCLUDE_SOURCE_INFO=1 -DPARTICLE_USER_MODULE -DUSE_THREADING=0 -DUSE_THREADING=0 -DUSE_SPI=SPI -DUSE_CS=A2 -DUSE_SPI=SPI -DUSE_CS=A2 -DUSER_FIRMWARE_IMAGE_SIZE=0x20000 -DUSER_FIRMWARE_IMAGE_LOCATION=0x80A0000 -DMODULAR_FIRMWARE=1 -DMODULE_VERSION=4 -DMODULE_FUNCTION=5 -DMODULE_INDEX=1 -DMODULE_DEPENDENCY=4,2,108 -D_WINSOCK_H -D_GNU_SOURCE -DLOG_MODULE_CATEGORY="\"app\""  -fno-exceptions -fno-rtti -fcheck-new -std=gnu++11 -c -o ../build/target/user/platform-6-m/wolfmqtt/src/internal.o /Users/cermak/Documents/src/wolfmqtt/src/internal.cpp
In file included from ../services/inc/service_debug.h:34:0,
                 from ../services/inc/debug.h:1,
                 from ../wiring/inc/spark_wiring.h:36,
                 from ./inc/application.h:40,
                 from /Users/cermak/Documents/src/wolfmqtt/inc/wolfssl/ssl.h:70,
                 from /Users/cermak/Documents/src/wolfmqtt/inc/wolfssl/internal.h:29,
                 from /Users/cermak/Documents/src/wolfmqtt/src/internal.cpp:32:
../services/inc/logging.h:260:1: error: template with C linkage
 template<typename T>

Hello @cermak and @jenschr

Wondering how your efforts are coming?
Having an operational SSL Client ported over would be a great step forward.

Thanks in advance.

@jimini - It is slow going. The bare SSL client I believe is working. Adding the mqtt client (wolfmqtt) using SSL is proving problematic. What I am doing now is simply pulling mqtt items into the operational wolfssl client piecemeal to be sure things compile all along the way. The two groups of headers for wolfssl and wolfmqtt do not play nicely with the Particle headers (see prior post) – so there will be a bit of refactoring needed once I understand how all the code interacts with each other.

If you have the time to write your own mqtt library with a well understood API, then you can begin using the SSL client right away. I believe the CA, client certificate and private key can be loaded into the wolfssl client to provide the necessary handshake to AWS IoT. Once that is done, you can just work with the raw API for AWS IoT.

This is a volunteer effort for me. The effort has been slowed down substantially as I’ve been recently brought back into the workforce. As I make progress, I will be updating this post & github and the three or four posts I have going in the forum. I am pretty deep down the rabbit hole. It continues to be fun project.

The only real concern for this port is the memory footprint. The resulting firmware will only leave a small amount of space for custom code. @jenschr has a compelling hardware solution that could solve some of the space utilization. None of this does any good, if the software isn’t there.

More later as progress continues.

Edit: I’ve been working on this for so long, I almost forgot the original motivation for this project. For the greenhouse, I am pushing data to Ubidots via other means. As sooo many suggest, we can just use the Pub/Sub technology provided. I like direct means as much as possible. So, the original motivation is to get a SSL client working and improve the Ubidots library so I can push data back and forth using the API via https://things.ubidots.com.

1 Like

Thanks @cermak

Heck, even an operational SSL client would let me talk direct to my API/Lambda… is your repo runnable, and what are you using for your build tool-chain?

@jimini - The repo is setup to compile using the particle CLI.

If you clone the repo:

REPO : github.com/jr3cermak/particle/tree/master/libraries/wolfssl

Move the wolfssl directory into a working particle CLI structure. For the Mac, the typical path is ${HOME}/Particle/libraries. Move the wolfssl directory in there, cd to libraries/wolfssl and

$ particle compile photon examples/wolfssl_client/wolfssl_client.ino

Compiling code for photon

Including:
    examples/wolfssl_client/wolfssl_client.ino
    library.properties
    src/asm.cpp
    src/aes.cpp
    src/arc4.cpp
    src/async.cpp
    src/camellia.cpp
    src/asn.cpp
    src/blake2b.cpp
    src/chacha.cpp
    src/chacha20_poly1305.cpp
    src/cmac.cpp
    src/compress.cpp
    src/coding.cpp
    src/curve25519.cpp
    src/crl.cpp
    src/des3.cpp
    src/ecc.cpp
    src/dsa.cpp
    src/dh.cpp
    src/ecc_fp.cpp
    src/ed25519.cpp
    src/fe_operations.cpp
    src/error.cpp
    src/fe_low_mem.cpp
    src/ge_operations.cpp
    src/ge_low_mem.cpp
    src/hash.cpp
    src/hc128.cpp
    src/integer.cpp
    src/internal.cpp
    src/hmac.cpp
    src/idea.cpp
    src/io.cpp
    src/keys.cpp
    src/logging.cpp
    src/md2.cpp
    src/md4.cpp
    src/md5.cpp
    src/memory.cpp
    src/pkcs12.cpp
    src/misc.cpp
    src/ocsp.cpp
    src/pkcs7.cpp
    src/poly1305.cpp
    src/pwdbased.cpp
    src/random.cpp
    src/rabbit.cpp
    src/ripemd.cpp
    src/rsa.cpp
    src/sha256.cpp
    src/sha512.cpp
    src/sha.cpp
    src/sniffer.cpp
    src/signature.cpp
    src/srp.cpp
    src/ssl.cpp
    src/tfm.cpp
    src/tls.cpp
    src/wc_port.cpp
    src/wc_encrypt.cpp
    src/wolfevent.cpp
    src/wolfmath.cpp
    src/wolfssl/callbacks.h
    src/wolfcrypt/src/misc.c
    src/wolfssl/crl.h
    src/wolfssl/certs_test.h
    src/wolfssl/internal.h
    src/wolfssl/error-ssl.h
    src/wolfssl/io.h
    src/wolfssl/include.am
    src/wolfssl/ocsp.h
    src/wolfssl/options.h
    src/wolfssl/options.h.in
    src/wolfssl/sniffer.h
    src/wolfssl/sniffer_error.h
    src/wolfssl/sniffer_error.rc
    src/wolfssl/ssl.h
    src/wolfssl/version.h.in
    src/wolfssl/version.h
    src/wolfssl/test.h
    src/wolfssl/openssl/aes.h
    src/wolfssl/openssl/asn1.h
    src/wolfssl/openssl/bio.h
    src/wolfssl/openssl/bn.h
    src/wolfssl/openssl/des.h
    src/wolfssl/openssl/dh.h
    src/wolfssl/openssl/dsa.h
    src/wolfssl/openssl/ec.h
    src/wolfssl/openssl/ec25519.h
    src/wolfssl/openssl/crypto.h
    src/wolfssl/openssl/ed25519.h
    src/wolfssl/openssl/ecdh.h
    src/wolfssl/openssl/engine.h
    src/wolfssl/openssl/ecdsa.h
    src/wolfssl/openssl/hmac.h
    src/wolfssl/openssl/include.am
    src/wolfssl/openssl/evp.h
    src/wolfssl/openssl/md4.h
    src/wolfssl/openssl/md5.h
    src/wolfssl/openssl/lhash.h
    src/wolfssl/openssl/err.h
    src/wolfssl/openssl/conf.h
    src/wolfssl/openssl/ocsp.h
    src/wolfssl/openssl/opensslv.h
    src/wolfssl/openssl/pkcs12.h
    src/wolfssl/openssl/ossl_typ.h
    src/wolfssl/openssl/ripemd.h
    src/wolfssl/openssl/pem.h
    src/wolfssl/openssl/rsa.h
    src/wolfssl/openssl/ssl.h
    src/wolfssl/openssl/sha.h
    src/wolfssl/openssl/opensslconf.h
    src/wolfssl/openssl/rand.h
    src/wolfssl/openssl/stack.h
    src/wolfssl/openssl/ui.h
    src/wolfssl/openssl/x509.h
    src/wolfssl/openssl/ssl23.h
    src/wolfssl/openssl/x509v3.h
    src/wolfssl/wolfcrypt/aes.h
    src/wolfssl/wolfcrypt/arc4.h
    src/wolfssl/wolfcrypt/asn.h
    src/wolfssl/wolfcrypt/asn_public.h
    src/wolfssl/wolfcrypt/blake2-impl.h
    src/wolfssl/wolfcrypt/blake2-int.h
    src/wolfssl/wolfcrypt/async.h
    src/wolfssl/wolfcrypt/blake2.h
    src/wolfssl/wolfcrypt/camellia.h
    src/wolfssl/wolfcrypt/chacha.h
    src/wolfssl/wolfcrypt/chacha20_poly1305.h
    src/wolfssl/wolfcrypt/cmac.h
    src/wolfssl/wolfcrypt/compress.h
    src/wolfssl/wolfcrypt/curve25519.h
    src/wolfssl/wolfcrypt/coding.h
    src/wolfssl/wolfcrypt/dh.h
    src/wolfssl/wolfcrypt/dsa.h
    src/wolfssl/wolfcrypt/ecc.h
    src/wolfssl/wolfcrypt/des3.h
    src/wolfssl/wolfcrypt/ed25519.h
    src/wolfssl/wolfcrypt/error-crypt.h
    src/wolfssl/wolfcrypt/fe_operations.h
    src/wolfssl/wolfcrypt/fips_test.h
    src/wolfssl/wolfcrypt/ge_operations.h
    src/wolfssl/wolfcrypt/hash.h
    src/wolfssl/wolfcrypt/hc128.h
    src/wolfssl/wolfcrypt/hmac.h
    src/wolfssl/wolfcrypt/idea.h
    src/wolfssl/wolfcrypt/include.am
    src/wolfssl/wolfcrypt/integer.h
    src/wolfssl/wolfcrypt/md4.h
    src/wolfssl/wolfcrypt/md5.h
    src/wolfssl/wolfcrypt/md2.h
    src/wolfssl/wolfcrypt/logging.h
    src/wolfssl/wolfcrypt/mem_track.h
    src/wolfssl/wolfcrypt/misc.h
    src/wolfssl/wolfcrypt/mpi_class.h
    src/wolfssl/wolfcrypt/memory.h
    src/wolfssl/wolfcrypt/mpi_superclass.h
    src/wolfssl/wolfcrypt/pkcs7.h
    src/wolfssl/wolfcrypt/poly1305.h
    src/wolfssl/wolfcrypt/pkcs12.h
    src/wolfssl/wolfcrypt/random.h
    src/wolfssl/wolfcrypt/pwdbased.h
    src/wolfssl/wolfcrypt/ripemd.h
    src/wolfssl/wolfcrypt/rabbit.h
    src/wolfssl/wolfcrypt/sha.h
    src/wolfssl/wolfcrypt/rsa.h
    src/wolfssl/wolfcrypt/sha256.h
    src/wolfssl/wolfcrypt/sha512.h
    src/wolfssl/wolfcrypt/settings.h
    src/wolfssl/wolfcrypt/srp.h
    src/wolfssl/wolfcrypt/tfm.h
    src/wolfssl/wolfcrypt/signature.h
    src/wolfssl/wolfcrypt/visibility.h
    src/wolfssl/wolfcrypt/wc_port.h
    src/wolfssl/wolfcrypt/types.h
    src/wolfssl/wolfcrypt/wolfevent.h
    src/wolfssl/wolfcrypt/wc_encrypt.h
    src/wolfssl/wolfcrypt/wolfmath.h
    src/wolfssl/wolfcrypt/port/nrf51.h
    src/wolfssl/wolfcrypt/port/atmel/atmel.h
    src/wolfssl/wolfcrypt/port/intel/quickassist.h
    src/wolfssl/wolfcrypt/port/intel/quickassist_mem.h
    src/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h
    src/wolfssl/wolfcrypt/port/nxp/ksdk_port.h
    src/wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h
    src/wolfssl/wolfcrypt/port/ti/ti-ccm.h
    src/wolfssl/wolfcrypt/port/ti/ti-hash.h
attempting to compile firmware 
downloading binary from: /v1/binaries/596fee8ca3c4e51405d98936
saving to: photon_firmware_1500507769795.bin
Memory use: 
   text	   data	    bss	    dec	    hex	filename
  97772	    124	   2116	 100012	  186ac	/workspace/target/workspace.elf

Compile succeeded.
Saved firmware to: /Users/cermak/Software/particle/libraries/wolfssl/photon_firmware_1500507769795.bin

This works connecting to a basic https site.

The next step is to get the certificates installed so you can connect to the API and you should be off to the races.

Thanks @cermak -

I’ll give that a try on my Windoze10 machine and see what I can see. I’ll also be watching for any additional updates you’ll make as well.

I concur with your memory overhead concerns, and with your notion of a more direct means than the webhook() pub/sub operations. My application doesn’t require a whole lotta code space, but I’ve yet to see what this SSL lib overhead requires.

@jimini - ok, I quickly cobbled together a local toolchain version that can ping the AWS IoT API. It just needs the certificates added to the SSL context and appropriate arguments sent with the https request.

Github branch mqtt: https://github.com/jr3cermak/particle/tree/mqtt/localtoolchain/wolfiot
EDIT: now on master

Drop the wolfiot directory into the path of your local toolchain and compile:
make all PLATFORM=photon APPDIR=../../wolfiot

See:

RobPro:modules cermak$ particle flash --serial wolfiot/target/wolfiot.bin;particle serial monitor --follow
! PROTIP: Hold the SETUP button on your device until it blinks blue!
? Press ENTER when your device is blinking BLUE 
sending file: wolfiot/target/wolfiot.bin

Flash success!
Polling for available serial device...
Opening serial monitor for com port: "/dev/cu.usbmodem1421"
Serial monitor opened successfully:
Restarting system to apply firmware update...
Serial connection closed.  Attempting to reconnect...
Serial monitor opened successfully:
Connected to data.iot.us-west-2.amazonaws.com
SSL version is TLSv1.2
SSL cipher suite is TLS_DHE_RSA_WITH_AES_256_CBC_SHA
client.available():128
Server response: HTTP/1.1 403 Forbidden
content-type: application/json
content-length: 91
date: Thu, 20 Jul 2017 04:19:18 GMT
x-amzn-RequestId: 09e08dc9-d932-d372-d859-90b2f4aa8027
x-amzn-ErrorType: ForbiddenException:

{"message":"Missing Authentication Token","traceId":"09e08dc9-d932-d372-d859-90b2f4aa8027"}
Connection complete.

There is nothing special in the Private.h file but eventual settings I never want to publish to github. That file should go into inc.

Private.h

/* Configuration */
#define DEFAULT_MQTT_HOST       "data.iot.us-west-2.amazonaws.com" /* broker.hivemq.com */
#define DEFAULT_CMD_TIMEOUT_MS  30000
#define DEFAULT_CON_TIMEOUT_MS  5000
#define DEFAULT_MQTT_QOS        MQTT_QOS_1
#define DEFAULT_KEEP_ALIVE_SEC  60
#define DEFAULT_CLIENT_ID       "WolfMQTTClient"
#define WOLFMQTT_TOPIC_NAME     "wolfMQTT/example/"
#define DEFAULT_TOPIC_NAME      WOLFMQTT_TOPIC_NAME"testTopic"

#define MAX_BUFFER_SIZE         1024
#define TEST_MESSAGE            "42"
#define TEST_TOPIC_COUNT        1

/* Certificates */

const unsigned char CAcert[] = "\
-----BEGIN CERTIFICATE-----\
....
-----END CERTIFICATE-----";

const unsigned char CLcert[] = "\
-----BEGIN CERTIFICATE-----\
....
-----END CERTIFICATE-----";

const unsigned char PRcert[] = "\
-----BEGIN RSA PRIVATE KEY-----\
....
-----END RSA PRIVATE KEY-----";

Add your certs and I believe the SSL context can be populated with the above certificates using Section 7.5 of the wolfssl manual. The NO_FILESYSTEM option.

My next block of time is to test this, hopefully. I believe the three routines needed to seed the CTX are:

// Load CA / Root CA certificate
int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX*, const unsigned
                                   char*, long, int)
// Load cert.pem
int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX*, const unsigned 
                                      char*, long, int)
// Load privkey.pem
int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX*, const unsigned 
                                     char*, long, int)

Arguments:

  • SSL CTX (context)
  • certificate string
  • string size
  • type: SSL_FILETYPE_PEM

Fantastic @cermak, thanks for your efforts here.
I will give this a whirl once I complete some hardware integration/fabrication so I can install a Photon on premise.

Getting closer. I am unable to load the IoT CA cert as I get a return error of -150.

Synced with time server.
Return code: -150
Failed to load CAcert.
Not connecting as certificate load failed.

I know the Photon is correctly synced with time and the other 2 certificates are loading fine since I do not see output. This means I am doing something bad with pulling the correct time into the library.

wolfssl/wolfcrypt/error-crypt.h: ASN_BEFORE_DATE_E = -150, /* ASN date error, current date before */

The certs in the Private.h need line feeds to be parsed correctly.

const unsigned char CAcert[] = "\
-----BEGIN CERTIFICATE-----\n\
MIIE0zCCA7....\n\
....
-----END CERTIFICATE-----\n";

Hopefully, one last battle with time.

It soundsvery close… wondering how your memory pool is sizing up?

Keep up the great work. I should have my prototype fabrications done later today, and I’ll be in a position to play with some new code configurations next week.

I believe we have a working prototype. I fixed the time bug. I was using HAL_Timer_Milliseconds() which is seconds since boot up instead of Time.now() which is the Unix epoch we are looking for.

The working prototype wolfiot.cpp and library is committed to github. EDIT: now on the master.

I have a bunch of debugging turned on. If we scale back on the number of routines being accessed, we can reduce the firmware size.

This is very raw access. The webduino library has nice routines for processing the response from the server capturing the header and data. That will take some additional effort to adapt. The void WebServer::processConnection(uint8_t sock) routine is specific for a server, but should be reusable for a client connection.

This is enough for me to proceed back up the rabbit hole I climbed down. I will be happy to take code updates via github pull requests.

Prototype firmware size:

   text	   data	    bss	    dec	    hex	filename
 124652	    216	   2308	 127176	  1f0c8	../../wolfiot/target/wolfiot.elf

Transcript of working Publish event.

From the Photon:

Serial connection closed.  Attempting to reconnect...
Serial monitor opened successfully:
Synced with time server.
Time now: 1500669750
Processing CA PEM file
Adding a CA
Got Cert Header
Got Algo ID
Getting Cert Name
ltime: 1500669750
timeDiff: 0
tim_p: 1500669750
ltime: 1500669750
timeDiff: 0
tim_p: 1500669750
Getting Cert Name
Got Subject Name
Got Key
Parsed Past Key
	Parsed new CA
	Freeing Parsed CA
	Freeing der CA
		OK Freeing der CA
   Processed a CA
Processed at least one valid CA. Other stuff OK
Checking cert signature type
Got Cert Header
Got Algo ID
Getting Cert Name
ltime: 1500669750
timeDiff: 0
tim_p: 1500669750
ltime: 1500669750
timeDiff: 0
tim_p: 1500669750
Getting Cert Name
Got Subject Name
Got Key
Not ECDSA cert signature
Connected to data.iot.us-west-2.amazonaws.com
SSL version is TLSv1.2
Header size: 194
handshake not complete, trying to finish
Growing output buffer
Shrinking output buffer
connect state: CLIENT_HELLO_SENT
Growing input buffer
received record layer msg
processing server hello
More messages in record
received record layer msg
processing certificate
Loading peer's cert chain
	Put another cert into chain
	Put another cert into chain
Got Cert Header
Got Algo ID
Getting Cert Name
ltime: 1500669750
timeDiff: 0
tim_p: 1500669750
ltime: 1500669750
timeDiff: 0
tim_p: 1500669750
Getting Cert Name
Got Subject Name
Got Key
Parsed Past Key
Certificate Policy extension not supported yet.
	Unsupported name type, skipping
About to verify certificate signature
Adding CA from chain
Adding a CA
Got Cert Header
Got Algo ID
Getting Cert Name
ltime: 1500669750
timeDiff: 0
tim_p: 1500669750
ltime: 1500669750
timeDiff: 0
tim_p: 1500669750
Getting Cert Name
Got Subject Name
Got Key
Parsed Past Key
Certificate Policy extension not supported yet.
	Unsupported name type, skipping
	Parsed new CA
	Freeing Parsed CA
	Freeing der CA
		OK Freeing der CA
Verifying Peer's cert
Got Cert Header
Got Algo ID
Getting Cert Name
ltime: 1500669750
timeDiff: 0
tim_p: 1500669750
ltime: 1500669750
timeDiff: 0
tim_p: 1500669750
Getting Cert Name
Got Subject Name
Got Key
Parsed Past Key
Certificate Policy extension not supported yet.
About to verify certificate signature
Verified Peer's cert
More messages in record
received record layer msg
processing server key exchange
More messages in record
received record layer msg
processing certificate request
More messages in record
received record layer msg
processing server hello done
connect state: HELLO_AGAIN
connect state: HELLO_AGAIN_REPLY
connect state: FIRST_REPLY_DONE
Growing output buffer
Shrinking output buffer
sent: certificate
connect state: FIRST_REPLY_FIRST
Growing output buffer
Shrinking output buffer
sent: client key exchange
connect state: FIRST_REPLY_SECOND
Growing output buffer
Trying RSA client cert
Shrinking output buffer
sent: certificate verify
connect state: FIRST_REPLY_THIRD
Growing output buffer
Shrinking output buffer
sent: change cipher spec
connect state: FIRST_REPLY_FOURTH
Growing output buffer
Shrinking output buffer
sent: finished
connect state: FINISHED_DONE
received record layer msg
got CHANGE CIPHER SPEC
received record layer msg
processing finished
connect state: SECOND_REPLY_DONE
Shrinking input buffer
Growing output buffer
Shrinking output buffer
Bytes written: 194
Data payload size: 89
Growing output buffer
Shrinking output buffer
Bytes written: 89
SSL cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
client.available():128
Server response: Growing input buffer
received record layer msg
got app DATA
HTTP/1.1 200 OK
content-type: application/json
content-length: 65
date: Fri, 21 Jul 2017 20:42:33 GMT
x-amzn-RequestId: 2fa3dc62-fadb-2e5f-5529-b5a2f8d51fb2
connection: Keep-Alive

{"message":"OK","traceId":"2fa3dc62-fadb-2e5f-552Shrinking input buffer
9-b5a2f8d51fb2"}
CTX ref count not 0 yet, no free
Connection complete.

Log messages as seen on AWS CloudWatch, this matches the traceId above.

2017-07-21 20:42:33.258 TRACEID:2fa3dc62-fadb-2e5f-5529-b5a2f8d51fb2 PRINCIPALID:752497542b54204429ce0b82a081b83e8603828e44689547ab73ceef3a0a83f7 [INFO] EVENT:PublishEvent TOPICNAME:temperatureA MESSAGE:PublishIn Status: SUCCESS
2017-07-21 20:42:33.258 TRACEID:2fa3dc62-fadb-2e5f-5529-b5a2f8d51fb2 PRINCIPALID:752497542b54204429ce0b82a081b83e8603828e44689547ab73ceef3a0a83f7 [INFO] EVENT:PublishEvent MESSAGE: IpAddress: 216.115.122.132 SourcePort: 44531

A python mqtt client (subscriber) to AWS IoT to show that the message was seen as sent from the Photon.

$ ./runBasic.sh 
2017-07-21 12:41:57,851 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Paho MQTT Client init.
2017-07-21 12:41:57,852 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - ClientID: basicPubSub
2017-07-21 12:41:57,853 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - Protocol: MQTTv3.1.1
2017-07-21 12:41:57,853 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Register Paho MQTT Client callbacks.
2017-07-21 12:41:57,854 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - mqttCore init.
2017-07-21 12:41:57,855 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Load CAFile from: VeriSignAmazonG5.pem
2017-07-21 12:41:57,855 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Load Key from: 752497542b-private.pem.key
2017-07-21 12:41:57,856 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Load Cert from: 752497542b-certificate.pem.crt
2017-07-21 12:41:57,857 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for backoff timing: baseReconnectTime = 1 sec
2017-07-21 12:41:57,857 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for backoff timing: maximumReconnectTime = 32 sec
2017-07-21 12:41:57,858 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for backoff timing: minimumConnectTime = 20 sec
2017-07-21 12:41:57,859 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for publish queueing: queueSize = -1
2017-07-21 12:41:57,860 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for publish queueing: dropBehavior = Drop Newest
2017-07-21 12:41:57,860 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for draining interval: 0.5 sec
2017-07-21 12:41:57,861 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Set maximum connect/disconnect timeout to be 10 second.
2017-07-21 12:41:57,862 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Set maximum MQTT operation timeout to be 5 second
2017-07-21 12:41:57,863 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - Connection type: TLSv1.2 Mutual Authentication
2017-07-21 12:41:58,423 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Connect result code 0
2017-07-21 12:41:58,424 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - Connected to AWS IoT.
2017-07-21 12:41:58,425 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Connect time consumption: 130.0ms.
2017-07-21 12:41:58,426 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Started a subscribe request 1
2017-07-21 12:41:58,535 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - _resubscribeCount: -1
2017-07-21 12:41:58,537 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Subscribe request 1 sent.
2017-07-21 12:41:58,543 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Subscribe request 1 succeeded. Time consumption: 110.0ms.
2017-07-21 12:41:58,543 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Recover subscribe context for the next request: subscribeSent: False
2017-07-21 12:42:18,424 - AWSIoTPythonSDK.core.util.progressiveBackoffCore - DEBUG - stableConnection: Resetting the backoff time to: 1 sec.
Received a new message: 
{ "serialNumber": "G030JF053216F1BS", "clickType": "SINGLE", "batteryVoltage": "2000mV" }
from topic: 
temperatureA
--------------
4 Likes

Give that man a cigar!
This is fantastic news @cermak.
Thank you for providing your chops for this port!

I will be able to vet this next week and report my experiences here.

The wolfssl library is published as 0.0.1 in the cloud. It should be available via the Build IDE, Particle DEV, Particle CLI and the local toolchain. If there is a kind soul working with po-utils to test things out, that would be great.

I’ve confirmed that I can generate a firmware binary using the Particle CLI and Particle DEV. I think I’ve beaten the cloud into submission, er wait, maybe that is the other way around? :head_bandage: @ScruffR provided a lot of help and suggestions. I can see a bit better how the pieces are fitting together – hopefully, I can make some better swipes that the documentation. (I think the big gotcha for me was I was attempting to compile the project and the library in the same tree. This goes against the guidance in the forum/documentation that things need to be largely in independent units.)

Once you set the library.properties with the project with whatever version of wolfiot.ino or wolfiot.cpp with certificates in that file or the external Private.h, you should get a binary. If you do the full song and dance out at the AWS IoT, you should see the data payload (you have to do the song and dance first to get the certs to put in your code…). I will see about a short tutorial that outlines the steps to setup a thingy.

In Particle DEV, this is the basic project with the reference to the library. Hit compile and away you go. It is magic. @jimini - hope this works! Give it a whirl and let me know and we can see about one additional example snippet for Lambda.

Do not try and look at the library on the Build IDE (web). All my attempts have met with failure. There is just too much code! Download it using the Particle CLI, make needed changes and use a private copy to perform the build. If you can use the library as is, you do not need to create a private copy.

The base size of the firmware when compiled is 90k. There is not a lot of extra room.

I am no where near done with the documentation for this. This is just announcing that the library is a bit more accessible now for testing.

3 Likes

I had to verify an electron was working. The sample code does work, though we should add a code snippet to be sure it is connected to the internet. Be aware, this will eat up your data plan with all the TLS/cert negotiation.

Electron:

Compiling code for electron

Including:
    src/Private.h
    src/wolfiot.cpp
    project.properties
attempting to compile firmware 
downloading binary from: /v1/binaries/597cf304248a1c30a58fad5c
saving to: electron_firmware_1501360879598.bin
Memory use: 
   text	   data	    bss	    dec	    hex	filename
  90172	    216	   2360	  92748	  16a4c	/workspace/target/workspace.elf

Serial monitor opened successfully:
Synced with time server.
Trying to reconnect...
Trying to reconnect...
Trying to reconnect...
Connected to data.iot.us-west-2.amazonaws.com
SSL version is TLSv1.2
Header size: 194
Bytes written: 194
Data payload size: 89
Bytes written: 89
SSL cipher suite: NONE
client.available():128
Server response:
HTTP/1.1 200 OK
content-type: application/json
content-length: 65
date: Sat, 29 Jul 2017 20:45:15 GMT
x-amzn-RequestId: 34779326-f4e1-3ece-dffc-2aebf5a9f72a
connection: Keep-Alive

{"message":"OK","traceId":"34779326-f4e1-3ece-dffc-2aebf5a9f72a"}
Connection complete.

I am going to remove the wolfmqtt port from the title of this post. There are several forks/tracks that will happen now that the wolfssl library is operating. I or others will open separate threads.

2 Likes

I couldn’t stand it…

I had to try integrating and building with this … using the wolfssl_client.ino as an example framework, I’ve integrated all the example SSL client specifics into my “test” app, and IT BUILDS! (woot!)

I’ve got some additional message construction work to do with my json POST request content for the API, but in the meantime I wanted to report here that it’s thumbs up so far :+1: @cermak

I’ll get another chance on Monday to finalize payloads and ping against my API endpoint.

@cermak, Just checking in - looks like you’ve done some amazing work!

How did you go with testing over the last few months? Is it good and stable?

I’m using the MQTT-TLS library at the moment, but having issues with it blocking my OTA updates and slowing down the Particle web API calls.

Would greatly welcome giving your library a shot if it is good to go? :slight_smile: