add initial native lwip example (#303)

Co-authored-by: David Garske <david@wolfssl.com>
pull/311/head
JacobBarthelmeh 2022-04-05 09:08:15 -06:00 committed by GitHub
parent a10c30d27b
commit f82abd8c62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 262 additions and 0 deletions

22
lwip/README.md 100644
View File

@ -0,0 +1,22 @@
# LWIP Native Example
Assumes there is an existing STM project with native LwIP support. wolfSSL needs to be compiled with the macro `WOLFSSL_LWIP_NATIVE`
The main function to call in the example code is `tls_echoclient_connect();`
Macros in `lwipopts.h` were also adjusted to better handle TLS packets, which can be as large as 16k. The macros adjusted were:
- MEM_SIZE(16*1024)
- MEMP_NUM_PBUF (10 -> 20)
- PBUF_POOL_SIZE (8 -> 9)
- PBUF_POOL_BUFSIZE (512 -> 2048)
- TCP_WND (2*TCP_MSS -> 11*TCP_MSS)
To start up a server for the example client to connect to use the bundled wolfSSL example
server on a desktop:
```
cd wolfssl
./configure && make
./examples/server/server -b -d -p 11111 -c ./certs/server-ecc.pem -k ./certs/ecc-key.pem -i
```

View File

@ -0,0 +1,240 @@
/* example-lwip-native-echoclient.c
*
* Copyright (C) 2006-2022 wolfSSL Inc.
*
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
* 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-1301, USA
*/
#include "lwip/debug.h"
#include "lwip/stats.h"
#include "lwip/tcp.h"
#include "lwip/memp.h"
#include <stdio.h>
#include <string.h>
#ifndef WOLFSSL_USER_SETTINGS
#include <wolfssl/options.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/ssl.h>
#ifndef NO_RSA
#define USE_CERT_BUFFERS_2048
#define CA_CERTS ca_cert_der_2048
#define CA_CERTS_LEN sizeof_ca_cert_der_2048
#define CLIENT_CERT client_cert_der_2048
#define CLIENT_CERT_LEN sizeof_client_cert_der_2048
#define CLIENT_KEY client_key_der_2048
#define CLIENT_KEY_LEN sizeof_client_key_der_2048
#elif defined(HAVE_ECC)
#define USE_CERT_BUFFERS_256
#define CA_CERTS ca_ecc_cert_der_256
#define CA_CERTS_LEN sizeof_ca_ecc_cert_der_256
#define CLIENT_CERT cliecc_cert_der_256
#define CLIENT_CERT_LEN sizeof_cliecc_cert_der_256
#define CLIENT_KEY ecc_clikey_der_256
#define CLIENT_KEY_LEN sizeof_ecc_clikey_der_256
#else
#error This examples requires either RSA or ECC to be enabled
#endif
#include <wolfssl/certs_test.h>
#include <wolfcrypt/test/test.h>
#ifndef DEST_PORT
#define DEST_PORT 11111
#endif
#ifndef DEST_IP_ADDR0
#define DEST_IP_ADDR0 127
#define DEST_IP_ADDR1 0
#define DEST_IP_ADDR2 0
#define DEST_IP_ADDR3 1
#endif
#ifndef MAX_MSG_SIZE
#define MAX_MSG_SIZE
#endif
#define TEST_MSG "TLS **TEST 1** "
static err_t tcp_echoclient_connected(void *arg, struct tcp_pcb *tpcb, err_t err);
static void TLS_shutdown(void);
static int TLS_connect(void);
static int TLS_setup(void);
struct tcp_pcb *tls_pcb = NULL;
struct tcp_pcb *debug_pcb = NULL;
static int tlsConnected = 0;
static int tcpConnected = 0;
static int tlsWaitingForReply = 0;
static WOLFSSL_CTX *ctx = NULL;
static WOLFSSL *ssl = NULL;
void loggingCb(const int logLevel, const char *const logMessage)
{
printf("%s\n", logMessage);
(void)logLevel;
}
void tls_echoclient_connect(void)
{
ip_addr_t DestIPaddr;
if (tcpConnected == 0) {
tls_pcb = tcp_new();
if (tls_pcb != NULL) {
IP4_ADDR(&DestIPaddr, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3);
tcp_connect(tls_pcb, &DestIPaddr, DEST_PORT,
tcp_echoclient_connected);
}
}
if (tcpConnected == 1 && tlsConnected == 0) {
TLS_connect();
}
if (tlsConnected == 1) {
int ret;
char reply[MAX_MSG_SIZE];
int err;
if (tlsWaitingForReply == 0) {
ret = wolfSSL_write(ssl, TEST_MSG, sizeof(TEST_MSG));
if (ret <= 0) {
loggingCb(0, "error when writing TLS message");
shutdown();
}
else {
tlsWaitingForReply = 1;
}
}
/* read a reply from the server */
if (tlsWaitingForReply == 1) {
memset(reply, 0, sizeof(reply));
ret = wolfSSL_read(ssl, reply, sizeof(reply));
if (ret <= 0) {
err = wolfSSL_get_error(ssl, 0);
if (err != SSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE) {
loggingCb(0, "error when reading TLS message");
shutdown();
}
}
if (ret > 0) {
loggingCb(0, reply);
shutdown(); /* received reply, done with connection */
}
}
}
}
static err_t tcp_echoclient_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
{
if (err == ERR_OK) {
tcpConnected = 1;
/* a tcp_poll could be added here for connection timeout checking */
return TLS_setup();
}
return ERR_OK;
}
/* setup all the TLS structures and load CA */
static int TLS_setup(void)
{
int ret;
#ifdef DEBUG_WOLFSSL
/* redirect wolfssl debug print outs */
wolfSSL_SetLoggingCb(loggingCb);
wolfSSL_Debugging_ON();
#endif
wolfSSL_Init(); /* called once on program startup */
ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
if (ctx == NULL) {
loggingCb(0, "ctx was null");
shutdown();
return ERR_MEM;
}
/* Load the CA */
ret = wolfSSL_CTX_load_verify_buffer(ctx, CA_CERTS, CA_CERTS_LEN,
WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
loggingCb(0, "error loading in verify buffer");
return ERR_MEM;
}
#if 1
/* Disable peer certificate validation for testing */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL);
#endif
ssl = wolfSSL_new(ctx);
if (ssl == NULL) {
loggingCb(0, "ssl was null");
return ERR_MEM;
}
wolfSSL_SetIO_LwIP(ssl, tls_pcb, NULL, NULL, NULL);
return ERR_OK;
}
static int TLS_connect(void)
{
if (wolfSSL_connect(ssl) != WOLFSSL_SUCCESS) {
/* check if hitting a want read/write case and should call again */
int err = wolfSSL_get_error(ssl, 0);
if (err != SSL_ERROR_WANT_READ && err != WOLFSSL_ERROR_WANT_WRITE) {
loggingCb(0, "connect error, shutting down");
loggingCb(0, wolfSSL_ERR_reason_error_string(err));
shutdown();
return ERR_CONN;
}
loggingCb(0, "found want read/write");
}
else {
loggingCb(0, "setting tlsConnected to 1");
tlsConnected = 1;
}
return ERR_OK;
}
/* close all connections and free TLS session */
static void TLS_shutdown(void)
{
if (ssl != NULL) {
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
}
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
}
tlsConnected = 0;
tlsWaitingForReply = 0;
wolfSSL_Cleanup();
if (tcpConnected == 1) {
tcp_output(tls_pcb);
tcp_close(tls_pcb);
tls_pcb = NULL;
tcpConnected = 0;
}
}