API skeleton for SSL/TLS client support

Completely non-functional. API sketch only.
This commit is contained in:
Alex Villacís Lasso
2021-10-06 18:28:23 -05:00
parent 8ee20adb2b
commit b3a01893fe
3 changed files with 86 additions and 0 deletions

View File

@@ -283,6 +283,18 @@ AsyncClient::AsyncClient(int sockfd)
, _rx_since_timeout(0) , _rx_since_timeout(0)
, _ack_timeout(ASYNC_MAX_ACK_TIME) , _ack_timeout(ASYNC_MAX_ACK_TIME)
, _connect_port(0) , _connect_port(0)
#if ASYNC_TCP_SSL_ENABLED
, _root_ca_len(0)
, _root_ca(NULL)
, _cli_cert_len(0)
, _cli_cert(NULL)
, _cli_key_len(0)
, _cli_key(NULL)
, _secure(false)
, _handshake_done(true)
, _psk_ident(0)
, _psk(0)
#endif // ASYNC_TCP_SSL_ENABLED
, _writeSpaceRemaining(TCP_SND_BUF) , _writeSpaceRemaining(TCP_SND_BUF)
, _conn_state(0) , _conn_state(0)
{ {
@@ -468,7 +480,11 @@ uint16_t AsyncClient::localPort() {
} }
#if ASYNC_TCP_SSL_ENABLED
bool AsyncClient::connect(IPAddress ip, uint16_t port, bool secure)
#else
bool AsyncClient::connect(IPAddress ip, uint16_t port) bool AsyncClient::connect(IPAddress ip, uint16_t port)
#endif // ASYNC_TCP_SSL_ENABLED
{ {
if (_socket != -1) { if (_socket != -1) {
log_w("already connected, state %d", _conn_state); log_w("already connected, state %d", _conn_state);
@@ -480,6 +496,11 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port)
return false; return false;
} }
#if ASYNC_TCP_SSL_ENABLED
_secure = secure;
_handshake_done = !secure;
#endif // ASYNC_TCP_SSL_ENABLED
int sockfd = socket(AF_INET, SOCK_STREAM, 0); int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) { if (sockfd < 0) {
log_e("socket: %d", errno); log_e("socket: %d", errno);
@@ -523,7 +544,11 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port)
} }
void _tcpsock_dns_found(const char * name, struct ip_addr * ipaddr, void * arg); void _tcpsock_dns_found(const char * name, struct ip_addr * ipaddr, void * arg);
#if ASYNC_TCP_SSL_ENABLED
bool AsyncClient::connect(const char* host, uint16_t port, bool secure){
#else
bool AsyncClient::connect(const char* host, uint16_t port){ bool AsyncClient::connect(const char* host, uint16_t port){
#endif // ASYNC_TCP_SSL_ENABLED
ip_addr_t addr; ip_addr_t addr;
if(!_start_asyncsock_task()){ if(!_start_asyncsock_task()){
@@ -535,11 +560,19 @@ bool AsyncClient::connect(const char* host, uint16_t port){
err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcpsock_dns_found, this); err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcpsock_dns_found, this);
if(err == ERR_OK) { if(err == ERR_OK) {
log_v("\taddr resolved as %08x, connecting...", addr.u_addr.ip4.addr); log_v("\taddr resolved as %08x, connecting...", addr.u_addr.ip4.addr);
#if ASYNC_TCP_SSL_ENABLED
return connect(IPAddress(addr.u_addr.ip4.addr), port, secure);
#else
return connect(IPAddress(addr.u_addr.ip4.addr), port); return connect(IPAddress(addr.u_addr.ip4.addr), port);
#endif // ASYNC_TCP_SSL_ENABLED
} else if(err == ERR_INPROGRESS) { } else if(err == ERR_INPROGRESS) {
log_v("\twaiting for DNS resolution"); log_v("\twaiting for DNS resolution");
_conn_state = 1; _conn_state = 1;
_connect_port = port; _connect_port = port;
#if ASYNC_TCP_SSL_ENABLED
_secure = secure;
_handshake_done = !secure;
#endif // ASYNC_TCP_SSL_ENABLED
return true; return true;
} }
log_e("error: %d", err); log_e("error: %d", err);
@@ -952,6 +985,28 @@ int8_t AsyncClient::abort(){
return ERR_ABRT; return ERR_ABRT;
} }
#if ASYNC_TCP_SSL_ENABLED
void AsyncClient::setRootCa(const char* rootca, const size_t len) {
_root_ca = (char*)rootca;
_root_ca_len = len;
}
void AsyncClient::setClientCert(const char* cli_cert, const size_t len) {
_cli_cert = (char*)cli_cert;
_cli_cert_len = len;
}
void AsyncClient::setClientKey(const char* cli_key, const size_t len) {
_cli_key = (char*)cli_key;
_cli_key_len = len;
}
void AsyncClient::setPsk(const char* psk_ident, const char* psk) {
_psk_ident = psk_ident;
_psk = psk;
}
#endif // ASYNC_TCP_SSL_ENABLED
const char * AsyncClient::errorToString(int8_t error){ const char * AsyncClient::errorToString(int8_t error){
switch(error){ switch(error){
case ERR_OK: return "OK"; case ERR_OK: return "OK";

View File

@@ -24,11 +24,19 @@
#ifndef ASYNCTCP_H_ #ifndef ASYNCTCP_H_
#define ASYNCTCP_H_ #define ASYNCTCP_H_
// TODO: se debe quitar este #define para que pueda habilitarse a voluntad el SSL
// según el proyecto. Se coloca aquí para probar el desarrollo
#define ASYNC_TCP_SSL_ENABLED 1
#include "IPAddress.h" #include "IPAddress.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include <functional> #include <functional>
#include <deque> #include <deque>
#include <list> #include <list>
#if ASYNC_TCP_SSL_ENABLED
#include <ssl_client.h>
#include "tcp_mbedtls.h"
#endif
extern "C" { extern "C" {
#include "lwip/err.h" #include "lwip/err.h"
@@ -46,6 +54,7 @@ class AsyncClient;
#define ASYNC_MAX_ACK_TIME 5000 #define ASYNC_MAX_ACK_TIME 5000
#define ASYNC_WRITE_FLAG_COPY 0x01 //will allocate new buffer to hold the data while sending (else will hold reference to the data given) #define ASYNC_WRITE_FLAG_COPY 0x01 //will allocate new buffer to hold the data while sending (else will hold reference to the data given)
#define ASYNC_WRITE_FLAG_MORE 0x02 //will not send PSH flag, meaning that there should be more data to be sent before the application should react. #define ASYNC_WRITE_FLAG_MORE 0x02 //will not send PSH flag, meaning that there should be more data to be sent before the application should react.
#define SSL_HANDSHAKE_TIMEOUT 5000 // timeout to complete SSL handshake
typedef std::function<void(void*, AsyncClient*)> AcConnectHandler; typedef std::function<void(void*, AsyncClient*)> AcConnectHandler;
typedef std::function<void(void*, AsyncClient*, size_t len, uint32_t time)> AcAckHandler; typedef std::function<void(void*, AsyncClient*, size_t len, uint32_t time)> AcAckHandler;
@@ -86,8 +95,17 @@ class AsyncClient : public AsyncSocketBase
AsyncClient(int sockfd = -1); AsyncClient(int sockfd = -1);
~AsyncClient(); ~AsyncClient();
#if ASYNC_TCP_SSL_ENABLED
bool connect(IPAddress ip, uint16_t port, bool secure = false);
bool connect(const char* host, uint16_t port, bool secure = false);
void setRootCa(const char* rootca, const size_t len);
void setClientCert(const char* cli_cert, const size_t len);
void setClientKey(const char* cli_key, const size_t len);
void setPsk(const char* psk_ident, const char* psk);
#else
bool connect(IPAddress ip, uint16_t port); bool connect(IPAddress ip, uint16_t port);
bool connect(const char* host, uint16_t port); bool connect(const char* host, uint16_t port);
#endif // ASYNC_TCP_SSL_ENABLED
void close(bool now = false); void close(bool now = false);
int8_t abort(); int8_t abort();
@@ -174,6 +192,19 @@ class AsyncClient : public AsyncSocketBase
uint16_t _connect_port = 0; uint16_t _connect_port = 0;
//const char * _connect_dnsname = NULL; //const char * _connect_dnsname = NULL;
#if ASYNC_TCP_SSL_ENABLED
size_t _root_ca_len;
char* _root_ca;
size_t _cli_cert_len;
char* _cli_cert;
size_t _cli_key_len;
char* _cli_key;
bool _secure;
bool _handshake_done;
const char* _psk_ident;
const char* _psk;
#endif // ASYNC_TCP_SSL_ENABLED
// The following private struct represents a buffer enqueued with the add() // The following private struct represents a buffer enqueued with the add()
// method. Each of these buffers are flushed whenever the socket becomes // method. Each of these buffers are flushed whenever the socket becomes
// writable // writable

0
src/tcp_mbedtls.h Normal file
View File