diff --git a/src/AsyncTCP.cpp b/src/AsyncTCP.cpp index 2a06f34..3d81963 100644 --- a/src/AsyncTCP.cpp +++ b/src/AsyncTCP.cpp @@ -283,6 +283,18 @@ AsyncClient::AsyncClient(int sockfd) , _rx_since_timeout(0) , _ack_timeout(ASYNC_MAX_ACK_TIME) , _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) , _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) +#endif // ASYNC_TCP_SSL_ENABLED { if (_socket != -1) { log_w("already connected, state %d", _conn_state); @@ -480,6 +496,11 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port) 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); if (sockfd < 0) { 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); +#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){ +#endif // ASYNC_TCP_SSL_ENABLED ip_addr_t addr; 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); if(err == ERR_OK) { 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); +#endif // ASYNC_TCP_SSL_ENABLED } else if(err == ERR_INPROGRESS) { log_v("\twaiting for DNS resolution"); _conn_state = 1; _connect_port = port; +#if ASYNC_TCP_SSL_ENABLED + _secure = secure; + _handshake_done = !secure; +#endif // ASYNC_TCP_SSL_ENABLED return true; } log_e("error: %d", err); @@ -952,6 +985,28 @@ int8_t AsyncClient::abort(){ 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){ switch(error){ case ERR_OK: return "OK"; diff --git a/src/AsyncTCP.h b/src/AsyncTCP.h index 9660aac..36d9cdf 100644 --- a/src/AsyncTCP.h +++ b/src/AsyncTCP.h @@ -24,11 +24,19 @@ #ifndef 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 "sdkconfig.h" #include #include #include +#if ASYNC_TCP_SSL_ENABLED +#include +#include "tcp_mbedtls.h" +#endif extern "C" { #include "lwip/err.h" @@ -46,6 +54,7 @@ class AsyncClient; #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_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 AcConnectHandler; typedef std::function AcAckHandler; @@ -86,8 +95,17 @@ class AsyncClient : public AsyncSocketBase AsyncClient(int sockfd = -1); ~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(const char* host, uint16_t port); +#endif // ASYNC_TCP_SSL_ENABLED void close(bool now = false); int8_t abort(); @@ -174,6 +192,19 @@ class AsyncClient : public AsyncSocketBase uint16_t _connect_port = 0; //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() // method. Each of these buffers are flushed whenever the socket becomes // writable diff --git a/src/tcp_mbedtls.h b/src/tcp_mbedtls.h new file mode 100644 index 0000000..e69de29