forked from SuperHouse/esp-open-rtos
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add websocket example that supports permessage-deflate extension
- Loading branch information
Showing
19 changed files
with
2,175 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
PROGRAM=websocket_mbedtls | ||
COMPONENTS = FreeRTOS lwip core extras/mbedtls | ||
|
||
include ../../common.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* Adler-32 checksum | ||
* | ||
* Copyright (c) 2003 by Joergen Ibsen / Jibz | ||
* All Rights Reserved | ||
* | ||
* http://www.ibsensoftware.com/ | ||
* | ||
* This software is provided 'as-is', without any express | ||
* or implied warranty. In no event will the authors be | ||
* held liable for any damages arising from the use of | ||
* this software. | ||
* | ||
* Permission is granted to anyone to use this software | ||
* for any purpose, including commercial applications, | ||
* and to alter it and redistribute it freely, subject to | ||
* the following restrictions: | ||
* | ||
* 1. The origin of this software must not be | ||
* misrepresented; you must not claim that you | ||
* wrote the original software. If you use this | ||
* software in a product, an acknowledgment in | ||
* the product documentation would be appreciated | ||
* but is not required. | ||
* | ||
* 2. Altered source versions must be plainly marked | ||
* as such, and must not be misrepresented as | ||
* being the original software. | ||
* | ||
* 3. This notice may not be removed or altered from | ||
* any source distribution. | ||
*/ | ||
|
||
/* | ||
* Adler-32 algorithm taken from the zlib source, which is | ||
* Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler | ||
*/ | ||
|
||
#include "tinf.h" | ||
|
||
#define A32_BASE 65521 | ||
#define A32_NMAX 5552 | ||
|
||
unsigned int tinf_adler32(const void *data, unsigned int length) | ||
{ | ||
const unsigned char *buf = (const unsigned char *)data; | ||
|
||
unsigned int s1 = 1; | ||
unsigned int s2 = 0; | ||
|
||
while (length > 0) | ||
{ | ||
int k = length < A32_NMAX ? length : A32_NMAX; | ||
int i; | ||
|
||
for (i = k / 16; i; --i, buf += 16) | ||
{ | ||
s1 += buf[0]; s2 += s1; s1 += buf[1]; s2 += s1; | ||
s1 += buf[2]; s2 += s1; s1 += buf[3]; s2 += s1; | ||
s1 += buf[4]; s2 += s1; s1 += buf[5]; s2 += s1; | ||
s1 += buf[6]; s2 += s1; s1 += buf[7]; s2 += s1; | ||
|
||
s1 += buf[8]; s2 += s1; s1 += buf[9]; s2 += s1; | ||
s1 += buf[10]; s2 += s1; s1 += buf[11]; s2 += s1; | ||
s1 += buf[12]; s2 += s1; s1 += buf[13]; s2 += s1; | ||
s1 += buf[14]; s2 += s1; s1 += buf[15]; s2 += s1; | ||
} | ||
|
||
for (i = k % 16; i; --i) { s1 += *buf++; s2 += s1; } | ||
|
||
s1 %= A32_BASE; | ||
s2 %= A32_BASE; | ||
|
||
length -= k; | ||
} | ||
|
||
return (s2 << 16) | s1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* This is the CA certificate for the CA trust chain of | ||
www.howsmyssl.com in PEM format, as dumped via: | ||
openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/null | ||
The CA cert is the last cert in the chain output by the server. | ||
*/ | ||
#include <stdio.h> | ||
#include <stdint.h> | ||
#include <string.h> | ||
|
||
/* | ||
1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 | ||
i:/O=Digital Signature Trust Co./CN=DST Root CA X3 | ||
*/ | ||
const char *server_root_cert = "-----BEGIN CERTIFICATE-----\r\n" | ||
"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\r\n" | ||
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\r\n" | ||
"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\r\n" | ||
"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\r\n" | ||
"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\r\n" | ||
"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\r\n" | ||
"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\r\n" | ||
"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\r\n" | ||
"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\r\n" | ||
"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\r\n" | ||
"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\r\n" | ||
"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\r\n" | ||
"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\r\n" | ||
"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\r\n" | ||
"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\r\n" | ||
"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\r\n" | ||
"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\r\n" | ||
"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\r\n" | ||
"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\r\n" | ||
"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\r\n" | ||
"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\r\n" | ||
"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\r\n" | ||
"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\r\n" | ||
"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\r\n" | ||
"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\r\n" | ||
"-----END CERTIFICATE-----\r\n"; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
#include "espressif/esp_common.h" | ||
#include "esp/uart.h" | ||
|
||
#include <string.h> | ||
|
||
#include "FreeRTOS.h" | ||
#include "task.h" | ||
|
||
#include "lwip/err.h" | ||
#include "lwip/sockets.h" | ||
#include "lwip/sys.h" | ||
#include "lwip/netdb.h" | ||
#include "lwip/dns.h" | ||
#include "lwip/api.h" | ||
|
||
#include "ssid_config.h" | ||
|
||
/* mbedtls/config.h MUST appear before all other mbedtls headers, or | ||
you'll get the default config. | ||
(Although mostly that isn't a big problem, you just might get | ||
errors at link time if functions don't exist.) */ | ||
#include "mbedtls/config.h" | ||
|
||
#include "mbedtls/net.h" | ||
#include "mbedtls/debug.h" | ||
#include "mbedtls/ssl.h" | ||
#include "mbedtls/entropy.h" | ||
#include "mbedtls/ctr_drbg.h" | ||
#include "mbedtls/error.h" | ||
#include "mbedtls/certs.h" | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#include "conn.h" | ||
|
||
/* SSL file descriptors */ | ||
#define SSL_HANDLES_SIZE 4 | ||
mbedtls_ssl_context* sslHandles[SSL_HANDLES_SIZE] = {NULL, NULL, NULL, NULL}; | ||
unsigned char ctxC = 0; | ||
|
||
mbedtls_ssl_config conf; | ||
mbedtls_x509_crt cacert; | ||
mbedtls_ctr_drbg_context ctr_drbg; | ||
mbedtls_entropy_context entropy; | ||
|
||
/* Connect to a hostname and port using TLS 1.2 and | ||
return a index for one SSL connection on the pool or -1 if error | ||
*/ | ||
int ConnConnect(char *hostname, int port) { | ||
int ret = 0; | ||
mbedtls_ssl_context *sslFD; | ||
mbedtls_net_context *socketFD; | ||
int sslHandle = 0; | ||
char s_port[10]; | ||
|
||
// configure mbedtls | ||
if (!ctxC) { | ||
mbedtls_ssl_config_init( &conf ); | ||
mbedtls_x509_crt_init( &cacert ); | ||
mbedtls_ctr_drbg_init( &ctr_drbg ); | ||
mbedtls_entropy_init( &entropy ); | ||
|
||
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, | ||
(const unsigned char *) "ssl_client1", | ||
strlen( "ssl_client1" ) ) ) != 0 ) | ||
{ | ||
printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ); | ||
return -1; | ||
} | ||
|
||
ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem, | ||
mbedtls_test_cas_pem_len ); | ||
if( ret < 0 ) | ||
{ | ||
printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret ); | ||
return -1; | ||
} | ||
|
||
|
||
if( ( ret = mbedtls_ssl_config_defaults( &conf, | ||
MBEDTLS_SSL_IS_CLIENT, | ||
MBEDTLS_SSL_TRANSPORT_STREAM, | ||
MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) | ||
{ | ||
printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); | ||
return -1; | ||
} | ||
|
||
mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL ); | ||
mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); | ||
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); | ||
|
||
ctxC = 1; | ||
} | ||
|
||
// find a free slot at sslHandles | ||
while(sslHandle < SSL_HANDLES_SIZE) { | ||
if (sslHandles[sslHandle] == NULL) { | ||
sslFD = malloc(sizeof(mbedtls_ssl_context)); | ||
socketFD = malloc(sizeof(mbedtls_net_context)); | ||
mbedtls_ssl_init( sslFD ); | ||
mbedtls_net_init( socketFD ); | ||
sslHandles[sslHandle] = sslFD; | ||
break; | ||
} | ||
sslHandle++; | ||
} | ||
|
||
// no free slot at sslHandles | ||
if (sslHandle == SSL_HANDLES_SIZE) { | ||
return -1; | ||
} | ||
|
||
// connect mbedtls socket | ||
memset(s_port, 0, sizeof(s_port)); | ||
sprintf(s_port, "%d", port); | ||
ret = mbedtls_net_connect(socketFD, hostname, s_port, MBEDTLS_NET_PROTO_TCP); | ||
if (ret != 0) { | ||
ConnClose(sslHandle); | ||
return -1; | ||
} | ||
|
||
if(( ret = mbedtls_ssl_setup( sslFD, &conf ) ) != 0 ) | ||
{ | ||
printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret ); | ||
ConnClose(sslHandle); | ||
return -1; | ||
} | ||
|
||
if( ( ret = mbedtls_ssl_set_hostname( sslFD, "mbed TLS Server 1" ) ) != 0 ) | ||
{ | ||
printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret ); | ||
ConnClose(sslHandle); | ||
return -1; | ||
} | ||
|
||
mbedtls_ssl_set_bio( sslFD, socketFD, mbedtls_net_send, mbedtls_net_recv, NULL ); | ||
|
||
while( ( ret = mbedtls_ssl_handshake( sslFD ) ) != 0 ) | ||
{ | ||
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) | ||
{ | ||
printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret ); | ||
ConnClose(sslHandle); | ||
return -1; | ||
} | ||
} | ||
|
||
return sslHandle; | ||
} | ||
|
||
int ConnReadBytesAvailable(int sslHandle) { | ||
mbedtls_ssl_context* sslFD = NULL; | ||
mbedtls_net_context* socketFD = NULL; | ||
int count = 0; | ||
|
||
if (sslHandle >= 0) sslFD = sslHandles[sslHandle]; | ||
else return -1; | ||
|
||
if (sslFD) { | ||
socketFD = (mbedtls_net_context *) sslFD->p_bio; | ||
lwip_ioctl(socketFD->fd, FIONREAD, &count); | ||
return count; | ||
} else { | ||
return -1; | ||
} | ||
} | ||
|
||
/* Read bytes from a valid SSL connection on the pool. Blocking! */ | ||
int ConnRead(int sslHandle, void *buf, int num) { | ||
mbedtls_ssl_context* sslFD = NULL; | ||
int ret; | ||
|
||
if (sslHandle >= 0) sslFD = sslHandles[sslHandle]; | ||
else return -1; | ||
|
||
if (sslFD) { | ||
if (num == 0) return 0; | ||
ret = mbedtls_ssl_read(sslFD, buf, num); | ||
return ret; | ||
} else { | ||
return -1; | ||
} | ||
} | ||
|
||
/* Write bytes to a valid SSL connection on the pool */ | ||
int ConnWrite(int sslHandle, const void *buf, int num) { | ||
mbedtls_ssl_context* sslFD = NULL; | ||
int ret; | ||
|
||
if (sslHandle >= 0) sslFD = sslHandles[sslHandle]; | ||
else return -1; | ||
|
||
if (sslFD) { | ||
if (num == 0) return 0; | ||
ret = mbedtls_ssl_write(sslFD, buf, num); | ||
return ret; | ||
} else { | ||
return -1; | ||
} | ||
} | ||
|
||
/* Close a valid SSL connection on the pool, release the resources and | ||
open the slot to another connection */ | ||
void ConnClose(int sslHandle) { | ||
mbedtls_ssl_context *sslFD = NULL; | ||
|
||
if (sslHandle >= 0) sslFD = sslHandles[sslHandle]; | ||
else return; | ||
|
||
if (sslFD) { | ||
mbedtls_ssl_close_notify( sslFD ); | ||
|
||
mbedtls_net_free( sslFD->p_bio ); | ||
free(sslFD->p_bio); | ||
|
||
mbedtls_ssl_free( sslFD ); | ||
free(sslFD); | ||
} | ||
|
||
sslHandles[sslHandle] = NULL; | ||
} | ||
|
||
void sleep_ms(int milliseconds) | ||
{ | ||
vTaskDelay(milliseconds / portTICK_RATE_MS); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#ifndef CONN | ||
#define CONN | ||
|
||
int ConnConnect(char *host, int port); | ||
int ConnReadBytesAvailable(int sslHandle); | ||
int ConnRead(int sslHandle, void *buf, int num); | ||
int ConnWrite(int sslHandle, const void *buf, int num); | ||
void ConnClose(int sslHandle); | ||
void sleep_ms(int milliseconds); | ||
|
||
#endif |
Oops, something went wrong.