mirror of
https://github.com/pvvx/RTL00_WEB.git
synced 2025-07-31 20:31:05 +00:00
update
This commit is contained in:
parent
a9ef4ff5c0
commit
b8c699eb1c
243 changed files with 1850 additions and 76723 deletions
299
USDK/component/common/network/httpd/httpd.h
Normal file
299
USDK/component/common/network/httpd/httpd.h
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file httpd.h
|
||||
* @author
|
||||
* @version
|
||||
* @brief This file provides user interface for HTTP/HTTPS server.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and possession or use of this module requires written permission of RealTek.
|
||||
*
|
||||
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef _HTTPD_H_
|
||||
#define _HTTPD_H_
|
||||
|
||||
/** @addtogroup httpd HTTPD
|
||||
* @ingroup network
|
||||
* @brief HTTP/HTTPS server functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "platform_stdlib.h"
|
||||
#include "platform_opts.h"
|
||||
|
||||
#define HTTPD_SECURE_NONE 0 /*!< Running with HTTP server */
|
||||
#define HTTPD_SECURE_TLS 1 /*!< Running with HTTPS server */
|
||||
#define HTTPD_SECURE_TLS_VERIFY 2 /*!< Running with HTTPS server and verify client */
|
||||
|
||||
#define HTTPD_THREAD_SINGLE 0 /*!< Multi-thread mode for request handling */
|
||||
#define HTTPD_THREAD_MULTIPLE 1 /*!< Single-thread mode for request handling */
|
||||
|
||||
#define HTTPD_DEBUG_OFF 0 /*!< Disable httpd debug log */
|
||||
#define HTTPD_DEBUG_ON 1 /*!< Enable httpd debug log */
|
||||
#define HTTPD_DEBUG_VERBOSE 2 /*!< Enable httpd verbose debug log */
|
||||
|
||||
#define HTTPD_TLS_POLARSSL 0 /*!< Use PolarSSL for TLS when HTTPS */
|
||||
#define HTTPD_TLS_MBEDTLS 1 /*!< Use mbedTLS for TLS when HTTPS */
|
||||
|
||||
#if CONFIG_USE_POLARSSL
|
||||
#define HTTPD_USE_TLS HTTPD_TLS_POLARSSL
|
||||
#elif CONFIG_USE_MBEDTLS
|
||||
#define HTTPD_USE_TLS HTTPD_TLS_MBEDTLS
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The structure is the context used for HTTP request header parsing.
|
||||
* @note Only header string includes string terminator.
|
||||
*/
|
||||
struct http_request {
|
||||
uint8_t *header; /*!< HTTP header string parsed in HTTP request */
|
||||
size_t header_len; /*!< HTTP header string length */
|
||||
uint8_t *method; /*!< Pointer to HTTP method in the parsed HTTP header string */
|
||||
size_t method_len; /*!< HTTP method data length */
|
||||
uint8_t *path; /*!< Pointer to resource path in the parsed HTTP header string */
|
||||
size_t path_len; /*!< Resource path data length */
|
||||
uint8_t *query; /*!< Pointer to query string in the parsed HTTP header string */
|
||||
size_t query_len; /*!< Query string data length */
|
||||
uint8_t *version; /*!< Pointer to HTTP version in the parsed HTTP header string */
|
||||
size_t version_len; /*!< HTTP version data length */
|
||||
uint8_t *host; /*!< Pointer to Host header field in the parsed HTTP header string */
|
||||
size_t host_len; /*!< Host header field data length */
|
||||
uint8_t *content_type; /*!< Pointer to Content-Type header field in the parsed HTTP header string */
|
||||
size_t content_type_len; /*!< Content-Type header field data length */
|
||||
size_t content_len; /*!< Value of Content-Length header field parsed in HTTP header string */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The structure is the context used for client connection.
|
||||
*/
|
||||
struct httpd_conn {
|
||||
int sock; /*!< Client socket descriptor for connection */
|
||||
struct http_request request; /*!< Context for HTTP request */
|
||||
void *tls; /*!< Context for TLS connection */
|
||||
uint8_t *response_header; /*!< Pointer to transmission buffer of HTTP response header */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This function is used to start an HTTP or HTTPS server.
|
||||
* @param[in] port: service port
|
||||
* @param[in] max_conn: max client connections allowed
|
||||
* @param[in] stack_bytes: thread stack size in bytes
|
||||
* @param[in] thread_mode: server running thread mode. Must be HTTPD_THREAD_SINGLE, HTTPD_THREAD_MULTIPLE.
|
||||
* @param[in] secure: security mode for HTTP or HTTPS. Must be HTTPD_SECURE_NONE, HTTPD_SECURE_TLS, HTTPD_SECURE_TLS_VERIFY.
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpd_start(uint16_t port, uint8_t max_conn, uint32_t stack_bytes, uint8_t thread_mode, uint8_t secure);
|
||||
|
||||
/**
|
||||
* @brief This function is used to stop a running server
|
||||
* @return None
|
||||
*/
|
||||
void httpd_stop(void);
|
||||
|
||||
/**
|
||||
* @brief This function is used to register a callback function for a Web page request handling.
|
||||
* @param[in] path: resource path for a page
|
||||
* @param[in] callback: callback function to handle the request to page
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpd_reg_page_callback(char *path, void (*callback)(struct httpd_conn *conn));
|
||||
|
||||
/**
|
||||
* @brief This function is used to clear all registered page callback functions.
|
||||
* @return None
|
||||
* @note All page callback will be cleared automatically if httpd_stop().
|
||||
*/
|
||||
void httpd_clear_page_callbacks(void);
|
||||
|
||||
/**
|
||||
* @brief This function is used to setup httpd debug.
|
||||
* @param[in] debug: flag to enable/disable httpd debug. Must be HTTPD_DEBUG_OFF, HTTPD_DEBUG_ON, HTTPD_DEBUG_VERBOSE.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_setup_debug(uint8_t debug);
|
||||
|
||||
/**
|
||||
* @brief This function is used to setup certificate and key for server before starting with HTTPS.
|
||||
* @param[in] server_cert: string of server certificate
|
||||
* @param[in] server_key: string of server private key
|
||||
* @param[in] ca_certs: string including certificates in CA trusted chain
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
* @note Must be used before httpd_start() if staring HTTPS server
|
||||
*/
|
||||
int httpd_setup_cert(const char *server_cert, const char *server_key, const char *ca_certs);
|
||||
|
||||
/**
|
||||
* @brief This function is used to setup authorization for server.
|
||||
* @param[in] user: string of user name for authorization
|
||||
* @param[in] password: string of password for authorization
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
* @note Must be used before httpd_start() if basic authorization is used
|
||||
*/
|
||||
int httpd_setup_user_password(char *user, char *password);
|
||||
|
||||
/**
|
||||
* @brief This function is used to free memory allocated by httpd API, such as httpd_request_get_header_field() and httpd_request_get_query_key().
|
||||
* @param[in] ptr: pointer to memory to be deallocated
|
||||
* @return None
|
||||
*/
|
||||
void httpd_free(void *ptr);
|
||||
|
||||
/**
|
||||
* @brief This function is used to close a client connection and release context resource.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return None
|
||||
* @note Multiple requests/response can be handled in a connection before connection closed. All connections will be closed automatically if httpd_stop().
|
||||
*/
|
||||
void httpd_conn_close(struct httpd_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to dump the parsed HTTP header of request in connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return None
|
||||
*/
|
||||
void httpd_conn_dump_header(struct httpd_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to check HTTP method of request in connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] method: HTTP method string to compare with
|
||||
* @return 0 : if different
|
||||
* @return 1 : if matched
|
||||
*/
|
||||
int httpd_request_is_method(struct httpd_conn *conn, char *method);
|
||||
|
||||
/**
|
||||
* @brief This function is used to read HTTP header from client socket descriptor and parse content to connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
* @note httpd_request_read_header() is automatically invoked by httpd server to parse request before executing page callback
|
||||
*/
|
||||
int httpd_request_read_header(struct httpd_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to read data from HTTP/HTTPS connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[out] data: buffer for data read
|
||||
* @param[in] data_len: buffer length
|
||||
* @return return value of lwip socket read() for HTTP and PolarSSL ssl_read() for HTTPS
|
||||
*/
|
||||
int httpd_request_read_data(struct httpd_conn *conn, uint8_t *data, size_t data_len);
|
||||
|
||||
/**
|
||||
* @brief This function is used to get a header field from HTTP header of connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] field: header field string to search
|
||||
* @param[out] value: search result stored in memory allocated
|
||||
* @return 0 : if found
|
||||
* @return -1 : if not found
|
||||
* @note The search result memory should be free by httpd_free().
|
||||
*/
|
||||
int httpd_request_get_header_field(struct httpd_conn *conn, char *field, char **value);
|
||||
|
||||
/**
|
||||
* @brief This function is used to get a key value from query string in HTTP header of connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] key: key name string to search
|
||||
* @param[out] value: search result stored in memory allocated
|
||||
* @return 0 : if found
|
||||
* @return -1 : if not found
|
||||
* @note The search result memory should be free by httpd_free().
|
||||
*/
|
||||
int httpd_request_get_query_key(struct httpd_conn *conn, char *key, char **value);
|
||||
|
||||
/**
|
||||
* @brief This function is used to start a HTTP response in connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] status: string of status code in HTTP response
|
||||
* @param[in] content_type: string of Content-Type header field written to HTTP response. No Content-Type in HTTP response if NULL.
|
||||
* @param[in] content_len: value of Content-Length header field written to HTTP response. No Content-Length in HTTP response if NULL.
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpd_response_write_header_start(struct httpd_conn *conn, char *status, char *content_type, size_t content_len);
|
||||
|
||||
/**
|
||||
* @brief This function is used to add an HTTP header field to HTTP response.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] name: HTTP header field name string
|
||||
* @param[in] value: HTTP header field value
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpd_response_write_header(struct httpd_conn *conn, char *name, char *value);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write HTTP response header data to connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return return value of lwip socket write() for HTTP and PolarSSL ssl_write() for HTTPS
|
||||
*/
|
||||
int httpd_response_write_header_finish(struct httpd_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write HTTP response body data to connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] data: data to be written
|
||||
* @param[in] data_len: data length
|
||||
* @return return value of lwip socket write() for HTTP and PolarSSL ssl_write() for HTTPS
|
||||
*/
|
||||
int httpd_response_write_data(struct httpd_conn *conn, uint8_t *data, size_t data_len);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 400 Bad Request.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_bad_request(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 401 Unauthorized.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_unauthorized(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 404 Not Found.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_not_found(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 405 Method Not Allowed.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_method_not_allowed(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 429 Too Many Requests.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_too_many_requests(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 500 Internal Server Error.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_internal_server_error(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/*\@}*/
|
||||
|
||||
#endif /* _HTTPD_H_ */
|
||||
372
USDK/component/common/network/httpd/httpd_tls.c
Normal file
372
USDK/component/common/network/httpd/httpd_tls.c
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "platform_stdlib.h"
|
||||
|
||||
#include "httpd.h"
|
||||
|
||||
#if (HTTPD_USE_TLS == HTTPD_TLS_POLARSSL)
|
||||
#include "polarssl/ssl.h"
|
||||
#include "polarssl/memory.h"
|
||||
#include "polarssl/base64.h"
|
||||
|
||||
struct httpd_tls {
|
||||
ssl_context ctx; /*!< Context for PolarSSL */
|
||||
};
|
||||
|
||||
static x509_crt httpd_certs; /*!< Certificates of server and CA */
|
||||
static pk_context httpd_key; /*!< Private key of server */
|
||||
|
||||
static int _verify_func(void *data, x509_crt *crt, int depth, int *flags)
|
||||
{
|
||||
char buf[1024];
|
||||
x509_crt_info(buf, sizeof(buf) - 1, "", crt);
|
||||
|
||||
if(*flags)
|
||||
printf("\n[HTTPD] ERROR: certificate verify\n%s\n", buf);
|
||||
else
|
||||
printf("\n[HTTPD] Certificate verified\n%s\n", buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif (HTTPD_USE_TLS == HTTPD_TLS_MBEDTLS)
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/net_sockets.h"
|
||||
#include "mbedtls/base64.h"
|
||||
|
||||
struct httpd_tls {
|
||||
mbedtls_ssl_context ctx; /*!< Context for mbedTLS */
|
||||
mbedtls_ssl_config conf; /*!< Configuration for mbedTLS */
|
||||
};
|
||||
|
||||
static mbedtls_x509_crt httpd_certs; /*!< Certificates of server and CA */
|
||||
static mbedtls_pk_context httpd_key; /*!< Private key of server */
|
||||
|
||||
static int _verify_func(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
|
||||
{
|
||||
char buf[1024];
|
||||
mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
|
||||
|
||||
if(*flags)
|
||||
printf("\n[HTTPD] ERROR: certificate verify\n%s\n", buf);
|
||||
else
|
||||
printf("\n[HTTPD] Certificate verified\n%s\n", buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void* _calloc_func(size_t nmemb, size_t size)
|
||||
{
|
||||
size_t mem_size;
|
||||
void *ptr = NULL;
|
||||
|
||||
mem_size = nmemb * size;
|
||||
ptr = pvPortMalloc(mem_size);
|
||||
|
||||
if(ptr)
|
||||
memset(ptr, 0, mem_size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
#endif /* HTTPC_USE_POLARSSL */
|
||||
|
||||
static int _random_func(void *p_rng, unsigned char *output, size_t output_len)
|
||||
{
|
||||
rtw_get_random_bytes(output, output_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int httpd_tls_setup_init(const char *server_cert, const char *server_key, const char *ca_certs)
|
||||
{
|
||||
#if (HTTPD_USE_TLS == HTTPD_TLS_POLARSSL)
|
||||
int ret = 0;
|
||||
|
||||
memory_set_own(pvPortMalloc, vPortFree);
|
||||
memset(&httpd_certs, 0, sizeof(x509_crt));
|
||||
memset(&httpd_key, 0, sizeof(pk_context));
|
||||
x509_crt_init(&httpd_certs);
|
||||
pk_init(&httpd_key);
|
||||
|
||||
// set server certificate for the first certificate
|
||||
if((ret = x509_crt_parse(&httpd_certs, (const unsigned char *) server_cert, strlen(server_cert))) != 0) {
|
||||
printf("\n[HTTPD] ERROR: x509_crt_parse %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// set trusted ca certificates next to server certificate
|
||||
if((ret = x509_crt_parse(&httpd_certs, (const unsigned char *) ca_certs, strlen(ca_certs))) != 0) {
|
||||
printf("\n[HTTPD] ERROR: x509_crt_parse %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if((ret = pk_parse_key(&httpd_key, (const unsigned char *) server_key, strlen(server_key), NULL, 0)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: pk_parse_key %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if(ret) {
|
||||
x509_crt_free(&httpd_certs);
|
||||
pk_free(&httpd_key);
|
||||
}
|
||||
|
||||
return ret;
|
||||
#elif (HTTPD_USE_TLS == HTTPD_TLS_MBEDTLS)
|
||||
int ret = 0;
|
||||
|
||||
mbedtls_platform_set_calloc_free(_calloc_func, vPortFree);
|
||||
memset(&httpd_certs, 0, sizeof(mbedtls_x509_crt));
|
||||
memset(&httpd_key, 0, sizeof(mbedtls_pk_context));
|
||||
mbedtls_x509_crt_init(&httpd_certs);
|
||||
mbedtls_pk_init(&httpd_key);
|
||||
|
||||
// set server certificate for the first certificate
|
||||
if((ret = mbedtls_x509_crt_parse(&httpd_certs, (const unsigned char *) server_cert, strlen(server_cert) + 1)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: mbedtls_x509_crt_parse %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// set trusted ca certificates next to server certificate
|
||||
if((ret = mbedtls_x509_crt_parse(&httpd_certs, (const unsigned char *) ca_certs, strlen(ca_certs) + 1)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: mbedtls_x509_crt_parse %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if((ret = mbedtls_pk_parse_key(&httpd_key, (const unsigned char *) server_key, strlen(server_key) + 1, NULL, 0)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: mbedtls_pk_parse_key %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if(ret) {
|
||||
mbedtls_x509_crt_free(&httpd_certs);
|
||||
mbedtls_pk_free(&httpd_key);
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
void httpd_tls_setup_free(void)
|
||||
{
|
||||
#if (HTTPD_USE_TLS == HTTPD_TLS_POLARSSL)
|
||||
x509_crt_free(&httpd_certs);
|
||||
pk_free(&httpd_key);
|
||||
#elif (HTTPD_USE_TLS == HTTPD_TLS_MBEDTLS)
|
||||
mbedtls_x509_crt_free(&httpd_certs);
|
||||
mbedtls_pk_free(&httpd_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *httpd_tls_new_handshake(int *sock, uint8_t secure)
|
||||
{
|
||||
#if (HTTPD_USE_TLS == HTTPD_TLS_POLARSSL)
|
||||
int ret = 0;
|
||||
struct httpd_tls *tls = NULL;
|
||||
ssl_context *ssl = NULL;
|
||||
|
||||
if((tls = (struct httpd_tls *) malloc(sizeof(struct httpd_tls))) != NULL) {
|
||||
memset(tls, 0, sizeof(struct httpd_tls));
|
||||
ssl = &tls->ctx;
|
||||
|
||||
if((ret = ssl_init(ssl)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: ssl_init %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ssl_set_endpoint(ssl, SSL_IS_SERVER);
|
||||
ssl_set_authmode(ssl, SSL_VERIFY_NONE);
|
||||
ssl_set_rng(ssl, _random_func, NULL);
|
||||
ssl_set_bio(ssl, net_recv, sock, net_send, sock);
|
||||
ssl_set_ca_chain(ssl, httpd_certs.next, NULL, NULL);
|
||||
|
||||
if(secure == HTTPD_SECURE_TLS_VERIFY) {
|
||||
ssl_set_authmode(ssl, SSL_VERIFY_REQUIRED);
|
||||
ssl_set_verify(ssl, _verify_func, NULL);
|
||||
}
|
||||
|
||||
if((ret = ssl_set_own_cert(ssl, &httpd_certs, &httpd_key)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: ssl_set_own_cert %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if((ret = ssl_handshake(ssl)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: ssl_handshake %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
else {
|
||||
printf("\n[HTTPD] Use ciphersuite %s\n", ssl_get_ciphersuite(ssl));
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
printf("\n[HTTPD] ERROR: httpd_malloc\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if(ret && tls) {
|
||||
ssl_close_notify(ssl);
|
||||
ssl_free(ssl);
|
||||
free(tls);
|
||||
tls = NULL;
|
||||
}
|
||||
|
||||
return (void *) tls;
|
||||
#elif (HTTPD_USE_TLS == HTTPD_TLS_MBEDTLS)
|
||||
int ret = 0;
|
||||
struct httpd_tls *tls = NULL;
|
||||
mbedtls_ssl_context *ssl;
|
||||
mbedtls_ssl_config *conf;
|
||||
|
||||
if((tls = (struct httpd_tls *) malloc(sizeof(struct httpd_tls))) != NULL) {
|
||||
memset(tls, 0, sizeof(struct httpd_tls));
|
||||
ssl = &tls->ctx;
|
||||
conf = &tls->conf;
|
||||
|
||||
mbedtls_ssl_init(ssl);
|
||||
mbedtls_ssl_config_init(conf);
|
||||
|
||||
if((ret = mbedtls_ssl_config_defaults(conf,
|
||||
MBEDTLS_SSL_IS_SERVER,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
|
||||
|
||||
printf("\n[HTTPD] ERROR: mbedtls_ssl_config_defaults %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
mbedtls_ssl_conf_rng(conf, _random_func, NULL);
|
||||
mbedtls_ssl_conf_ca_chain(conf, httpd_certs.next, NULL);
|
||||
|
||||
if(secure == HTTPD_SECURE_TLS_VERIFY) {
|
||||
mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
mbedtls_ssl_conf_verify(conf, _verify_func, NULL);
|
||||
}
|
||||
|
||||
if((ret = mbedtls_ssl_conf_own_cert(conf, &httpd_certs, &httpd_key)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: mbedtls_ssl_conf_own_cert %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if((ret = mbedtls_ssl_setup(ssl, conf)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: mbedtls_ssl_setup %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio(ssl, sock, mbedtls_net_send, mbedtls_net_recv, NULL);
|
||||
|
||||
if((ret = mbedtls_ssl_handshake(ssl)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: mbedtls_ssl_handshake %d\n", ret);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
else {
|
||||
printf("\n[HTTPD] Use ciphersuite %s\n", mbedtls_ssl_get_ciphersuite(ssl));
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
printf("\n[HTTPD] ERROR: httpd_malloc\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if(ret && tls) {
|
||||
mbedtls_ssl_close_notify(ssl);
|
||||
mbedtls_ssl_free(ssl);
|
||||
mbedtls_ssl_config_free(conf);
|
||||
free(tls);
|
||||
tls = NULL;
|
||||
}
|
||||
|
||||
return (void *) tls;
|
||||
#endif
|
||||
}
|
||||
|
||||
void httpd_tls_free(void *tls_in)
|
||||
{
|
||||
struct httpd_tls *tls = (struct httpd_tls *) tls_in;
|
||||
|
||||
#if (HTTPD_USE_TLS == HTTPD_TLS_POLARSSL)
|
||||
ssl_free(&tls->ctx);
|
||||
free(tls);
|
||||
#elif (HTTPD_USE_TLS == HTTPD_TLS_MBEDTLS)
|
||||
mbedtls_ssl_free(&tls->ctx);
|
||||
mbedtls_ssl_config_free(&tls->conf);
|
||||
free(tls);
|
||||
#endif
|
||||
}
|
||||
|
||||
void httpd_tls_close(void *tls_in)
|
||||
{
|
||||
struct httpd_tls *tls = (struct httpd_tls *) tls_in;
|
||||
|
||||
#if (HTTPD_USE_TLS == HTTPD_TLS_POLARSSL)
|
||||
ssl_close_notify(&tls->ctx);
|
||||
#elif (HTTPD_USE_TLS == HTTPD_TLS_MBEDTLS)
|
||||
mbedtls_ssl_close_notify(&tls->ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
int httpd_tls_read(void *tls_in, uint8_t *buf, size_t buf_len)
|
||||
{
|
||||
struct httpd_tls *tls = (struct httpd_tls *) tls_in;
|
||||
|
||||
#if (HTTPD_USE_TLS == HTTPD_TLS_POLARSSL)
|
||||
return ssl_read(&tls->ctx, buf, buf_len);
|
||||
#elif (HTTPD_USE_TLS == HTTPD_TLS_MBEDTLS)
|
||||
return mbedtls_ssl_read(&tls->ctx, buf, buf_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
int httpd_tls_write(void *tls_in, uint8_t *buf, size_t buf_len)
|
||||
{
|
||||
struct httpd_tls *tls = (struct httpd_tls *) tls_in;
|
||||
|
||||
#if (HTTPD_USE_TLS == HTTPD_TLS_POLARSSL)
|
||||
return ssl_write(&tls->ctx, buf, buf_len);
|
||||
#elif (HTTPD_USE_TLS == HTTPD_TLS_MBEDTLS)
|
||||
return mbedtls_ssl_write(&tls->ctx, buf, buf_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
int httpd_base64_encode(uint8_t *data, size_t data_len, char *base64_buf, size_t buf_len)
|
||||
{
|
||||
#if (HTTPD_USE_TLS == HTTPD_TLS_POLARSSL)
|
||||
int ret = 0;
|
||||
|
||||
if((ret = base64_encode(base64_buf, &buf_len, data, data_len)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: base64_encode %d\n", ret);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
#elif (HTTPD_USE_TLS == HTTPD_TLS_MBEDTLS)
|
||||
int ret = 0;
|
||||
size_t output_len = 0;
|
||||
|
||||
if((ret = mbedtls_base64_encode(base64_buf, buf_len, &output_len, data, data_len)) != 0) {
|
||||
printf("\n[HTTPD] ERROR: mbedtls_base64_encode %d\n", ret);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue