]>
Commit | Line | Data |
---|---|---|
b1322259 | 1 | /* |
fecb3aae | 2 | * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. |
d02b48c6 | 3 | * |
09abbca1 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
b1322259 RS |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
d02b48c6 RE |
8 | */ |
9 | ||
d02b48c6 RE |
10 | #include <stdio.h> |
11 | #include <errno.h> | |
706457b7 | 12 | #include "bio_local.h" |
a3e53d56 | 13 | #include "internal/bio_tfo.h" |
b39fc560 | 14 | #include "internal/cryptlib.h" |
6ba76c4f | 15 | #include "internal/ktls.h" |
c836f8ef DSH |
16 | |
17 | #ifndef OPENSSL_NO_SOCK | |
18 | ||
0f113f3e | 19 | # include <openssl/bio.h> |
d02b48c6 | 20 | |
0f113f3e | 21 | # ifdef WATT32 |
2c25ebd1 RL |
22 | /* Watt-32 uses same names */ |
23 | # undef sock_write | |
24 | # undef sock_read | |
25 | # undef sock_puts | |
26 | # define sock_write SockWrite | |
0f113f3e MC |
27 | # define sock_read SockRead |
28 | # define sock_puts SockPuts | |
29 | # endif | |
f642ebc1 | 30 | |
a3e53d56 TS |
31 | struct bss_sock_st { |
32 | BIO_ADDR tfo_peer; | |
33 | int tfo_first; | |
34 | #ifndef OPENSSL_NO_KTLS | |
35 | unsigned char ktls_record_type; | |
36 | #endif | |
37 | }; | |
38 | ||
0e1c0612 UM |
39 | static int sock_write(BIO *h, const char *buf, int num); |
40 | static int sock_read(BIO *h, char *buf, int size); | |
41 | static int sock_puts(BIO *h, const char *str); | |
42 | static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2); | |
d02b48c6 RE |
43 | static int sock_new(BIO *h); |
44 | static int sock_free(BIO *data); | |
45 | int BIO_sock_should_retry(int s); | |
d02b48c6 | 46 | |
04f6b0fd | 47 | static const BIO_METHOD methods_sockp = { |
0f113f3e MC |
48 | BIO_TYPE_SOCKET, |
49 | "socket", | |
3befffa3 | 50 | bwrite_conv, |
0f113f3e | 51 | sock_write, |
d07aee2c | 52 | bread_conv, |
0f113f3e MC |
53 | sock_read, |
54 | sock_puts, | |
b4ff6622 | 55 | NULL, /* sock_gets, */ |
0f113f3e MC |
56 | sock_ctrl, |
57 | sock_new, | |
58 | sock_free, | |
b4ff6622 | 59 | NULL, /* sock_callback_ctrl */ |
0f113f3e | 60 | }; |
d02b48c6 | 61 | |
04f6b0fd | 62 | const BIO_METHOD *BIO_s_socket(void) |
0f113f3e | 63 | { |
26a7d938 | 64 | return &methods_sockp; |
0f113f3e | 65 | } |
d02b48c6 | 66 | |
6b691a5c | 67 | BIO *BIO_new_socket(int fd, int close_flag) |
0f113f3e MC |
68 | { |
69 | BIO *ret; | |
d02b48c6 | 70 | |
0f113f3e MC |
71 | ret = BIO_new(BIO_s_socket()); |
72 | if (ret == NULL) | |
26a7d938 | 73 | return NULL; |
0f113f3e | 74 | BIO_set_fd(ret, fd, close_flag); |
6ba76c4f BP |
75 | # ifndef OPENSSL_NO_KTLS |
76 | { | |
77 | /* | |
78 | * The new socket is created successfully regardless of ktls_enable. | |
79 | * ktls_enable doesn't change any functionality of the socket, except | |
80 | * changing the setsockopt to enable the processing of ktls_start. | |
81 | * Thus, it is not a problem to call it for non-TLS sockets. | |
82 | */ | |
83 | ktls_enable(fd); | |
84 | } | |
85 | # endif | |
26a7d938 | 86 | return ret; |
0f113f3e | 87 | } |
d02b48c6 | 88 | |
6b691a5c | 89 | static int sock_new(BIO *bi) |
0f113f3e MC |
90 | { |
91 | bi->init = 0; | |
92 | bi->num = 0; | |
0f113f3e | 93 | bi->flags = 0; |
a3e53d56 TS |
94 | bi->ptr = OPENSSL_zalloc(sizeof(struct bss_sock_st)); |
95 | if (bi->ptr == NULL) | |
96 | return 0; | |
208fb891 | 97 | return 1; |
0f113f3e | 98 | } |
d02b48c6 | 99 | |
6b691a5c | 100 | static int sock_free(BIO *a) |
0f113f3e MC |
101 | { |
102 | if (a == NULL) | |
26a7d938 | 103 | return 0; |
0f113f3e MC |
104 | if (a->shutdown) { |
105 | if (a->init) { | |
8731a4fc | 106 | BIO_closesocket(a->num); |
0f113f3e MC |
107 | } |
108 | a->init = 0; | |
109 | a->flags = 0; | |
110 | } | |
a3e53d56 TS |
111 | OPENSSL_free(a->ptr); |
112 | a->ptr = NULL; | |
208fb891 | 113 | return 1; |
0f113f3e MC |
114 | } |
115 | ||
6b691a5c | 116 | static int sock_read(BIO *b, char *out, int outl) |
0f113f3e MC |
117 | { |
118 | int ret = 0; | |
119 | ||
120 | if (out != NULL) { | |
121 | clear_socket_error(); | |
e401ef80 BP |
122 | # ifndef OPENSSL_NO_KTLS |
123 | if (BIO_get_ktls_recv(b)) | |
124 | ret = ktls_read_record(b->num, out, outl); | |
125 | else | |
126 | # endif | |
127 | ret = readsocket(b->num, out, outl); | |
0f113f3e MC |
128 | BIO_clear_retry_flags(b); |
129 | if (ret <= 0) { | |
130 | if (BIO_sock_should_retry(ret)) | |
131 | BIO_set_retry_read(b); | |
d924dbf4 MC |
132 | else if (ret == 0) |
133 | b->flags |= BIO_FLAGS_IN_EOF; | |
0f113f3e MC |
134 | } |
135 | } | |
26a7d938 | 136 | return ret; |
0f113f3e | 137 | } |
d02b48c6 | 138 | |
0e1c0612 | 139 | static int sock_write(BIO *b, const char *in, int inl) |
0f113f3e | 140 | { |
6ba76c4f | 141 | int ret = 0; |
a3e53d56 TS |
142 | # if !defined(OPENSSL_NO_KTLS) || defined(OSSL_TFO_SENDTO) |
143 | struct bss_sock_st *data = (struct bss_sock_st *)b->ptr; | |
144 | # endif | |
0f113f3e MC |
145 | |
146 | clear_socket_error(); | |
6ba76c4f BP |
147 | # ifndef OPENSSL_NO_KTLS |
148 | if (BIO_should_ktls_ctrl_msg_flag(b)) { | |
a3e53d56 | 149 | unsigned char record_type = data->ktls_record_type; |
6ba76c4f BP |
150 | ret = ktls_send_ctrl_message(b->num, record_type, in, inl); |
151 | if (ret >= 0) { | |
152 | ret = inl; | |
153 | BIO_clear_ktls_ctrl_msg_flag(b); | |
154 | } | |
155 | } else | |
a3e53d56 TS |
156 | # endif |
157 | # if defined(OSSL_TFO_SENDTO) | |
158 | if (data->tfo_first) { | |
159 | struct bss_sock_st *data = (struct bss_sock_st *)b->ptr; | |
160 | socklen_t peerlen = BIO_ADDR_sockaddr_size(&data->tfo_peer); | |
161 | ||
162 | ret = sendto(b->num, in, inl, OSSL_TFO_SENDTO, | |
163 | BIO_ADDR_sockaddr(&data->tfo_peer), peerlen); | |
164 | data->tfo_first = 0; | |
165 | } else | |
6ba76c4f BP |
166 | # endif |
167 | ret = writesocket(b->num, in, inl); | |
0f113f3e MC |
168 | BIO_clear_retry_flags(b); |
169 | if (ret <= 0) { | |
170 | if (BIO_sock_should_retry(ret)) | |
171 | BIO_set_retry_write(b); | |
172 | } | |
26a7d938 | 173 | return ret; |
0f113f3e | 174 | } |
d02b48c6 | 175 | |
0e1c0612 | 176 | static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) |
0f113f3e MC |
177 | { |
178 | long ret = 1; | |
179 | int *ip; | |
a3e53d56 | 180 | struct bss_sock_st *data = (struct bss_sock_st *)b->ptr; |
6ba76c4f | 181 | # ifndef OPENSSL_NO_KTLS |
4b09e192 | 182 | ktls_crypto_info_t *crypto_info; |
6ba76c4f | 183 | # endif |
0f113f3e MC |
184 | |
185 | switch (cmd) { | |
186 | case BIO_C_SET_FD: | |
a3e53d56 TS |
187 | /* minimal sock_free() */ |
188 | if (b->shutdown) { | |
189 | if (b->init) | |
190 | BIO_closesocket(b->num); | |
191 | b->flags = 0; | |
192 | } | |
0f113f3e MC |
193 | b->num = *((int *)ptr); |
194 | b->shutdown = (int)num; | |
195 | b->init = 1; | |
a3e53d56 TS |
196 | data->tfo_first = 0; |
197 | memset(&data->tfo_peer, 0, sizeof(data->tfo_peer)); | |
0f113f3e MC |
198 | break; |
199 | case BIO_C_GET_FD: | |
200 | if (b->init) { | |
201 | ip = (int *)ptr; | |
202 | if (ip != NULL) | |
203 | *ip = b->num; | |
204 | ret = b->num; | |
205 | } else | |
206 | ret = -1; | |
207 | break; | |
208 | case BIO_CTRL_GET_CLOSE: | |
209 | ret = b->shutdown; | |
210 | break; | |
211 | case BIO_CTRL_SET_CLOSE: | |
212 | b->shutdown = (int)num; | |
213 | break; | |
214 | case BIO_CTRL_DUP: | |
215 | case BIO_CTRL_FLUSH: | |
216 | ret = 1; | |
217 | break; | |
6ba76c4f | 218 | # ifndef OPENSSL_NO_KTLS |
e401ef80 | 219 | case BIO_CTRL_SET_KTLS: |
4b09e192 | 220 | crypto_info = (ktls_crypto_info_t *)ptr; |
7f0f8824 | 221 | ret = ktls_start(b->num, crypto_info, num); |
6ba76c4f | 222 | if (ret) |
e401ef80 | 223 | BIO_set_ktls_flag(b, num); |
6ba76c4f BP |
224 | break; |
225 | case BIO_CTRL_GET_KTLS_SEND: | |
f16e52b6 | 226 | return BIO_should_ktls_flag(b, 1) != 0; |
e401ef80 | 227 | case BIO_CTRL_GET_KTLS_RECV: |
f16e52b6 | 228 | return BIO_should_ktls_flag(b, 0) != 0; |
e401ef80 | 229 | case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG: |
6ba76c4f | 230 | BIO_set_ktls_ctrl_msg_flag(b); |
a3e53d56 | 231 | data->ktls_record_type = (unsigned char)num; |
6ba76c4f BP |
232 | ret = 0; |
233 | break; | |
e401ef80 | 234 | case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG: |
6ba76c4f BP |
235 | BIO_clear_ktls_ctrl_msg_flag(b); |
236 | ret = 0; | |
237 | break; | |
238 | # endif | |
d924dbf4 | 239 | case BIO_CTRL_EOF: |
f16e52b6 | 240 | ret = (b->flags & BIO_FLAGS_IN_EOF) != 0; |
d924dbf4 | 241 | break; |
a3e53d56 TS |
242 | case BIO_C_GET_CONNECT: |
243 | if (ptr != NULL && num == 2) { | |
244 | const char **pptr = (const char **)ptr; | |
245 | ||
246 | *pptr = (const char *)&data->tfo_peer; | |
247 | } else { | |
248 | ret = 0; | |
249 | } | |
250 | break; | |
251 | case BIO_C_SET_CONNECT: | |
252 | if (ptr != NULL && num == 2) { | |
253 | ret = BIO_ADDR_make(&data->tfo_peer, | |
254 | BIO_ADDR_sockaddr((const BIO_ADDR *)ptr)); | |
255 | if (ret) | |
256 | data->tfo_first = 1; | |
257 | } else { | |
258 | ret = 0; | |
259 | } | |
260 | break; | |
0f113f3e MC |
261 | default: |
262 | ret = 0; | |
263 | break; | |
264 | } | |
26a7d938 | 265 | return ret; |
0f113f3e | 266 | } |
d02b48c6 | 267 | |
0e1c0612 | 268 | static int sock_puts(BIO *bp, const char *str) |
0f113f3e MC |
269 | { |
270 | int n, ret; | |
d02b48c6 | 271 | |
0f113f3e MC |
272 | n = strlen(str); |
273 | ret = sock_write(bp, str, n); | |
26a7d938 | 274 | return ret; |
0f113f3e | 275 | } |
d02b48c6 | 276 | |
6b691a5c | 277 | int BIO_sock_should_retry(int i) |
0f113f3e MC |
278 | { |
279 | int err; | |
58964a49 | 280 | |
0f113f3e MC |
281 | if ((i == 0) || (i == -1)) { |
282 | err = get_last_socket_error(); | |
d02b48c6 | 283 | |
26a7d938 | 284 | return BIO_sock_non_fatal_error(err); |
0f113f3e | 285 | } |
26a7d938 | 286 | return 0; |
0f113f3e | 287 | } |
d02b48c6 | 288 | |
6b691a5c | 289 | int BIO_sock_non_fatal_error(int err) |
0f113f3e MC |
290 | { |
291 | switch (err) { | |
1fbab1dc | 292 | # if defined(OPENSSL_SYS_WINDOWS) |
0f113f3e MC |
293 | # if defined(WSAEWOULDBLOCK) |
294 | case WSAEWOULDBLOCK: | |
295 | # endif | |
d02b48c6 RE |
296 | # endif |
297 | ||
0f113f3e MC |
298 | # ifdef EWOULDBLOCK |
299 | # ifdef WSAEWOULDBLOCK | |
300 | # if WSAEWOULDBLOCK != EWOULDBLOCK | |
301 | case EWOULDBLOCK: | |
302 | # endif | |
303 | # else | |
304 | case EWOULDBLOCK: | |
dfeab068 | 305 | # endif |
d02b48c6 | 306 | # endif |
d02b48c6 | 307 | |
0f113f3e MC |
308 | # if defined(ENOTCONN) |
309 | case ENOTCONN: | |
310 | # endif | |
311 | ||
312 | # ifdef EINTR | |
313 | case EINTR: | |
314 | # endif | |
315 | ||
316 | # ifdef EAGAIN | |
317 | # if EWOULDBLOCK != EAGAIN | |
318 | case EAGAIN: | |
d02b48c6 | 319 | # endif |
d02b48c6 | 320 | # endif |
d02b48c6 | 321 | |
0f113f3e MC |
322 | # ifdef EPROTO |
323 | case EPROTO: | |
324 | # endif | |
58964a49 | 325 | |
0f113f3e MC |
326 | # ifdef EINPROGRESS |
327 | case EINPROGRESS: | |
328 | # endif | |
d02b48c6 | 329 | |
0f113f3e MC |
330 | # ifdef EALREADY |
331 | case EALREADY: | |
d02b48c6 | 332 | # endif |
208fb891 | 333 | return 1; |
0f113f3e MC |
334 | default: |
335 | break; | |
336 | } | |
26a7d938 | 337 | return 0; |
0f113f3e MC |
338 | } |
339 | ||
340 | #endif /* #ifndef OPENSSL_NO_SOCK */ |