Get access to the new Intel® IoT Developer Kit, a complete hardware and software solution that allows developers to create exciting new solutions with the Intel® Galileo and Intel® Edison boards. Visit the Intel® Developer Zone for IoT.
Introduction
Getting Started
Step 1: Building wolfSSL for Yocto
Step 2: Installing wolfSSL On Galileo
Step 3: Modifying the Compile Patterns for the Arduino IDE
Step 4: Installing the wolfSSL Build Files on the Arduino IDE System
Example Sketches
Notices
Downloads
The Intel® Galileo development board is an Arduino*-certified development and prototyping board. Built on the Yocto 1.4 Poky Linux* release, Galileo merges an Arduino development environment with a complete Linux-based computer system allowing enthusiasts to incorporate Linux system calls and OS-provided services in their Ardunio sketches.
One long-standing limitation in the Arduino platform has been a lack of SSL support. Without SSL Arduino-based devices are incapable of securely transmitting data using HTTPS, and are thus forced to communicate insecurely using plain HTTP. In order to work around this limitation, devices that participate in the build out of the Internet of Things must rely on secondary devices which serve as bridges to the internet. The Arduino device communicates using HTTP to the bridge, which in turn communicates to the internet-based service using HTTPS.
This solution works well for devices that have a fixed network location, but it does require additional hardware and introduces a concentration point for multiple devices that itself may be vulnerable to attack. For mobile devices that may occasionally rely on public wireless networks, this approach can be entirely impractical. The best level of protection for connected devices is achieved with SSL support directly on the device itself.
On Galileo an Arduino sketch is just a C++ program that is cross-compiled into machine code and executed as a process that is managed by the operating system. That means that it has access to the same system resources as any other compiled program, and specifically that program can be linked against arbitrary, compiled libraries. The implication here is that adding SSL support is as simple as linking the Arduino sketch to an existing SSL library.
This paper examines two methods for adding SSL support to Arduino sketches running on Galileo via the wolfSSL library from wolfSSL, Inc.* (formerly named the CyaSSL library). The wolfSSL library is a lightweight SSL/TLS library that is designed for resource-constrained environments and embedded applications, and is distributed under the GPLv2 license.
This paper looks at two methods for linking the wolfSSL library to an Arduino sketch, but both of them follow the same basic steps:
- Build wolfSSL for Yocto
- Install the wolfSSL shared library onto your Galileo image
- Modify the compile patterns for the Arduino IDE for Galileo
- Install the wolfSSL build files onto the system hosting the Arduino IDE
This procedure is moderately complex and does require a firm grasp of the Linux environment, shell commands, software packages and software build procedures, as well as methods of transferring files to and from a Linux system. While this paper does go into some detail on specific Linux commands, it is not a step-by-step instruction manual and it assumes that the reader knows how to manipulate files on a Linux system.
These procedures should work on both Galileo and Galileo 2 boards.
In the dynamic linking method the Arduino sketch is dynamically linked with the shared object library, libwolfssl.so. This method is the easiest to program for since the sketch just calls the library functions directly.
There are disadvantages to this approach, however:
- The Arduino IDE for Galileo uses a single configuration for compiling all sketches, so the linker will put a reference to libwolfssl.so in the resulting executable whether or not it’s needed by a sketch. This is not a problem if the target Galileo system has the wolfSSL library installed on it, but if any sketch is compiled for another system that does not have the library then those sketches will not execute.
- The system hosting the Arduino IDE for Galileo must have the cross-compiled wolfSSL library installed into the Arduino IDE build tree.
In the dynamic loading method the Arduino sketch is linked with the dynamic linking loader library, libdl. The wolfSSL library and its symbols are loaded dynamically during execution using dlopen() and dlsym(). This method is more tedious to program for since the function names cannot be resolved directly by the linker and must be explicitly loaded by the code and saved as function pointers.
The advantages over the dynamic linking method are:
- libdl is part of the Galileo SD card image, so arbitrary sketches compiled by the modified IDE will still run on other Galileo systems.
- The system hosting the Arduino IDE for Galileo only needs to have the wolfSSL header files installed into the build tree.
- Any dynamic library is available to the Arduino sketch with just this single modification.
The first step in bringing SSL support to the Arduino environment is to build the wolfSSL library for Yocto using uClibc as the C library. This is accomplished using the cross compiler that is bundled with Intel’s Arduino IDE for Linux. This step must be performed on a Linux system.
There have been multiple releases of the IDE since the original Galileo release and any of them will do, but because path names have changed from release to release this document assumes that you will be using the latest build as of this writing, which is the Intel bundle version 1.0.4 with Arduino IDE version 1.6.0.
Choose the 32-bit or 64-bit archive, whichever is correct for your Linux distribution.
If you have already used this version of the IDE to build sketches for your Galileo device then it has already been configured properly and you can skip this task.
If you have not built a sketch with it yet, then you will need to run the installation script in order to correctly set the path names in the package configuration files. This script, install_script.sh, is located in the hardware/tools/i586 directory inside the root of your IDE package. Run it with no arguments:
~/galileo/arduino-1.6.0+Intel/hardware/tools/i586$ ./install_script.sh
Setting it up.../tmp/tmp.7FGQfwEaNz/relocate_sdk.sh /nfs/common/galileo/arduino-1.6.0+Intel/hardware/tools/i586/relocate_sdk.sh
link:/nfs/common/galileo/arduino-1.6.0+Intel/hardware/tools/i586/sysroots/x86_64-pokysdk-linux/lib/ld-linux-x86-64.so.2
link:/nfs/common/galileo/arduino-1.6.0+Intel/hardware/tools/i586/sysroots/x86_64-pokysdk-linux/lib/libpthread.so.0
link:/nfs/common/galileo/arduino-1.6.0+Intel/hardware/tools/i586/sysroots/x86_64-pokysdk-linux/lib/libnss_compat.so.2
link:/nfs/common/galileo/arduino-1.6.0+Intel/hardware/tools/i586/sysroots/x86_64-pokysdk-linux/lib/librt.so.1
link:/nfs/common/galileo/arduino-1.6.0+Intel/hardware/tools/i586/sysroots/x86_64-pokysdk-linux/lib/libresolv.so.2
…
SDK has been successfully set up and is ready to be used.
The cross-compiler is now ready for use.
To build the wolfSSL library for Galileo you need to download the source code from wolfSSL, Inc. As of this writing, the latest version is 3.4.0 and is distributed as a Zip archive. Unzip the source into a directory of your choosing.
In order to build the library, you must first set up your shell environment to reference the cross compiler. The environment setup files assume a Bourne shell environment so you must perform these steps in an appropriate and compatible shell such as sh or bash. Starting from a clean shell environment is strongly recommended.
First, source the environment setup file from the Intel Arduino IDE. Be sure to use the path to your Intel Arduino IDE instead of the path given in the example:
~/src/wolfssl-3.4.0$ . ~/galileo/arduino-1.6.0+Intel/hardware/tools/i586/environment-setup-i586-poky-linux-uclibc
This step will not generate any output.
Now, you are ready to run the configure script for wolfSSL. It is necessary to provide configure with a number of options in order to properly initialize it for a cross compile.
~/src/wolfssl-3.4.0$ ./configure --prefix=$HOME/wolfssl --host=i586-poky-linux-uclibc \
--target=i586-poky-linux-uclibc
Note that you must supply absolute paths to the configure script, and cannot use ~ as a shortcut for your home directory. Use the $HOME shell variable instead.
The --prefix option tells build system where to install the library. Since you won’t actually be installing the library on this system, any directory will do. This example shows it going in $HOME/wolfssl.
The --host and --target options tell the build system that this will be a cross-compile, targeting the architecture identified as i586-poky-linux-uclibc.
The configure script will generate a lot of output. When it finishes, assuming there are no errors, you can build the software using “make”.
~/src/wolfssl-3.4.0$ make
make[1]: Entering directory `/nfs/users/johnm/src/wolfssl-3.4.0'
CC wolfcrypt/test/testsuite_testsuite_test-test.o
CC examples/client/testsuite_testsuite_test-client.o
CC examples/server/testsuite_testsuite_test-server.o
CC examples/client/tests_unit_test-client.o
CC examples/server/tests_unit_test-server.o
CC wolfcrypt/src/src_libwolfssl_la-hmac.lo
CC wolfcrypt/src/src_libwolfssl_la-random.lo
…
CCLD examples/client/client
CCLD examples/echoserver/echoserver
CCLD testsuite/testsuite.test
CCLD tests/unit.test
make[1]: Leaving directory `/nfs/users/johnm/src/wolfssl-3.4.0'
And then install it to the local/temporary location via “make install”:
~/src/wolfssl-3.4.0$ make install
Your library will now be in the directory you specified to the --prefix option of configure, in the lib subdirectory:
~/src/wolfssl-3.4.0$ cd $HOME/wolfssl/lib
~/wolfssl/lib$ ls -CFs
total 188
4 libwolfssl.la* 0 libwolfssl.so.0@ 4 pkgconfig/
0 libwolfssl.so@ 180 libwolfssl.so.0.0.0*
You’re now ready to install the wolfSSL library onto Galileo.
There are two general approaches for installing the wolfSSL package onto Galileo: the first is to copy the files directly to the Galileo filesystem image, and the second is to copy the files onto a running Galileo system over a network connection. In either case, however, you do need to know which image you are running on your system, the SD-Card Linux image, or the IoT Developer Kit image.
The SD-Card Linux image is the original system image for Galileo boards. It is a very minimal system image which is less than 312 MB in size. It lacks development tools (e.g., there is no compiler) and advanced Linux utilities. As of this writing, the latest version of the SD-Card image is 1.0.4.
Both installation methods are discussed below, but installing directly to the Galileo filesystem image is preferred because you have more powerful utilities at your disposal.
This method is easier and less error-prone than the other since you have file synchronization tools available to you, and you don’t have the added complexities of networking. All that is necessary is to mount the Galileo filesystem image as a filesystem on the build machine and then you can use rsync to copy the wolfSSL package into place. You can either copy this file to your build system, or mount the microSD card with the image directly on your Linux system using a card reader.
In the Galileo SD Card filesystem tree, the main Galileo filesystem image is called image-full-galileo-clanton.ext3 and it can be mounted using the loop device. Create a mount point (directory) on your build system—the example below uses /mnt/galileo—and then use the mount command to mount it:
~/wolfssl$ cd /mnt
/mnt$ sudo mkdir galileo
/mnt$ mount –t ext3 –o loop /path/to/image-full-galileo-clanton.ext3 /mnt/galileo
The Galileo filesystem should now be visible as /mnt/galileo.
Use rsync to copy the shared library and its symlinks into place. They should be installed into /usr/lib on your Galileo system:
/mnt$ rsync –a $HOME/wolfssl/lib/lib* /mnt/galileo/usr/lib
Be sure to replace $HOME/wolfSSL with the actual location of your local wolfSSL build.
For this method, the Galileo system must be up and running with an active network connection and you will need to know its IP address. Because Galileo lacks file synchronization utilities such as rsync, files will have to be copied using tar to ensure that symbolic links are handled correctly.
First, use cd to switch to the lib subdirectory of your local wolfSSL build.
~/wolfssl$ cd $HOME/wolfssl/lib
Now use tar to create an archive of the shared library and its symlinks, and the copy it to Galileo with scp.
~/wolfssl/lib$ tar cf /tmp/wolfssl.tar lib*
~/wolfssl/lib$ cd /tmp
/tmp$ scp wolfssl.tar root@192.168.1.2:/tmp
root@192.168.1.2’s password:
Be sure to enter the IP address of your Galileo instead of the example.
Now log in to your Galileo device and untar the archive:
/tmp$ ssh root@192.168.1.2
root@192.168.1.2’s password:
root@clanton:~# cd /usr/lib
root@clanton:/usr/lib# tar xf /tmp/wolfssl.tar
The IoT Developer Kit image is a much larger and more traditional Linux system image which includes developer tools and many useful system utilities and daemons. It is distributed as a raw disk image which includes both FAT32 and ext3 disk partitions, and it must be direct-written to an SD card.
Software archive:
| https://software.intel.com/en-us/iot/downloads
|
Target file:
| iotdk-galileo-image.bz2
|
Both installation methods are discussed below.
As of this writing, you also need to replace the uClibc library on your Developer Kit image with the one bundled with your Intel Arduino IDE. Due to differences in the build procedure used for these two copies of the library, not all of the symbols that are exported in the IDE version are present in the Developer Kit version and that can lead to runtime crashes of Arduino sketches. The wolfSSL library, in particular, introduces a dependency on one of these symbols that is missing from the Developer Kit’s build of uClibc, and if you do not replace the library on the Galileo system attempts to use libwolfssl will fail.
This method is easiest if you connect an SD card reader to your Linux system. Since the Developer Kit image contains an ext3 partition, most Linux distributions will automatically mount it for you, typically under /media or /mnt. Use the df command with the -T option to help you determine the mount point.
~$ df -T | grep ext3
/dev/sde2 ext3 991896 768032 172664 82% /media/johnm/048ce1b1-be13-4a5d-8352-2df03c0d9ed8
In this case, the mount point is /media/johnm/048ce1b1-be13-4a5d-8352-2df03c0d9ed8:
~$ /bin/ls -CFs /media/johnm/048ce1b1-be13-4a5d-8352-2df03c0d9ed8
total 96
4 bin/ 4 home/ 4 media/ 4 proc/ 4 sys/ 4 www/
4 boot/ 4 lib/ 4 mnt/ 4 run/ 4 tmp/
4 dev/ 4 lib32/ 4 node_app_slot/ 4 sbin/ 4 usr/
4 etc/ 16 lost+found/ 4 opt/ 4 sketch/ 4 var/
The libraries used by Arduino sketches are kept in /lib32. Use cd to change to that directory and copy the wolfSSL shared libraries and their symlinks into this directory using rsync in order to preserve the symbolic links.
~/wolfssl$ cd /path-to-mountpoint/lib32
lib32$ rsync –a $HOME/wolfssl/lib/lib* .
Be sure to replace path-to-mountpoint with the actual mount point for your SD card’s Galileo filesystem.
Now, you need to replace the Developer Kit’s uClibc library with the one from your Intel Arduino IDE package. Instead of removing it or overwriting it, the following procedure will simply rename it, effectively disabling the original copy of the library but without permanently deleting it:
lib32$ mv libuClibc-0.9.34-git.so libuClibc-0.9.34-git.so.dist
lib32$ cp ~/galileo/arduino-1.6.0+Intel/hardware/tools/i586/sysroots/i586-poky-linux-uclibc/lib/libuClibc-0.9.34-git.so .
Remember to use your actual path to your Intel Arduino IDE in place of the example one.
For this method, the Galileo system must be up and running with an active network connection and you will need to know its IP address. Because Galileo lacks file synchronization utilities such as rsync, files will have to be copied using tar to ensure that symbolic links are handled correctly.
First, use cd to switch to the lib subdirectory of your local wolfSSL build.
~/wolfssl$ cd $HOME/wolfssl/lib
Now use tar to create an archive of the shared library and its symlinks, and the copy it to Galileo with scp.
~/wolfssl/lib$ tar cf /tmp/wolfssl.tar lib*
~/wolfssl/lib$ cd /tmp
/tmp$ scp wolfssl.tar root@192.168.1.2:/tmp
root@192.168.1.2’s password:
Be sure to enter the IP address of your Galileo instead of the example.
Now log in to your Galileo device and untar the archive:
/tmp$ ssh root@192.168.1.2
root@192.168.1.2’s password:
root@quark:~# cd /lib32
root@quark:/lib32# tar xf /tmp/wolfssl.tar
Next, you need to replace the Developer Kit’s uClibc library with the one from your Intel Arduino IDE package. Instead of removing it or overwriting it, the following procedure will simply rename it, effectively disabling the original copy of the library but without permanently deleting it (this will also prevent the actively running sketch from crashing):
root@quark:/lib32$ mv libuClibc-0.9.34-git.so libuClibc-0.9.34-git.so.dist
Log out of your Galileo system and use scp to copy the library from your Intel Arduino IDE to your Galileo:
~$ scp ~/galileo/arduino-1.6.0+Intel/hardware/tools/i586/sysroots/i586-poky-linux-uclibc/lib/libuClibc-0.9.34-git.so root@192.168.1.2:/lib32
Remember to use your actual path to your Intel Arduino IDE in place of the example one, and your Galileo’s IP address.
To compile sketches that want to use the wolfSSL library you need to modify the compile patterns for the Arduino IDE for Galileo. The specific modification that is necessary depends on the method you have chosen for linking to libwolfssl, but no matter the method compile patters live inside of hardware/intel/i586-uclibc for the Intel 1.0.4 with Arduino IDE 1.5.3 and later.
The file that holds your compile patterns is named platform.txt.
You will be editing the line “recipe.c.combine.pattern
”, which looks similar to this:
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -march={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm -lpthread
If you are using the dynamic linking method, then you need to tell the linker to add libwolfssl to the list of libraries when linking the executable. Add -lwolfssl to the end of the line.
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -march={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm –lpthread -lwolfssl
Be sure not to add any line breaks.
In the dynamic loading method, you need to tell the linker to add the dynamic loader library to the list of libraries. Add -ldl to the end of the line.
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -march={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm -ldl
Be sure not to add any line breaks.
The last step before you can compile sketches is to install the wolfSSL build files into the Arduino IDE for Galileo build tree. For the 1.6.0 release, the build tree is in hardware/tools/i586/i586-poky-linux-uclibc. In there you will find a UNIX-like directory structure containing directories etc, lib, usr, and var.
Whether you are using the dynamic loading or dynamic linking method you will need to have the wolfSSL header files installed where the Arduino IDE can find them so that you can include them in your sketches with:
#include <wolfssl/ssl.h>
You can find the header files in the local installation of wolfSSL that you created in Step 1, in include subdirectory. For backwards compatability reasons, the wolfSSL distribution includes header files in include/cyassl and include/wolfssl.
The wolfSSL header files must but installed into usr/include:
If you are using the dynamic linking method, then you must also install the cross-compiled libraries into usr/lib. You can skip this step if you are using the dynamic loading method.
The libraries are in the local installation that was created in Step 1, inside the lib directory. From there copy:
libwolfssl.la
libwolfssl.so
libwolfssl.so.*
All but one of the shared object files will be symlinks, but it is okay for them to be copied as just regular files.
The following example sketches show how to interact with the wolfSSL library using both the dynamic linking and dynamic loading methods. They perform the same function: connect to a target web server and fetch a web page using SSL. The page source is printed to the Arduino IDE for Galileo’s serial console.
These sketches are licensed under the Intel Sample Source Code license. In addition to browsing the source here, you can download them directly.
Note: Be sure to change the server name and, if necessary, the page URL to fetch.
#include <LiquidCrystal.h>
#include <dlfcn.h>
#include <wolfssl/ssl.h>
#include <Ethernet.h>
#include <string.h>
const char server[]= "www.example.com"; const char req[]= "GET / HTTP/1.0\r\n\r\n";
int repeat;
int wolfssl_init ();
int client_send (WOLFSSL *, char *, int, void *);
int client_recv (WOLFSSL *, char *, int, void *);
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void *handle;
EthernetClient client;
WOLFSSL_CTX *ctx= NULL;
WOLFSSL *ssl= NULL;
WOLFSSL_METHOD *method= NULL;
void setup() {
Serial.begin(9600);
Serial.println("Initializing");
lcd.begin(16,2);
lcd.clear();
if ( wolfssl_init() == 0 ) goto fail;
Serial.println("OK");
repeat= 5;
return;
fail:
Serial.print("wolfSSL setup failed");
repeat= 0;
}
int wolfssl_init ()
{
char err[17];
method= wolfTLSv1_2_client_method();
ctx= wolfSSL_CTX_new(method);
if ( ctx == NULL ) return 0;
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
wolfSSL_SetIORecv(ctx, client_recv);
wolfSSL_SetIOSend(ctx, client_send);
return 1;
}
int client_recv (WOLFSSL *_ssl, char *buf, int sz, void *_ctx)
{
int i= 0;
while ( client.available() > 0 && i < sz) {
buf[i++]= client.read();
}
return i;
}
int client_send (WOLFSSL *_ssl, char *buf, int sz, void *_ctx)
{
int n= client.write((byte *) buf, sz);
return n;
}
void loop() {
char errstr[81];
char buf[256];
int err;
if (repeat) {
if ( client.connect(server, 443) ) {
int bwritten, bread, totread;
Serial.print("Connected to ");
Serial.println(server);
ssl= wolfSSL_new(ctx);
if ( ssl == NULL ) {
err= wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string_n(err, errstr, 80);
Serial.print("wolfSSL_new: ");
Serial.println(errstr);
}
Serial.println(req);
bwritten= wolfSSL_write(ssl, (char *) req, strlen(req));
Serial.print("Bytes written= ");
Serial.println(bwritten);
if ( bwritten > 0 ) {
totread= 0;
while ( client.available() || wolfSSL_pending(ssl) ) {
bread= wolfSSL_read(ssl, buf, sizeof(buf)-1);
totread+= bread;
if ( bread > 0 ) {
buf[bread]= '\0';
Serial.print(buf);
} else {
Serial.println();
Serial.println("Read error");
}
}
Serial.print("Bytes read= ");
Serial.println(bread);
}
if ( ssl != NULL ) wolfSSL_free(ssl);
client.stop();
Serial.println("Connection closed");
}
--repeat;
}
delay(5000);
}
#include <dlfcn.h>
#include <wolfssl/ssl.h>
#include <Ethernet.h>
#include <string.h>
#define WOLFSSL_SHLIB_PATH "libwolfssl.so"
const char server[]= "www.example.com"; const char req[]= "GET / HTTP/1.0\r\n\r\n"; int repeat;
int wolfssl_dlload ();
int wolfssl_init ();
int client_send (WOLFSSL *, char *, int, void *);
int client_recv (WOLFSSL *, char *, int, void *);
void *handle;
EthernetClient client;
WOLFSSL_CTX *ctx= NULL;
WOLFSSL *ssl= NULL;
WOLFSSL_METHOD *method= NULL;
typedef struct wolfssl_handle_struct {
WOLFSSL_METHOD *(*wolfTLSv1_2_client_method)();
WOLFSSL_CTX *(*wolfSSL_CTX_new)(WOLFSSL_METHOD *);
void (*wolfSSL_CTX_set_verify)(WOLFSSL_CTX *, int , VerifyCallback);
int (*wolfSSL_connect)(WOLFSSL *);
int (*wolfSSL_shutdown)(WOLFSSL *);
int (*wolfSSL_get_error)(WOLFSSL *, int);
void (*wolfSSL_ERR_error_string_n)(unsigned long, char *, unsigned long);
WOLFSSL *(*wolfSSL_new)(WOLFSSL_CTX *);
void (*wolfSSL_free)(WOLFSSL *);
void (*wolfSSL_SetIORecv)(WOLFSSL_CTX *, CallbackIORecv);
void (*wolfSSL_SetIOSend)(WOLFSSL_CTX *, CallbackIORecv);
int (*wolfSSL_read)(WOLFSSL *, void *, int);
int (*wolfSSL_write)(WOLFSSL *, void *, int);
int (*wolfSSL_pending)(WOLFSSL *);
} wolfssl_t;
wolfssl_t wolf;
void setup() {
Serial.begin(9600);
Serial.println("Initializing");
if ( wolfssl_dlload() == 0 ) goto fail;
if ( wolfssl_init() == 0 ) goto fail;
repeat= 5;
return;
fail:
Serial.print("wolfSSL setup failed");
repeat= 0;
}
int wolfssl_init ()
{
char err[17];
method= wolf.wolfTLSv1_2_client_method();
ctx= wolf.wolfSSL_CTX_new(method);
if ( ctx == NULL ) return 0;
wolf.wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
wolf.wolfSSL_SetIORecv(ctx, client_recv);
wolf.wolfSSL_SetIOSend(ctx, client_send);
return 1;
}
int wolfssl_dlload ()
{
char *err;
handle= dlopen(WOLFSSL_SHLIB_PATH, RTLD_NOW);
if ( handle == NULL ) {
err= dlerror();
goto fail;
}
wolf.wolfTLSv1_2_client_method= (WOLFSSL_METHOD *(*)()) dlsym(handle, "wolfTLSv1_2_client_method");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_CTX_new= (WOLFSSL_CTX *(*)(WOLFSSL_METHOD *)) dlsym(handle, "wolfSSL_CTX_new");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_CTX_set_verify= (void (*)(WOLFSSL_CTX* , int , VerifyCallback)) dlsym(handle, "wolfSSL_CTX_set_verify");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_connect= (int (*)(WOLFSSL *)) dlsym(handle, "wolfSSL_connect");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_get_error= (int (*)(WOLFSSL *, int)) dlsym(handle, "wolfSSL_get_error");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_ERR_error_string_n= (void (*)(unsigned long, char *, unsigned long)) dlsym(handle, "wolfSSL_ERR_error_string_n");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_new= (WOLFSSL *(*)(WOLFSSL_CTX *)) dlsym(handle, "wolfSSL_new");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_free= (void (*)(WOLFSSL *)) dlsym(handle, "wolfSSL_free");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_SetIORecv= (void (*)(WOLFSSL_CTX *, CallbackIORecv)) dlsym(handle, "wolfSSL_SetIORecv");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_SetIOSend= (void (*)(WOLFSSL_CTX *, CallbackIORecv)) dlsym(handle, "wolfSSL_SetIOSend");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_read= (int (*)(WOLFSSL *, void *, int)) dlsym(handle, "wolfSSL_read");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_write= (int (*)(WOLFSSL *, void *, int)) dlsym(handle, "wolfSSL_write");
if ( (err= dlerror()) != NULL ) goto fail;
wolf.wolfSSL_pending= (int (*)(WOLFSSL *)) dlsym(handle, "wolfSSL_pending");
if ( (err= dlerror()) != NULL ) goto fail;
Serial.println("OK");
return 1;
fail:
Serial.println(err);
return 0;
}
int client_recv (WOLFSSL *_ssl, char *buf, int sz, void *_ctx)
{
int i= 0;
while ( client.available() > 0 && i < sz) {
buf[i++]= client.read();
}
return i;
}
int client_send (WOLFSSL *_ssl, char *buf, int sz, void *_ctx)
{
int n= client.write((byte *) buf, sz);
return n;
}
void loop() {
char errstr[81];
char buf[256];
int err;
if (repeat) {
if ( client.connect(server, 443) ) {
int bwritten, bread, totread;
Serial.print("Connected to ");
Serial.println(server);
ssl= wolf.wolfSSL_new(ctx);
if ( ssl == NULL ) {
err= wolf.wolfSSL_get_error(ssl, 0);
wolf.wolfSSL_ERR_error_string_n(err, errstr, 80);
Serial.print("wolfSSL_new: ");
Serial.println(errstr);
}
Serial.println(req);
bwritten= wolf.wolfSSL_write(ssl, (char *) req, strlen(req));
Serial.print("Bytes written= ");
Serial.println(bwritten);
if ( bwritten > 0 ) {
totread= 0;
while ( client.available() || wolf.wolfSSL_pending(ssl) ) {
bread= wolf.wolfSSL_read(ssl, buf, sizeof(buf)-1);
totread+= bread;
if ( bread > 0 ) {
buf[bread]= '\0';
Serial.print(buf);
} else {
Serial.println();
Serial.println("Read error");
}
}
Serial.print("Bytes read= ");
Serial.println(totread);
}
if ( ssl != NULL ) wolf.wolfSSL_free(ssl);
client.stop();
Serial.println("Connection closed");
}
--repeat;
}
delay(5000);
}
INFORMATION IN THIS DOCUMENT IS PROVIDED IN CONNECTION WITH INTEL PRODUCTS. NO LICENSE, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY INTELLECTUAL PROPERTY RIGHTS IS GRANTED BY THIS DOCUMENT. EXCEPT AS PROVIDED IN INTEL'S TERMS AND CONDITIONS OF SALE FOR SUCH PRODUCTS, INTEL ASSUMES NO LIABILITY WHATSOEVER AND INTEL DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY, RELATING TO SALE AND/OR USE OF INTEL PRODUCTS INCLUDING LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT.
UNLESS OTHERWISE AGREED IN WRITING BY INTEL, THE INTEL PRODUCTS ARE NOT DESIGNED NOR INTENDED FOR ANY APPLICATION IN WHICH THE FAILURE OF THE INTEL PRODUCT COULD CREATE A SITUATION WHERE PERSONAL INJURY OR DEATH MAY OCCUR.
Intel may make changes to specifications and product descriptions at any time, without notice. Designers must not rely on the absence or characteristics of any features or instructions marked "reserved" or "undefined." Intel reserves these for future definition and shall have no responsibility whatsoever for conflicts or incompatibilities arising from future changes to them. The information here is subject to change without notice. Do not finalize a design with this information.
The products described in this document may contain design defects or errors known as errata which may cause the product to deviate from published specifications. Current characterized errata are available on request.
Contact your local Intel sales office or your distributor to obtain the latest specifications and before placing your product order.
Copies of documents which have an order number and are referenced in this document, or other Intel literature, may be obtained by calling 1-800-548-4725, or go to: http://www.intel.com/design/literature.htm
Intel, the Intel logo, VTune, Cilk and Xeon are trademarks of Intel Corporation in the U.S. and other countries.
*Other names and brands may be claimed as the property of others
Copyright© 2012 Intel Corporation. All rights reserved.
Intel® Developer Zone for IoT
Start inventing today with the Intel® IoT Developer Program which offers knowledge, tools, kits and a community of experts to quickly and easily turn your innovative ideas into IoT Solutions.
Dream it, Build it with the Intel® IoT Developer Kit for Intel® Edison and Intel® Galileo platforms. These kits are versatile, performance-optimized and fully integrated end-to-end IoT solutions supporting a variety of programming environments, tools, security, cloud connectivity and hardware.
For more resources and to learn how the new Intel® IoT Developer Kit v1.0 can help streamline your IoT projects: