mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-27 21:16:50 +03:00
Merge remote-tracking branch 'origin/master' into axtls-8266
This commit is contained in:
commit
6209eaca16
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
*.o
|
||||||
|
bin/
|
||||||
|
Makefile.local
|
||||||
|
.DS_Store
|
||||||
|
|
43
.travis.yml
Normal file
43
.travis.yml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
sudo: false
|
||||||
|
language: bash
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
|
||||||
|
script:
|
||||||
|
# Download Arduino IDE
|
||||||
|
- wget -O arduino.tar.xz https://www.arduino.cc/download.php?f=/arduino-nightly-linux64.tar.xz
|
||||||
|
- tar xf arduino.tar.xz
|
||||||
|
- mv arduino-nightly $HOME/arduino_ide
|
||||||
|
# Download ESP8266 Arduino core
|
||||||
|
- cd $HOME/arduino_ide/hardware
|
||||||
|
- mkdir esp8266com
|
||||||
|
- cd esp8266com
|
||||||
|
- git clone https://github.com/esp8266/Arduino.git esp8266
|
||||||
|
- cd esp8266
|
||||||
|
- export ESP8266_ARDUINO_DIR="$PWD"
|
||||||
|
# Download toolchain and esptool
|
||||||
|
- cd tools
|
||||||
|
- python get.py
|
||||||
|
- export PATH="$PATH:$PWD/xtensa-lx106-elf/bin"
|
||||||
|
# Build axTLS
|
||||||
|
- cd $TRAVIS_BUILD_DIR
|
||||||
|
- make
|
||||||
|
# Copy the library into Arduino core
|
||||||
|
- cp bin/libaxtls.a $ESP8266_ARDUINO_DIR/tools/sdk/lib/libaxtls.a
|
||||||
|
# Try building examples in ESP8266WiFi library from the ESP8266 Arduino core
|
||||||
|
- /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16
|
||||||
|
- sleep 3
|
||||||
|
- export DISPLAY=:1.0
|
||||||
|
- export PATH="$HOME/arduino_ide:$PATH"
|
||||||
|
- which arduino
|
||||||
|
- cd $ESP8266_ARDUINO_DIR
|
||||||
|
- source tests/common.sh
|
||||||
|
- arduino --board esp8266com:esp8266:generic --save-prefs
|
||||||
|
- arduino --get-pref sketchbook.path
|
||||||
|
- build_sketches $HOME/arduino_ide $ESP8266_ARDUINO_DIR/libraries/ESP8266WiFi/examples/HTTPSRequest
|
||||||
|
# Feel free to add more test cases (for other environments) here
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
email:
|
||||||
|
on_success: change
|
||||||
|
on_failure: change
|
67
Makefile
Normal file
67
Makefile
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
TOOLCHAIN_PREFIX := xtensa-lx106-elf-
|
||||||
|
CC := $(TOOLCHAIN_PREFIX)gcc
|
||||||
|
AR := $(TOOLCHAIN_PREFIX)ar
|
||||||
|
LD := $(TOOLCHAIN_PREFIX)gcc
|
||||||
|
OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy
|
||||||
|
|
||||||
|
|
||||||
|
XTENSA_LIBS ?= $(shell $(CC) -print-sysroot)
|
||||||
|
|
||||||
|
|
||||||
|
OBJ_FILES := \
|
||||||
|
crypto/aes.o \
|
||||||
|
crypto/bigint.o \
|
||||||
|
crypto/hmac.o \
|
||||||
|
crypto/md2.o \
|
||||||
|
crypto/md5.o \
|
||||||
|
crypto/rc4.o \
|
||||||
|
crypto/rsa.o \
|
||||||
|
crypto/sha1.o \
|
||||||
|
ssl/asn1.o \
|
||||||
|
ssl/gen_cert.o \
|
||||||
|
ssl/loader.o \
|
||||||
|
ssl/os_port.o \
|
||||||
|
ssl/p12.o \
|
||||||
|
ssl/tls1.o \
|
||||||
|
ssl/tls1_clnt.o \
|
||||||
|
ssl/tls1_svr.o \
|
||||||
|
ssl/x509.o \
|
||||||
|
crypto/crypto_misc.o \
|
||||||
|
|
||||||
|
|
||||||
|
CPPFLAGS += -I$(XTENSA_LIBS)/include \
|
||||||
|
-Icrypto \
|
||||||
|
-Issl \
|
||||||
|
-I.
|
||||||
|
|
||||||
|
LDFLAGS += -L$(XTENSA_LIBS)/lib \
|
||||||
|
-L$(XTENSA_LIBS)/arch/lib \
|
||||||
|
|
||||||
|
|
||||||
|
CFLAGS+=-std=c99 -DESP8266
|
||||||
|
|
||||||
|
CFLAGS += -Wall -Os -g -O2 -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mno-text-section-literals -D__ets__ -DICACHE_FLASH
|
||||||
|
BIN_DIR := bin
|
||||||
|
AXTLS_AR := $(BIN_DIR)/libaxtls.a
|
||||||
|
|
||||||
|
all: $(AXTLS_AR)
|
||||||
|
|
||||||
|
$(AXTLS_AR): | $(BIN_DIR)
|
||||||
|
|
||||||
|
$(AXTLS_AR): $(OBJ_FILES)
|
||||||
|
for file in $(OBJ_FILES); do \
|
||||||
|
$(OBJCOPY) \
|
||||||
|
--rename-section .text=.irom0.text \
|
||||||
|
--rename-section .literal=.irom0.literal \
|
||||||
|
$$file; \
|
||||||
|
done
|
||||||
|
$(AR) cru $@ $^
|
||||||
|
|
||||||
|
$(BIN_DIR):
|
||||||
|
mkdir -p $(BIN_DIR)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(OBJ_FILES) $(AXTLS_AR)
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: all clean
|
29
README.md
Normal file
29
README.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
Replacement for Espressif's libssl, kept as close as possible to [axTLS](http://axtls.sourceforge.net/) source.
|
||||||
|
Currently based on axTLS 1.4.9, will be upgraded to 1.5.3.
|
||||||
|
|
||||||
|
[](https://travis-ci.org/igrr/axtls-8266)
|
||||||
|
|
||||||
|
This is not a self-sufficient library. Application has to provide the following symbols (list not complete yet):
|
||||||
|
```
|
||||||
|
ax_port_malloc
|
||||||
|
ax_port_calloc
|
||||||
|
ax_port_realloc
|
||||||
|
ax_port_free
|
||||||
|
ax_port_read
|
||||||
|
ax_port_write
|
||||||
|
ax_port_open
|
||||||
|
ax_port_close
|
||||||
|
ax_get_file
|
||||||
|
phy_get_rand (provided by the IoT SDK)
|
||||||
|
ets_printf (in ESP8266 ROM)
|
||||||
|
ets_putc (in ESP8266 ROM)
|
||||||
|
gettimeofday
|
||||||
|
time
|
||||||
|
ctime
|
||||||
|
```
|
||||||
|
|
||||||
|
For use with LwIP raw TCP API, see [compat/README.md](compat/README.md)
|
||||||
|
|
||||||
|
To build, add xtensa toolchain to your path, and run `make`.
|
||||||
|
|
||||||
|
See [LICENSE](LICENSE) file for axTLS license.
|
149
compat/README.md
Normal file
149
compat/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 "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.
|
285
compat/lwipr_compat.c
Normal file
285
compat/lwipr_compat.c
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
/*
|
||||||
|
* 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 <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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
95
compat/lwipr_compat.h
Normal file
95
compat/lwipr_compat.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* 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 */
|
27
compat/lwipr_platform.h
Normal file
27
compat/lwipr_platform.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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_ */
|
BIN
crypto/aes.o
BIN
crypto/aes.o
Binary file not shown.
@ -1218,6 +1218,7 @@ bigint *bi_mont(BI_CTX *ctx, bigint *bixy)
|
|||||||
|
|
||||||
check(bixy);
|
check(bixy);
|
||||||
|
|
||||||
|
ax_wdt_feed();
|
||||||
if (ctx->use_classical) /* just use classical instead */
|
if (ctx->use_classical) /* just use classical instead */
|
||||||
{
|
{
|
||||||
return bi_mod(ctx, bixy);
|
return bi_mod(ctx, bixy);
|
||||||
@ -1274,6 +1275,7 @@ bigint *bi_barrett(BI_CTX *ctx, bigint *bi)
|
|||||||
check(bi);
|
check(bi);
|
||||||
check(bim);
|
check(bim);
|
||||||
|
|
||||||
|
ax_wdt_feed();
|
||||||
/* use Classical method instead - Barrett cannot help here */
|
/* use Classical method instead - Barrett cannot help here */
|
||||||
if (bi->size > k*2)
|
if (bi->size > k*2)
|
||||||
{
|
{
|
||||||
|
BIN
crypto/bigint.o
BIN
crypto/bigint.o
Binary file not shown.
@ -42,7 +42,12 @@
|
|||||||
#include "wincrypt.h"
|
#include "wincrypt.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifdef ESP8266
|
||||||
|
#define CONFIG_SSL_SKELETON_MODE 1
|
||||||
|
uint32_t phy_get_rand();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_USE_DEV_URANDOM)
|
||||||
static int rng_fd = -1;
|
static int rng_fd = -1;
|
||||||
#elif defined(CONFIG_WIN32_USE_CRYPTO_LIB)
|
#elif defined(CONFIG_WIN32_USE_CRYPTO_LIB)
|
||||||
static HCRYPTPROV gCryptProv;
|
static HCRYPTPROV gCryptProv;
|
||||||
@ -120,6 +125,7 @@ EXP_FUNC void STDCALL RNG_initialize()
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(ESP8266)
|
||||||
#else
|
#else
|
||||||
/* start of with a stack to copy across */
|
/* start of with a stack to copy across */
|
||||||
int i;
|
int i;
|
||||||
@ -146,7 +152,7 @@ EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size)
|
|||||||
*/
|
*/
|
||||||
EXP_FUNC void STDCALL RNG_terminate(void)
|
EXP_FUNC void STDCALL RNG_terminate(void)
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
#if defined(CONFIG_USE_DEV_URANDOM)
|
||||||
close(rng_fd);
|
close(rng_fd);
|
||||||
#elif defined(CONFIG_WIN32_USE_CRYPTO_LIB)
|
#elif defined(CONFIG_WIN32_USE_CRYPTO_LIB)
|
||||||
CryptReleaseContext(gCryptProv, 0);
|
CryptReleaseContext(gCryptProv, 0);
|
||||||
@ -164,6 +170,13 @@ EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data)
|
|||||||
#elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB)
|
#elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB)
|
||||||
/* use Microsoft Crypto Libraries */
|
/* use Microsoft Crypto Libraries */
|
||||||
CryptGenRandom(gCryptProv, num_rand_bytes, rand_data);
|
CryptGenRandom(gCryptProv, num_rand_bytes, rand_data);
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
for (size_t cb = 0; cb < num_rand_bytes; cb += 4) {
|
||||||
|
uint32_t r = phy_get_rand();
|
||||||
|
size_t left = num_rand_bytes - cb;
|
||||||
|
left = (left < 4) ? left : 4;
|
||||||
|
memcpy(rand_data + cb, &r, left);
|
||||||
|
}
|
||||||
#else /* nothing else to use, so use a custom RNG */
|
#else /* nothing else to use, so use a custom RNG */
|
||||||
/* The method we use when we've got nothing better. Use RC4, time
|
/* The method we use when we've got nothing better. Use RC4, time
|
||||||
and a couple of random seeds to generate a random sequence */
|
and a couple of random seeds to generate a random sequence */
|
||||||
@ -210,8 +223,9 @@ void get_random_NZ(int num_rand_bytes, uint8_t *rand_data)
|
|||||||
|
|
||||||
for (i = 0; i < num_rand_bytes; i++)
|
for (i = 0; i < num_rand_bytes; i++)
|
||||||
{
|
{
|
||||||
while (rand_data[i] == 0) /* can't be 0 */
|
while (rand_data[i] == 0) {
|
||||||
rand_data[i] = (uint8_t)(rand());
|
get_random(1, rand_data + i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,4 +378,3 @@ error:
|
|||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
BIN
crypto/hmac.o
BIN
crypto/hmac.o
Binary file not shown.
BIN
crypto/md2.o
BIN
crypto/md2.o
Binary file not shown.
BIN
crypto/md5.o
BIN
crypto/md5.o
Binary file not shown.
BIN
crypto/rc4.o
BIN
crypto/rc4.o
Binary file not shown.
@ -146,7 +146,7 @@ int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
|
|||||||
const int byte_size = ctx->num_octets;
|
const int byte_size = ctx->num_octets;
|
||||||
int i, size;
|
int i, size;
|
||||||
bigint *decrypted_bi, *dat_bi;
|
bigint *decrypted_bi, *dat_bi;
|
||||||
uint8_t *block = (uint8_t *)alloca(byte_size);
|
uint8_t *block = (uint8_t *)malloc(byte_size);
|
||||||
|
|
||||||
memset(out_data, 0, byte_size); /* initialise */
|
memset(out_data, 0, byte_size); /* initialise */
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
|
|||||||
/* get only the bit we want */
|
/* get only the bit we want */
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
memcpy(out_data, &block[i], size);
|
memcpy(out_data, &block[i], size);
|
||||||
|
free(block);
|
||||||
return size ? size : -1;
|
return size ? size : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
crypto/rsa.o
BIN
crypto/rsa.o
Binary file not shown.
BIN
crypto/sha1.o
BIN
crypto/sha1.o
Binary file not shown.
147
replacements/time.c
Normal file
147
replacements/time.c
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* time.c - ESP8266-specific functions for SNTP
|
||||||
|
* Copyright (c) 2015 Peter Dobler. All rights reserved.
|
||||||
|
* This file is part of the esp8266 core for Arduino environment.
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
* This library 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 Lesser General Public License for more details.
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <sntp.h>
|
||||||
|
|
||||||
|
extern uint32_t system_get_time(void);
|
||||||
|
extern uint64_t system_mktime(uint32_t year, uint32_t mon, uint32_t day, uint32_t hour, uint32_t min, uint32_t sec);
|
||||||
|
|
||||||
|
static int errno_var = 0;
|
||||||
|
|
||||||
|
int* __errno(void) {
|
||||||
|
// DEBUGV("__errno is called last error: %d (not current)\n", errno_var);
|
||||||
|
return &errno_var;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long millis(void)
|
||||||
|
{
|
||||||
|
return system_get_time() / 1000UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long micros(void)
|
||||||
|
{
|
||||||
|
return system_get_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _TIMEVAL_DEFINED
|
||||||
|
#define _TIMEVAL_DEFINED
|
||||||
|
struct timeval {
|
||||||
|
time_t tv_sec;
|
||||||
|
suseconds_t tv_usec;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern char* sntp_asctime(const struct tm *t);
|
||||||
|
extern struct tm* sntp_localtime(const time_t *clock);
|
||||||
|
|
||||||
|
// time gap in seconds from 01.01.1900 (NTP time) to 01.01.1970 (UNIX time)
|
||||||
|
#define DIFF1900TO1970 2208988800UL
|
||||||
|
|
||||||
|
static int s_daylightOffset_sec = 0;
|
||||||
|
static long s_timezone_sec = 0;
|
||||||
|
static time_t s_bootTime = 0;
|
||||||
|
|
||||||
|
// calculate offset used in gettimeofday
|
||||||
|
static void ensureBootTimeIsSet()
|
||||||
|
{
|
||||||
|
if (!s_bootTime)
|
||||||
|
{
|
||||||
|
time_t now = sntp_get_current_timestamp();
|
||||||
|
if (now)
|
||||||
|
{
|
||||||
|
s_bootTime = now - millis() / 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setServer(int id, const char* name_or_ip)
|
||||||
|
{
|
||||||
|
if (name_or_ip)
|
||||||
|
{
|
||||||
|
//TODO: check whether server is given by name or IP
|
||||||
|
sntp_setservername(id, (char*) name_or_ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void configTime(int timezone, int daylightOffset_sec, const char* server1, const char* server2, const char* server3)
|
||||||
|
{
|
||||||
|
sntp_stop();
|
||||||
|
|
||||||
|
setServer(0, server1);
|
||||||
|
setServer(1, server2);
|
||||||
|
setServer(2, server3);
|
||||||
|
|
||||||
|
s_timezone_sec = timezone;
|
||||||
|
s_daylightOffset_sec = daylightOffset_sec;
|
||||||
|
sntp_set_timezone(timezone/3600);
|
||||||
|
sntp_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
int clock_gettime(clockid_t unused, struct timespec *tp)
|
||||||
|
{
|
||||||
|
tp->tv_sec = millis() / 1000;
|
||||||
|
tp->tv_nsec = micros() * 1000;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// seconds since 1970
|
||||||
|
time_t mktime(struct tm *t)
|
||||||
|
{
|
||||||
|
// system_mktime expects month in range 1..12
|
||||||
|
#define START_MONTH 1
|
||||||
|
return DIFF1900TO1970 + system_mktime(t->tm_year, t->tm_mon + START_MONTH, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t time(time_t * t)
|
||||||
|
{
|
||||||
|
time_t seconds = sntp_get_current_timestamp();
|
||||||
|
if (t)
|
||||||
|
{
|
||||||
|
*t = seconds;
|
||||||
|
}
|
||||||
|
return seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* asctime(const struct tm *t)
|
||||||
|
{
|
||||||
|
return sntp_asctime(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tm* localtime(const time_t *clock)
|
||||||
|
{
|
||||||
|
return sntp_localtime(clock);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ctime(const time_t *t)
|
||||||
|
{
|
||||||
|
struct tm* p_tm = localtime(t);
|
||||||
|
char* result = asctime(p_tm);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gettimeofday(struct timeval *tp, void *tzp)
|
||||||
|
{
|
||||||
|
if (tp)
|
||||||
|
{
|
||||||
|
ensureBootTimeIsSet();
|
||||||
|
tp->tv_sec = (s_bootTime + millis()) / 1000;
|
||||||
|
tp->tv_usec = micros() * 1000;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
BIN
ssl/asn1.o
BIN
ssl/asn1.o
Binary file not shown.
43
ssl/cert.h
43
ssl/cert.h
@ -1,43 +0,0 @@
|
|||||||
unsigned char default_certificate[] = {
|
|
||||||
0x30, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xab,
|
|
||||||
0x08, 0x18, 0xa7, 0x03, 0x07, 0x27, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a,
|
|
||||||
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34,
|
|
||||||
0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x29, 0x61,
|
|
||||||
0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
|
|
||||||
0x20, 0x44, 0x6f, 0x64, 0x67, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
|
|
||||||
0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
|
|
||||||
0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x32,
|
|
||||||
0x32, 0x36, 0x32, 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x17, 0x0d, 0x32,
|
|
||||||
0x34, 0x30, 0x39, 0x30, 0x33, 0x32, 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a,
|
|
||||||
0x30, 0x2c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
|
|
||||||
0x0d, 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65,
|
|
||||||
0x63, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
|
|
||||||
0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81,
|
|
||||||
0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
|
||||||
0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02,
|
|
||||||
0x81, 0x81, 0x00, 0xcd, 0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, 0x76,
|
|
||||||
0xd4, 0x13, 0x30, 0x0e, 0xbf, 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f,
|
|
||||||
0x51, 0x09, 0x9d, 0x29, 0x2f, 0xb2, 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90,
|
|
||||||
0x80, 0xa1, 0x71, 0xdf, 0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14,
|
|
||||||
0x90, 0x0a, 0xf9, 0xb7, 0x07, 0x0b, 0xe1, 0xda, 0xe7, 0x09, 0xbf, 0x0d,
|
|
||||||
0x57, 0x41, 0x86, 0x60, 0xa1, 0xc1, 0x27, 0x91, 0x5b, 0x0a, 0x98, 0x46,
|
|
||||||
0x1b, 0xf6, 0xa2, 0x84, 0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa,
|
|
||||||
0x91, 0xf8, 0x61, 0x04, 0x50, 0x70, 0xeb, 0xb4, 0x43, 0xb7, 0xdc, 0x9a,
|
|
||||||
0xcc, 0x31, 0x01, 0x14, 0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, 0x69, 0x82,
|
|
||||||
0xd6, 0xc6, 0xc4, 0xbe, 0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32,
|
|
||||||
0x7a, 0x86, 0x0e, 0x91, 0x82, 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, 0x02,
|
|
||||||
0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
|
|
||||||
0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x40,
|
|
||||||
0xb4, 0x94, 0x9a, 0xa8, 0x89, 0x72, 0x1d, 0x07, 0xe5, 0xb3, 0x6b, 0x88,
|
|
||||||
0x21, 0xc2, 0x38, 0x36, 0x9e, 0x7a, 0x8c, 0x49, 0x48, 0x68, 0x0c, 0x06,
|
|
||||||
0xe8, 0xdb, 0x1f, 0x4e, 0x05, 0xe6, 0x31, 0xe3, 0xfd, 0xe6, 0x0d, 0x6b,
|
|
||||||
0xd8, 0x13, 0x17, 0xe0, 0x2d, 0x0d, 0xb8, 0x7e, 0xcb, 0x20, 0x6c, 0xa8,
|
|
||||||
0x73, 0xa7, 0xfd, 0xe3, 0xa7, 0xfa, 0xf3, 0x02, 0x60, 0x78, 0x1f, 0x13,
|
|
||||||
0x40, 0x45, 0xee, 0x75, 0xf5, 0x10, 0xfd, 0x8f, 0x68, 0x74, 0xd4, 0xac,
|
|
||||||
0xae, 0x04, 0x09, 0x55, 0x2c, 0xdb, 0xd8, 0x07, 0x07, 0x65, 0x69, 0x27,
|
|
||||||
0x6e, 0xbf, 0x5e, 0x61, 0x40, 0x56, 0x8b, 0xd7, 0x33, 0x3b, 0xff, 0x6e,
|
|
||||||
0x53, 0x7e, 0x9d, 0x3f, 0xc0, 0x40, 0x3a, 0xab, 0xa0, 0x50, 0x4e, 0x80,
|
|
||||||
0x47, 0x46, 0x0d, 0x1e, 0xdb, 0x4c, 0xf1, 0x1b, 0x5d, 0x3c, 0x2a, 0x54,
|
|
||||||
0xa7, 0x4d, 0xfa, 0x7b, 0x72, 0x66, 0xc5
|
|
||||||
};
|
|
||||||
unsigned int default_certificate_len = 475;
|
|
@ -46,9 +46,9 @@
|
|||||||
#undef CONFIG_SSL_USE_PKCS12
|
#undef CONFIG_SSL_USE_PKCS12
|
||||||
#define CONFIG_SSL_EXPIRY_TIME 24
|
#define CONFIG_SSL_EXPIRY_TIME 24
|
||||||
#define CONFIG_X509_MAX_CA_CERTS 150
|
#define CONFIG_X509_MAX_CA_CERTS 150
|
||||||
#define CONFIG_SSL_MAX_CERTS 3
|
#define CONFIG_SSL_MAX_CERTS 1
|
||||||
#undef CONFIG_SSL_CTX_MUTEXING
|
#undef CONFIG_SSL_CTX_MUTEXING
|
||||||
//#define CONFIG_USE_DEV_URANDOM 1
|
#undef CONFIG_USE_DEV_URANDOM
|
||||||
#undef CONFIG_WIN32_USE_CRYPTO_LIB
|
#undef CONFIG_WIN32_USE_CRYPTO_LIB
|
||||||
#undef CONFIG_OPENSSL_COMPATIBLE
|
#undef CONFIG_OPENSSL_COMPATIBLE
|
||||||
#undef CONFIG_PERFORMANCE_TESTING
|
#undef CONFIG_PERFORMANCE_TESTING
|
||||||
|
@ -76,6 +76,7 @@ struct _x509_ctx
|
|||||||
uint8_t sig_type;
|
uint8_t sig_type;
|
||||||
RSA_CTX *rsa_ctx;
|
RSA_CTX *rsa_ctx;
|
||||||
bigint *digest;
|
bigint *digest;
|
||||||
|
uint8_t *fingerprint;
|
||||||
struct _x509_ctx *next;
|
struct _x509_ctx *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ static void gen_pub_key2(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
|
|||||||
|
|
||||||
int seq_offset;
|
int seq_offset;
|
||||||
int pub_key_size = rsa_ctx->num_octets;
|
int pub_key_size = rsa_ctx->num_octets;
|
||||||
uint8_t *block = (uint8_t *)alloca(pub_key_size);
|
uint8_t *block = (uint8_t *)malloc(pub_key_size);
|
||||||
int seq_size = pre_adjust_with_size(
|
int seq_size = pre_adjust_with_size(
|
||||||
ASN1_SEQUENCE, &seq_offset, buf, offset);
|
ASN1_SEQUENCE, &seq_offset, buf, offset);
|
||||||
buf[(*offset)++] = ASN1_INTEGER;
|
buf[(*offset)++] = ASN1_INTEGER;
|
||||||
@ -236,6 +236,7 @@ static void gen_pub_key2(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
|
|||||||
set_gen_length(pub_key_size, buf, offset);
|
set_gen_length(pub_key_size, buf, offset);
|
||||||
|
|
||||||
memcpy(&buf[*offset], block, pub_key_size);
|
memcpy(&buf[*offset], block, pub_key_size);
|
||||||
|
free(block);
|
||||||
*offset += pub_key_size;
|
*offset += pub_key_size;
|
||||||
memcpy(&buf[*offset], pub_key_seq, sizeof(pub_key_seq));
|
memcpy(&buf[*offset], pub_key_seq, sizeof(pub_key_seq));
|
||||||
*offset += sizeof(pub_key_seq);
|
*offset += sizeof(pub_key_seq);
|
||||||
@ -282,8 +283,8 @@ static void gen_signature(const RSA_CTX *rsa_ctx, const uint8_t *sha_dgst,
|
|||||||
ASN1_NULL, 0x00, ASN1_OCTET_STRING, 0x14
|
ASN1_NULL, 0x00, ASN1_OCTET_STRING, 0x14
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t *enc_block = (uint8_t *)alloca(rsa_ctx->num_octets);
|
uint8_t *enc_block = (uint8_t *)malloc(rsa_ctx->num_octets);
|
||||||
uint8_t *block = (uint8_t *)alloca(sizeof(asn1_sig) + SHA1_SIZE);
|
uint8_t *block = (uint8_t *)malloc(sizeof(asn1_sig) + SHA1_SIZE);
|
||||||
int sig_size;
|
int sig_size;
|
||||||
|
|
||||||
/* add the digest as an embedded asn.1 sequence */
|
/* add the digest as an embedded asn.1 sequence */
|
||||||
@ -297,6 +298,8 @@ static void gen_signature(const RSA_CTX *rsa_ctx, const uint8_t *sha_dgst,
|
|||||||
set_gen_length(sig_size+1, buf, offset);
|
set_gen_length(sig_size+1, buf, offset);
|
||||||
buf[(*offset)++] = 0; /* bit string is multiple of 8 */
|
buf[(*offset)++] = 0; /* bit string is multiple of 8 */
|
||||||
memcpy(&buf[*offset], enc_block, sig_size);
|
memcpy(&buf[*offset], enc_block, sig_size);
|
||||||
|
free(enc_block);
|
||||||
|
free(block);
|
||||||
*offset += sig_size;
|
*offset += sig_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,7 +345,7 @@ EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const c
|
|||||||
{
|
{
|
||||||
int ret = X509_OK, offset = 0, seq_offset;
|
int ret = X509_OK, offset = 0, seq_offset;
|
||||||
/* allocate enough space to load a new certificate */
|
/* allocate enough space to load a new certificate */
|
||||||
uint8_t *buf = (uint8_t *)alloca(ssl_ctx->rsa_ctx->num_octets*2 + 512);
|
uint8_t *buf = (uint8_t *)malloc(ssl_ctx->rsa_ctx->num_octets*2 + 512);
|
||||||
uint8_t sha_dgst[SHA1_SIZE];
|
uint8_t sha_dgst[SHA1_SIZE];
|
||||||
int seq_size = pre_adjust_with_size(ASN1_SEQUENCE,
|
int seq_size = pre_adjust_with_size(ASN1_SEQUENCE,
|
||||||
&seq_offset, buf, &offset);
|
&seq_offset, buf, &offset);
|
||||||
@ -357,6 +360,7 @@ EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const c
|
|||||||
memcpy(*cert_data, buf, offset);
|
memcpy(*cert_data, buf, offset);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
free(buf);
|
||||||
return ret < 0 ? ret : offset;
|
return ret < 0 ? ret : offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
ssl/gen_cert.o
BIN
ssl/gen_cert.o
Binary file not shown.
11
ssl/loader.c
11
ssl/loader.c
@ -434,9 +434,9 @@ int load_key_certs(SSL_CTX *ssl_ctx)
|
|||||||
else if (!(options & SSL_NO_DEFAULT_KEY))
|
else if (!(options & SSL_NO_DEFAULT_KEY))
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
|
#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
|
||||||
static const /* saves a few more bytes */
|
extern const unsigned char* default_private_key;
|
||||||
#include "private_key.h"
|
extern const unsigned int default_private_key_len;
|
||||||
|
if (default_private_key != NULL && default_private_key_len > 0)
|
||||||
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_RSA_KEY, default_private_key,
|
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_RSA_KEY, default_private_key,
|
||||||
default_private_key_len, NULL);
|
default_private_key_len, NULL);
|
||||||
#endif
|
#endif
|
||||||
@ -462,8 +462,9 @@ int load_key_certs(SSL_CTX *ssl_ctx)
|
|||||||
else if (!(options & SSL_NO_DEFAULT_KEY))
|
else if (!(options & SSL_NO_DEFAULT_KEY))
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
|
#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
|
||||||
static const /* saves a few bytes and RAM */
|
extern const unsigned char* default_certificate;
|
||||||
#include "cert.h"
|
extern const unsigned int default_certificate_len;
|
||||||
|
if (default_certificate != NULL && default_certificate_len > 0)
|
||||||
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CERT,
|
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CERT,
|
||||||
default_certificate, default_certificate_len, NULL);
|
default_certificate, default_certificate_len, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
BIN
ssl/loader.o
BIN
ssl/loader.o
Binary file not shown.
@ -37,6 +37,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
#include "os_port.h"
|
#include "os_port.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -96,63 +97,3 @@ EXP_FUNC int STDCALL getdomainname(char *buf, int buf_size)
|
|||||||
|
|
||||||
static const char * out_of_mem_str = "out of memory";
|
static const char * out_of_mem_str = "out of memory";
|
||||||
static const char * file_open_str = "Could not open file \"%s\"";
|
static const char * file_open_str = "Could not open file \"%s\"";
|
||||||
|
|
||||||
/*
|
|
||||||
* Some functions that call display some error trace and then call abort().
|
|
||||||
* This just makes life much easier on embedded systems, since we're
|
|
||||||
* suffering major trauma...
|
|
||||||
*/
|
|
||||||
EXP_FUNC void * STDCALL ax_malloc(size_t s)
|
|
||||||
{
|
|
||||||
void *x;
|
|
||||||
|
|
||||||
if ((x = malloc(s)) == NULL)
|
|
||||||
exit_now(out_of_mem_str);
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXP_FUNC void * STDCALL ax_realloc(void *y, size_t s)
|
|
||||||
{
|
|
||||||
void *x;
|
|
||||||
|
|
||||||
if ((x = realloc(y, s)) == NULL)
|
|
||||||
exit_now(out_of_mem_str);
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXP_FUNC void * STDCALL ax_calloc(size_t n, size_t s)
|
|
||||||
{
|
|
||||||
void *x;
|
|
||||||
|
|
||||||
if ((x = calloc(n, s)) == NULL)
|
|
||||||
exit_now(out_of_mem_str);
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXP_FUNC int STDCALL ax_open(const char *pathname, int flags)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
if ((x = open(pathname, flags)) < 0)
|
|
||||||
exit_now(file_open_str, pathname);
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a call which will deliberately exit an application, but will
|
|
||||||
* display some information before dying.
|
|
||||||
*/
|
|
||||||
void exit_now(const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list argp;
|
|
||||||
|
|
||||||
va_start(argp, format);
|
|
||||||
vfprintf(stderr, format, argp);
|
|
||||||
va_end(argp);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -44,9 +44,6 @@ extern "C" {
|
|||||||
#include "os_int.h"
|
#include "os_int.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define STDCALL __stdcall
|
#define STDCALL __stdcall
|
||||||
#define EXP_FUNC __declspec(dllexport)
|
#define EXP_FUNC __declspec(dllexport)
|
||||||
@ -62,8 +59,29 @@ extern "C" {
|
|||||||
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
|
|
||||||
|
#include "util/time.h"
|
||||||
|
#include <errno.h>
|
||||||
|
// #define alloca(size) __builtin_alloca(size)
|
||||||
|
#define TTY_FLUSH()
|
||||||
|
#ifdef putc
|
||||||
|
#undef putc
|
||||||
|
#endif
|
||||||
|
#define putc(x, f) ets_putc(x)
|
||||||
|
#ifdef printf
|
||||||
|
#undef printf
|
||||||
|
#endif
|
||||||
|
#define printf(...) ets_printf(__VA_ARGS__)
|
||||||
|
|
||||||
|
#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 SOCKET_CLOSE(A) ax_port_close(A)
|
||||||
|
#define get_file ax_get_file
|
||||||
|
#define EWOULDBLOCK EAGAIN
|
||||||
|
|
||||||
|
#define hmac_sha1 ax_hmac_sha1
|
||||||
|
#define hmac_md5 ax_hmac_md5
|
||||||
|
|
||||||
|
void ax_wdt_feed();
|
||||||
|
|
||||||
#elif defined(WIN32)
|
#elif defined(WIN32)
|
||||||
|
|
||||||
@ -152,17 +170,28 @@ EXP_FUNC int STDCALL getdomainname(char *buf, int buf_size);
|
|||||||
#endif /* Not Win32 */
|
#endif /* Not Win32 */
|
||||||
|
|
||||||
/* some functions to mutate the way these work */
|
/* some functions to mutate the way these work */
|
||||||
#define malloc(A) ax_malloc(A)
|
#define malloc(A) ax_port_malloc(A, __FILE__, __LINE__)
|
||||||
#ifndef realloc
|
#ifndef realloc
|
||||||
#define realloc(A,B) ax_realloc(A,B)
|
#define realloc(A,B) ax_port_realloc(A,B, __FILE__, __LINE__)
|
||||||
#endif
|
#endif
|
||||||
#define calloc(A,B) ax_calloc(A,B)
|
#define calloc(A,B) ax_port_calloc(A,B, __FILE__, __LINE__)
|
||||||
|
#define free(x) ax_port_free(x)
|
||||||
|
|
||||||
EXP_FUNC void * STDCALL ax_malloc(size_t s);
|
EXP_FUNC void * STDCALL ax_port_malloc(size_t s, const char*, int);
|
||||||
EXP_FUNC void * STDCALL ax_realloc(void *y, size_t s);
|
EXP_FUNC void * STDCALL ax_port_realloc(void *y, size_t s, const char*, int);
|
||||||
EXP_FUNC void * STDCALL ax_calloc(size_t n, size_t s);
|
EXP_FUNC void * STDCALL ax_port_calloc(size_t n, size_t s, const char*, int);
|
||||||
|
EXP_FUNC void * STDCALL ax_port_free(void*);
|
||||||
EXP_FUNC int STDCALL ax_open(const char *pathname, int flags);
|
EXP_FUNC int STDCALL ax_open(const char *pathname, int flags);
|
||||||
|
|
||||||
|
inline uint32_t htonl(uint32_t n){
|
||||||
|
return ((n & 0xff) << 24) |
|
||||||
|
((n & 0xff00) << 8) |
|
||||||
|
((n & 0xff0000UL) >> 8) |
|
||||||
|
((n & 0xff000000UL) >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ntohl htonl
|
||||||
|
|
||||||
#ifdef CONFIG_PLATFORM_LINUX
|
#ifdef CONFIG_PLATFORM_LINUX
|
||||||
void exit_now(const char *format, ...) __attribute((noreturn));
|
void exit_now(const char *format, ...) __attribute((noreturn));
|
||||||
#else
|
#else
|
||||||
|
BIN
ssl/os_port.o
BIN
ssl/os_port.o
Binary file not shown.
@ -1,54 +0,0 @@
|
|||||||
unsigned char default_private_key[] = {
|
|
||||||
0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcd,
|
|
||||||
0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, 0x76, 0xd4, 0x13, 0x30, 0x0e,
|
|
||||||
0xbf, 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f, 0x51, 0x09, 0x9d, 0x29,
|
|
||||||
0x2f, 0xb2, 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90, 0x80, 0xa1, 0x71, 0xdf,
|
|
||||||
0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14, 0x90, 0x0a, 0xf9, 0xb7,
|
|
||||||
0x07, 0x0b, 0xe1, 0xda, 0xe7, 0x09, 0xbf, 0x0d, 0x57, 0x41, 0x86, 0x60,
|
|
||||||
0xa1, 0xc1, 0x27, 0x91, 0x5b, 0x0a, 0x98, 0x46, 0x1b, 0xf6, 0xa2, 0x84,
|
|
||||||
0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa, 0x91, 0xf8, 0x61, 0x04,
|
|
||||||
0x50, 0x70, 0xeb, 0xb4, 0x43, 0xb7, 0xdc, 0x9a, 0xcc, 0x31, 0x01, 0x14,
|
|
||||||
0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, 0x69, 0x82, 0xd6, 0xc6, 0xc4, 0xbe,
|
|
||||||
0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32, 0x7a, 0x86, 0x0e, 0x91,
|
|
||||||
0x82, 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01,
|
|
||||||
0x02, 0x81, 0x81, 0x00, 0x95, 0xaa, 0x6e, 0x11, 0xf5, 0x6a, 0x8b, 0xa2,
|
|
||||||
0xc6, 0x48, 0xc6, 0x7c, 0x37, 0x6b, 0x1f, 0x55, 0x10, 0x76, 0x26, 0x24,
|
|
||||||
0xc3, 0xf2, 0x5c, 0x5a, 0xdd, 0x2e, 0xf3, 0xa4, 0x1e, 0xbc, 0x7b, 0x1c,
|
|
||||||
0x80, 0x10, 0x85, 0xbc, 0xd8, 0x45, 0x3c, 0xb8, 0xb2, 0x06, 0x53, 0xb5,
|
|
||||||
0xd5, 0x7a, 0xe7, 0x0e, 0x92, 0xe6, 0x42, 0xc2, 0xe2, 0x2a, 0xd5, 0xd1,
|
|
||||||
0x03, 0x9f, 0x6f, 0x53, 0x74, 0x68, 0x72, 0x8e, 0xbf, 0x03, 0xbb, 0xab,
|
|
||||||
0xbd, 0xa1, 0xf9, 0x81, 0x7d, 0x12, 0xd4, 0x9d, 0xb6, 0xae, 0x4c, 0xad,
|
|
||||||
0xca, 0xa8, 0xc9, 0x80, 0x8d, 0x0d, 0xd5, 0xd0, 0xa1, 0xbf, 0xec, 0x60,
|
|
||||||
0x48, 0x49, 0xed, 0x97, 0x0f, 0x5e, 0xed, 0xfc, 0x39, 0x15, 0x96, 0x9e,
|
|
||||||
0x5d, 0xe2, 0xb4, 0x5d, 0x2e, 0x04, 0xdc, 0x08, 0xa2, 0x65, 0x29, 0x2d,
|
|
||||||
0x37, 0xfb, 0x62, 0x90, 0x1b, 0x7b, 0xe5, 0x3a, 0x58, 0x05, 0x55, 0xc1,
|
|
||||||
0x02, 0x41, 0x00, 0xfc, 0x69, 0x28, 0xc9, 0xa8, 0xc4, 0x5c, 0xe3, 0xd0,
|
|
||||||
0x5e, 0xaa, 0xda, 0xde, 0x87, 0x74, 0xdb, 0xcb, 0x40, 0x78, 0x8e, 0x1d,
|
|
||||||
0x12, 0x96, 0x16, 0x61, 0x3f, 0xb3, 0x3e, 0xa3, 0x0d, 0xdc, 0x49, 0xa5,
|
|
||||||
0x25, 0x87, 0xc5, 0x97, 0x85, 0x9d, 0xbb, 0xb4, 0xf0, 0x44, 0xfd, 0x6c,
|
|
||||||
0xe8, 0xd2, 0x8c, 0xec, 0x33, 0x81, 0x46, 0x1e, 0x10, 0x12, 0x33, 0x16,
|
|
||||||
0x95, 0x00, 0x4f, 0x75, 0xb4, 0xe5, 0x79, 0x02, 0x41, 0x00, 0xd0, 0xeb,
|
|
||||||
0x65, 0x07, 0x10, 0x3b, 0xd9, 0x03, 0xeb, 0xdc, 0x6f, 0x4b, 0x8f, 0xc3,
|
|
||||||
0x87, 0xce, 0x76, 0xd6, 0xc5, 0x14, 0x21, 0x4e, 0xe7, 0x4f, 0x1b, 0xe8,
|
|
||||||
0x05, 0xf8, 0x84, 0x1a, 0xe0, 0xc5, 0xd6, 0xe3, 0x08, 0xb3, 0x54, 0x57,
|
|
||||||
0x02, 0x1f, 0xd4, 0xd9, 0xfb, 0xff, 0x40, 0xb1, 0x56, 0x1c, 0x60, 0xf7,
|
|
||||||
0xac, 0x91, 0xf3, 0xd3, 0xc6, 0x7f, 0x84, 0xfd, 0x84, 0x9d, 0xea, 0x26,
|
|
||||||
0xee, 0xc9, 0x02, 0x41, 0x00, 0xa6, 0xcf, 0x1c, 0x6c, 0x81, 0x03, 0x1c,
|
|
||||||
0x5c, 0x56, 0x05, 0x6a, 0x26, 0x70, 0xef, 0xd6, 0x13, 0xb7, 0x74, 0x28,
|
|
||||||
0xf7, 0xca, 0x50, 0xd1, 0x2d, 0x83, 0x21, 0x64, 0xe4, 0xdd, 0x3f, 0x38,
|
|
||||||
0xb8, 0xd6, 0xd2, 0x41, 0xb3, 0x1c, 0x9a, 0xea, 0x0d, 0xf5, 0xda, 0xdf,
|
|
||||||
0xcd, 0x17, 0x9f, 0x9a, 0x1e, 0x15, 0xaf, 0x48, 0x1c, 0xbd, 0x9b, 0x63,
|
|
||||||
0x5b, 0xad, 0xed, 0xd4, 0xa1, 0xae, 0xa9, 0x59, 0x09, 0x02, 0x40, 0x4e,
|
|
||||||
0x08, 0xce, 0xa8, 0x8f, 0xc0, 0xba, 0xf3, 0x83, 0x02, 0xc8, 0x33, 0x62,
|
|
||||||
0x14, 0x77, 0xc2, 0x7f, 0x93, 0x02, 0xf3, 0xdc, 0xe9, 0x1a, 0xee, 0xea,
|
|
||||||
0x8e, 0x84, 0xc4, 0x69, 0x9b, 0x9c, 0x7f, 0x69, 0x1f, 0x4e, 0x1d, 0xa5,
|
|
||||||
0x90, 0x06, 0x44, 0x1b, 0x7d, 0xfc, 0x69, 0x40, 0x21, 0xbc, 0xf7, 0x46,
|
|
||||||
0xa4, 0xdc, 0x39, 0x7b, 0xe8, 0x8b, 0x49, 0x10, 0x44, 0x9d, 0x67, 0x5a,
|
|
||||||
0x91, 0x86, 0x39, 0x02, 0x40, 0x41, 0x2c, 0x4e, 0xfe, 0xd9, 0x90, 0x89,
|
|
||||||
0x00, 0x5c, 0x94, 0x0a, 0x4a, 0x7e, 0x1b, 0x1a, 0x80, 0x06, 0x01, 0x37,
|
|
||||||
0xda, 0x50, 0x61, 0x9d, 0x9c, 0xfe, 0x25, 0x7f, 0xd8, 0xd4, 0xc4, 0x9e,
|
|
||||||
0x81, 0xf2, 0x0c, 0x1e, 0x38, 0x21, 0x1e, 0x90, 0x3f, 0xd4, 0xba, 0x6c,
|
|
||||||
0x53, 0xcb, 0xf0, 0x77, 0x79, 0x9b, 0xf1, 0xfa, 0x3f, 0x81, 0xdc, 0xf3,
|
|
||||||
0x21, 0x02, 0x6d, 0xb7, 0x95, 0xc3, 0x2e, 0xce, 0xd5
|
|
||||||
};
|
|
||||||
unsigned int default_private_key_len = 609;
|
|
13
ssl/ssl.h
13
ssl/ssl.h
@ -83,6 +83,7 @@ extern "C" {
|
|||||||
#define SSL_DISPLAY_CERTS 0x00200000
|
#define SSL_DISPLAY_CERTS 0x00200000
|
||||||
#define SSL_DISPLAY_RSA 0x00400000
|
#define SSL_DISPLAY_RSA 0x00400000
|
||||||
#define SSL_CONNECT_IN_PARTS 0x00800000
|
#define SSL_CONNECT_IN_PARTS 0x00800000
|
||||||
|
#define SSL_READ_BLOCKING 0x01000000
|
||||||
|
|
||||||
/* errors that can be generated */
|
/* errors that can be generated */
|
||||||
#define SSL_OK 0
|
#define SSL_OK 0
|
||||||
@ -241,10 +242,11 @@ EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd);
|
|||||||
* can be null if no session resumption is being used or required. This option
|
* can be null if no session resumption is being used or required. This option
|
||||||
* is not used in skeleton mode.
|
* is not used in skeleton mode.
|
||||||
* @param sess_id_size The size of the session id (max 32)
|
* @param sess_id_size The size of the session id (max 32)
|
||||||
|
* @param host_name If non-zero, host name to be sent to server for SNI support
|
||||||
* @return An SSL object reference. Use ssl_handshake_status() to check
|
* @return An SSL object reference. Use ssl_handshake_status() to check
|
||||||
* if a handshake succeeded.
|
* if a handshake succeeded.
|
||||||
*/
|
*/
|
||||||
EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size);
|
EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size, const char* host_name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Free any used resources on this connection.
|
* @brief Free any used resources on this connection.
|
||||||
@ -371,6 +373,15 @@ EXP_FUNC void STDCALL ssl_display_error(int error_code);
|
|||||||
*/
|
*/
|
||||||
EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl);
|
EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if certificate fingerprint (SHA1) matches the one given.
|
||||||
|
*
|
||||||
|
* @param ssl [in] An SSL object reference.
|
||||||
|
* @param fp [in] SHA1 fingerprint to match against
|
||||||
|
* @return SSL_OK if the certificate is verified.
|
||||||
|
*/
|
||||||
|
EXP_FUNC int STDCALL ssl_match_fingerprint(const SSL *ssl, const uint8_t* fp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieve an X.509 distinguished name component.
|
* @brief Retrieve an X.509 distinguished name component.
|
||||||
*
|
*
|
||||||
|
197
ssl/tls1.c
197
ssl/tls1.c
@ -50,8 +50,10 @@ static const char * client_finished = "client finished";
|
|||||||
static int do_handshake(SSL *ssl, uint8_t *buf, int read_len);
|
static int do_handshake(SSL *ssl, uint8_t *buf, int read_len);
|
||||||
static int set_key_block(SSL *ssl, int is_write);
|
static int set_key_block(SSL *ssl, int is_write);
|
||||||
static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len);
|
static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len);
|
||||||
static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt);
|
static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt, void* cached);
|
||||||
static int send_raw_packet(SSL *ssl, uint8_t protocol);
|
static int send_raw_packet(SSL *ssl, uint8_t protocol);
|
||||||
|
static void certificate_free(SSL* ssl);
|
||||||
|
static int increase_bm_data_size(SSL *ssl, size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The server will pick the cipher based on the order that the order that the
|
* The server will pick the cipher based on the order that the order that the
|
||||||
@ -65,11 +67,11 @@ static void session_free(SSL_SESSION *ssl_sessions[], int sess_index);
|
|||||||
|
|
||||||
const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] =
|
const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] =
|
||||||
#ifdef CONFIG_SSL_PROT_LOW /* low security, fast speed */
|
#ifdef CONFIG_SSL_PROT_LOW /* low security, fast speed */
|
||||||
{ SSL_RC4_128_SHA, SSL_AES128_SHA, SSL_AES256_SHA, SSL_RC4_128_MD5 };
|
{ SSL_AES128_SHA, SSL_AES256_SHA};
|
||||||
#elif CONFIG_SSL_PROT_MEDIUM /* medium security, medium speed */
|
#elif CONFIG_SSL_PROT_MEDIUM /* medium security, medium speed */
|
||||||
{ SSL_AES128_SHA, SSL_AES256_SHA, SSL_RC4_128_SHA, SSL_RC4_128_MD5 };
|
{ SSL_AES128_SHA, SSL_AES256_SHA};
|
||||||
#else /* CONFIG_SSL_PROT_HIGH */ /* high security, low speed */
|
#else /* CONFIG_SSL_PROT_HIGH */ /* high security, low speed */
|
||||||
{ SSL_AES256_SHA, SSL_AES128_SHA, SSL_RC4_128_SHA, SSL_RC4_128_MD5 };
|
{ SSL_AES256_SHA, SSL_AES128_SHA};
|
||||||
#endif
|
#endif
|
||||||
#endif /* CONFIG_SSL_SKELETON_MODE */
|
#endif /* CONFIG_SSL_SKELETON_MODE */
|
||||||
|
|
||||||
@ -115,33 +117,7 @@ static const cipher_info_t cipher_info[NUM_PROTOCOLS] =
|
|||||||
hmac_sha1, /* hmac algorithm */
|
hmac_sha1, /* hmac algorithm */
|
||||||
(crypt_func)AES_cbc_encrypt, /* encrypt */
|
(crypt_func)AES_cbc_encrypt, /* encrypt */
|
||||||
(crypt_func)AES_cbc_decrypt /* decrypt */
|
(crypt_func)AES_cbc_decrypt /* decrypt */
|
||||||
},
|
}
|
||||||
{ /* RC4-SHA */
|
|
||||||
SSL_RC4_128_SHA, /* RC4-SHA */
|
|
||||||
16, /* key size */
|
|
||||||
0, /* iv size */
|
|
||||||
2*(SHA1_SIZE+16), /* key block size */
|
|
||||||
0, /* no padding */
|
|
||||||
SHA1_SIZE, /* digest size */
|
|
||||||
hmac_sha1, /* hmac algorithm */
|
|
||||||
(crypt_func)RC4_crypt, /* encrypt */
|
|
||||||
(crypt_func)RC4_crypt /* decrypt */
|
|
||||||
},
|
|
||||||
/*
|
|
||||||
* This protocol is from SSLv2 days and is unlikely to be used - but was
|
|
||||||
* useful for testing different possible digest algorithms.
|
|
||||||
*/
|
|
||||||
{ /* RC4-MD5 */
|
|
||||||
SSL_RC4_128_MD5, /* RC4-MD5 */
|
|
||||||
16, /* key size */
|
|
||||||
0, /* iv size */
|
|
||||||
2*(MD5_SIZE+16), /* key block size */
|
|
||||||
0, /* no padding */
|
|
||||||
MD5_SIZE, /* digest size */
|
|
||||||
hmac_md5, /* hmac algorithm */
|
|
||||||
(crypt_func)RC4_crypt, /* encrypt */
|
|
||||||
(crypt_func)RC4_crypt /* decrypt */
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -273,10 +249,9 @@ EXP_FUNC void STDCALL ssl_free(SSL *ssl)
|
|||||||
free(ssl->encrypt_ctx);
|
free(ssl->encrypt_ctx);
|
||||||
free(ssl->decrypt_ctx);
|
free(ssl->decrypt_ctx);
|
||||||
disposable_free(ssl);
|
disposable_free(ssl);
|
||||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
certificate_free(ssl);
|
||||||
x509_free(ssl->x509_ctx);
|
free(ssl->bm_all_data);
|
||||||
#endif
|
free(ssl->host_name);
|
||||||
|
|
||||||
free(ssl);
|
free(ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +260,9 @@ EXP_FUNC void STDCALL ssl_free(SSL *ssl)
|
|||||||
*/
|
*/
|
||||||
EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data)
|
EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data)
|
||||||
{
|
{
|
||||||
int ret = basic_read(ssl, in_data);
|
int ret = SSL_OK;
|
||||||
|
do {
|
||||||
|
ret= basic_read(ssl, in_data);
|
||||||
|
|
||||||
/* check for return code so we can send an alert */
|
/* check for return code so we can send an alert */
|
||||||
if (ret < SSL_OK && ret != SSL_CLOSE_NOTIFY)
|
if (ret < SSL_OK && ret != SSL_CLOSE_NOTIFY)
|
||||||
@ -299,7 +276,7 @@ EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} while (IS_SET_SSL_FLAG(SSL_READ_BLOCKING) && (ssl->got_bytes < ssl->need_bytes) && ret == 0 && !IS_SET_SSL_FLAG(SSL_NEED_RECORD));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,14 +286,18 @@ EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data)
|
|||||||
EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len)
|
EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len)
|
||||||
{
|
{
|
||||||
int n = out_len, nw, i, tot = 0;
|
int n = out_len, nw, i, tot = 0;
|
||||||
|
|
||||||
/* maximum size of a TLS packet is around 16kB, so fragment */
|
/* maximum size of a TLS packet is around 16kB, so fragment */
|
||||||
|
|
||||||
|
if (ssl->can_free_certificates) {
|
||||||
|
certificate_free(ssl);
|
||||||
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
nw = n;
|
nw = n;
|
||||||
|
|
||||||
if (nw > RT_MAX_PLAIN_LENGTH) /* fragment if necessary */
|
if (nw > ssl->max_plain_length) /* fragment if necessary */
|
||||||
nw = RT_MAX_PLAIN_LENGTH;
|
nw = ssl->max_plain_length;
|
||||||
|
|
||||||
if ((i = send_packet(ssl, PT_APP_PROTOCOL_DATA,
|
if ((i = send_packet(ssl, PT_APP_PROTOCOL_DATA,
|
||||||
&out_data[tot], nw)) <= 0)
|
&out_data[tot], nw)) <= 0)
|
||||||
@ -564,6 +545,8 @@ SSL *ssl_new(SSL_CTX *ssl_ctx, int client_fd)
|
|||||||
{
|
{
|
||||||
SSL *ssl = (SSL *)calloc(1, sizeof(SSL));
|
SSL *ssl = (SSL *)calloc(1, sizeof(SSL));
|
||||||
ssl->ssl_ctx = ssl_ctx;
|
ssl->ssl_ctx = ssl_ctx;
|
||||||
|
ssl->max_plain_length = 1460*4;
|
||||||
|
ssl->bm_all_data = (uint8_t*) calloc(1, ssl->max_plain_length + RT_EXTRA);
|
||||||
ssl->need_bytes = SSL_RECORD_SIZE; /* need a record */
|
ssl->need_bytes = SSL_RECORD_SIZE; /* need a record */
|
||||||
ssl->client_fd = client_fd;
|
ssl->client_fd = client_fd;
|
||||||
ssl->flag = SSL_NEED_RECORD;
|
ssl->flag = SSL_NEED_RECORD;
|
||||||
@ -571,11 +554,15 @@ SSL *ssl_new(SSL_CTX *ssl_ctx, int client_fd)
|
|||||||
ssl->hs_status = SSL_NOT_OK; /* not connected */
|
ssl->hs_status = SSL_NOT_OK; /* not connected */
|
||||||
#ifdef CONFIG_ENABLE_VERIFICATION
|
#ifdef CONFIG_ENABLE_VERIFICATION
|
||||||
ssl->ca_cert_ctx = ssl_ctx->ca_cert_ctx;
|
ssl->ca_cert_ctx = ssl_ctx->ca_cert_ctx;
|
||||||
|
ssl->can_free_certificates = false;
|
||||||
#endif
|
#endif
|
||||||
disposable_new(ssl);
|
disposable_new(ssl);
|
||||||
|
|
||||||
/* a bit hacky but saves a few bytes of memory */
|
/* a bit hacky but saves a few bytes of memory */
|
||||||
ssl->flag |= ssl_ctx->options;
|
ssl->flag |= ssl_ctx->options;
|
||||||
|
if (IS_SET_SSL_FLAG(SSL_CONNECT_IN_PARTS) && IS_SET_SSL_FLAG(SSL_READ_BLOCKING)) {
|
||||||
|
CLR_SSL_FLAG(SSL_READ_BLOCKING);
|
||||||
|
}
|
||||||
SSL_CTX_LOCK(ssl_ctx->mutex);
|
SSL_CTX_LOCK(ssl_ctx->mutex);
|
||||||
|
|
||||||
if (ssl_ctx->head == NULL)
|
if (ssl_ctx->head == NULL)
|
||||||
@ -590,6 +577,11 @@ SSL *ssl_new(SSL_CTX *ssl_ctx, int client_fd)
|
|||||||
ssl_ctx->tail = ssl;
|
ssl_ctx->tail = ssl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssl->encrypt_ctx = malloc(sizeof(AES_CTX));
|
||||||
|
ssl->decrypt_ctx = malloc(sizeof(AES_CTX));
|
||||||
|
|
||||||
|
ssl->host_name = NULL;
|
||||||
|
|
||||||
SSL_CTX_UNLOCK(ssl_ctx->mutex);
|
SSL_CTX_UNLOCK(ssl_ctx->mutex);
|
||||||
return ssl;
|
return ssl;
|
||||||
}
|
}
|
||||||
@ -646,19 +638,36 @@ static void increment_write_sequence(SSL *ssl)
|
|||||||
static void add_hmac_digest(SSL *ssl, int mode, uint8_t *hmac_header,
|
static void add_hmac_digest(SSL *ssl, int mode, uint8_t *hmac_header,
|
||||||
const uint8_t *buf, int buf_len, uint8_t *hmac_buf)
|
const uint8_t *buf, int buf_len, uint8_t *hmac_buf)
|
||||||
{
|
{
|
||||||
int hmac_len = buf_len + 8 + SSL_RECORD_SIZE;
|
const size_t prefix_size = 8 + SSL_RECORD_SIZE;
|
||||||
uint8_t *t_buf = (uint8_t *)alloca(hmac_len+10);
|
bool hmac_inplace = (uint32_t)buf - (uint32_t)ssl->bm_data >= prefix_size;
|
||||||
|
uint8_t tmp[prefix_size];
|
||||||
|
int hmac_len = buf_len + prefix_size;
|
||||||
|
uint8_t *t_buf;
|
||||||
|
if (hmac_inplace) {
|
||||||
|
t_buf = ((uint8_t*)buf) - prefix_size;
|
||||||
|
memcpy(tmp, t_buf, prefix_size);
|
||||||
|
} else {
|
||||||
|
t_buf = (uint8_t *)malloc(hmac_len+10);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(t_buf, (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_WRITE) ?
|
memcpy(t_buf, (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_WRITE) ?
|
||||||
ssl->write_sequence : ssl->read_sequence, 8);
|
ssl->write_sequence : ssl->read_sequence, 8);
|
||||||
memcpy(&t_buf[8], hmac_header, SSL_RECORD_SIZE);
|
memcpy(&t_buf[8], hmac_header, SSL_RECORD_SIZE);
|
||||||
|
if (!hmac_inplace) {
|
||||||
memcpy(&t_buf[8+SSL_RECORD_SIZE], buf, buf_len);
|
memcpy(&t_buf[8+SSL_RECORD_SIZE], buf, buf_len);
|
||||||
|
}
|
||||||
|
|
||||||
ssl->cipher_info->hmac(t_buf, hmac_len,
|
ssl->cipher_info->hmac(t_buf, hmac_len,
|
||||||
(mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ) ?
|
(mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ) ?
|
||||||
ssl->server_mac : ssl->client_mac,
|
ssl->server_mac : ssl->client_mac,
|
||||||
ssl->cipher_info->digest_size, hmac_buf);
|
ssl->cipher_info->digest_size, hmac_buf);
|
||||||
|
|
||||||
|
if (hmac_inplace) {
|
||||||
|
memcpy(t_buf, tmp, prefix_size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
free(t_buf);
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
print_blob("record", hmac_header, SSL_RECORD_SIZE);
|
print_blob("record", hmac_header, SSL_RECORD_SIZE);
|
||||||
print_blob("buf", buf, buf_len);
|
print_blob("buf", buf, buf_len);
|
||||||
@ -899,14 +908,18 @@ void finished_digest(SSL *ssl, const char *label, uint8_t *digest)
|
|||||||
/**
|
/**
|
||||||
* Retrieve (and initialise) the context of a cipher.
|
* Retrieve (and initialise) the context of a cipher.
|
||||||
*/
|
*/
|
||||||
static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt)
|
static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt, void* cached)
|
||||||
{
|
{
|
||||||
switch (ssl->cipher)
|
switch (ssl->cipher)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_SSL_SKELETON_MODE
|
#ifndef CONFIG_SSL_SKELETON_MODE
|
||||||
case SSL_AES128_SHA:
|
case SSL_AES128_SHA:
|
||||||
{
|
{
|
||||||
AES_CTX *aes_ctx = (AES_CTX *)malloc(sizeof(AES_CTX));
|
AES_CTX *aes_ctx;
|
||||||
|
if (cached)
|
||||||
|
aes_ctx = (AES_CTX*) cached;
|
||||||
|
else
|
||||||
|
aes_ctx = (AES_CTX*) malloc(sizeof(AES_CTX));
|
||||||
AES_set_key(aes_ctx, key, iv, AES_MODE_128);
|
AES_set_key(aes_ctx, key, iv, AES_MODE_128);
|
||||||
|
|
||||||
if (is_decrypt)
|
if (is_decrypt)
|
||||||
@ -919,7 +932,12 @@ static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt)
|
|||||||
|
|
||||||
case SSL_AES256_SHA:
|
case SSL_AES256_SHA:
|
||||||
{
|
{
|
||||||
AES_CTX *aes_ctx = (AES_CTX *)malloc(sizeof(AES_CTX));
|
AES_CTX *aes_ctx;
|
||||||
|
if (cached)
|
||||||
|
aes_ctx = (AES_CTX*) cached;
|
||||||
|
else
|
||||||
|
aes_ctx = (AES_CTX*) malloc(sizeof(AES_CTX));
|
||||||
|
|
||||||
AES_set_key(aes_ctx, key, iv, AES_MODE_256);
|
AES_set_key(aes_ctx, key, iv, AES_MODE_256);
|
||||||
|
|
||||||
if (is_decrypt)
|
if (is_decrypt)
|
||||||
@ -934,7 +952,12 @@ static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt)
|
|||||||
#endif
|
#endif
|
||||||
case SSL_RC4_128_SHA:
|
case SSL_RC4_128_SHA:
|
||||||
{
|
{
|
||||||
RC4_CTX *rc4_ctx = (RC4_CTX *)malloc(sizeof(RC4_CTX));
|
RC4_CTX* rc4_ctx;
|
||||||
|
if (cached)
|
||||||
|
rc4_ctx = (RC4_CTX*) cached;
|
||||||
|
else
|
||||||
|
rc4_ctx = (RC4_CTX*) malloc(sizeof(RC4_CTX));
|
||||||
|
|
||||||
RC4_setup(rc4_ctx, key, 16);
|
RC4_setup(rc4_ctx, key, 16);
|
||||||
return (void *)rc4_ctx;
|
return (void *)rc4_ctx;
|
||||||
}
|
}
|
||||||
@ -979,7 +1002,7 @@ static int send_raw_packet(SSL *ssl, uint8_t protocol)
|
|||||||
#endif
|
#endif
|
||||||
return SSL_ERROR_CONN_LOST;
|
return SSL_ERROR_CONN_LOST;
|
||||||
}
|
}
|
||||||
|
#ifndef ESP8266
|
||||||
/* keep going until the write buffer has some space */
|
/* keep going until the write buffer has some space */
|
||||||
if (sent != pkt_size)
|
if (sent != pkt_size)
|
||||||
{
|
{
|
||||||
@ -991,6 +1014,7 @@ static int send_raw_packet(SSL *ssl, uint8_t protocol)
|
|||||||
if (select(ssl->client_fd + 1, NULL, &wfds, NULL, NULL) < 0)
|
if (select(ssl->client_fd + 1, NULL, &wfds, NULL, NULL) < 0)
|
||||||
return SSL_ERROR_CONN_LOST;
|
return SSL_ERROR_CONN_LOST;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_SSL_FLAG(SSL_NEED_RECORD); /* reset for next time */
|
SET_SSL_FLAG(SSL_NEED_RECORD); /* reset for next time */
|
||||||
@ -1073,11 +1097,12 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length)
|
|||||||
ssl->cipher_info->iv_size)
|
ssl->cipher_info->iv_size)
|
||||||
{
|
{
|
||||||
uint8_t iv_size = ssl->cipher_info->iv_size;
|
uint8_t iv_size = ssl->cipher_info->iv_size;
|
||||||
uint8_t *t_buf = alloca(msg_length + iv_size);
|
uint8_t *t_buf = malloc(msg_length + iv_size);
|
||||||
memcpy(t_buf + iv_size, ssl->bm_data, msg_length);
|
memcpy(t_buf + iv_size, ssl->bm_data, msg_length);
|
||||||
get_random(iv_size, t_buf);
|
get_random(iv_size, t_buf);
|
||||||
msg_length += iv_size;
|
msg_length += iv_size;
|
||||||
memcpy(ssl->bm_data, t_buf, msg_length);
|
memcpy(ssl->bm_data, t_buf, msg_length);
|
||||||
|
free(t_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now encrypt the packet */
|
/* now encrypt the packet */
|
||||||
@ -1164,7 +1189,7 @@ static int set_key_block(SSL *ssl, int is_write)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free(is_write ? ssl->encrypt_ctx : ssl->decrypt_ctx);
|
// free(is_write ? ssl->encrypt_ctx : ssl->decrypt_ctx);
|
||||||
|
|
||||||
/* now initialise the ciphers */
|
/* now initialise the ciphers */
|
||||||
if (is_client)
|
if (is_client)
|
||||||
@ -1172,18 +1197,18 @@ static int set_key_block(SSL *ssl, int is_write)
|
|||||||
finished_digest(ssl, server_finished, ssl->dc->final_finish_mac);
|
finished_digest(ssl, server_finished, ssl->dc->final_finish_mac);
|
||||||
|
|
||||||
if (is_write)
|
if (is_write)
|
||||||
ssl->encrypt_ctx = crypt_new(ssl, client_key, client_iv, 0);
|
ssl->encrypt_ctx = crypt_new(ssl, client_key, client_iv, 0, ssl->encrypt_ctx);
|
||||||
else
|
else
|
||||||
ssl->decrypt_ctx = crypt_new(ssl, server_key, server_iv, 1);
|
ssl->decrypt_ctx = crypt_new(ssl, server_key, server_iv, 1, ssl->decrypt_ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
finished_digest(ssl, client_finished, ssl->dc->final_finish_mac);
|
finished_digest(ssl, client_finished, ssl->dc->final_finish_mac);
|
||||||
|
|
||||||
if (is_write)
|
if (is_write)
|
||||||
ssl->encrypt_ctx = crypt_new(ssl, server_key, server_iv, 0);
|
ssl->encrypt_ctx = crypt_new(ssl, server_key, server_iv, 0, ssl->encrypt_ctx);
|
||||||
else
|
else
|
||||||
ssl->decrypt_ctx = crypt_new(ssl, client_key, client_iv, 1);
|
ssl->decrypt_ctx = crypt_new(ssl, client_key, client_iv, 1, ssl->decrypt_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssl->cipher_info = ciph_info;
|
ssl->cipher_info = ciph_info;
|
||||||
@ -1199,6 +1224,10 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
|||||||
int read_len, is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
|
int read_len, is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
|
||||||
uint8_t *buf = ssl->bm_data;
|
uint8_t *buf = ssl->bm_data;
|
||||||
|
|
||||||
|
if (ssl->can_free_certificates) {
|
||||||
|
certificate_free(ssl);
|
||||||
|
}
|
||||||
|
|
||||||
read_len = SOCKET_READ(ssl->client_fd, &buf[ssl->bm_read_index],
|
read_len = SOCKET_READ(ssl->client_fd, &buf[ssl->bm_read_index],
|
||||||
ssl->need_bytes-ssl->got_bytes);
|
ssl->need_bytes-ssl->got_bytes);
|
||||||
|
|
||||||
@ -1271,10 +1300,23 @@ int basic_read(SSL *ssl, uint8_t **in_data)
|
|||||||
/* do we violate the spec with the message size? */
|
/* do we violate the spec with the message size? */
|
||||||
if (ssl->need_bytes > RT_MAX_PLAIN_LENGTH+RT_EXTRA-BM_RECORD_OFFSET)
|
if (ssl->need_bytes > RT_MAX_PLAIN_LENGTH+RT_EXTRA-BM_RECORD_OFFSET)
|
||||||
{
|
{
|
||||||
|
printf("ssl->need_bytes=%d violates spec\r\n", ssl->need_bytes, RT_MAX_PLAIN_LENGTH+RT_EXTRA-BM_RECORD_OFFSET);
|
||||||
ret = SSL_ERROR_INVALID_PROT_MSG;
|
ret = SSL_ERROR_INVALID_PROT_MSG;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* is the allocated buffer large enough to handle all the data? if not, increase its size*/
|
||||||
|
if (ssl->need_bytes > ssl->max_plain_length+RT_EXTRA-BM_RECORD_OFFSET)
|
||||||
|
{
|
||||||
|
printf("ssl->need_bytes=%d > %d\r\n", ssl->need_bytes, ssl->max_plain_length+RT_EXTRA-BM_RECORD_OFFSET);
|
||||||
|
ret = increase_bm_data_size(ssl, ssl->need_bytes + BM_RECORD_OFFSET - RT_EXTRA);
|
||||||
|
if (ret != SSL_OK)
|
||||||
|
{
|
||||||
|
ret = SSL_ERROR_INVALID_PROT_MSG;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CLR_SSL_FLAG(SSL_NEED_RECORD);
|
CLR_SSL_FLAG(SSL_NEED_RECORD);
|
||||||
memcpy(ssl->hmac_header, buf, 3); /* store for hmac */
|
memcpy(ssl->hmac_header, buf, 3); /* store for hmac */
|
||||||
ssl->record_type = buf[0];
|
ssl->record_type = buf[0];
|
||||||
@ -1386,6 +1428,25 @@ error:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int increase_bm_data_size(SSL *ssl, size_t size)
|
||||||
|
{
|
||||||
|
if (ssl->max_plain_length == RT_MAX_PLAIN_LENGTH) {
|
||||||
|
return SSL_OK;
|
||||||
|
}
|
||||||
|
size_t required = (size + 1023) & ~(1023); // round up to 1k
|
||||||
|
required = (required < RT_MAX_PLAIN_LENGTH) ? required : RT_MAX_PLAIN_LENGTH;
|
||||||
|
uint8_t* new_bm_all_data = (uint8_t*) realloc(ssl->bm_all_data, required + RT_EXTRA);
|
||||||
|
if (!new_bm_all_data) {
|
||||||
|
printf("failed to grow plain buffer\r\n");
|
||||||
|
ssl->hs_status = SSL_ERROR_DEAD;
|
||||||
|
return SSL_ERROR_CONN_LOST;
|
||||||
|
}
|
||||||
|
ssl->bm_all_data = new_bm_all_data;
|
||||||
|
ssl->bm_data = ssl->bm_all_data + BM_RECORD_OFFSET;
|
||||||
|
ssl->max_plain_length = required;
|
||||||
|
return SSL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do some basic checking of data and then perform the appropriate handshaking.
|
* Do some basic checking of data and then perform the appropriate handshaking.
|
||||||
*/
|
*/
|
||||||
@ -1640,7 +1701,18 @@ void disposable_free(SSL *ssl)
|
|||||||
free(ssl->dc);
|
free(ssl->dc);
|
||||||
ssl->dc = NULL;
|
ssl->dc = NULL;
|
||||||
}
|
}
|
||||||
|
ssl->can_free_certificates = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void certificate_free(SSL* ssl)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||||
|
if (ssl->x509_ctx) {
|
||||||
|
x509_free(ssl->x509_ctx);
|
||||||
|
ssl->x509_ctx = 0;
|
||||||
|
}
|
||||||
|
ssl->can_free_certificates = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_SSL_SKELETON_MODE /* no session resumption in this mode */
|
#ifndef CONFIG_SSL_SKELETON_MODE /* no session resumption in this mode */
|
||||||
@ -1884,6 +1956,25 @@ error:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXP_FUNC int STDCALL ssl_match_fingerprint(const SSL *ssl, const uint8_t* fp)
|
||||||
|
{
|
||||||
|
if (ssl->x509_ctx == NULL || ssl->x509_ctx->fingerprint == NULL)
|
||||||
|
return 1;
|
||||||
|
int res = memcmp(ssl->x509_ctx->fingerprint, fp, SHA1_SIZE);
|
||||||
|
if (res != 0) {
|
||||||
|
printf("cert FP: ");
|
||||||
|
for (int i = 0; i < SHA1_SIZE; ++i) {
|
||||||
|
printf("%02X ", ssl->x509_ctx->fingerprint[i]);
|
||||||
|
}
|
||||||
|
printf("\r\ntest FP: ");
|
||||||
|
for (int i = 0; i < SHA1_SIZE; ++i) {
|
||||||
|
printf("%02X ", fp[i]);
|
||||||
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_SSL_CERT_VERIFICATION */
|
#endif /* CONFIG_SSL_CERT_VERIFICATION */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,7 +82,7 @@ extern "C" {
|
|||||||
#ifdef CONFIG_SSL_SKELETON_MODE
|
#ifdef CONFIG_SSL_SKELETON_MODE
|
||||||
#define NUM_PROTOCOLS 1
|
#define NUM_PROTOCOLS 1
|
||||||
#else
|
#else
|
||||||
#define NUM_PROTOCOLS 4
|
#define NUM_PROTOCOLS 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PARANOIA_CHECK(A, B) if (A < B) { \
|
#define PARANOIA_CHECK(A, B) if (A < B) { \
|
||||||
@ -175,10 +175,11 @@ struct _SSL
|
|||||||
const cipher_info_t *cipher_info;
|
const cipher_info_t *cipher_info;
|
||||||
void *encrypt_ctx;
|
void *encrypt_ctx;
|
||||||
void *decrypt_ctx;
|
void *decrypt_ctx;
|
||||||
uint8_t bm_all_data[RT_MAX_PLAIN_LENGTH+RT_EXTRA];
|
uint8_t *bm_all_data;
|
||||||
uint8_t *bm_data;
|
uint8_t *bm_data;
|
||||||
uint16_t bm_index;
|
uint16_t bm_index;
|
||||||
uint16_t bm_read_index;
|
uint16_t bm_read_index;
|
||||||
|
size_t max_plain_length;
|
||||||
struct _SSL *next; /* doubly linked list */
|
struct _SSL *next; /* doubly linked list */
|
||||||
struct _SSL *prev;
|
struct _SSL *prev;
|
||||||
struct _SSL_CTX *ssl_ctx; /* back reference to a clnt/svr ctx */
|
struct _SSL_CTX *ssl_ctx; /* back reference to a clnt/svr ctx */
|
||||||
@ -188,14 +189,15 @@ struct _SSL
|
|||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||||
X509_CTX *x509_ctx;
|
X509_CTX *x509_ctx;
|
||||||
|
bool can_free_certificates;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t session_id[SSL_SESSION_ID_SIZE];
|
uint8_t session_id[SSL_SESSION_ID_SIZE];
|
||||||
uint8_t client_mac[SHA1_SIZE]; /* for HMAC verification */
|
uint8_t client_mac[SHA1_SIZE]; /* for HMAC verification */
|
||||||
uint8_t server_mac[SHA1_SIZE]; /* for HMAC verification */
|
uint8_t server_mac[SHA1_SIZE]; /* for HMAC verification */
|
||||||
uint8_t read_sequence[8]; /* 64 bit sequence number */
|
uint8_t read_sequence[8]; /* 64 bit sequence number */
|
||||||
uint8_t write_sequence[8]; /* 64 bit sequence number */
|
uint8_t write_sequence[8]; /* 64 bit sequence number */
|
||||||
uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */
|
uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */
|
||||||
|
char *host_name; /* Needed for the SNI support */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _SSL SSL;
|
typedef struct _SSL SSL;
|
||||||
|
@ -48,7 +48,7 @@ static int send_cert_verify(SSL *ssl);
|
|||||||
* Establish a new SSL connection to an SSL server.
|
* Establish a new SSL connection to an SSL server.
|
||||||
*/
|
*/
|
||||||
EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const
|
EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const
|
||||||
uint8_t *session_id, uint8_t sess_id_size)
|
uint8_t *session_id, uint8_t sess_id_size, const char* host_name)
|
||||||
{
|
{
|
||||||
SSL *ssl = ssl_new(ssl_ctx, client_fd);
|
SSL *ssl = ssl_new(ssl_ctx, client_fd);
|
||||||
ssl->version = SSL_PROTOCOL_VERSION_MAX; /* try top version first */
|
ssl->version = SSL_PROTOCOL_VERSION_MAX; /* try top version first */
|
||||||
@ -66,6 +66,10 @@ EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const
|
|||||||
SET_SSL_FLAG(SSL_SESSION_RESUME); /* just flag for later */
|
SET_SSL_FLAG(SSL_SESSION_RESUME); /* just flag for later */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(host_name != NULL && strlen(host_name) > 0) {
|
||||||
|
ssl->host_name = (char *)strdup(host_name);
|
||||||
|
}
|
||||||
|
|
||||||
SET_SSL_FLAG(SSL_IS_CLIENT);
|
SET_SSL_FLAG(SSL_IS_CLIENT);
|
||||||
do_client_connect(ssl);
|
do_client_connect(ssl);
|
||||||
return ssl;
|
return ssl;
|
||||||
@ -119,7 +123,10 @@ int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
|
|||||||
|
|
||||||
case HS_FINISHED:
|
case HS_FINISHED:
|
||||||
ret = process_finished(ssl, buf, hs_len);
|
ret = process_finished(ssl, buf, hs_len);
|
||||||
disposable_free(ssl); /* free up some memory */
|
disposable_free(ssl);
|
||||||
|
if (ssl->ssl_ctx->options & SSL_READ_BLOCKING) {
|
||||||
|
ssl->flag |= SSL_READ_BLOCKING;
|
||||||
|
}
|
||||||
/* note: client renegotiation is not allowed after this */
|
/* note: client renegotiation is not allowed after this */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -217,6 +224,26 @@ static int send_client_hello(SSL *ssl)
|
|||||||
|
|
||||||
buf[offset++] = 1; /* no compression */
|
buf[offset++] = 1; /* no compression */
|
||||||
buf[offset++] = 0;
|
buf[offset++] = 0;
|
||||||
|
|
||||||
|
if (ssl->host_name != NULL) {
|
||||||
|
unsigned int host_len = strlen(ssl->host_name);
|
||||||
|
|
||||||
|
buf[offset++] = 0;
|
||||||
|
buf[offset++] = host_len+9; /* extensions length */
|
||||||
|
|
||||||
|
buf[offset++] = 0;
|
||||||
|
buf[offset++] = 0; /* server_name(0) (65535) */
|
||||||
|
buf[offset++] = 0;
|
||||||
|
buf[offset++] = host_len+5; /* server_name length */
|
||||||
|
buf[offset++] = 0;
|
||||||
|
buf[offset++] = host_len+3; /* server_list length */
|
||||||
|
buf[offset++] = 0; /* host_name(0) (255) */
|
||||||
|
buf[offset++] = 0;
|
||||||
|
buf[offset++] = host_len; /* host_name length */
|
||||||
|
strncpy((char*) &buf[offset], ssl->host_name, host_len);
|
||||||
|
offset += host_len;
|
||||||
|
}
|
||||||
|
|
||||||
buf[3] = offset - 4; /* handshake size */
|
buf[3] = offset - 4; /* handshake size */
|
||||||
|
|
||||||
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
|
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
|
||||||
|
15
ssl/x509.c
15
ssl/x509.c
@ -119,6 +119,12 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
|
|||||||
|
|
||||||
bi_ctx = x509_ctx->rsa_ctx->bi_ctx;
|
bi_ctx = x509_ctx->rsa_ctx->bi_ctx;
|
||||||
|
|
||||||
|
x509_ctx->fingerprint = malloc(SHA1_SIZE);
|
||||||
|
SHA1_CTX sha_fp_ctx;
|
||||||
|
SHA1_Init(&sha_fp_ctx);
|
||||||
|
SHA1_Update(&sha_fp_ctx, &cert[0], cert_size);
|
||||||
|
SHA1_Final(x509_ctx->fingerprint, &sha_fp_ctx);
|
||||||
|
|
||||||
#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
|
#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
|
||||||
/* use the appropriate signature algorithm (SHA1/MD5/MD2) */
|
/* use the appropriate signature algorithm (SHA1/MD5/MD2) */
|
||||||
if (x509_ctx->sig_type == SIG_TYPE_MD5)
|
if (x509_ctx->sig_type == SIG_TYPE_MD5)
|
||||||
@ -245,6 +251,11 @@ void x509_free(X509_CTX *x509_ctx)
|
|||||||
bi_free(x509_ctx->rsa_ctx->bi_ctx, x509_ctx->digest);
|
bi_free(x509_ctx->rsa_ctx->bi_ctx, x509_ctx->digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (x509_ctx->fingerprint)
|
||||||
|
{
|
||||||
|
free(x509_ctx->fingerprint);
|
||||||
|
}
|
||||||
|
|
||||||
if (x509_ctx->subject_alt_dnsnames)
|
if (x509_ctx->subject_alt_dnsnames)
|
||||||
{
|
{
|
||||||
for (i = 0; x509_ctx->subject_alt_dnsnames[i]; ++i)
|
for (i = 0; x509_ctx->subject_alt_dnsnames[i]; ++i)
|
||||||
@ -270,7 +281,7 @@ static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
|
|||||||
int i, size;
|
int i, size;
|
||||||
bigint *decrypted_bi, *dat_bi;
|
bigint *decrypted_bi, *dat_bi;
|
||||||
bigint *bir = NULL;
|
bigint *bir = NULL;
|
||||||
uint8_t *block = (uint8_t *)alloca(sig_len);
|
uint8_t *block = (uint8_t *)malloc(sig_len);
|
||||||
|
|
||||||
/* decrypt */
|
/* decrypt */
|
||||||
dat_bi = bi_import(ctx, sig, sig_len);
|
dat_bi = bi_import(ctx, sig, sig_len);
|
||||||
@ -297,7 +308,7 @@ static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
|
|||||||
bir = bi_import(ctx, sig_ptr, len);
|
bir = bi_import(ctx, sig_ptr, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(block);
|
||||||
/* save a few bytes of memory */
|
/* save a few bytes of memory */
|
||||||
bi_clear_cache(ctx);
|
bi_clear_cache(ctx);
|
||||||
return bir;
|
return bir;
|
||||||
|
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
|
11
util/time.h
Normal file
11
util/time.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef TIME_H
|
||||||
|
#define TIME_H
|
||||||
|
|
||||||
|
struct timeval
|
||||||
|
{
|
||||||
|
time_t tv_sec;
|
||||||
|
long tv_usec;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //TIME_H
|
Loading…
x
Reference in New Issue
Block a user