mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
Initial version of axTLS integration with lwip raw tcp mode (http://lwip.wikia.com/wiki/Raw/TCP).
This commit is contained in:
parent
514b6685c5
commit
d78e7a0799
186
tools/make_certs.sh
Executable file
186
tools/make_certs.sh
Executable file
@ -0,0 +1,186 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2007, Cameron Rich
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the axTLS project nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
AXDIR=`pwd`/`dirname $0`
|
||||
CWD=`mktemp -d` && cd $dir
|
||||
cd $CWD
|
||||
|
||||
#
|
||||
# Generate the certificates and keys for testing.
|
||||
#
|
||||
|
||||
PROJECT_NAME="axTLS Project"
|
||||
|
||||
# Generate the openssl configuration files.
|
||||
cat > ca_cert.conf << EOF
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
prompt = no
|
||||
|
||||
[ req_distinguished_name ]
|
||||
O = $PROJECT_NAME Dodgy Certificate Authority
|
||||
EOF
|
||||
|
||||
cat > certs.conf << EOF
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
prompt = no
|
||||
|
||||
[ req_distinguished_name ]
|
||||
O = $PROJECT_NAME
|
||||
CN = 127.0.0.1
|
||||
EOF
|
||||
|
||||
cat > device_cert.conf << EOF
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
prompt = no
|
||||
|
||||
[ req_distinguished_name ]
|
||||
O = $PROJECT_NAME Device Certificate
|
||||
EOF
|
||||
|
||||
# private key generation
|
||||
openssl genrsa -out axTLS.ca_key.pem 1024
|
||||
openssl genrsa -out axTLS.key_512.pem 512
|
||||
openssl genrsa -out axTLS.key_1024.pem 1024
|
||||
openssl genrsa -out axTLS.key_1042.pem 1042
|
||||
openssl genrsa -out axTLS.key_2048.pem 2048
|
||||
openssl genrsa -out axTLS.key_4096.pem 4096
|
||||
openssl genrsa -out axTLS.device_key.pem 1024
|
||||
openssl genrsa -aes128 -passout pass:abcd -out axTLS.key_aes128.pem 512
|
||||
openssl genrsa -aes256 -passout pass:abcd -out axTLS.key_aes256.pem 512
|
||||
|
||||
|
||||
# convert private keys into DER format
|
||||
openssl rsa -in axTLS.key_512.pem -out axTLS.key_512 -outform DER
|
||||
openssl rsa -in axTLS.key_1024.pem -out axTLS.key_1024 -outform DER
|
||||
openssl rsa -in axTLS.key_1042.pem -out axTLS.key_1042 -outform DER
|
||||
openssl rsa -in axTLS.key_2048.pem -out axTLS.key_2048 -outform DER
|
||||
openssl rsa -in axTLS.key_4096.pem -out axTLS.key_4096 -outform DER
|
||||
openssl rsa -in axTLS.device_key.pem -out axTLS.device_key -outform DER
|
||||
|
||||
# cert requests
|
||||
openssl req -out axTLS.ca_x509.req -key axTLS.ca_key.pem -new \
|
||||
-config ./ca_cert.conf
|
||||
openssl req -out axTLS.x509_512.req -key axTLS.key_512.pem -new \
|
||||
-config ./certs.conf
|
||||
openssl req -out axTLS.x509_1024.req -key axTLS.key_1024.pem -new \
|
||||
-config ./certs.conf
|
||||
openssl req -out axTLS.x509_1042.req -key axTLS.key_1042.pem -new \
|
||||
-config ./certs.conf
|
||||
openssl req -out axTLS.x509_2048.req -key axTLS.key_2048.pem -new \
|
||||
-config ./certs.conf
|
||||
openssl req -out axTLS.x509_4096.req -key axTLS.key_4096.pem -new \
|
||||
-config ./certs.conf
|
||||
openssl req -out axTLS.x509_device.req -key axTLS.device_key.pem -new \
|
||||
-config ./device_cert.conf
|
||||
openssl req -out axTLS.x509_aes128.req -key axTLS.key_aes128.pem \
|
||||
-new -config ./certs.conf -passin pass:abcd
|
||||
openssl req -out axTLS.x509_aes256.req -key axTLS.key_aes256.pem \
|
||||
-new -config ./certs.conf -passin pass:abcd
|
||||
|
||||
# generate the actual certs.
|
||||
openssl x509 -req -in axTLS.ca_x509.req -out axTLS.ca_x509.pem \
|
||||
-sha1 -days 5000 -signkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_512.req -out axTLS.x509_512.pem \
|
||||
-sha1 -CAcreateserial -days 5000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_1024.req -out axTLS.x509_1024.pem \
|
||||
-sha1 -CAcreateserial -days 5000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_1042.req -out axTLS.x509_1042.pem \
|
||||
-sha1 -CAcreateserial -days 5000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_2048.req -out axTLS.x509_2048.pem \
|
||||
-md5 -CAcreateserial -days 5000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_4096.req -out axTLS.x509_4096.pem \
|
||||
-md5 -CAcreateserial -days 5000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_device.req -out axTLS.x509_device.pem \
|
||||
-sha1 -CAcreateserial -days 5000 \
|
||||
-CA axTLS.x509_512.pem -CAkey axTLS.key_512.pem
|
||||
openssl x509 -req -in axTLS.x509_aes128.req \
|
||||
-out axTLS.x509_aes128.pem \
|
||||
-sha1 -CAcreateserial -days 5000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
openssl x509 -req -in axTLS.x509_aes256.req \
|
||||
-out axTLS.x509_aes256.pem \
|
||||
-sha1 -CAcreateserial -days 5000 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
|
||||
# note: must be root to do this
|
||||
DATE_NOW=`date`
|
||||
if date -s "Jan 1 2025"; then
|
||||
openssl x509 -req -in axTLS.x509_512.req -out axTLS.x509_bad_before.pem \
|
||||
-sha1 -CAcreateserial -days 365 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
date -s "$DATE_NOW"
|
||||
touch axTLS.x509_bad_before.pem
|
||||
fi
|
||||
openssl x509 -req -in axTLS.x509_512.req -out axTLS.x509_bad_after.pem \
|
||||
-sha1 -CAcreateserial -days -365 \
|
||||
-CA axTLS.ca_x509.pem -CAkey axTLS.ca_key.pem
|
||||
|
||||
# some cleanup
|
||||
rm axTLS*.req
|
||||
rm axTLS.srl
|
||||
rm *.conf
|
||||
|
||||
# need this for the client tests
|
||||
openssl x509 -in axTLS.ca_x509.pem -outform DER -out axTLS.ca_x509.cer
|
||||
openssl x509 -in axTLS.x509_512.pem -outform DER -out axTLS.x509_512.cer
|
||||
openssl x509 -in axTLS.x509_1024.pem -outform DER -out axTLS.x509_1024.cer
|
||||
openssl x509 -in axTLS.x509_1042.pem -outform DER -out axTLS.x509_1042.cer
|
||||
openssl x509 -in axTLS.x509_2048.pem -outform DER -out axTLS.x509_2048.cer
|
||||
openssl x509 -in axTLS.x509_4096.pem -outform DER -out axTLS.x509_4096.cer
|
||||
openssl x509 -in axTLS.x509_device.pem -outform DER -out axTLS.x509_device.cer
|
||||
|
||||
# generate pkcs8 files (use RC4-128 for encryption)
|
||||
openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8
|
||||
openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -outform DER -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8
|
||||
openssl pkcs8 -in axTLS.key_512.pem -nocrypt -topk8 -out axTLS.unencrypted_pem.p8
|
||||
openssl pkcs8 -in axTLS.key_512.pem -nocrypt -topk8 -outform DER -out axTLS.unencrypted.p8
|
||||
|
||||
# generate pkcs12 files (use RC4-128 for encryption)
|
||||
openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem -certfile axTLS.ca_x509.pem -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128 -name "p12_with_CA" -out axTLS.withCA.p12 -password pass:abcd
|
||||
openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128 -name "p12_without_CA" -out axTLS.withoutCA.p12 -password pass:abcd
|
||||
openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128 -out axTLS.noname.p12 -password pass:abcd
|
||||
|
||||
# PEM certificate chain
|
||||
cat axTLS.ca_x509.pem >> axTLS.x509_device.pem
|
||||
|
||||
# set default key/cert for use in the server
|
||||
xxd -i axTLS.x509_1024.cer | sed -e \
|
||||
"s/axTLS_x509_1024_cer/default_certificate/" > $AXDIR/../ssl/cert.h
|
||||
xxd -i axTLS.key_1024 | sed -e \
|
||||
"s/axTLS_key_1024/default_private_key/" > $AXDIR/../ssl/private_key.h
|
149
util/README.md
Normal file
149
util/README.md
Normal file
@ -0,0 +1,149 @@
|
||||
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 "util/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.
|
241
util/lwipr_compat.c
Normal file
241
util/lwipr_compat.c
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
tcp_recved(tcp, p->tot_len);
|
||||
do {
|
||||
read_bytes = ssl_read(ssl, in_data);
|
||||
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) {
|
||||
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 | TCP_WRITE_FLAG_MORE);
|
||||
if(err < SSL_OK) {
|
||||
AXL_DEBUG("Got error: %d\n", err);
|
||||
}
|
||||
|
||||
if (err == ERR_MEM) {
|
||||
tcp_len /= 2;
|
||||
}
|
||||
} while (err == ERR_MEM && tcp_len > 1);
|
||||
AXL_DEBUG("send_raw_packet length %d\n", tcp_len);
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
82
util/lwipr_compat.h
Normal file
82
util/lwipr_compat.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* All those functions will run only if LWIP tcp raw mode is used
|
||||
*/
|
||||
#if LWIP_RAW==1
|
||||
|
||||
#include "lwip/tcp.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 printf
|
||||
#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;
|
||||
|
||||
AxlTcpDataArray axlFdArray;
|
||||
|
||||
/*
|
||||
* High Level Functions - these are the ones that should be used directly
|
||||
*/
|
||||
|
||||
void axl_init(int capacity);
|
||||
int axl_append(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);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* LWIPR_COMPAT_H */
|
Loading…
x
Reference in New Issue
Block a user