kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'feature/esp_https_server_callback' into 'master'
feature: Added user callback for esp_https_server Closes IDFGH-5771 See merge request espressif/esp-idf!15405pull/7680/head
commit
b94bbdbd9c
|
@ -500,7 +500,7 @@ esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
|
|||
return esp_ret;
|
||||
}
|
||||
} else {
|
||||
mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
}
|
||||
|
||||
if (cfg->servercert_buf != NULL && cfg->serverkey_buf != NULL) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_http_server.h"
|
||||
#include "esp_tls.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -20,6 +21,22 @@ typedef enum {
|
|||
HTTPD_SSL_TRANSPORT_INSECURE // SSL disabled
|
||||
} httpd_ssl_transport_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Callback data struct, contains the ESP-TLS connection handle
|
||||
*/
|
||||
typedef struct esp_https_server_user_cb_arg {
|
||||
const esp_tls_t *tls;
|
||||
} esp_https_server_user_cb_arg_t;
|
||||
|
||||
/**
|
||||
* @brief Callback function prototype
|
||||
* Can be used to get connection or client information (SSL context)
|
||||
* E.g. Client certificate, Socket FD, Connection state, etc.
|
||||
*
|
||||
* @param user_cb Callback data struct
|
||||
*/
|
||||
typedef void esp_https_server_user_cb(esp_https_server_user_cb_arg_t *user_cb);
|
||||
|
||||
/**
|
||||
* HTTPS server config struct
|
||||
*
|
||||
|
@ -66,6 +83,9 @@ struct httpd_ssl_config {
|
|||
|
||||
/** Enable tls session tickets */
|
||||
bool session_tickets;
|
||||
|
||||
/** User callback for esp_https_server */
|
||||
esp_https_server_user_cb *user_cb;
|
||||
};
|
||||
|
||||
typedef struct httpd_ssl_config httpd_ssl_config_t;
|
||||
|
@ -113,6 +133,7 @@ typedef struct httpd_ssl_config httpd_ssl_config_t;
|
|||
.port_secure = 443, \
|
||||
.port_insecure = 80, \
|
||||
.session_tickets = false, \
|
||||
.user_cb = NULL, \
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,6 +15,7 @@ const static char *TAG = "esp_https_server";
|
|||
typedef struct httpd_ssl_ctx {
|
||||
esp_tls_cfg_server_t *tls_cfg;
|
||||
httpd_open_func_t open_fn;
|
||||
esp_https_server_user_cb *user_cb;
|
||||
} httpd_ssl_ctx_t;
|
||||
|
||||
/**
|
||||
|
@ -119,6 +120,13 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd)
|
|||
if (global_ctx->open_fn) {
|
||||
(global_ctx->open_fn)(server, sockfd);
|
||||
}
|
||||
|
||||
if (global_ctx->user_cb) {
|
||||
esp_https_server_user_cb_arg_t user_cb_data = {0};
|
||||
user_cb_data.tls = tls;
|
||||
(global_ctx->user_cb)((void *)&user_cb_data);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
fail:
|
||||
esp_tls_server_session_delete(tls);
|
||||
|
@ -172,6 +180,7 @@ static httpd_ssl_ctx_t *create_secure_context(const struct httpd_ssl_config *con
|
|||
}
|
||||
|
||||
ssl_ctx->tls_cfg = cfg;
|
||||
ssl_ctx->user_cb = config->user_cb;
|
||||
/* cacert = CA which signs client cert, or client cert itself , which is mapped to client_verify_cert_pem */
|
||||
if(config->client_verify_cert_pem != NULL) {
|
||||
cfg->cacert_buf = (unsigned char *)malloc(config->client_verify_cert_len);
|
||||
|
|
|
@ -1,18 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2021 Espressif Systems (Shanghai) CO 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.
|
||||
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import http.client
|
||||
import os
|
||||
|
@ -43,6 +32,61 @@ server_cert_pem = '-----BEGIN CERTIFICATE-----\n'\
|
|||
'hb6pnMh3jRq4h0+5CZielA4/a+TdrNPv/qok67ot/XJdY3qHCCd8O2b14OVq9jo=\n'\
|
||||
'-----END CERTIFICATE-----\n'
|
||||
|
||||
client_cert_pem = '-----BEGIN CERTIFICATE-----\n' \
|
||||
'MIID7TCCAtWgAwIBAgIUBdm7RStsshnl3CCpknSJhXQK4GcwDQYJKoZIhvcNAQEL\n' \
|
||||
'BQAwgYUxCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdKaWFuZ3N1MQ8wDQYDVQQHDAZT\n' \
|
||||
'dXpob3UxEjAQBgNVBAoMCUVzcHJlc3NpZjEMMAoGA1UECwwDY29tMRIwEAYDVQQD\n' \
|
||||
'DAkxMjcuMC4wLjExHTAbBgkqhkiG9w0BCQEWDmVzcDMyeEBlc3AuY29tMB4XDTIx\n' \
|
||||
'MTAwNTExMTMxMFoXDTMxMTAwMzExMTMxMFowgYUxCzAJBgNVBAYTAkNOMRAwDgYD\n' \
|
||||
'VQQIDAdKaWFuZ3N1MQ8wDQYDVQQHDAZTdXpob3UxEjAQBgNVBAoMCUVzcHJlc3Np\n' \
|
||||
'ZjEMMAoGA1UECwwDY29tMRIwEAYDVQQDDAkxMjcuMC4wLjExHTAbBgkqhkiG9w0B\n' \
|
||||
'CQEWDmVzcDMyeEBlc3AuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n' \
|
||||
'AQEAu2nP0HPtgKvRUwFuOs72caf4oyeK33OVfa6fGGttr/QYyw9PrwtdFDyEWEiI\n' \
|
||||
'4P4hnxNC+bvNSYtJUzF9EmkqrUtKxhBsRVTKWOqumcgtiMWOxpdVKl0936ne2Pqh\n' \
|
||||
'SweddrQwvPDFuB3hRikRX11+d5vkjFBV9FoZobKHWemDkXSc2R99xRie5PJoEfoz\n' \
|
||||
'rmu5zjCaPHxzkyZsmH4MILfTuhUGc/Eye9Nl+lpY5KLjM14ZMQLK1CHRuI/oqCN6\n' \
|
||||
'1WQrgUY5EyXGe0jXHTVhlL2RN8njxJ/4r3JnK/BQkcXTIMPOP8jIv9Sy1HhxfXKy\n' \
|
||||
'HzLqOBn0Ft+mOADrpAWX8WnwUQIDAQABo1MwUTAdBgNVHQ4EFgQUpu4d8d+IywjB\n' \
|
||||
'HMiKX84L+1ri8BIwHwYDVR0jBBgwFoAUpu4d8d+IywjBHMiKX84L+1ri8BIwDwYD\n' \
|
||||
'VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXm5Hn/aKKO3RnHqqfxok\n' \
|
||||
'Hbw5yA2L2T6VPj2puI0Sh5GW62INjM0Kszy3L5mQqLUSsjcEcFAZmpeo14ytPRLG\n' \
|
||||
'o6+WG/4er3hBA7D8oDni7hp8Qs+/EtNuEuoU+qQiKsT2DvA5rafT7laNfvjgqaoJ\n' \
|
||||
'YMTCvzKLnMBaglB+qC9grgvJwMN0RTzHyY6UySdNZmcf5QXWLWjsX8E8/u4iSq8l\n' \
|
||||
'eZlddTjh7HGGEOim7AkvKR9VYAvKGOV+FvUzCxPpoTr6kS2NGwnR7QnvKADECtLj\n' \
|
||||
'gf+hW1FalMn0yTVspg4+BNbIThh0thbsvPDUTekMNfaRKKHZpJP2Ty3LkCbANLBR\n' \
|
||||
'tQ==\n' \
|
||||
'-----END CERTIFICATE-----\n'
|
||||
|
||||
|
||||
client_key_pem = '-----BEGIN PRIVATE KEY-----\n' \
|
||||
'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7ac/Qc+2Aq9FT\n' \
|
||||
'AW46zvZxp/ijJ4rfc5V9rp8Ya22v9BjLD0+vC10UPIRYSIjg/iGfE0L5u81Ji0lT\n' \
|
||||
'MX0SaSqtS0rGEGxFVMpY6q6ZyC2IxY7Gl1UqXT3fqd7Y+qFLB512tDC88MW4HeFG\n' \
|
||||
'KRFfXX53m+SMUFX0WhmhsodZ6YORdJzZH33FGJ7k8mgR+jOua7nOMJo8fHOTJmyY\n' \
|
||||
'fgwgt9O6FQZz8TJ702X6WljkouMzXhkxAsrUIdG4j+ioI3rVZCuBRjkTJcZ7SNcd\n' \
|
||||
'NWGUvZE3yePEn/ivcmcr8FCRxdMgw84/yMi/1LLUeHF9crIfMuo4GfQW36Y4AOuk\n' \
|
||||
'BZfxafBRAgMBAAECggEBAJuJZ1UCwRtGfUS8LTVVSiZtVuZhDNoB3REfeR4VGkUq\n' \
|
||||
'+eCcZm9JqQgAaX2zRRYlEtYocC8+c1MT69jFe51p9mc302ipfJHVmtFMg3dRMKkP\n' \
|
||||
'/DxIn/+2voD/Q9kjt/TC7yXyyXglApKZCbrmnmpc93ZgxL7GdW+Dzz3pIne2WuC9\n' \
|
||||
'T6ie71R8X60sau6ApMgkUq6On0f21v/VLkNU67tQJGBF6Q1HE8PK7Ptun3WSBVNm\n' \
|
||||
'FNNJKRBwiqfWXe9hPlqqCWayYBrojSqJJXn5Xd6n5XzLDPzAXuPlkPF3VwWeXGam\n' \
|
||||
'3RBZA26gwv50E1PeiUQOipkR57J+O9j/oA07AnhsxPkCgYEA8RMvE3ImZTkPVqdX\n' \
|
||||
'72E2A5ScJswVvZelnRS/mG8U+8UlvevAu5MYr717DHKHy3yOw/u7wbkqk6KEIcyz\n' \
|
||||
'ctNPBPqTweaZ28eEY/+lXSdQaWLD2UgZC8JIcMOSeFugghEHeBaxLzUYBNDToE3q\n' \
|
||||
'1El2HJ7W14QuTA+CEtCEb+tc7ssCgYEAxwQkBTT8A7mOEE0phfUACqaBuAXld+zu\n' \
|
||||
'I3PNJDIhg1ZABEJ9vo9+3duFDoEHVsJOetijrBBxf/XAvi3bTJ+gAjcA54cGpkxz\n' \
|
||||
'6ssbFWZeC9exyo0ILKn33o716GrCvQn1kmuF2gasmAcrOVsMygawR7P02oasDP/X\n' \
|
||||
'UckbZdqofdMCgYEAom0GfteePv0e9Idzm/mnZuot+4Xt7/vIvflIze+p96hxMXEy\n' \
|
||||
'Pi9xppbH3S8dh2C44Bsv+epEYYxR8mP1VBxDVVtvSmmQqJ/Y93c7d3QRna/JvQ/y\n' \
|
||||
'sBWKsU9T1HwHvRq0KZlAcEoZkMUSkSNuYPHN/qKWpkaM2vpn7T1Ivg+aYdkCgYA/\n' \
|
||||
'CGO0NnzfXSTOqvHM2LVDqksJkuyD2Enwdpvxq+MLawTplHmpIl/HOuDgoCNH6lDa\n' \
|
||||
'/cSRGcApDBgY5ANCOIiASxWBPzXu8+X+5odUdtCwpYdNJPAC3W6BUfw2uaGmKAJc\n' \
|
||||
'dqu1S0nc+OBK0Tiyv/2TKD8T+3WAxINZBv4je2bEOwKBgEavm5zTN9NILJsJCf9k\n' \
|
||||
'te7+uDFuyoNWkL1vmMPuJYVC1QMVq1yr3DSaxA19BG9P4ZyOMOwVlPVWA+LofD4D\n' \
|
||||
'S+w4Jjl2KDI4tSLUr6bsAJWdDfmrmGmRN3Kpds4RXaymV3rjj7qRk1J+ivtwo89s\n' \
|
||||
'Vj+VslYzxw7FKKmnBgh/qGbJ\n' \
|
||||
'-----END PRIVATE KEY-----\n'
|
||||
|
||||
success_response = '<h1>Hello Secure World!</h1>'
|
||||
|
||||
|
||||
|
@ -74,10 +118,23 @@ def test_examples_protocol_https_server_simple(env, extra_data): # type: (tiny_
|
|||
|
||||
Utility.console_log('Performing GET request over an SSL connection with the server')
|
||||
|
||||
CLIENT_CERT_FILE = 'client_cert.pem'
|
||||
CLIENT_KEY_FILE = 'client_key.pem'
|
||||
|
||||
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
||||
ssl_context.verify_mode = ssl.CERT_REQUIRED
|
||||
ssl_context.check_hostname = False
|
||||
ssl_context.load_verify_locations(cadata=server_cert_pem)
|
||||
|
||||
with open(CLIENT_CERT_FILE, 'w') as cert, open(CLIENT_KEY_FILE, 'w') as key:
|
||||
cert.write(client_cert_pem)
|
||||
key.write(client_key_pem)
|
||||
|
||||
ssl_context.load_cert_chain(certfile=CLIENT_CERT_FILE, keyfile=CLIENT_KEY_FILE)
|
||||
|
||||
os.remove(CLIENT_CERT_FILE)
|
||||
os.remove(CLIENT_KEY_FILE)
|
||||
|
||||
conn = http.client.HTTPSConnection(got_ip, got_port, context=ssl_context)
|
||||
Utility.console_log('Performing SSL handshake with the server')
|
||||
conn.request('GET','/')
|
||||
|
@ -89,6 +146,16 @@ def test_examples_protocol_https_server_simple(env, extra_data): # type: (tiny_
|
|||
Utility.console_log('Response obtained does not match with correct response')
|
||||
raise RuntimeError('Failed to test SSL connection')
|
||||
|
||||
Utility.console_log('Checking user callback: Obtaining client certificate...')
|
||||
|
||||
serial_number = dut1.expect(re.compile(r'serial number(.*)'), timeout=5)[0]
|
||||
issuer_name = dut1.expect(re.compile(r'issuer name(.*)'), timeout=5)[0]
|
||||
expiry = dut1.expect(re.compile(r'expires on(.*)'), timeout=5)[0]
|
||||
|
||||
Utility.console_log('Serial No.' + serial_number)
|
||||
Utility.console_log('Issuer Name' + issuer_name)
|
||||
Utility.console_log('Expires on' + expiry)
|
||||
|
||||
Utility.console_log('Correct response obtained')
|
||||
Utility.console_log('SSL connection test successful\nClosing the connection')
|
||||
conn.close()
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
menu "Example Configuration"
|
||||
|
||||
config EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
|
||||
bool "Enable user callback with HTTPS Server"
|
||||
default false
|
||||
help
|
||||
Enable user callback for esp_https_server which can be used to get SSL context (connection information)
|
||||
E.g. Certificate of the connected client
|
||||
|
||||
endmenu
|
|
@ -18,6 +18,7 @@
|
|||
#include "protocol_examples_common.h"
|
||||
|
||||
#include <esp_https_server.h>
|
||||
#include "esp_tls.h"
|
||||
|
||||
/* A simple example that demonstrates how to create GET and POST
|
||||
* handlers and start an HTTPS server.
|
||||
|
@ -25,7 +26,6 @@
|
|||
|
||||
static const char *TAG = "example";
|
||||
|
||||
|
||||
/* An HTTP GET handler */
|
||||
static esp_err_t root_get_handler(httpd_req_t *req)
|
||||
{
|
||||
|
@ -35,13 +35,43 @@ static esp_err_t root_get_handler(httpd_req_t *req)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
|
||||
/**
|
||||
* Example callback function to get the certificate of connected clients,
|
||||
* whenever a new SSL connection is created
|
||||
*
|
||||
* Can also be used to other information like Socket FD, Connection state, etc.
|
||||
*/
|
||||
void https_server_user_callback(esp_https_server_user_cb_arg_t *user_cb)
|
||||
{
|
||||
ESP_LOGI(TAG, "Session Created!");
|
||||
const mbedtls_x509_crt *cert;
|
||||
|
||||
const size_t buf_size = 1024;
|
||||
char *buf = calloc(buf_size, sizeof(char));
|
||||
if (buf == NULL) {
|
||||
ESP_LOGE(TAG, "Out of memory - Callback execution failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
cert = mbedtls_ssl_get_peer_cert(&user_cb->tls->ssl);
|
||||
if (cert != NULL) {
|
||||
mbedtls_x509_crt_info((char *) buf, buf_size - 1, " ", cert);
|
||||
ESP_LOGI(TAG, "Peer certificate info:\n%s", buf);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Could not obtain the peer certificate!");
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const httpd_uri_t root = {
|
||||
.uri = "/",
|
||||
.method = HTTP_GET,
|
||||
.handler = root_get_handler
|
||||
};
|
||||
|
||||
|
||||
static httpd_handle_t start_webserver(void)
|
||||
{
|
||||
httpd_handle_t server = NULL;
|
||||
|
@ -61,6 +91,9 @@ static httpd_handle_t start_webserver(void)
|
|||
conf.prvtkey_pem = prvtkey_pem_start;
|
||||
conf.prvtkey_len = prvtkey_pem_end - prvtkey_pem_start;
|
||||
|
||||
#if CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
|
||||
conf.user_cb = https_server_user_callback;
|
||||
#endif
|
||||
esp_err_t ret = httpd_ssl_start(&server, &conf);
|
||||
if (ESP_OK != ret) {
|
||||
ESP_LOGI(TAG, "Error starting server!");
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
CONFIG_ESP_HTTPS_SERVER_ENABLE=y
|
||||
CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK=y
|
||||
|
|
|
@ -3738,7 +3738,6 @@ examples/protocols/http_server/ws_echo_server/ws_server_example_test.py
|
|||
examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c
|
||||
examples/protocols/https_request/example_test.py
|
||||
examples/protocols/https_request/main/https_request_example_main.c
|
||||
examples/protocols/https_server/simple/example_test.py
|
||||
examples/protocols/https_server/simple/main/main.c
|
||||
examples/protocols/https_server/wss_server/main/keep_alive.c
|
||||
examples/protocols/https_server/wss_server/main/keep_alive.h
|
||||
|
|
Ładowanie…
Reference in New Issue