diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..6816a4b76 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "compat"] + path = compat + url = https://github.com/attachix/lwirax.git diff --git a/README.md b/README.md index 48b4c5e88..fe46b327c 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ time ctime ``` -For use with LwIP raw TCP API, see [compat/README.md](compat/README.md) +For use with LwIP raw TCP API, see [compat/README.md](https://github.com/attachix/lwirax/blob/master/README.md) To build, add xtensa toolchain to your path, and run `make`. diff --git a/compat b/compat new file mode 160000 index 000000000..227b8e248 --- /dev/null +++ b/compat @@ -0,0 +1 @@ +Subproject commit 227b8e248b6013f88c14bc37a8b8574cf0d8535a diff --git a/compat/README.md b/compat/README.md deleted file mode 100644 index fff33837d..000000000 --- a/compat/README.md +++ /dev/null @@ -1,149 +0,0 @@ -If you are using [LWIP raw tcp mode](http://lwip.wikia.com/wiki/Raw/TCP) and want to add SSL support below are the steps that can help you to achieve this with the help of [axTLS]( http://axtls.sourceforge.net/ ). - -First you have to include the `lwipr_compat.h` header. - -```C -#include "compat/lwipr_compat.h" -``` - -Then in the code block where you initialize the tcp raw connection you should call `axl_init`. -Take a look at the example below: - -```C -lwip_init(); - -/* - * The line below should be added AFTER the lwip_init code - * AND BEFORE the call to tcp_new() - * The parameter value 10 specifies how many SSL connections are expected - */ -axl_init(10); - -// .. some more code -tcp = tcp_new(); -tcp_sent(tcp, staticOnSent); -tcp_recv(tcp, staticOnReceive); -tcp_err(tcp, staticOnError); -tcp_poll(tcp, staticOnPoll, 4); -// ... and even more code -res = tcp_connect(tcp, &addr, port, staticOnConnected); - - -``` - -Now we should add in our `staticOnConnected` funciton code to create new ssl context and ssl object. -In the example below the `sslObj` and `sslContext` are defined as global - -```C -// global definitions -SSL *sslObj = NULL; -SSLCTX* sslContext = NULL; - -// and some more code... - -err_t staticOnConnected(void *arg, struct tcp_pcb *tcp, err_t err) -{ - int clientfd = -1; - uint32_t options = 0; - - if (tcp == NULL) { - /* @TODO: Take care to handle error conditions */ - return -1; - } - - clientfd = axl_append(tcp); - if(clientfd == -1) { - printf("Unable to add LWIP tcp -> clientfd mapping\n"); - return ERR_OK; - } - - printf("Connected: ClientId: %d\n", clientfd); -#ifdef SSL_DEBUG - options |= SSL_DISPLAY_STATES | SSL_DISPLAY_BYTES; -#endif - - // if you want to verify the server certificate later you can also add the following option - options |= SSL_SERVER_VERIFY_LATER - - sslContext = ssl_ctx_new(SSL_CONNECT_IN_PARTS | options, 1); // !!! SSL_CONNECT_IN_PARTS must be in the flags !!! - sslObj = ssl_client_new(sslContext, clientfd, NULL, 0); - - return ERR_OK; -} -``` - - -Once we are connected we can send and receive information. For the receiving part we can do the following - -```C -err_t staticOnReceive(void *arg, struct tcp_pcb *tcp, struct pbuf *p, err_t err) -{ - uint8_t *read_buf = NULL; - int read_bytes = 0; - - printf("Err: %d\n", err); - - if(tcp == NULL || p == NULL) { - /* @TODO: Take care to handle error conditions */ - return -1; - } - - read_bytes = axl_ssl_read(sslObj, &read_buf, tcp, p); - if(read_bytes > 0) { - printf("Got data: %s", read_buf); - // @TODO: Do something useful with the read_buf - } - - return ERR_OK; -} -``` - -In the receiving part you can also add debug code to display more information about the SSL handshake, once it was successul. - - -```C -err_t staticOnReceive(void *arg, struct tcp_pcb *tcp, struct pbuf *p, err_t err) -{ - static int show_info = 0; - const char *common_name = NULL; - - // .. - read_bytes = axl_ssl_read(sslObj, &read_buf, tcp, p); - if(read_bytes > 0) { - printf("Got data: %s", read_buf); - // @TODO: Do something useful with the read_buf - } - - if(!show_info && ssl_handshake_status(sslObj) == SSL_OK) { - common_name = ssl_get_cert_dn(sslObj, SSL_X509_CERT_COMMON_NAME); - if (common_name) { - printf("Common Name:\t\t\t%s\n", common_name); - } - - // These two funcitons below can be found in the axtls examples - display_session_id(sslObj); - display_cipher(sslObj); - show_info = 1; - } - - return ERR_OK; -} - -``` - - -And for the sending part we can use the following code sample as a start - -```C -void someSendingfunction() { - uint8_t *out_buf; - int out_bytes = 0; - - // ... take care to store something in the out_buf - - axl_ssl_write(sslObj, out_buf, out_bytes); -} - -``` - -Good luck and send your success stories at slaff@attachix.com. diff --git a/compat/lwipr_compat.c b/compat/lwipr_compat.c deleted file mode 100644 index a334454fb..000000000 --- a/compat/lwipr_compat.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Compatibility for AxTLS with LWIP raw tcp mode (http://lwip.wikia.com/wiki/Raw/TCP) - * - * Created on: Jan 15, 2016 - * Author: Slavey Karadzhov - */ -#include "lwipr_compat.h" - -AxlTcpDataArray axlFdArray; - -#include - -/* High Level "public" functions */ - -/** - * Function that should be called once we are ready to use the axTLS - LWIP raw compatibility - */ -void axl_init(int capacity) { - ax_fd_init(&axlFdArray, capacity); -} - -/** - * Appends a tcp to the internal array. Returns client file descriptor - */ -int axl_append(struct tcp_pcb *tcp) { - return ax_fd_append(&axlFdArray, tcp); -} - -/** - * Frees the internal mapping from this tcp. Returns the number of occurrences of the tcp - */ -int axl_free(struct tcp_pcb *tcp) { - int i; - int occurances = 0; - - if(tcp == NULL) { - return 0; - } - - AxlTcpDataArray *vector = &axlFdArray; - AXL_DEBUG("AXL: Freeing %d tcp item", vector->size); - for (i = 0; i < vector->size; i++) { - if (vector->data[i].tcp == tcp) { - if(vector->data[i].tcp_pbuf != NULL) { - pbuf_free(vector->data[i].tcp_pbuf); - vector->data[i].tcp_pbuf = NULL; - } - vector->data[i].tcp = NULL; - vector->data[i].pbuf_offset = 0; - occurances++; - } - } - - return occurances; -} - -/** - * Reads data from the SSL over TCP stream. Returns decrypted data. - * @param SSL *sslObj - * @param uint8_t **in_data - pointer to the decrypted incoming data, or NULL if nothing was read - * @param void *arg - possible arguments passed to the tcp raw layer during initialization - * @param tcp_pcb *tcp - pointer to the raw tcp object - * @param pbuf *p - pointer to the buffer with the TCP packet data - * - * @return int - * 0 - when everything is fine but there are no symbols to process yet - * < 0 - when there is an error - * > 0 - the length of the clear text characters that were read - */ -int axl_ssl_read(SSL *ssl, uint8_t **in_data, struct tcp_pcb *tcp, struct pbuf *p) { - int read_bytes = 0; - int total_bytes = 0; - int clientfd = -1; - - AxlTcpData* data = NULL; - - if (ssl == NULL) { - return ERR_AXL_INVALID_SSL; - } - - clientfd = ax_fd_getfd(&axlFdArray, tcp); - if(clientfd == -1) { - return ERR_AXL_INVALID_CLIENTFD; - } - - data = ax_fd_get(&axlFdArray, clientfd); - if(data == NULL) { - return ERR_AXL_INVALID_CLIENTFD_DATA; - } - - if (p != NULL) { - data->tcp_pbuf = p; - data->pbuf_offset = 0; - } - - AXL_DEBUG("READY TO READ SOME DATA\n"); - - tcp_recved(tcp, p->tot_len); - do { - WATCHDOG_FEED(); - read_bytes = ssl_read(ssl, in_data); - AXL_DEBUG("axl_ssl_read: Read bytes: %d\n", read_bytes); - if(read_bytes < SSL_OK) { - /* An error has occurred. Give it back for further processing */ - total_bytes = read_bytes; - break; - } - total_bytes+= read_bytes; - } while (p->tot_len - data->pbuf_offset > 0); - - pbuf_free(p); - - return total_bytes; -} - -/* - * Lower Level LWIP RAW functions - */ - -/* - * The LWIP tcp raw version of the SOCKET_WRITE(A, B, C) - */ -int ax_port_write(int clientfd, uint8_t *buf, uint16_t bytes_needed) { - AxlTcpData *data = NULL; - int tcp_len = 0; - err_t err = ERR_OK; - - data = ax_fd_get(&axlFdArray, clientfd); - if(data == NULL) { - return ERR_AXL_INVALID_CLIENTFD; - } - - if (data == NULL || data->tcp == NULL || buf == NULL || bytes_needed == 0) { - AXL_DEBUG("Return Zero.\n"); - return 0; - } - - if (tcp_sndbuf(data->tcp) < bytes_needed) { - tcp_len = tcp_sndbuf(data->tcp); - if(tcp_len == 0) { - AXL_DEBUG("The send buffer is full! We have problem.\n"); - return 0; - } - - } else { - tcp_len = bytes_needed; - } - - if (tcp_len > 2 * data->tcp->mss) { - tcp_len = 2 * data->tcp->mss; - } - - do { - err = tcp_write(data->tcp, buf, tcp_len, TCP_WRITE_FLAG_COPY); - if(err < SSL_OK) { - AXL_DEBUG("Got error: %d\n", err); - } - - if (err == ERR_MEM) { - AXL_DEBUG("Not enough memory to write data with length: %d (%d)\n", tcp_len, bytes_needed); - tcp_len /= 2; - } - } while (err == ERR_MEM && tcp_len > 1); - AXL_DEBUG("send_raw_packet length %d(%d)\n", tcp_len, bytes_needed); - if (err == ERR_OK) { - err = tcp_output(data->tcp); - if(err != ERR_OK) { - AXL_DEBUG("tcp_output got err: %d\n", err); - } - } - - return tcp_len; -} - -/* - * The LWIP tcp raw version of the SOCKET_READ(A, B, C) - */ -int ax_port_read(int clientfd, uint8_t *buf, int bytes_needed) { - AxlTcpData *data = NULL; - uint8_t *read_buf = NULL; - uint8_t *pread_buf = NULL; - u16_t recv_len = 0; - - data = ax_fd_get(&axlFdArray, clientfd); - if (data == NULL) { - return ERR_AXL_INVALID_CLIENTFD_DATA; - } - - if(data->tcp_pbuf == NULL || data->tcp_pbuf->tot_len == 0) { - AXL_DEBUG("Nothing to read?! May be the connection needs resetting?\n"); - return 0; - } - - read_buf =(uint8_t*)calloc(data->tcp_pbuf->len + 1, sizeof(uint8_t)); - pread_buf = read_buf; - if (pread_buf != NULL){ - recv_len = pbuf_copy_partial(data->tcp_pbuf, read_buf, bytes_needed, data->pbuf_offset); - data->pbuf_offset += recv_len; - } - - if (recv_len != 0) { - memcpy(buf, read_buf, recv_len); - } - - if(bytes_needed < recv_len) { - AXL_DEBUG("Bytes needed: %d, Bytes read: %d\n", bytes_needed, recv_len); - } - - free(pread_buf); - pread_buf = NULL; - - return recv_len; -} - -int ax_get_file(const char *filename, uint8_t **buf) { - *buf = 0; - return 0; -} - -void ax_wdt_feed() { -} - -/* - * Utility functions - */ -void ax_fd_init(AxlTcpDataArray *vector, int capacity) { - vector->size = 0; - vector->capacity = capacity; - vector->data = (AxlTcpData*) malloc(sizeof(AxlTcpData) * vector->capacity); -} - -int ax_fd_append(AxlTcpDataArray *vector, struct tcp_pcb *tcp) { - int index; - - ax_fd_double_capacity_if_full(vector); - index = vector->size++; - vector->data[index].tcp = tcp; - vector->data[index].tcp_pbuf = NULL; - vector->data[index].pbuf_offset = 0; - - return index; -} - -AxlTcpData* ax_fd_get(AxlTcpDataArray *vector, int index) { - if (index >= vector->size || index < 0) { - AXL_DEBUG("Index %d out of bounds for vector of size %d\n", index, - vector->size); - return NULL; - } - return &(vector->data[index]); -} - -int ax_fd_getfd(AxlTcpDataArray *vector, struct tcp_pcb *tcp) { - int i; - for (i = 0; i < vector->size; i++) { - if (vector->data[i].tcp == tcp) { - return i; - } - } - - return -1; -} - -void ax_fd_set(AxlTcpDataArray *vector, int index, struct tcp_pcb *tcp) { - AxlTcpData value; - while (index >= vector->size) { - ax_fd_append(vector, 0); - } - - value.tcp = tcp; - value.tcp_pbuf = NULL; - value.pbuf_offset = 0; - vector->data[index] = value; -} - -void ax_fd_double_capacity_if_full(AxlTcpDataArray *vector) { - if (vector->size >= vector->capacity) { - vector->capacity *= 2; - vector->data = (AxlTcpData*)realloc(vector->data, sizeof(AxlTcpData) * vector->capacity); - } -} - -void ax_fd_free(AxlTcpDataArray *vector) { - free(vector->data); -} diff --git a/compat/lwipr_compat.h b/compat/lwipr_compat.h deleted file mode 100644 index 1a8846f94..000000000 --- a/compat/lwipr_compat.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Compatibility for AxTLS with LWIP raw tcp mode (http://lwip.wikia.com/wiki/Raw/TCP) - * - * Created on: Jan 15, 2016 - * Author: Slavey Karadzhov - */ - -#ifndef LWIPR_COMPAT_H -#define LWIPR_COMPAT_H - -/* - * All those functions will run only if LWIP tcp raw mode is used - */ -#if LWIP_RAW==1 - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lwipr_platform.h" -#include "ssl/ssl.h" -#include "ssl/tls1.h" - -#define ERR_AXL_INVALID_SSL -101 -#define ERR_AXL_INVALID_TCP -102 -#define ERR_AXL_INVALID_CLIENTFD -103 -#define ERR_AXL_INVALID_CLIENTFD_DATA -104 - -#define SOCKET_READ(A, B, C) ax_port_read(A, B, C) -#define SOCKET_WRITE(A, B, C) ax_port_write(A, B, C) - -/* - * Define the AXL_DEBUG function to add debug functionality - */ -#ifndef AXL_DEBUG - #define AXL_DEBUG(...) -#endif - -/** - * Define watchdog function to be called during CPU intensive operations. - */ -#ifndef WATCHDOG_FEED - #define WATCHDOG_FEED() -#endif - -typedef struct { - struct tcp_pcb *tcp; - struct pbuf *tcp_pbuf; - int pbuf_offset; -} AxlTcpData; - - -typedef struct { - int size; /* slots used so far */ - int capacity; /* total available slots */ - AxlTcpData *data; /* array of TcpData objects */ -} AxlTcpDataArray; - -/* - * High Level Functions - these are the ones that should be used directly - */ - -void axl_init(int capacity); -int axl_append(struct tcp_pcb *tcp); -int axl_free(struct tcp_pcb *tcp); - -#define axl_ssl_write(A, B, C) ssl_write(A, B, C) -int axl_ssl_read(SSL *sslObj, uint8_t **in_data, struct tcp_pcb *tcp, struct pbuf *p); - -/* - * Lower Level Socket Functions - used internally from axTLS - */ - -int ax_port_write(int clientfd, uint8_t *buf, uint16_t bytes_needed); -int ax_port_read(int clientfd, uint8_t *buf, int bytes_needed); - -/* - * Lower Level Utility functions - */ -void ax_fd_init(AxlTcpDataArray *vector, int capacity); -int ax_fd_append(AxlTcpDataArray *vector, struct tcp_pcb *tcp); -AxlTcpData* ax_fd_get(AxlTcpDataArray *vector, int index); -int ax_fd_getfd(AxlTcpDataArray *vector, struct tcp_pcb *tcp); -void ax_fd_set(AxlTcpDataArray *vector, int index, struct tcp_pcb *tcp); -void ax_fd_double_capacity_if_full(AxlTcpDataArray *vector); -void ax_fd_free(AxlTcpDataArray *vector); - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_RAW==1 */ - -#endif /* LWIPR_COMPAT_H */ diff --git a/compat/lwipr_platform.h b/compat/lwipr_platform.h deleted file mode 100644 index 518e8bf4e..000000000 --- a/compat/lwipr_platform.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * lwipr_platform.h - * - * Created on: Feb 8, 2016 - * Author: slavey - * - */ - -#ifndef AXTLS_8266_COMPAT_LWIPR_PLATFORM_H_ -#define AXTLS_8266_COMPAT_LWIPR_PLATFORM_H_ - -/* Add here all platform specific things */ - - -// Some calls require the watchdog to be reset -#ifndef WATCHDOG_FEED - #define WATCHDOG_FEED() -#endif - - -/* SSL_DEBUG is for more information */ -#ifndef SSL_DEBUG - #define AXL_DEBUG(...) -#endif - - -#endif /* AXTLS_8266_COMPAT_LWIPR_PLATFORM_H_ */