From 1b6974e4eecaad51d5a61a2eaece24c419878eac Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 15 Feb 2022 13:51:57 -0800 Subject: [PATCH] Improve TLS example to accept STDIN and "exit" command. Improve documentation. --- btle/ecies/README.md | 26 ++++++++++++++++++++--- btle/ecies/ecc-client.c | 8 +++++-- btle/ecies/ecc-server.c | 5 ++++- btle/tls/README.md | 23 ++++++++++++++------ btle/tls/client-tls13-btle.c | 41 ++++++++++++++++++++++++------------ btle/tls/server-tls13-btle.c | 32 +++++++++++++++++----------- 6 files changed, 97 insertions(+), 38 deletions(-) diff --git a/btle/ecies/README.md b/btle/ecies/README.md index 05127bff..dedcaee0 100644 --- a/btle/ecies/README.md +++ b/btle/ecies/README.md @@ -5,6 +5,8 @@ This example demonstrates a lightweight method for exchanging data securely over The first phase is key establishment, which is done through ECDH and HDKF. ECC was chosen for these examples because its lightweight and widely used. Then salt exchanged for each message to prevent reply attacks. The encryption is done with AES CBC. The data integrity is done using HMAC-SHA256. +The peer's key should be validated against a known key or certificate. Client should hash and verify this public key against trusted certificate (already exchanged) out of band. An ECC signature is about 65 bytes. + ## ECC Encrypt/Decrypt Example See `BTLESecureMessageExchange.pdf` for details. @@ -24,7 +26,7 @@ sudo make install ``` #define HAVE_ECC -#define HAVE_ECC_ENCRYP +#define HAVE_ECC_ENCRYPT #define HAVE_HKDF ``` @@ -34,11 +36,29 @@ Use two consoles and STDIN to exchange data between the client and server. From the client enter a message and hit enter. This will be encrypted and sent to the server. The server will decrypt, print and re-encrypt the message and send it back to the client (echo). +Type "exit" to close the connection. + ``` -./ecc-server -./ecc-client +% ./ecc-server +Waiting for client +Recv 16: asdf +Recv 16: exit +Exit, closing connection ``` +``` +% ./ecc-client +Enter text to send: +asdf +Recv 16: asdf +Enter text to send: +exit +Recv 16: exit +Exit, closing connection +``` + +Note: The messages are padded to the AES block size 16-bytes. + ### Debugging To enable debugging or switch to using a static version of wolfSSL edit the `Makefile` and uncomment `CFLAGS+=$(DEBUG_FLAGS)` and `STATIC_LIB+=$(LIB_PATH)/lib/libwolfssl.a`. Then comment out `LIBS+=$(DYN_LIB) -lm`. diff --git a/btle/ecies/ecc-client.c b/btle/ecies/ecc-client.c index 56d1f063..431b1261 100644 --- a/btle/ecies/ecc-client.c +++ b/btle/ecies/ecc-client.c @@ -151,9 +151,11 @@ int main(int argc, char** argv) } /* get message to send */ - plainSz = sizeof(plain); + printf("Enter text to send:\n"); + plainSz = sizeof(plain)-1; fgets((char*)plain, plainSz, stdin); plainSz = strlen((char*)plain); + /* pad message at 16 bytes for AES block size */ ret = btle_msg_pad(plain, (int*)&plainSz, devCtx); if (ret != 0) { printf("btle_msg_pad failed %d\n", ret); @@ -194,8 +196,10 @@ int main(int argc, char** argv) printf("Recv %d: %s\n", plainSz, plain); /* check for exit flag */ - if (strstr((char*)plain, "EXIT")) + if (strcasestr((char*)plain, "EXIT")) { + printf("Exit, closing connection\n"); break; + } /* reset context (reset my salt) */ ret = wc_ecc_ctx_reset(cliCtx, &rng); diff --git a/btle/ecies/ecc-server.c b/btle/ecies/ecc-server.c index 907024b6..efdc6223 100644 --- a/btle/ecies/ecc-server.c +++ b/btle/ecies/ecc-server.c @@ -57,6 +57,7 @@ int main(int argc, char** argv) } /* open BTLE */ + printf("Waiting for client\n"); ret = btle_open(&devCtx, BTLE_ROLE_SERVER); if (ret != 0) { printf("btle_open failed %d!\n", ret); @@ -188,8 +189,10 @@ int main(int argc, char** argv) } /* check for exit flag */ - if (strstr((char*)plain, "EXIT")) + if (strcasestr((char*)plain, "EXIT")) { + printf("Exit, closing connection\n"); break; + } /* reset context (reset my salt) */ ret = wc_ecc_ctx_reset(srvCtx, &rng); diff --git a/btle/tls/README.md b/btle/tls/README.md index d46471f0..fbd61821 100644 --- a/btle/tls/README.md +++ b/btle/tls/README.md @@ -16,22 +16,33 @@ sudo make install Use two consoles run the examples to send a test message securely. The server will present an ECC server certificate and the client will validate it. +The client will attempt STDIN input and the server will echo. Use "exit" to close the connection. + ``` % ./server-tls13-btle Waiting for client TLS accepting TLS Accept handshake done -Read (0): Testing 1, 2 and 3 -Sent (0): Testing 1, 2 and 3 +Read (5): asdf +Sent (5): asdf +Read (5): exit +Sent (5): exit +Exit, closing connection ``` ``` - % ./client-tls13-btle +% ./client-tls13-btle TLS connecting TLS Connect handshake done -Sending test string -Sent (0): Testing 1, 2 and 3 -Read (0): Testing 1, 2 and 3 +Enter text to send: +asdf +Sent (5): asdf +Read (5): asdf +Enter text to send: +exit +Sent (5): exit +Read (5): exit +Exit, closing connection ``` ### Debugging diff --git a/btle/tls/client-tls13-btle.c b/btle/tls/client-tls13-btle.c index bf7f6187..e268fa27 100644 --- a/btle/tls/client-tls13-btle.c +++ b/btle/tls/client-tls13-btle.c @@ -87,8 +87,8 @@ int main(int argc, char** argv) WOLFSSL_CTX* ctx = NULL; WOLFSSL* ssl = NULL; CbCtx_t cBctx; - const char testStr[] = "Testing 1, 2 and 3"; - byte readBuf[100]; + byte plain[BTLE_MSG_MAX_SIZE]; + word32 plainSz; memset(&cBctx, 0, sizeof(cBctx)); @@ -166,19 +166,32 @@ int main(int argc, char** argv) } printf("TLS Connect handshake done\n"); - printf("Sending test string\n"); - do { - ret = wolfSSL_write(ssl, testStr, XSTRLEN(testStr)); - err = wolfSSL_get_error(ssl, ret); - } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE); - printf("Sent (%d): %s\n", err, testStr); + while (1) { + /* get message to send */ + printf("Enter text to send:\n"); - XMEMSET(readBuf, 0, sizeof(readBuf)); - do { - ret = wolfSSL_read(ssl, readBuf, sizeof(readBuf)-1); - err = wolfSSL_get_error(ssl, ret); - } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE); - printf("Read (%d): %s\n", err, readBuf); + plainSz = sizeof(plain)-1; + fgets((char*)plain, plainSz, stdin); + plainSz = strlen((char*)plain); + + do { + ret = wolfSSL_write(ssl, plain, plainSz); + err = wolfSSL_get_error(ssl, ret); + } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE); + printf("Sent (%d): %s\n", ret, plain); + + do { + ret = wolfSSL_read(ssl, plain, sizeof(plain)-1); + err = wolfSSL_get_error(ssl, ret); + } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE); + printf("Read (%d): %s\n", ret, plain); + + /* check for exit flag */ + if (strcasestr((char*)plain, "EXIT")) { + printf("Exit, closing connection\n"); + break; + } + }; ret = 0; /* Success */ diff --git a/btle/tls/server-tls13-btle.c b/btle/tls/server-tls13-btle.c index 1ba52922..79f1548b 100644 --- a/btle/tls/server-tls13-btle.c +++ b/btle/tls/server-tls13-btle.c @@ -162,19 +162,27 @@ int main(int argc, char** argv) } printf("TLS Accept handshake done\n"); - /* Waiting for data to echo */ - XMEMSET(echoBuffer, 0, sizeof(echoBuffer)); - do { - ret = wolfSSL_read(ssl, echoBuffer, sizeof(echoBuffer)-1); - err = wolfSSL_get_error(ssl, ret); - } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE); - printf("Read (%d): %s\n", err, echoBuffer); + while (1) { + /* Waiting for data to echo */ + memset(echoBuffer, 0, sizeof(echoBuffer)); + do { + ret = wolfSSL_read(ssl, echoBuffer, sizeof(echoBuffer)-1); + err = wolfSSL_get_error(ssl, ret); + } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE); + printf("Read (%d): %s\n", ret, echoBuffer); - do { - ret = wolfSSL_write(ssl, echoBuffer, XSTRLEN((char*)echoBuffer)); - err = wolfSSL_get_error(ssl, ret); - } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE); - printf("Sent (%d): %s\n", err, echoBuffer); + do { + ret = wolfSSL_write(ssl, echoBuffer, XSTRLEN((char*)echoBuffer)); + err = wolfSSL_get_error(ssl, ret); + } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE); + printf("Sent (%d): %s\n", ret, echoBuffer); + + /* check for exit flag */ + if (strcasestr((char*)echoBuffer, "EXIT")) { + printf("Exit, closing connection\n"); + break; + } + } ret = 0; /* Success */