add initial native lwip example (#303)
Co-authored-by: David Garske <david@wolfssl.com>pull/311/head
parent
a10c30d27b
commit
f82abd8c62
|
@ -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
|
||||
```
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue