From f67f403dceee103d0eed9c61372442e61fe91dfc Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 26 Jan 2023 17:36:23 -0700 Subject: [PATCH] SE050: add demo TLS client applications --- SE050/README.md | 74 ++- SE050/wolfssl/CMakeLists.txt | 2 + .../wolfcrypt_benchmark/CMakeLists.txt | 2 +- SE050/wolfssl/wolfcrypt_benchmark/benchmark.c | 2 +- SE050/wolfssl/wolfcrypt_benchmark/benchmark.h | 2 +- .../wolfcrypt_benchmark/wolfcrypt_benchmark.c | 2 +- .../wolfcrypt_generate_csr.c | 2 +- .../wolfcrypt_key_cert_insert.c | 2 +- SE050/wolfssl/wolfcrypt_test/CMakeLists.txt | 2 +- SE050/wolfssl/wolfcrypt_test/test.c | 2 +- SE050/wolfssl/wolfcrypt_test/test.h | 2 +- SE050/wolfssl/wolfcrypt_test/wolfcrypt_test.c | 2 +- SE050/wolfssl/wolfssl_client/CMakeLists.txt | 34 ++ SE050/wolfssl/wolfssl_client/README.md | 109 ++++ SE050/wolfssl/wolfssl_client/wolfssl_client.c | 260 +++++++++ .../wolfssl_client_cert_key/CMakeLists.txt | 34 ++ .../wolfssl/wolfssl_client_cert_key/README.md | 145 +++++ .../wolfssl_client_cert_key.c | 523 ++++++++++++++++++ 18 files changed, 1179 insertions(+), 22 deletions(-) create mode 100644 SE050/wolfssl/wolfssl_client/CMakeLists.txt create mode 100644 SE050/wolfssl/wolfssl_client/README.md create mode 100644 SE050/wolfssl/wolfssl_client/wolfssl_client.c create mode 100644 SE050/wolfssl/wolfssl_client_cert_key/CMakeLists.txt create mode 100644 SE050/wolfssl/wolfssl_client_cert_key/README.md create mode 100644 SE050/wolfssl/wolfssl_client_cert_key/wolfssl_client_cert_key.c diff --git a/SE050/README.md b/SE050/README.md index 08bd0c3a..d979069c 100644 --- a/SE050/README.md +++ b/SE050/README.md @@ -16,29 +16,56 @@ running these examples. ## Installing Example Applications These instructions assume that the SE050 middleware has already been installed -in Raspbian and is located at `/home/pi/se_mw/simw-top`. +in Raspbian and is located at `/home/pi/se_mw/simw-top`. Also that wolfSSL has +been built and installed. See instructions in the wolfSSL repository at +`wolfcrypt/src/port/nxp/README_SE050.md`. -Before building these demo, the "wolfssl" folder which contains these demos -should be copied into the SE05x middleware source tree at: +Example SE050 Pi installation steps: + +```sh +$ cd se_mw/simw-top +$ mkdir build && cd build +$ ccmake . +# Make sure the following are set: +# `Host OS` to `Raspbian` +# `Host Crypto` to `None` (see HostCrypto section below) +# `SMCOM` to `T1oI2C` +$ c # to configure +$ g # to generate +$ q +$ cmake --build . +$ sudo make install +``` + +Example wolfSSL installation: ``` -/home/pi/se_mw/simw-top/demos/wolfssl +./configure --with-se050=/home/pi/se_mw/simw-top/ --enable-keygen --enable-cryptocb \ + --disable-examples --disable-crypttests +make +sudo make install ``` +Before building these demos, the "wolfssl" folder which contains these demos +should be copied into the SE05x middleware source tree at: `~/se_mw/simw-top/demos/wolfssl`. +Example: `cp -r wolfssl ~/se_mw/simw-top/demos/` + This will mean the wolfSSL demo applications will be at: ``` -/home/pi/se_mw/simw-top/demos/wolfssl/wolfcrypt_benchmark -/home/pi/se_mw/simw-top/demos/wolfssl/wolfcrypt_generate_csr -/home/pi/se_mw/simw-top/demos/wolfssl/wolfcrypt_key_cert_insert -/home/pi/se_mw/simw-top/demos/wolfssl/wolfcrypt_test +~/se_mw/simw-top/demos/wolfssl/wolfcrypt_benchmark +~/se_mw/simw-top/demos/wolfssl/wolfcrypt_generate_csr +~/se_mw/simw-top/demos/wolfssl/wolfcrypt_key_cert_insert +~/se_mw/simw-top/demos/wolfssl/wolfcrypt_test +~/se_mw/simw-top/demos/wolfssl/wolfssl_client +~/se_mw/simw-top/demos/wolfssl/wolfssl_client_cert_key ``` The 'wolfssl' demo directory needs to be tied into the CMake build system. Open the following file: ``` -/home/pi/se_mw/simw-top/demos/CMakeLists.txt +~/se_mw/simw-top/demos/CMakeLists.txt ``` Add the following at the bottom of this file: @@ -50,9 +77,9 @@ ADD_SUBDIRECTORY(wolfssl) If the SE05x middleware has not yet been set up for compilation: ``` -$ cd /home/pi/se_mw/simw-top/scripts -$ ./create_cmake_projects.py rpi -$ cd /home/pi/se_mw/simw-top_build/raspbian_native_se050_t1oi2c +$ cd ~/se_mw/simw-top/scripts +$ python ./create_cmake_projects.py rpi +$ cd ~/se_mw/simw-top_build/raspbian_native_se050_t1oi2c $ ccmake . < adjust options to match SE050 dev kit > < 'c', to configure > @@ -68,6 +95,13 @@ included here need benchmark.c, benchmark.h, test.c, and test.h copied over from a valid wolfSSL source tree. See notes in those example README.md files for more information. +``` +cp ~/wolfssl/wolfcrypt/benchmark/benchmark.c ./wolfssl/wolfcrypt_benchmark/ +cp ~/wolfssl/wolfcrypt/benchmark/benchmark.h ./wolfssl/wolfcrypt_benchmark/ +cp ~/wolfssl/wolfcrypt/test/test.c ./wolfssl/wolfcrypt_test/ +cp ~/wolfssl/wolfcrypt/test/test.h ./wolfssl/wolfcrypt_test/ +``` + ## NXP SE050 EdgeLock Configuration wolfSSL most recently tested these examples on a Raspberry Pi with NXP @@ -105,6 +139,22 @@ generated and stored in the SE050. This examples requires that wolfSSL be compiled with `--enable-certgen --enable-certreq`. For details, see [README.md](./wolfssl/wolfcrypt_generate_csr/README.md). +### wolfSSL SSL/TLS Client Example + +This example demonstrates a simple SSL/TLS client, using hardware-based +cryptography supported inside the SE050. It loads and uses a certificate +and private key from C arrays/buffers. For a more advanced demo which uses +the private key directly from the SE050, see the following example. For details, +see [README.md](./wolfssl/wolfssl_client/README.md). + +### wolfSSL SSL/TLS Client Example with Cert and Private Key in SE050 + +This example demonstrates a simple SSL/TLS client, using hardware-based +cryptography supported inside the SE050. It loads and uses a certificate +and private key from C arrays/buffers into the SE050, then does all private key +operations inside the SE050 for the TLS private key, based on a key ID. +For details, see [README.md](./wolfssl/wolfssl_client_cert_key/README.md). + ## Support For support questions and issues, please email wolfSSL at support@wolfssl.com. diff --git a/SE050/wolfssl/CMakeLists.txt b/SE050/wolfssl/CMakeLists.txt index 9d2d6a79..47a4f60f 100644 --- a/SE050/wolfssl/CMakeLists.txt +++ b/SE050/wolfssl/CMakeLists.txt @@ -2,3 +2,5 @@ ADD_SUBDIRECTORY(wolfcrypt_benchmark) ADD_SUBDIRECTORY(wolfcrypt_test) ADD_SUBDIRECTORY(wolfcrypt_key_cert_insert) ADD_SUBDIRECTORY(wolfcrypt_generate_csr) +ADD_SUBDIRECTORY(wolfssl_client) +ADD_SUBDIRECTORY(wolfssl_client_cert_key) diff --git a/SE050/wolfssl/wolfcrypt_benchmark/CMakeLists.txt b/SE050/wolfssl/wolfcrypt_benchmark/CMakeLists.txt index 5c979ee0..a5e708fb 100644 --- a/SE050/wolfssl/wolfcrypt_benchmark/CMakeLists.txt +++ b/SE050/wolfssl/wolfcrypt_benchmark/CMakeLists.txt @@ -12,7 +12,7 @@ ADD_EXECUTABLE( TARGET_COMPILE_DEFINITIONS( ${PROJECT_NAME} - PRIVATE SIMW_DEMO_ENABLE__DEMO_WOLFCRYPTBENCHMARK NO_MAIN_DRIVER BENCH_EMBEDDED USE_CERT_BUFFERS_2048 USE_CERT_BUFFERS_256 + PRIVATE SIMW_DEMO_ENABLE__DEMO_WOLFCRYPTBENCHMARK NO_MAIN_DRIVER BENCH_EMBEDDED USE_CERT_BUFFERS_2048 USE_CERT_BUFFERS_256 USE_FLAT_BENCHMARK_H ) TARGET_INCLUDE_DIRECTORIES( diff --git a/SE050/wolfssl/wolfcrypt_benchmark/benchmark.c b/SE050/wolfssl/wolfcrypt_benchmark/benchmark.c index dbe183a4..95afa555 100644 --- a/SE050/wolfssl/wolfcrypt_benchmark/benchmark.c +++ b/SE050/wolfssl/wolfcrypt_benchmark/benchmark.c @@ -1,6 +1,6 @@ /* benchmark.c * - * Copyright (C) 2006-2022 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/SE050/wolfssl/wolfcrypt_benchmark/benchmark.h b/SE050/wolfssl/wolfcrypt_benchmark/benchmark.h index 9a192a32..a624ce87 100644 --- a/SE050/wolfssl/wolfcrypt_benchmark/benchmark.h +++ b/SE050/wolfssl/wolfcrypt_benchmark/benchmark.h @@ -1,6 +1,6 @@ /* benchmark.h * - * Copyright (C) 2006-2022 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/SE050/wolfssl/wolfcrypt_benchmark/wolfcrypt_benchmark.c b/SE050/wolfssl/wolfcrypt_benchmark/wolfcrypt_benchmark.c index 74480523..f4a008f4 100644 --- a/SE050/wolfssl/wolfcrypt_benchmark/wolfcrypt_benchmark.c +++ b/SE050/wolfssl/wolfcrypt_benchmark/wolfcrypt_benchmark.c @@ -1,6 +1,6 @@ /* wolfcrypt_benchmark.c * - * Copyright (C) 2006-2022 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/SE050/wolfssl/wolfcrypt_generate_csr/wolfcrypt_generate_csr.c b/SE050/wolfssl/wolfcrypt_generate_csr/wolfcrypt_generate_csr.c index b29c502b..26e434bb 100644 --- a/SE050/wolfssl/wolfcrypt_generate_csr/wolfcrypt_generate_csr.c +++ b/SE050/wolfssl/wolfcrypt_generate_csr/wolfcrypt_generate_csr.c @@ -1,6 +1,6 @@ /* wolfcrypt_generate_csr.c * - * Copyright (C) 2006-2022 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/SE050/wolfssl/wolfcrypt_key_cert_insert/wolfcrypt_key_cert_insert.c b/SE050/wolfssl/wolfcrypt_key_cert_insert/wolfcrypt_key_cert_insert.c index 4d9ec9cb..31d06007 100644 --- a/SE050/wolfssl/wolfcrypt_key_cert_insert/wolfcrypt_key_cert_insert.c +++ b/SE050/wolfssl/wolfcrypt_key_cert_insert/wolfcrypt_key_cert_insert.c @@ -1,6 +1,6 @@ /* wolfcrypt_key_cert_insert.c * - * Copyright (C) 2006-2022 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/SE050/wolfssl/wolfcrypt_test/CMakeLists.txt b/SE050/wolfssl/wolfcrypt_test/CMakeLists.txt index 373b3803..4b763580 100644 --- a/SE050/wolfssl/wolfcrypt_test/CMakeLists.txt +++ b/SE050/wolfssl/wolfcrypt_test/CMakeLists.txt @@ -12,7 +12,7 @@ ADD_EXECUTABLE( TARGET_COMPILE_DEFINITIONS( ${PROJECT_NAME} - PRIVATE SIMW_DEMO_ENABLE__DEMO_WOLFCRYPTTEST NO_MAIN_DRIVER BENCH_EMBEDDED USE_CERT_BUFFERS_2048 USE_CERT_BUFFERS_256 + PRIVATE SIMW_DEMO_ENABLE__DEMO_WOLFCRYPTTEST NO_MAIN_DRIVER BENCH_EMBEDDED USE_CERT_BUFFERS_2048 USE_CERT_BUFFERS_256 USE_FLAT_TEST_H ) TARGET_INCLUDE_DIRECTORIES( diff --git a/SE050/wolfssl/wolfcrypt_test/test.c b/SE050/wolfssl/wolfcrypt_test/test.c index 92d250b6..9e837fbd 100644 --- a/SE050/wolfssl/wolfcrypt_test/test.c +++ b/SE050/wolfssl/wolfcrypt_test/test.c @@ -1,6 +1,6 @@ /* test.c * - * Copyright (C) 2006-2022 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/SE050/wolfssl/wolfcrypt_test/test.h b/SE050/wolfssl/wolfcrypt_test/test.h index 26668318..85c0e40b 100644 --- a/SE050/wolfssl/wolfcrypt_test/test.h +++ b/SE050/wolfssl/wolfcrypt_test/test.h @@ -1,6 +1,6 @@ /* test.h * - * Copyright (C) 2006-2022 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/SE050/wolfssl/wolfcrypt_test/wolfcrypt_test.c b/SE050/wolfssl/wolfcrypt_test/wolfcrypt_test.c index bdd4f8ec..417e697f 100644 --- a/SE050/wolfssl/wolfcrypt_test/wolfcrypt_test.c +++ b/SE050/wolfssl/wolfcrypt_test/wolfcrypt_test.c @@ -1,6 +1,6 @@ /* wolfcrypt_test.c * - * Copyright (C) 2006-2022 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/SE050/wolfssl/wolfssl_client/CMakeLists.txt b/SE050/wolfssl/wolfssl_client/CMakeLists.txt new file mode 100644 index 00000000..ffa9fdcc --- /dev/null +++ b/SE050/wolfssl/wolfssl_client/CMakeLists.txt @@ -0,0 +1,34 @@ +PROJECT(wolfssl_client) +FILE( + GLOB + files + *.c +) + +ADD_EXECUTABLE( + ${PROJECT_NAME} + ${KSDK_STARTUP_FILE} ${files} +) + +TARGET_COMPILE_DEFINITIONS( + ${PROJECT_NAME} + PRIVATE SIMW_DEMO_ENABLE__DEMO_WOLFSSL_CLIENT NO_MAIN_DRIVER USE_CERT_BUFFERS_2048 USE_CERT_BUFFERS_256 +) + +TARGET_INCLUDE_DIRECTORIES( + ${PROJECT_NAME} + PRIVATE ${SIMW_TOP_DIR}/sss/ex/inc /home/pi/se_mw/wolfssl +) + +TARGET_LINK_LIBRARIES( + ${PROJECT_NAME} + SSS_APIs + ex_common + wolfssl +) + +CREATE_BINARY(${PROJECT_NAME}) + +IF(SSS_HAVE_HOST_LINUX_LIKE) + INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) +ENDIF() diff --git a/SE050/wolfssl/wolfssl_client/README.md b/SE050/wolfssl/wolfssl_client/README.md new file mode 100644 index 00000000..d60fb37b --- /dev/null +++ b/SE050/wolfssl/wolfssl_client/README.md @@ -0,0 +1,109 @@ +# wolfSSL SSL/TLS Client Demo Application + +This demo application runs a wolfSSL TLS example client. It connects to the +main wolfSSL example server (distributed with wolfSSL proper). + +This example client uses SE050-based cryptography inside the module where +supported. It does not load the client certificate and private key into the +SE050 module. For a more advanced demo that does load these into the SE050 +and uses the private key directly from the module based on key ID, see the +wolfSSL client demo located up a directory below, or read the associated +[README.md](../wolfssl_client_cert_key/README.md) for that demo. + +``` +wolfssl_client_cert_key/wolfssl_client_cert_key.c +``` + +## Building the Demo + +Before building this demo, follow initial setup instructions in the parent +[README.md](../../README.md). + +Compiling the middleware will also compile this demo application: + +``` +$ cd /home/pi/se_mw/simw-top_build/raspbian_native_se050_t1oi2c +$ cmake --build . +``` + +## Running the Demo + +To run the demo, first start the wolfSSL example server. This demo client +assumes the server will be available at **127.0.0.1:11111**: + +``` +$ cd +$ ./examples/server/server +``` + +Then, to run this demo: + +``` +$ cd /home/pi/se_mw/simw-top_build/raspbian_native_se050_t1oi2c/bin +$ ./wolfssl_client +``` + +On successful run, output similar to the following will print out: + +``` +App :INFO :PlugAndTrust_v04.02.00_20220524 +App :INFO :Running ./wolfssl_client +App :INFO :If you want to over-ride the selection, use ENV=EX_SSS_BOOT_SSS_PORT or pass in command line arguments. +sss :INFO :atr (Len=35) + 00 A0 00 00 03 96 04 03 E8 00 FE 02 0B 03 E8 08 + 01 00 00 00 00 64 00 00 0A 4A 43 4F 50 34 20 41 + 54 50 4F +sss :WARN :Communication channel is Plain. +sss :WARN :!!!Not recommended for production use.!!! +App :INFO :wolfSSL example client + +App :INFO :Running wc_se050_set_config() +App :INFO :SE050 config successfully set in wolfSSL +App :INFO :Created and configured socket +App :INFO :Socket connected +App :INFO :Created WOLFSSL_CTX +App :INFO :Created WOLFSSL_CTX +App :INFO :Loaded CA certs into CTX +App :INFO :Loaded client certificate into CTX +App :INFO :Loaded client private key into CTX +App :INFO :Created new WOLFSSL +App :INFO :Set wolfSSL fd +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id FFFF +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10000 +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10001 +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10002 +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10003 +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10004 +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10005 +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10006 +App :INFO :Sending message to server: GET /index.html HTTP/1.0 + + + +App :INFO :wolfSSL_write sent 28 bytes + +App :INFO :Server response: I hear you fa shizzle! + +App :INFO :TLS shutdown not complete +App :INFO :TLS shutdown complete +App :INFO :Done with sample app +App :INFO :ex_sss Finished +``` + +## Demo Notes + +It is expected to see warning messages in the console log about failures to +delete key ids. wolfCrypt internally tries to delete temporary/test keys, +and if those keys have not been stored in the SE050 the debug logs will show +these messages. + +See the source code of the demo for more notes about wolfSSL API usage. + diff --git a/SE050/wolfssl/wolfssl_client/wolfssl_client.c b/SE050/wolfssl/wolfssl_client/wolfssl_client.c new file mode 100644 index 00000000..5794b7bf --- /dev/null +++ b/SE050/wolfssl/wolfssl_client/wolfssl_client.c @@ -0,0 +1,260 @@ +/* wolfssl_client.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Simple wolfSSL TLS client example demonstrating integration with SE050. + * + * This example uses SE050 hardware cryptography for cryptography operations + * needed by wolfSSL for SSL/TLS (where supported), but does not store the + * client certificate nor private key inside the SE050 module. + * + * For a more advanced example that demonstrates storing the client RSA or + * ECC private key inside the SE050 and using a key ID to conduct crypto + * operations using that key inside the module, please see the demo at: + * + * wolfssl_client_cert_key/wolfssl_client_cert_key.c + * + * This example has been set up to load a RSA client certificate and private + * key, and by default configured to connect to the wolfSSL proper example + * server. The wolfSSL example server ships with wolfSSL and by default is + * compiled as part of the wolfSSL package. Example server should be started + * with: + * + * $ ./examples/server/server + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#define SERVER_IP "127.0.0.1" +#define DEFAULT_PORT 11111 + +#ifdef __cplusplus +} +#endif + +#if defined(SIMW_DEMO_ENABLE__DEMO_WOLFSSL_CLIENT) + +static ex_sss_boot_ctx_t gex_sss_boot_ctx; + +static const char httpGetMsg[] = "GET /index.html HTTP/1.0\r\n\r\n"; + +#define EX_SSS_BOOT_PCONTEXT (&gex_sss_boot_ctx) +#define EX_SSS_BOOT_DO_ERASE 1 +#define EX_SSS_BOOT_EXPOSE_ARGC_ARGV 0 + +#include + +sss_status_t ex_sss_entry(ex_sss_boot_ctx_t *pCtx) +{ + sss_status_t status = kStatus_SSS_Success; + sss_session_t *pSession = (sss_session_t*)&pCtx->session; + sss_key_store_t *pKeyStore = (sss_key_store_t*)&pCtx->ks; + + int sockfd; + int ret = WOLFSSL_SUCCESS; + struct sockaddr_in servAddr; + char buff[256]; + size_t len; + word32 keyId = 0; + char reply[256]; + + WOLFSSL_CTX* ctx = NULL; + WOLFSSL* ssl = NULL; + + LOG_I("wolfSSL example client\n"); + + LOG_I("Running wc_se050_set_config()"); + if (wc_se050_set_config(pSession, NULL, pKeyStore) != 0) { + LOG_E("wc_se050_set_config failed"); + ret = WOLFSSL_FAILURE; + } + else { + LOG_I("SE050 config successfully set in wolfSSL"); + } + + /* Initialize wolfSSL library, enable debug logs if compiled in */ + wolfSSL_Init(); + wolfSSL_Debugging_ON(); + + /* Create and set up socket */ + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + LOG_E("Failed to create socket"); + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(DEFAULT_PORT); + + if (inet_pton(AF_INET, SERVER_IP, &servAddr.sin_addr) != 1) { + LOG_E("Invalid address, inet_pton failed"); + ret = WOLFSSL_FAILURE; + } + } + + /* Connect to server */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Created and configured socket"); + if (connect(sockfd, (struct sockaddr*) &servAddr, + sizeof(servAddr)) == -1) { + LOG_E("failed to connect"); + ret = WOLFSSL_FAILURE; + } + } + + /* Make new SSL context */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Socket connected"); + ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()); + if (ctx == NULL) { + LOG_E("wolfSSL_CTX_new failed"); + ret = WOLFSSL_FAILURE; + } + } + + /* Load trusted CA cert to verify server, from buffer in certs_test.h */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Created WOLFSSL_CTX"); + ret = wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048, + sizeof_ca_cert_der_2048, SSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_CTX_load_verify_buffer failed"); + } + } + + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Created WOLFSSL_CTX"); + ret = wolfSSL_CTX_load_verify_buffer(ctx, ca_ecc_cert_der_256, + sizeof_ca_ecc_cert_der_256, SSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_CTX_load_verify_buffer failed"); + } + } + + /* Load client cert into CTX from buffer in certs_test.h */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Loaded CA certs into CTX"); + ret = wolfSSL_CTX_use_certificate_buffer(ctx, client_cert_der_2048, + sizeof_client_cert_der_2048, SSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_CTX_use_certificate_buffer failed"); + } + } + + /* Load private key into CTX from buffer in certs_test.h */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Loaded client certificate into CTX"); + ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, client_key_der_2048, + sizeof_client_key_der_2048, SSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_CTX_use_PrivateKey_buffer failed"); + } + } + + /* Create a WOLFSSL session */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Loaded client private key into CTX"); + ssl = wolfSSL_new(ctx); + if (ssl == NULL) { + LOG_E("wolfSSL_new failed"); + ret = WOLFSSL_FAILURE; + } + } + + /* Pass socket descriptor to wolfSSL session */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Created new WOLFSSL"); + ret = wolfSSL_set_fd(ssl, sockfd); + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_set_fd failed"); + } + } + + /* Do SSL/TLS handshake with peer */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Set wolfSSL fd"); + ret = wolfSSL_connect(ssl); + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_connect failed, err = %d", wolfSSL_get_error(ssl, ret)); + } + } + + /* Send simple HTTP GET to server */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Sending message to server: %s\n", httpGetMsg); + ret = wolfSSL_write(ssl, httpGetMsg, XSTRLEN(httpGetMsg)); + if (ret <= 0) { + LOG_E("wolfSSL_write failed"); + ret = WOLFSSL_FAILURE; + } + else { + LOG_I("wolfSSL_write sent %d bytes\n", ret); + ret = WOLFSSL_SUCCESS; + } + } + + /* Read server response */ + if (ret == WOLFSSL_SUCCESS) { + XMEMSET(reply, 0, sizeof(reply)); + ret = wolfSSL_read(ssl, reply, sizeof(reply)-1); + if (ret <= 0) { + LOG_E("wolfSSL_read failed"); + ret = WOLFSSL_FAILURE; + } + else { + LOG_I("Server response: %s\n", reply); + ret = WOLFSSL_SUCCESS; + } + } + + /* Bidirectional shutdown */ + if (ret == WOLFSSL_SUCCESS) { + while (wolfSSL_shutdown(ssl) == SSL_SHUTDOWN_NOT_DONE) { + LOG_I("TLS shutdown not complete"); + } + LOG_I("TLS shutdown complete"); + } + + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); + wolfSSL_Cleanup(); + close(sockfd); + + if (ret == WOLFSSL_FAILURE) { + status = kStatus_SSS_Fail; + } + + LOG_I("Done with sample app"); + return status; +} + +#endif /* SIMW_DEMO_ENABLE__DEMO_WOLFSSL_CLIENT */ diff --git a/SE050/wolfssl/wolfssl_client_cert_key/CMakeLists.txt b/SE050/wolfssl/wolfssl_client_cert_key/CMakeLists.txt new file mode 100644 index 00000000..2c1abf77 --- /dev/null +++ b/SE050/wolfssl/wolfssl_client_cert_key/CMakeLists.txt @@ -0,0 +1,34 @@ +PROJECT(wolfssl_client_cert_key) +FILE( + GLOB + files + *.c +) + +ADD_EXECUTABLE( + ${PROJECT_NAME} + ${KSDK_STARTUP_FILE} ${files} +) + +TARGET_COMPILE_DEFINITIONS( + ${PROJECT_NAME} + PRIVATE SIMW_DEMO_ENABLE__DEMO_WOLFSSL_CLIENT_CERT_KEY NO_MAIN_DRIVER USE_CERT_BUFFERS_2048 USE_CERT_BUFFERS_256 WOLF_PRIVATE_KEY_ID +) + +TARGET_INCLUDE_DIRECTORIES( + ${PROJECT_NAME} + PRIVATE ${SIMW_TOP_DIR}/sss/ex/inc /home/pi/se_mw/wolfssl +) + +TARGET_LINK_LIBRARIES( + ${PROJECT_NAME} + SSS_APIs + ex_common + wolfssl +) + +CREATE_BINARY(${PROJECT_NAME}) + +IF(SSS_HAVE_HOST_LINUX_LIKE) + INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) +ENDIF() diff --git a/SE050/wolfssl/wolfssl_client_cert_key/README.md b/SE050/wolfssl/wolfssl_client_cert_key/README.md new file mode 100644 index 00000000..a8cf46cb --- /dev/null +++ b/SE050/wolfssl/wolfssl_client_cert_key/README.md @@ -0,0 +1,145 @@ +# wolfSSL SSL/TLS Client Demo Application with Cert and Private Key in SE050 + +This demo application runs a wolfSSL TLS example client. It connects to the +main wolfSSL example server (distributed with wolfSSL proper). + +This example client uses SE050-based cryptography inside the module where +supported. It also loads a client certificate and private RSA or ECC key into +the SE050 module. The certificate is extracted back out to be loaded into +wolfSSL context when needed. The private key is left in the SE050 module and +associated private key operations are done inside the SE050 using the matching +SE050 key ID. + +If looking for a more simple example that does not load the client certificate +and private key into the SE050 module, see the wolfSSL client demo located up a +directory below, or read the associated +[README.md](../wolfssl_client/README.md) for that demo. + +``` +wolfssl_client/wolfssl_client.c +``` + +## Building the Demo + +Before building this demo, follow initial setup instructions in the parent +[README.md](../../README.md). + +The wolfSSL library linked against will need to have `-DWOLF_PRIVATE_KEY_ID` +defined when configuring/building the library. This enables the use of a +key ID with the SE050 through the wolfSSL SSL/TLS API. This should be added +to CFLAGS when doing ./configure (or preprocessor defines if not using +configure). For example, wolfSSL configuration used when testing this demo +on Raspberry Pi with an SE050 EdgeLock dev kit: + +``` +$ cd +$ ./configure --with-se050 --enable-certgen --disable-examples CFLAGS="-DSIZEOF_LONG_LONG=8 -DSE050_KEYID_START=0x0000FFFF -DWOLFSSL_SE050_NO_TRNG -DWOLF_PRIVATE_KEY_ID" +``` + +Compiling the middleware will also compile this demo application: + +``` +$ cd /home/pi/se_mw/simw-top_build/raspbian_native_se050_t1oi2c +$ cmake --build . +``` + +## Running the Demo + +To run the demo, first start the wolfSSL example server. This demo client +assumes the server will be available at **127.0.0.1:11111**. The example +server will need to be started differently depending on how the SE050 demo +client has been configured (see source code for optional defines). The default +configuration uses RSA certs and keys, which require the wolfSSL example +server to be started with default credentials: + +``` +$ cd +$ ./examples/server/server +``` + +If the SE050 client demo has been configured to use ECC certs and keys, +by defining `EXAMPLE_USE_RSA = 0`, then the wolfSSL example server should +be started using: + +``` +$ cd +$ ./examples/server/server -c ./certs/server-ecc.pem -k ./certs/ecc-key.pem \ + -A ./certs/client-ecc-cert.pem +``` + +Then, to run this demo: + +``` +$ cd /home/pi/se_mw/simw-top_build/raspbian_native_se050_t1oi2c/bin +$ ./wolfssl_client_cert_key +``` + +The demo can be configured to load and use the client certificate from the +SE050 after loading in with the `EXAMPLE_READ_CERT_FROM_SE050` define. + +On successful run, output similar to the following will print out: + +``` +App :INFO :PlugAndTrust_v04.02.00_20220524 +App :INFO :Running ./wolfssl_client_cert_key +App :INFO :If you want to over-ride the selection, use ENV=EX_SSS_BOOT_SSS_PORT or pass in command line arguments. +sss :INFO :atr (Len=35) + 00 A0 00 00 03 96 04 03 E8 00 FE 02 0B 03 E8 08 + 01 00 00 00 00 64 00 00 0A 4A 43 4F 50 34 20 41 + 54 50 4F +sss :WARN :Communication channel is Plain. +sss :WARN :!!!Not recommended for production use.!!! +App :INFO :------------------------------------------------------------------ +App :INFO :wolfSSL example client +App :INFO :Using RSA certs/keys inside SE050 +App :INFO :------------------------------------------------------------------ +App :INFO :Running wc_se050_set_config() +App :INFO :SE050 config successfully set in wolfSSL +App :INFO :Inserted RSA private key into SE050 key ID: 0x00005002 + +App :INFO :Inserted RSA certificate into SE050 key ID: 0x00005003 + +App :INFO :Created and configured socket +App :INFO :Socket connected +App :INFO :Created WOLFSSL_CTX +App :INFO :Loaded client private key into CTX +App :INFO :Created new WOLFSSL +App :INFO :Set wolfSSL fd +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id FFFF +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10000 +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10001 +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10002 +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10003 +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10004 +sss :WARN :nxEnsure:'ret == SM_OK' failed. At Line:6971 Function:sss_se05x_TXn +sss :WARN :Could not delete Key id 10005 +App :INFO :Sending message to server: GET /index.html HTTP/1.0 + + + +App :INFO :wolfSSL_write sent 28 bytes +App :INFO :Server response: I hear you fa shizzle! + +App :INFO :TLS shutdown not complete +App :INFO :TLS shutdown complete +App :INFO :Erased RSA private key, key ID: 0x00005002 +App :INFO :Erased RSA certificate, key ID: 0x00005003 +App :INFO :Done with sample app +App :INFO :ex_sss Finished +``` + +## Demo Notes + +It is expected to see warning messages in the console log about failures to +delete key ids. wolfCrypt internally tries to delete temporary/test keys, +and if those keys have not been stored in the SE050 the debug logs will show +these messages. + +See the source code of the demo for more notes about wolfSSL API usage. + diff --git a/SE050/wolfssl/wolfssl_client_cert_key/wolfssl_client_cert_key.c b/SE050/wolfssl/wolfssl_client_cert_key/wolfssl_client_cert_key.c new file mode 100644 index 00000000..2032b12c --- /dev/null +++ b/SE050/wolfssl/wolfssl_client_cert_key/wolfssl_client_cert_key.c @@ -0,0 +1,523 @@ +/* wolfssl_client_cert_key.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Simple wolfSSL TLS client example demonstrating integration with SE050, + * where client certificate and private key are stored in the SE050. + * + * Credential for this example have been set up to connect to the wolfSSL + * proper example server. The wolfSSL example server ships with wolfSSL and + * by default is compiled as part of the wolfSSL package. Example server + * should be started with: + * + * RSA certs/keys (default for wolfSSL example server): + * + * $ ./examples/server/server + * + * ECC certs/keys: + * + * $ ./examples/server/server -c ./certs/server-ecc.pem -k ./certs/ecc-key.pem \ + * -A ./certs/client-ecc-cert.pem + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Server endpoint IP and host, change if needed */ +#define SERVER_IP "127.0.0.1" +#define DEFAULT_PORT 11111 + +/* This needs to be a signed int that isn't -2 */ +#define HARDWARE_ID 10 + +#ifdef __cplusplus +} +#endif + +#if defined(SIMW_DEMO_ENABLE__DEMO_WOLFSSL_CLIENT_CERT_KEY) + +static ex_sss_boot_ctx_t gex_sss_boot_ctx; + +/* Message to be sent to server */ +static const char httpGetMsg[] = "GET /index.html HTTP/1.0\r\n\r\n"; + +#define EX_SSS_BOOT_PCONTEXT (&gex_sss_boot_ctx) +#define EX_SSS_BOOT_DO_ERASE 1 +#define EX_SSS_BOOT_EXPOSE_ARGC_ARGV 0 + +/* SE050 key ID's to store example certs and keys into */ +#define KEYID_RSA_PRIVATE 0x00005002 /* stores client_key_der_2048 */ +#define KEYID_RSA_CERT 0x00005003 /* stores client_cert_der_2048 */ +#define KEYID_ECC_PRIVATE 0x00005005 /* stores ecc_clikey_der_256 */ +#define KEYID_ECC_CERT 0x00005006 /* stores cliecc_cert_der_256 */ + +/* Use RSA or ECC certs/keys with this example. Default is RSA, but set to + * 0 to use ECC certs/keys (KEYID_ECC_PRIVATE/KEYID_ECC_CERT) instead. */ +#define EXAMPLE_USE_RSA 1 + +/* Define to 1 to extract and load client certificate from SE050 key ID. + * This example already loads the client certificate from C array / buffer + * into the SE050 key ID slot KEYID_RSA_CERT or KEYID_ECC_CERT for demo + * purposes. If this is defined to 0, the demo will not extract back out the + * certificate from SE050 and instead load directly from the C array again + * into wolfSSL. */ +#define EXAMPLE_READ_CERT_FROM_SE050 1 + +#include + +/** + * Insert example certs/keys into SE050 key IDs. This functionality + * might be done offline or at provisioning in production code. Provided + * here for a complete example which includes storing the certs/keys into + * SE050 module. + * + * Example certs/keys used here are distributed with wolfSSL in + * . There are file equivalents to these credentials + * under the "certs" directory in wolfSSL. + * + * Key ID Credential + * ------ -------------------------------- + * KEYID_RSA_PRIVATE Client RSA private key (client_key_der_2048) + * KEYID_RSA_CERT Client RSA certificate (client_cert_der_248) + * KEYID_ECC_PRIVATE Client ECC private key (ecc_clikey_der_256) + * KEYID_ECC_CERT Client ECC certificate (cliecc_cert_der_256) + * + * Return 0 on success, negative on error. + */ +static int write_certs_keys_to_se050(void) +{ + int ret = 0; + +#if EXAMPLE_USE_RSA == 1 + /* Insert RSA private key */ + ret = wc_se050_rsa_insert_private_key(KEYID_RSA_PRIVATE, + client_key_der_2048, + sizeof_client_key_der_2048); + if (ret != 0) { + LOG_I("Error in se050_rsa_insert_private_key, ret = %d\n", ret); + } else { + LOG_I("Inserted RSA private key into SE050 key ID: 0x%08x\n", + KEYID_RSA_PRIVATE); + } + + /* Insert RSA certificate */ + ret = wc_se050_insert_binary_object(KEYID_RSA_CERT, + client_cert_der_2048, + sizeof_client_cert_der_2048); + if (ret != 0) { + LOG_I("Error in wc_se050_insert_binary_object, ret = %d\n", ret); + } else { + LOG_I("Inserted RSA certificate into SE050 key ID: 0x%08x\n", + KEYID_RSA_CERT); + } + +#else /* Load ECC cert/key */ + + /* Insert ECC private key */ + ret = wc_se050_ecc_insert_private_key(KEYID_ECC_PRIVATE, ecc_clikey_der_256, + sizeof_ecc_clikey_der_256); + if (ret != 0) { + LOG_I("Error in se050_ecc_insert_private_key, ret = %d\n", ret); + } else { + LOG_I("Inserted ECC private key into SE050 key ID: 0x%08x\n", + KEYID_ECC_PRIVATE); + } + + /* Insert ECC certificate */ + ret = wc_se050_insert_binary_object(KEYID_ECC_CERT, cliecc_cert_der_256, + sizeof_cliecc_cert_der_256); + if (ret != 0) { + LOG_I("Error in wc_se050_insert_binary_object, ret = %d\n", ret); + } else { + LOG_I("Inserted ECC certificate into SE050 key ID: 0x%08x\n", + KEYID_ECC_CERT); + } + +#endif /* EXAMPLE_USE_RSA */ + + return ret; +} + +/** + * Erase sample certs/keys from SE050. This may not be needed in + * production code, as credentials may need to remain stored in SE050. + * Included here for complete example, and to cleanup SE050 use. + * + * Returns 0 on success, negative on error. + */ +static int erase_certs_keys_from_se050(void) +{ + int ret = 0; + +#if EXAMPLE_USE_RSA == 1 + ret = wc_se050_erase_object(KEYID_RSA_PRIVATE); + if (ret != 0) { + LOG_I("Failed to erase RSA private key, ret = %d", ret); + } else { + LOG_I("Erased RSA private key, key ID: 0x%08x", KEYID_RSA_PRIVATE); + } + ret = wc_se050_erase_object(KEYID_RSA_CERT); + if (ret != 0) { + LOG_I("Failed to erase RSA certificate, ret = %d", ret); + } else { + LOG_I("Erased RSA certificate, key ID: 0x%08x", KEYID_RSA_CERT); + } +#else + ret = wc_se050_erase_object(KEYID_ECC_PRIVATE); + if (ret != 0) { + LOG_I("Failed to erase ECC private key, ret = %d", ret); + } else { + LOG_I("Erased ECC private key, key ID: 0x%08x", KEYID_ECC_PRIVATE); + } + ret = wc_se050_erase_object(KEYID_ECC_CERT); + if (ret != 0) { + LOG_I("Failed to erase ECC certificate, ret = %d", ret); + } else { + LOG_I("Erased ECC certificate, key ID: 0x%08x", KEYID_ECC_CERT); + } +#endif /* EXAMPLE_USE_RSA */ + + return ret; +} + +/** + * Main entry point for SE050 middleware demos. + * + * pCtx - initialized pointer to ex_sss_boot_ctx_t + * + * Returns kStatus_SSS_Success on success, kStatus_SSS_Fail on failure + */ +sss_status_t ex_sss_entry(ex_sss_boot_ctx_t *pCtx) +{ + sss_status_t status = kStatus_SSS_Success; + sss_session_t *pSession = (sss_session_t*)&pCtx->session; + sss_key_store_t *pKeyStore = (sss_key_store_t*)&pCtx->ks; + + int sockfd; + int ret = WOLFSSL_SUCCESS; + int credentialsStored = 0; + int privateKeyId = 0; + int cliCertKeyId = 0; + struct sockaddr_in servAddr; + char buff[256]; + size_t len; + char reply[256]; + +#if EXAMPLE_READ_CERT_FROM_SE050 == 1 + unsigned char* tmpCert = NULL; + unsigned int tmpCertSz = 0; +#endif + + WOLFSSL_CTX* ctx = NULL; + WOLFSSL* ssl = NULL; + + LOG_I("------------------------------------------------------------------"); + LOG_I("wolfSSL example client"); +#if EXAMPLE_USE_RSA == 1 + LOG_I("Using RSA certs/keys inside SE050"); +#else + LOG_I("Using ECC certs/keys inside SE050"); +#endif + LOG_I("------------------------------------------------------------------"); + + /* Set private key ID based on demo config */ +#if EXAMPLE_USE_RSA == 1 + privateKeyId = KEYID_RSA_PRIVATE; + cliCertKeyId = KEYID_RSA_CERT; +#else + privateKeyId = KEYID_ECC_PRIVATE; + cliCertKeyId = KEYID_ECC_CERT; +#endif + + LOG_I("Running wc_se050_set_config()"); + if (wc_se050_set_config(pSession, NULL, pKeyStore) != 0) { + LOG_E("wc_se050_set_config failed"); + ret = WOLFSSL_FAILURE; + } + else { + LOG_I("SE050 config successfully set in wolfSSL"); + } + + /* Initialize wolfSSL library, enable debug logs if compiled in */ + wolfSSL_Init(); + wolfSSL_Debugging_ON(); + + /* Write example certs/keys to SE050 */ + ret = write_certs_keys_to_se050(); + if (ret != 0) { + LOG_E("Failed to write certs/keys to SE050"); + ret = WOLFSSL_FAILURE; + } + else { + credentialsStored = 1; + ret = WOLFSSL_SUCCESS; + } + + /* Create and set up socket */ + if (ret == WOLFSSL_SUCCESS) { + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + LOG_E("Failed to create socket"); + ret = WOLFSSL_FAILURE; + } + } + + if (ret == WOLFSSL_SUCCESS) { + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(DEFAULT_PORT); + + if (inet_pton(AF_INET, SERVER_IP, &servAddr.sin_addr) != 1) { + LOG_E("Invalid address, inet_pton failed"); + ret = WOLFSSL_FAILURE; + } + } + + /* Connect to server */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Created and configured socket"); + if (connect(sockfd, (struct sockaddr*) &servAddr, + sizeof(servAddr)) == -1) { + LOG_E("failed to connect"); + ret = WOLFSSL_FAILURE; + } + } + + /* Make new SSL context */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Socket connected"); + ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()); + if (ctx == NULL) { + LOG_E("wolfSSL_CTX_new failed"); + ret = WOLFSSL_FAILURE; + } + } + + /* Load trusted RSA or ECC CA cert to verify server, certs_test.h */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Created WOLFSSL_CTX"); +#if EXAMPLE_USE_RSA == 1 + ret = wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048, + sizeof_ca_cert_der_2048, SSL_FILETYPE_ASN1); +#else /* use ECC cert */ + ret = wolfSSL_CTX_load_verify_buffer(ctx, ca_ecc_cert_der_256, + sizeof_ca_ecc_cert_der_256, SSL_FILETYPE_ASN1); +#endif + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_CTX_load_verify_buffer failed"); + } + } + + /* Loading a Client/Server Certificate: + * + * This can be done in several different ways, and will be dependent on + * end user desired usage. The client/server certificate can be stored + * inside the SE050, but will need to be extracted back out in order to be + * loaded into wolfSSL. Alternatively, the certificate can be stored/kept + * in a buffer/array on the device (not SE050) and loaded from there. + * + * This example demonstrates both scenarios. When + * EXAMPLE_READ_CERT_FROM_SE050 is defined to 1, the demo will pull the + * client certificate out of the SE050 based on key ID where it has been + * loaded, then load that into wolfSSL. If not defined, the demo will + * directly load an example client certificate from a C array in + * , which matches the prviate key loaded into the + * SE050. */ +#if EXAMPLE_READ_CERT_FROM_SE050 == 1 + /* Read client cert from SE050 and load into WOLFSSL_CTX */ + if (ret == WOLFSSL_SUCCESS) { + /* Get object size at SE050 key ID, to allocate memory */ + ret = wc_se050_get_binary_object(cliCertKeyId, tmpCert, &tmpCertSz); + if (ret != LENGTH_ONLY_E) { + LOG_E("Failed to get size of certificate object in SE050"); + ret = WOLFSSL_FAILURE; + } + else { + ret = WOLFSSL_SUCCESS; + } + } + + if (ret == WOLFSSL_SUCCESS) { + /* Allocate memory to read client cert */ + tmpCert = (byte*)XMALLOC(tmpCertSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (tmpCert == NULL) { + LOG_E("Failed to allocate memory for client certificate"); + ret = WOLFSSL_FAILURE; + } + } + + if (ret == WOLFSSL_SUCCESS) { + /* Read client cert into tmp buffer */ + XMEMSET(tmpCert, 0, tmpCertSz); + + ret = wc_se050_get_binary_object(cliCertKeyId, tmpCert, &tmpCertSz); + if (ret != 0) { + LOG_E("Failed to read client cert from SE050"); + ret = WOLFSSL_FAILURE; + } + else { + ret = WOLFSSL_SUCCESS; + } + } + + if (ret == WOLFSSL_SUCCESS) { + ret = wolfSSL_CTX_use_certificate_buffer(ctx, tmpCert, tmpCertSz, + SSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_CTX_use_certificate_buffer failed"); + } + } +#else + /* Load client cert into CTX from buffer in certs_test.h */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Loaded CA certs into CTX"); + #if EXAMPLE_USE_RSA == 1 + ret = wolfSSL_CTX_use_certificate_buffer(ctx, client_cert_der_2048, + sizeof_client_cert_der_2048, SSL_FILETYPE_ASN1); + #else + ret = wolfSSL_CTX_use_certificate_buffer(ctx, cliecc_cert_der_256, + sizeof_cliecc_cert_der_256, SSL_FILETYPE_ASN1); + #endif + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_CTX_use_certificate_buffer failed"); + } + } +#endif /* EXAMPLE_READ_CERT_FROM_SE050 */ + + /* Set SE050 key slot to be used as client private key */ + if (ret == WOLFSSL_SUCCESS) { + ret = wolfSSL_CTX_use_PrivateKey_Id(ctx, + (const unsigned char*)&privateKeyId, + sizeof(int), HARDWARE_ID); + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_CTX_use_PrivateKey_Id failed"); + } + } + + /* Create a WOLFSSL session */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Loaded client private key into CTX"); + ssl = wolfSSL_new(ctx); + if (ssl == NULL) { + LOG_E("wolfSSL_new failed"); + ret = WOLFSSL_FAILURE; + } + } + + /* Pass socket descriptor to wolfSSL session */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Created new WOLFSSL"); + ret = wolfSSL_set_fd(ssl, sockfd); + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_set_fd failed"); + } + } + + /* Do SSL/TLS handshake with peer */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Set wolfSSL fd"); + ret = wolfSSL_connect(ssl); + if (ret != WOLFSSL_SUCCESS) { + LOG_E("wolfSSL_connect failed, err = %d", + wolfSSL_get_error(ssl, ret)); + } + } + + /* Send simple HTTP GET to server */ + if (ret == WOLFSSL_SUCCESS) { + LOG_I("Sending message to server: %s\n", httpGetMsg); + ret = wolfSSL_write(ssl, httpGetMsg, XSTRLEN(httpGetMsg)); + if (ret <= 0) { + LOG_E("wolfSSL_write failed"); + ret = WOLFSSL_FAILURE; + } + else { + LOG_I("wolfSSL_write sent %d bytes", ret); + ret = WOLFSSL_SUCCESS; + } + } + + /* Read server response */ + if (ret == WOLFSSL_SUCCESS) { + XMEMSET(reply, 0, sizeof(reply)); + ret = wolfSSL_read(ssl, reply, sizeof(reply)-1); + if (ret <= 0) { + LOG_E("wolfSSL_read failed"); + ret = WOLFSSL_FAILURE; + } + else { + LOG_I("Server response: %s\n", reply); + ret = WOLFSSL_SUCCESS; + } + } + + /* Bidirectional SSL/TLS shutdown, close_notify alerts */ + if (ret == WOLFSSL_SUCCESS) { + while (wolfSSL_shutdown(ssl) == SSL_SHUTDOWN_NOT_DONE) { + LOG_I("TLS shutdown not complete"); + } + LOG_I("TLS shutdown complete"); + } + + /* Free resources, close socket */ + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); + wolfSSL_Cleanup(); + close(sockfd); + +#if EXAMPLE_READ_CERT_FROM_SE050 == 1 + if (tmpCert != NULL) { + XFREE(tmpCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); + tmpCert = NULL; + tmpCertSz = 0; + } +#endif + + /* Erase example certs/keys from SE050 if stored */ + if (credentialsStored) { + ret = erase_certs_keys_from_se050(); + if (ret != 0) { + LOG_E("Error erasing certs/keys from SE050"); + } else { + ret = WOLFSSL_SUCCESS; + } + } + + if (ret == WOLFSSL_FAILURE) { + status = kStatus_SSS_Fail; + } + + LOG_I("Done with sample app"); + return status; +} + +#endif /* SIMW_DEMO_ENABLE__DEMO_WOLFSSL_CLIENT */ +