1 /*
2  * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef _ESP_HTTPS_SERVER_H_
8 #define _ESP_HTTPS_SERVER_H_
9 
10 #include <stdbool.h>
11 #include "esp_err.h"
12 #include "esp_http_server.h"
13 #include "esp_tls.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 typedef enum {
20     HTTPD_SSL_TRANSPORT_SECURE,      // SSL Enabled
21     HTTPD_SSL_TRANSPORT_INSECURE     // SSL disabled
22 } httpd_ssl_transport_mode_t;
23 
24 /**
25  * @brief Callback data struct, contains the ESP-TLS connection handle
26  */
27 typedef struct esp_https_server_user_cb_arg {
28     const esp_tls_t *tls;
29 } esp_https_server_user_cb_arg_t;
30 
31 /**
32  * @brief Callback function prototype
33  * Can be used to get connection or client information (SSL context)
34  * E.g. Client certificate, Socket FD, Connection state, etc.
35  *
36  * @param user_cb Callback data struct
37  */
38 typedef void esp_https_server_user_cb(esp_https_server_user_cb_arg_t *user_cb);
39 
40 /**
41  * HTTPS server config struct
42  *
43  * Please use HTTPD_SSL_CONFIG_DEFAULT() to initialize it.
44  */
45 struct httpd_ssl_config {
46     /**
47      * Underlying HTTPD server config
48      *
49      * Parameters like task stack size and priority can be adjusted here.
50      */
51     httpd_config_t httpd;
52 
53     /** CA certificate (here it is treated as server cert)
54      * Todo: Fix this change in release/v5.0 as it would be a breaking change
55      * i.e. Rename the nomenclature of variables holding different certs in https_server component as well as example
56      * 1)The cacert variable should hold the CA which is used to authenticate clients (should inherit current role of client_verify_cert_pem var)
57      * 2)There should be another variable servercert which whould hold servers own certificate (should inherit current role of cacert var) */
58     const uint8_t *cacert_pem;
59 
60     /** CA certificate byte length */
61     size_t cacert_len;
62 
63     /** Client verify authority certificate (CA used to sign clients, or client cert itself */
64     const uint8_t *client_verify_cert_pem;
65 
66     /** Client verify authority cert len */
67     size_t client_verify_cert_len;
68 
69     /** Private key */
70     const uint8_t *prvtkey_pem;
71 
72     /** Private key byte length */
73     size_t prvtkey_len;
74 
75     /** Transport Mode (default secure) */
76     httpd_ssl_transport_mode_t transport_mode;
77 
78     /** Port used when transport mode is secure (default 443) */
79     uint16_t port_secure;
80 
81     /** Port used when transport mode is insecure (default 80) */
82     uint16_t port_insecure;
83 
84     /** Enable tls session tickets */
85     bool session_tickets;
86 
87     /** User callback for esp_https_server */
88     esp_https_server_user_cb *user_cb;
89 };
90 
91 typedef struct httpd_ssl_config httpd_ssl_config_t;
92 
93 /**
94  * Default config struct init
95  *
96  * (http_server default config had to be copied for customization)
97  *
98  * Notes:
99  * - port is set when starting the server, according to 'transport_mode'
100  * - one socket uses ~ 40kB RAM with SSL, we reduce the default socket count to 4
101  * - SSL sockets are usually long-lived, closing LRU prevents pool exhaustion DOS
102  * - Stack size may need adjustments depending on the user application
103  */
104 #define HTTPD_SSL_CONFIG_DEFAULT() {              \
105     .httpd = {                                    \
106         .task_priority      = tskIDLE_PRIORITY+5, \
107         .stack_size         = 10240,              \
108         .core_id            = tskNO_AFFINITY,     \
109         .server_port        = 0,                  \
110         .ctrl_port          = 32768,              \
111         .max_open_sockets   = 4,                  \
112         .max_uri_handlers   = 8,                  \
113         .max_resp_headers   = 8,                  \
114         .backlog_conn       = 5,                  \
115         .lru_purge_enable   = true,               \
116         .recv_wait_timeout  = 5,                  \
117         .send_wait_timeout  = 5,                  \
118         .global_user_ctx = NULL,                  \
119         .global_user_ctx_free_fn = NULL,          \
120         .global_transport_ctx = NULL,             \
121         .global_transport_ctx_free_fn = NULL,     \
122         .open_fn = NULL,                          \
123         .close_fn = NULL,                         \
124         .uri_match_fn = NULL                      \
125     },                                            \
126     .cacert_pem = NULL,                           \
127     .cacert_len = 0,                              \
128     .client_verify_cert_pem = NULL,               \
129     .client_verify_cert_len = 0,                  \
130     .prvtkey_pem = NULL,                          \
131     .prvtkey_len = 0,                             \
132     .transport_mode = HTTPD_SSL_TRANSPORT_SECURE, \
133     .port_secure = 443,                           \
134     .port_insecure = 80,                          \
135     .session_tickets = false,                     \
136     .user_cb = NULL,                              \
137 }
138 
139 /**
140  * Create a SSL capable HTTP server (secure mode may be disabled in config)
141  *
142  * @param[in,out] config - server config, must not be const. Does not have to stay valid after
143  *                         calling this function.
144  * @param[out] handle - storage for the server handle, must be a valid pointer
145  * @return success
146  */
147 esp_err_t httpd_ssl_start(httpd_handle_t *handle, httpd_ssl_config_t *config);
148 
149 /**
150  * Stop the server. Blocks until the server is shut down.
151  *
152  * @param[in] handle
153  */
154 void httpd_ssl_stop(httpd_handle_t handle);
155 
156 #ifdef __cplusplus
157 }
158 #endif
159 
160 #endif // _ESP_HTTPS_SERVER_H_
161