xref: /curl/lib/vtls/vtls_int.h (revision 3a35901a)
1 #ifndef HEADER_CURL_VTLS_INT_H
2 #define HEADER_CURL_VTLS_INT_H
3 /***************************************************************************
4  *                                  _   _ ____  _
5  *  Project                     ___| | | |  _ \| |
6  *                             / __| | | | |_) | |
7  *                            | (__| |_| |  _ <| |___
8  *                             \___|\___/|_| \_\_____|
9  *
10  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
11  *
12  * This software is licensed as described in the file COPYING, which
13  * you should have received as part of this distribution. The terms
14  * are also available at https://curl.se/docs/copyright.html.
15  *
16  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17  * copies of the Software, and permit persons to whom the Software is
18  * furnished to do so, under the terms of the COPYING file.
19  *
20  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21  * KIND, either express or implied.
22  *
23  * SPDX-License-Identifier: curl
24  *
25  ***************************************************************************/
26 #include "curl_setup.h"
27 #include "cfilters.h"
28 #include "urldata.h"
29 
30 #ifdef USE_SSL
31 
32 struct ssl_connect_data;
33 
34 /* see https://www.iana.org/assignments/tls-extensiontype-values/ */
35 #define ALPN_HTTP_1_1_LENGTH 8
36 #define ALPN_HTTP_1_1 "http/1.1"
37 #define ALPN_H2_LENGTH 2
38 #define ALPN_H2 "h2"
39 #define ALPN_H3_LENGTH 2
40 #define ALPN_H3 "h3"
41 
42 /* conservative sizes on the ALPN entries and count we are handling,
43  * we can increase these if we ever feel the need or have to accommodate
44  * ALPN strings from the "outside". */
45 #define ALPN_NAME_MAX     10
46 #define ALPN_ENTRIES_MAX  3
47 #define ALPN_PROTO_BUF_MAX   (ALPN_ENTRIES_MAX * (ALPN_NAME_MAX + 1))
48 
49 struct alpn_spec {
50   const char entries[ALPN_ENTRIES_MAX][ALPN_NAME_MAX];
51   size_t count; /* number of entries */
52 };
53 
54 struct alpn_proto_buf {
55   unsigned char data[ALPN_PROTO_BUF_MAX];
56   int len;
57 };
58 
59 CURLcode Curl_alpn_to_proto_buf(struct alpn_proto_buf *buf,
60                                 const struct alpn_spec *spec);
61 CURLcode Curl_alpn_to_proto_str(struct alpn_proto_buf *buf,
62                                 const struct alpn_spec *spec);
63 
64 CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf,
65                                   struct Curl_easy *data,
66                                   struct ssl_connect_data *connssl,
67                                   const unsigned char *proto,
68                                   size_t proto_len);
69 
70 bool Curl_alpn_contains_proto(const struct alpn_spec *spec,
71                               const char *proto);
72 
73 /* enum for the nonblocking SSL connection state machine */
74 typedef enum {
75   ssl_connect_1,
76   ssl_connect_2,
77   ssl_connect_3,
78   ssl_connect_done
79 } ssl_connect_state;
80 
81 typedef enum {
82   ssl_connection_none,
83   ssl_connection_deferred,
84   ssl_connection_negotiating,
85   ssl_connection_complete
86 } ssl_connection_state;
87 
88 typedef enum {
89   ssl_earlydata_none,
90   ssl_earlydata_use,
91   ssl_earlydata_sending,
92   ssl_earlydata_sent,
93   ssl_earlydata_accepted,
94   ssl_earlydata_rejected
95 } ssl_earlydata_state;
96 
97 #define CURL_SSL_IO_NEED_NONE   (0)
98 #define CURL_SSL_IO_NEED_RECV   (1<<0)
99 #define CURL_SSL_IO_NEED_SEND   (1<<1)
100 
101 /* Max earlydata payload we want to send */
102 #define CURL_SSL_EARLY_MAX       (64*1024)
103 
104 /* Information in each SSL cfilter context: cf->ctx */
105 struct ssl_connect_data {
106   struct ssl_peer peer;
107   const struct alpn_spec *alpn;     /* ALPN to use or NULL for none */
108   void *backend;                    /* vtls backend specific props */
109   struct cf_call_data call_data;    /* data handle used in current call */
110   struct curltime handshake_done;   /* time when handshake finished */
111   char *alpn_negotiated;            /* negotiated ALPN value or NULL */
112   struct bufq earlydata;            /* earlydata to be send to peer */
113   size_t earlydata_max;             /* max earlydata allowed by peer */
114   size_t earlydata_skip;            /* sending bytes to skip when earlydata
115                                      * is accepted by peer */
116   ssl_connection_state state;
117   ssl_connect_state connecting_state;
118   ssl_earlydata_state earlydata_state;
119   int io_need;                      /* TLS signals special SEND/RECV needs */
120   BIT(use_alpn);                    /* if ALPN shall be used in handshake */
121   BIT(peer_closed);                 /* peer has closed connection */
122 };
123 
124 
125 #undef CF_CTX_CALL_DATA
126 #define CF_CTX_CALL_DATA(cf)  \
127   ((struct ssl_connect_data *)(cf)->ctx)->call_data
128 
129 
130 /* Definitions for SSL Implementations */
131 
132 struct Curl_ssl {
133   /*
134    * This *must* be the first entry to allow returning the list of available
135    * backends in curl_global_sslset().
136    */
137   curl_ssl_backend info;
138   unsigned int supports; /* bitfield, see above */
139   size_t sizeof_ssl_backend_data;
140 
141   int (*init)(void);
142   void (*cleanup)(void);
143 
144   size_t (*version)(char *buffer, size_t size);
145   int (*check_cxn)(struct Curl_cfilter *cf, struct Curl_easy *data);
146   CURLcode (*shut_down)(struct Curl_cfilter *cf, struct Curl_easy *data,
147                         bool send_shutdown, bool *done);
148   bool (*data_pending)(struct Curl_cfilter *cf,
149                        const struct Curl_easy *data);
150 
151   /* return 0 if a find random is filled in */
152   CURLcode (*random)(struct Curl_easy *data, unsigned char *entropy,
153                      size_t length);
154   bool (*cert_status_request)(void);
155 
156   CURLcode (*connect_blocking)(struct Curl_cfilter *cf,
157                                struct Curl_easy *data);
158   CURLcode (*connect_nonblocking)(struct Curl_cfilter *cf,
159                                   struct Curl_easy *data,
160                                   bool *done);
161 
162   /* During handshake/shutdown, adjust the pollset to include the socket
163    * for POLLOUT or POLLIN as needed. Mandatory. */
164   void (*adjust_pollset)(struct Curl_cfilter *cf, struct Curl_easy *data,
165                           struct easy_pollset *ps);
166   void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info);
167   void (*close)(struct Curl_cfilter *cf, struct Curl_easy *data);
168   void (*close_all)(struct Curl_easy *data);
169 
170   CURLcode (*set_engine)(struct Curl_easy *data, const char *engine);
171   CURLcode (*set_engine_default)(struct Curl_easy *data);
172   struct curl_slist *(*engines_list)(struct Curl_easy *data);
173 
174   bool (*false_start)(void);
175   CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen,
176                     unsigned char *sha256sum, size_t sha256sumlen);
177 
178   bool (*attach_data)(struct Curl_cfilter *cf, struct Curl_easy *data);
179   void (*detach_data)(struct Curl_cfilter *cf, struct Curl_easy *data);
180 
181   ssize_t (*recv_plain)(struct Curl_cfilter *cf, struct Curl_easy *data,
182                         char *buf, size_t len, CURLcode *code);
183   ssize_t (*send_plain)(struct Curl_cfilter *cf, struct Curl_easy *data,
184                         const void *mem, size_t len, CURLcode *code);
185 
186   CURLcode (*get_channel_binding)(struct Curl_easy *data, int sockindex,
187                                   struct dynbuf *binding);
188 
189 };
190 
191 extern const struct Curl_ssl *Curl_ssl;
192 
193 
194 int Curl_none_init(void);
195 void Curl_none_cleanup(void);
196 CURLcode Curl_none_shutdown(struct Curl_cfilter *cf, struct Curl_easy *data,
197                             bool send_shutdown, bool *done);
198 int Curl_none_check_cxn(struct Curl_cfilter *cf, struct Curl_easy *data);
199 void Curl_none_close_all(struct Curl_easy *data);
200 void Curl_none_session_free(void *ptr);
201 bool Curl_none_data_pending(struct Curl_cfilter *cf,
202                             const struct Curl_easy *data);
203 bool Curl_none_cert_status_request(void);
204 CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine);
205 CURLcode Curl_none_set_engine_default(struct Curl_easy *data);
206 struct curl_slist *Curl_none_engines_list(struct Curl_easy *data);
207 bool Curl_none_false_start(void);
208 void Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data,
209                               struct easy_pollset *ps);
210 
211 /**
212  * Get the SSL filter below the given one or NULL if there is none.
213  */
214 bool Curl_ssl_cf_is_proxy(struct Curl_cfilter *cf);
215 
216 /* extract a session ID
217  * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
218  * Caller must make sure that the ownership of returned sessionid object
219  * is properly taken (e.g. its refcount is incremented
220  * under sessionid mutex).
221  * @param cf      the connection filter wanting to use it
222  * @param data    the transfer involved
223  * @param peer    the peer the filter wants to talk to
224  * @param sessionid on return the TLS session
225  * @param idsize  on return the size of the TLS session data
226  * @param palpn   on return the ALPN string used by the session,
227  *                set to NULL when not interested
228  */
229 bool Curl_ssl_getsessionid(struct Curl_cfilter *cf,
230                            struct Curl_easy *data,
231                            const struct ssl_peer *peer,
232                            void **ssl_sessionid,
233                            size_t *idsize, /* set 0 if unknown */
234                            char **palpn);
235 
236 /* Set a TLS session ID for `peer`. Replaces an existing session ID if
237  * not already the same.
238  * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
239  * Call takes ownership of `ssl_sessionid`, using `sessionid_free_cb`
240  * to deallocate it. Is called in all outcomes, either right away or
241  * later when the session cache is cleaned up.
242  * Caller must ensure that it has properly shared ownership of this sessionid
243  * object with cache (e.g. incrementing refcount on success)
244  */
245 CURLcode Curl_ssl_set_sessionid(struct Curl_cfilter *cf,
246                                 struct Curl_easy *data,
247                                 const struct ssl_peer *peer,
248                                 const char *alpn,
249                                 void *sessionid,
250                                 size_t sessionid_size,
251                                 Curl_ssl_sessionid_dtor *sessionid_free_cb);
252 
253 #endif /* USE_SSL */
254 
255 #endif /* HEADER_CURL_VTLS_INT_H */
256