asio: Basic SSL/TLS support in asio port for ESP platform

This port employs IDF port of OpenSSL for most common features, others
are discouraged or not supported. The port also introduces several stubs
for OpenSSL functions which ASIO needs to get compiled and linked.

Upstream ASIO supports WolfSSL as SSL/TLS stack, as well, which is
another option for SSL support in ASIO on ESP platform.
pull/5688/head
David Cermak 2020-06-05 16:17:01 +02:00 zatwierdzone przez bot
rodzic 085d2b8d25
commit 9459c0dd43
10 zmienionych plików z 292 dodań i 11 usunięć

Wyświetl plik

@ -1,3 +1,5 @@
idf_component_register(SRCS "asio/asio/src/asio.cpp"
"asio/asio/src/asio_ssl.cpp"
"port/src/esp_asio_openssl_stubs.c"
INCLUDE_DIRS "asio/asio/include" "port/include"
REQUIRES lwip)
REQUIRES lwip openssl)

@ -1 +1 @@
Subproject commit 3b66e5b051381fb70de9c2791df70a06181c64e3
Subproject commit 61702cd13be0b8c9800a9793daae72768ede26af

Wyświetl plik

@ -1,6 +1,5 @@
COMPONENT_ADD_INCLUDEDIRS := asio/asio/include port/include
COMPONENT_PRIV_INCLUDEDIRS := private_include
COMPONENT_SRCDIRS := asio/asio/src
COMPONENT_OBJEXCLUDE := asio/asio/src/asio_ssl.o
COMPONENT_SRCDIRS := asio/asio/src port/src
COMPONENT_SUBMODULES += asio

Wyświetl plik

@ -0,0 +1,20 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_ASIO_OPENSSL_CONF_H
#define _ESP_ASIO_OPENSSL_CONF_H
#include "openssl/esp_asio_openssl_stubs.h"
#endif // _ESP_ASIO_OPENSSL_CONF_H

Wyświetl plik

@ -0,0 +1,185 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_ASIO_OPENSSL_STUBS_H
#define _ESP_ASIO_OPENSSL_STUBS_H
#include "internal/ssl_x509.h"
#include "internal/ssl_pkey.h"
#include "mbedtls/pem.h"
#include <stdint.h>
/**
* @note This header contains openssl API which are NOT implemented, and are only provided
* as stubs or no-operations to get the ASIO library compiled and working with most
* practical use cases as an embedded application on ESP platform
*/
#ifdef __cplusplus
extern "C" {
#endif
// The most applicable OpenSSL version wrtt ASIO usage
#define OPENSSL_VERSION_NUMBER 0x10100001L
// SSLv2 methods not supported
// OpenSSL port supports: TLS_ANY, TLS_1, TLS_1_1, TLS_1_2, SSL_3
#define OPENSSL_NO_SSL2
#define SSL2_VERSION 0x0002
#define SSL_R_SHORT_READ 219
#define SSL_OP_ALL 0
#define SSL_OP_SINGLE_DH_USE 0
//#define OPENSSL_VERSION_NUMBER 0x10001000L
#define SSL_OP_NO_COMPRESSION 0
//#define LIBRESSL_VERSION_NUMBER 1
//#define PEM_R_NO_START_LINE 110
// Translates mbedTLS PEM parse error, used by ASIO
#define PEM_R_NO_START_LINE -MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
#define SSL_OP_NO_SSLv2 0x01000000L
#define SSL_OP_NO_SSLv3 0x02000000L
#define SSL_OP_NO_TLSv1 0x04000000L
#define X509_FILETYPE_PEM 1
#define X509_FILETYPE_ASN1 2
#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1
#define SSL_FILETYPE_PEM X509_FILETYPE_PEM
#define NID_subject_alt_name 85
#define SSL_MODE_RELEASE_BUFFERS 0x00000000L
#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L
#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
#define GEN_DNS 2
#define GEN_IPADD 7
#define V_ASN1_OCTET_STRING 4
#define V_ASN1_IA5STRING 22
#define NID_commonName 13
#define SSL_CTX_get_app_data(ctx) ((void*)SSL_CTX_get_ex_data(ctx, 0))
/**
* @brief Frees DH object -- not implemented
*
* Current implementation calls SSL_ASSERT
*
* @param r DH object
*/
void DH_free(DH *r);
/**
* @brief Frees GENERAL_NAMES -- not implemented
*
* Current implementation calls SSL_ASSERT
*
* @param r GENERAL_NAMES object
*/
void GENERAL_NAMES_free(GENERAL_NAMES * gens);
/**
* @brief Returns subject name from X509 -- not implemented
*
* Current implementation calls SSL_ASSERT
*
* @param r X509 object
*/
X509_NAME *X509_get_subject_name(X509 *a);
/**
* @brief API provaded as declaration only
*
*/
int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
/**
* @brief API provaded as declaration only
*
*/
int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos);
/**
* @brief API provaded as declaration only
*
*/
X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
/**
* @brief API provaded as declaration only
*
*/
ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
/**
* @brief API provaded as declaration only
*
*/
void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
/**
* @brief API provaded as declaration only
*
*/
X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
/**
* @brief Reads DH params from a bio object -- not implemented
*
* Current implementation calls SSL_ASSERT
*/
DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u);
/**
* @brief API provaded as declaration only
*
*/
void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
/**
* @brief Sets DH params to ssl ctx -- not implemented
*
* Current implementation calls SSL_ASSERT
*/
int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh);
/**
* @brief Sets SSL mode -- not implemented
*
* Current implementation is no-op
*/
uint32_t SSL_set_mode(SSL *ssl, uint32_t mode);
/**
* @brief API provaded as declaration only
*
*/
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data);
/**
* @brief API provaded as declaration only
*
*/
void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
/**
* @brief Clears any existing chain associated with the current certificate of ctx.
*
*/
int SSL_CTX_clear_chain_certs(SSL_CTX *ctx);
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* _ESP_ASIO_OPENSSL_STUBS_H */

Wyświetl plik

@ -0,0 +1,60 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "esp_asio_config.h"
#include "internal/ssl_dbg.h"
#include "openssl/esp_asio_openssl_stubs.h"
// Unsupported features as macros to make the assertions more readable
#define ESP_OPENSSL_DH_IS_SUPPORTED 0
#define ESP_OPENSSL_GENERAL_NAMES_IS_SUPPORTED 0
void DH_free (DH *r)
{
SSL_ASSERT3(ESP_OPENSSL_DH_IS_SUPPORTED);
}
DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
{
SSL_ASSERT2(ESP_OPENSSL_DH_IS_SUPPORTED);
return NULL;
}
int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh)
{
SSL_ASSERT1(ESP_OPENSSL_DH_IS_SUPPORTED);
return -1;
}
void GENERAL_NAMES_free(GENERAL_NAMES * gens)
{
SSL_ASSERT3(ESP_OPENSSL_GENERAL_NAMES_IS_SUPPORTED);
}
X509_NAME *X509_get_subject_name(X509 *a)
{
SSL_ASSERT2(ESP_OPENSSL_GENERAL_NAMES_IS_SUPPORTED);
return NULL;
}
uint32_t SSL_set_mode(SSL *ssl, uint32_t mode)
{
return 0;
}
int SSL_CTX_clear_chain_certs(SSL_CTX *ctx)
{
return 1;
}

Wyświetl plik

@ -1590,12 +1590,14 @@ void SSL_set_verify_depth(SSL *ssl, int depth)
ssl->param.depth = depth;
}
#define ESP_OPENSSL_VERIFYCB_IS_SUPPORTED 0
/**
* @brief set the SSL context verifying of the SSL context
*/
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *))
{
SSL_ASSERT3(ctx);
SSL_ASSERT3(ESP_OPENSSL_VERIFYCB_IS_SUPPORTED);
ctx->verify_mode = mode;
ctx->default_verify_callback = verify_callback;
@ -1607,6 +1609,7 @@ void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509
void SSL_set_verify(SSL *ssl, int mode, int (*verify_callback)(int, X509_STORE_CTX *))
{
SSL_ASSERT3(ssl);
SSL_ASSERT3(ESP_OPENSSL_VERIFYCB_IS_SUPPORTED);
ssl->verify_mode = mode;
ssl->verify_callback = verify_callback;

Wyświetl plik

@ -276,14 +276,14 @@ failed1:
return 0;
}
#define ESP_OPENSSL_FILES_NOT_SUPPORTED 1
#define ESP_OPENSSL_FILES_IS_SUPPORTED 0
/**
* @brief load the private key file into SSL context
*/
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
{
// Using file name as private key is discouraged
SSL_ASSERT1(ESP_OPENSSL_FILES_NOT_SUPPORTED);
SSL_ASSERT1(ESP_OPENSSL_FILES_IS_SUPPORTED);
return -1;
}
@ -293,7 +293,7 @@ int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
{
// Using file name as private key is discouraged
SSL_ASSERT1(ESP_OPENSSL_FILES_NOT_SUPPORTED);
SSL_ASSERT1(ESP_OPENSSL_FILES_IS_SUPPORTED);
return -1;
}

Wyświetl plik

@ -89,7 +89,7 @@ static void ssl_platform_debug(void *ctx, int level,
}
#endif
int mbedtls_ssl_send(void *ctx, const unsigned char *buf, size_t len )
static int mbedtls_bio_send(void *ctx, const unsigned char *buf, size_t len )
{
BIO *bio = ctx;
int written = BIO_write(bio, buf, len);
@ -99,7 +99,7 @@ int mbedtls_ssl_send(void *ctx, const unsigned char *buf, size_t len )
return written;
}
static int mbedtls_ssl_recv(void *ctx, unsigned char *buf, size_t len )
static int mbedtls_bio_recv(void *ctx, unsigned char *buf, size_t len )
{
BIO *bio = ctx;
int read = BIO_read(bio, buf, len);
@ -316,7 +316,7 @@ int ssl_pm_handshake(SSL *ssl)
struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
if (ssl->bio) {
mbedtls_ssl_set_bio(&ssl_pm->ssl, ssl->bio, mbedtls_ssl_send, mbedtls_ssl_recv, NULL);
mbedtls_ssl_set_bio(&ssl_pm->ssl, ssl->bio, mbedtls_bio_send, mbedtls_bio_recv, NULL);
}
ret = ssl_pm_reload_crt(ssl);

Wyświetl plik

@ -13,7 +13,18 @@ Asio also comes with a number of examples which could be find under Documentatio
Supported features
^^^^^^^^^^^^^^^^^^
ESP platform port currently supports only network asynchronous socket operations; does not support serial port and ssl.
ESP platform port currently supports only network asynchronous socket operations; does not support serial port.
SSL/TLS support if disabled by default and could be enabled in component configuration menu and choosing TLS library from
- mbedTLS with OpenSSL translation layer (default option)
- wolfSSL
SSL support is very basic at this stage, not including
- Verification callbacks
- DH property files
- Certificates/private keys file APIs
Internal asio settings for ESP include
- EXCEPTIONS are enabled in ASIO if enabled in menuconfig
@ -27,5 +38,6 @@ ESP examples are based on standard asio :example:`protocols/asio`:
- :example:`protocols/asio/tcp_echo_server`
- :example:`protocols/asio/chat_client`
- :example:`protocols/asio/chat_server`
- :example:`protocols/asio/ssl_client_server`
Please refer to the specific example README.md for details