Invoke tear_down when exiting test_encode_tls_sct() prematurely
[openssl.git] / crypto / bio / bss_conn.c
1 /*
2  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
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
8  */
9
10 #include <stdio.h>
11 #include <errno.h>
12
13 #include "bio_local.h"
14 #include "internal/ktls.h"
15
16 #ifndef OPENSSL_NO_SOCK
17
18 typedef struct bio_connect_st {
19     int state;
20     int connect_family;
21     char *param_hostname;
22     char *param_service;
23     int connect_mode;
24 # ifndef OPENSSL_NO_KTLS
25     unsigned char record_type;
26 # endif
27
28     BIO_ADDRINFO *addr_first;
29     const BIO_ADDRINFO *addr_iter;
30     /*
31      * int socket; this will be kept in bio->num so that it is compatible
32      * with the bss_sock bio
33      */
34     /*
35      * called when the connection is initially made callback(BIO,state,ret);
36      * The callback should return 'ret'.  state is for compatibility with the
37      * ssl info_callback
38      */
39     BIO_info_cb *info_callback;
40 } BIO_CONNECT;
41
42 static int conn_write(BIO *h, const char *buf, int num);
43 static int conn_read(BIO *h, char *buf, int size);
44 static int conn_puts(BIO *h, const char *str);
45 static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
46 static int conn_new(BIO *h);
47 static int conn_free(BIO *data);
48 static long conn_callback_ctrl(BIO *h, int cmd, BIO_info_cb *);
49
50 static int conn_state(BIO *b, BIO_CONNECT *c);
51 static void conn_close_socket(BIO *data);
52 BIO_CONNECT *BIO_CONNECT_new(void);
53 void BIO_CONNECT_free(BIO_CONNECT *a);
54
55 #define BIO_CONN_S_BEFORE                1
56 #define BIO_CONN_S_GET_ADDR              2
57 #define BIO_CONN_S_CREATE_SOCKET         3
58 #define BIO_CONN_S_CONNECT               4
59 #define BIO_CONN_S_OK                    5
60 #define BIO_CONN_S_BLOCKED_CONNECT       6
61 #define BIO_CONN_S_CONNECT_ERROR         7
62
63 static const BIO_METHOD methods_connectp = {
64     BIO_TYPE_CONNECT,
65     "socket connect",
66     bwrite_conv,
67     conn_write,
68     bread_conv,
69     conn_read,
70     conn_puts,
71     NULL,                       /* conn_gets, */
72     conn_ctrl,
73     conn_new,
74     conn_free,
75     conn_callback_ctrl,
76 };
77
78 static int conn_state(BIO *b, BIO_CONNECT *c)
79 {
80     int ret = -1, i;
81     BIO_info_cb *cb = NULL;
82
83     if (c->info_callback != NULL)
84         cb = c->info_callback;
85
86     for (;;) {
87         switch (c->state) {
88         case BIO_CONN_S_BEFORE:
89             if (c->param_hostname == NULL && c->param_service == NULL) {
90                 ERR_raise_data(ERR_LIB_BIO,
91                                BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED,
92                                "hostname=%s service=%s",
93                                c->param_hostname, c->param_service);
94                 goto exit_loop;
95             }
96             c->state = BIO_CONN_S_GET_ADDR;
97             break;
98
99         case BIO_CONN_S_GET_ADDR:
100             {
101                 int family = AF_UNSPEC;
102                 switch (c->connect_family) {
103                 case BIO_FAMILY_IPV6:
104                     if (1) { /* This is a trick we use to avoid bit rot.
105                               * at least the "else" part will always be
106                               * compiled.
107                               */
108 #ifdef AF_INET6
109                         family = AF_INET6;
110                     } else {
111 #endif
112                         ERR_raise(ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY);
113                         goto exit_loop;
114                     }
115                     break;
116                 case BIO_FAMILY_IPV4:
117                     family = AF_INET;
118                     break;
119                 case BIO_FAMILY_IPANY:
120                     family = AF_UNSPEC;
121                     break;
122                 default:
123                     ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY);
124                     goto exit_loop;
125                 }
126                 if (BIO_lookup(c->param_hostname, c->param_service,
127                                BIO_LOOKUP_CLIENT,
128                                family, SOCK_STREAM, &c->addr_first) == 0)
129                     goto exit_loop;
130             }
131             if (c->addr_first == NULL) {
132                 ERR_raise(ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING);
133                 goto exit_loop;
134             }
135             c->addr_iter = c->addr_first;
136             c->state = BIO_CONN_S_CREATE_SOCKET;
137             break;
138
139         case BIO_CONN_S_CREATE_SOCKET:
140             ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
141                              BIO_ADDRINFO_socktype(c->addr_iter),
142                              BIO_ADDRINFO_protocol(c->addr_iter), 0);
143             if (ret == (int)INVALID_SOCKET) {
144                 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
145                                "calling socket(%s, %s)",
146                                c->param_hostname, c->param_service);
147                 ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
148                 goto exit_loop;
149             }
150             b->num = ret;
151             c->state = BIO_CONN_S_CONNECT;
152             break;
153
154         case BIO_CONN_S_CONNECT:
155             BIO_clear_retry_flags(b);
156             ERR_set_mark();
157             ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter),
158                               BIO_SOCK_KEEPALIVE | c->connect_mode);
159             b->retry_reason = 0;
160             if (ret == 0) {
161                 if (BIO_sock_should_retry(ret)) {
162                     BIO_set_retry_special(b);
163                     c->state = BIO_CONN_S_BLOCKED_CONNECT;
164                     b->retry_reason = BIO_RR_CONNECT;
165                     ERR_pop_to_mark();
166                 } else if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter))
167                            != NULL) {
168                     /*
169                      * if there are more addresses to try, do that first
170                      */
171                     BIO_closesocket(b->num);
172                     c->state = BIO_CONN_S_CREATE_SOCKET;
173                     ERR_pop_to_mark();
174                     break;
175                 } else {
176                     ERR_clear_last_mark();
177                     ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
178                                    "calling connect(%s, %s)",
179                                     c->param_hostname, c->param_service);
180                     c->state = BIO_CONN_S_CONNECT_ERROR;
181                     break;
182                 }
183                 goto exit_loop;
184             } else {
185                 ERR_clear_last_mark();
186                 c->state = BIO_CONN_S_OK;
187             }
188             break;
189
190         case BIO_CONN_S_BLOCKED_CONNECT:
191             i = BIO_sock_error(b->num);
192             if (i != 0) {
193                 BIO_clear_retry_flags(b);
194                 if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) != NULL) {
195                     /*
196                      * if there are more addresses to try, do that first
197                      */
198                     BIO_closesocket(b->num);
199                     c->state = BIO_CONN_S_CREATE_SOCKET;
200                     break;
201                 }
202                 ERR_raise_data(ERR_LIB_SYS, i,
203                                "calling connect(%s, %s)",
204                                 c->param_hostname, c->param_service);
205                 ERR_raise(ERR_LIB_BIO, BIO_R_NBIO_CONNECT_ERROR);
206                 ret = 0;
207                 goto exit_loop;
208             } else
209                 c->state = BIO_CONN_S_OK;
210             break;
211
212         case BIO_CONN_S_CONNECT_ERROR:
213             ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
214             ret = 0;
215             goto exit_loop;
216
217         case BIO_CONN_S_OK:
218             ret = 1;
219             goto exit_loop;
220         default:
221             /* abort(); */
222             goto exit_loop;
223         }
224
225         if (cb != NULL) {
226             if ((ret = cb((BIO *)b, c->state, ret)) == 0)
227                 goto end;
228         }
229     }
230
231     /* Loop does not exit */
232  exit_loop:
233     if (cb != NULL)
234         ret = cb((BIO *)b, c->state, ret);
235  end:
236     return ret;
237 }
238
239 BIO_CONNECT *BIO_CONNECT_new(void)
240 {
241     BIO_CONNECT *ret;
242
243     if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
244         ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
245         return NULL;
246     }
247     ret->state = BIO_CONN_S_BEFORE;
248     ret->connect_family = BIO_FAMILY_IPANY;
249     return ret;
250 }
251
252 void BIO_CONNECT_free(BIO_CONNECT *a)
253 {
254     if (a == NULL)
255         return;
256     OPENSSL_free(a->param_hostname);
257     OPENSSL_free(a->param_service);
258     BIO_ADDRINFO_free(a->addr_first);
259     OPENSSL_free(a);
260 }
261
262 const BIO_METHOD *BIO_s_connect(void)
263 {
264     return &methods_connectp;
265 }
266
267 static int conn_new(BIO *bi)
268 {
269     bi->init = 0;
270     bi->num = (int)INVALID_SOCKET;
271     bi->flags = 0;
272     if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL)
273         return 0;
274     else
275         return 1;
276 }
277
278 static void conn_close_socket(BIO *bio)
279 {
280     BIO_CONNECT *c;
281
282     c = (BIO_CONNECT *)bio->ptr;
283     if (bio->num != (int)INVALID_SOCKET) {
284         /* Only do a shutdown if things were established */
285         if (c->state == BIO_CONN_S_OK)
286             shutdown(bio->num, 2);
287         BIO_closesocket(bio->num);
288         bio->num = (int)INVALID_SOCKET;
289     }
290 }
291
292 static int conn_free(BIO *a)
293 {
294     BIO_CONNECT *data;
295
296     if (a == NULL)
297         return 0;
298     data = (BIO_CONNECT *)a->ptr;
299
300     if (a->shutdown) {
301         conn_close_socket(a);
302         BIO_CONNECT_free(data);
303         a->ptr = NULL;
304         a->flags = 0;
305         a->init = 0;
306     }
307     return 1;
308 }
309
310 static int conn_read(BIO *b, char *out, int outl)
311 {
312     int ret = 0;
313     BIO_CONNECT *data;
314
315     data = (BIO_CONNECT *)b->ptr;
316     if (data->state != BIO_CONN_S_OK) {
317         ret = conn_state(b, data);
318         if (ret <= 0)
319             return ret;
320     }
321
322     if (out != NULL) {
323         clear_socket_error();
324 # ifndef OPENSSL_NO_KTLS
325         if (BIO_get_ktls_recv(b))
326             ret = ktls_read_record(b->num, out, outl);
327         else
328 # endif
329             ret = readsocket(b->num, out, outl);
330         BIO_clear_retry_flags(b);
331         if (ret <= 0) {
332             if (BIO_sock_should_retry(ret))
333                 BIO_set_retry_read(b);
334             else if (ret == 0)
335                 b->flags |= BIO_FLAGS_IN_EOF;
336         }
337     }
338     return ret;
339 }
340
341 static int conn_write(BIO *b, const char *in, int inl)
342 {
343     int ret;
344     BIO_CONNECT *data;
345
346     data = (BIO_CONNECT *)b->ptr;
347     if (data->state != BIO_CONN_S_OK) {
348         ret = conn_state(b, data);
349         if (ret <= 0)
350             return ret;
351     }
352
353     clear_socket_error();
354 # ifndef OPENSSL_NO_KTLS
355     if (BIO_should_ktls_ctrl_msg_flag(b)) {
356         ret = ktls_send_ctrl_message(b->num, data->record_type, in, inl);
357         if (ret >= 0) {
358             ret = inl;
359             BIO_clear_ktls_ctrl_msg_flag(b);
360         }
361     } else
362 # endif
363         ret = writesocket(b->num, in, inl);
364     BIO_clear_retry_flags(b);
365     if (ret <= 0) {
366         if (BIO_sock_should_retry(ret))
367             BIO_set_retry_write(b);
368     }
369     return ret;
370 }
371
372 static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
373 {
374     BIO *dbio;
375     int *ip;
376     const char **pptr = NULL;
377     long ret = 1;
378     BIO_CONNECT *data;
379 # ifndef OPENSSL_NO_KTLS
380     ktls_crypto_info_t *crypto_info;
381 # endif
382
383     data = (BIO_CONNECT *)b->ptr;
384
385     switch (cmd) {
386     case BIO_CTRL_RESET:
387         ret = 0;
388         data->state = BIO_CONN_S_BEFORE;
389         conn_close_socket(b);
390         BIO_ADDRINFO_free(data->addr_first);
391         data->addr_first = NULL;
392         b->flags = 0;
393         break;
394     case BIO_C_DO_STATE_MACHINE:
395         /* use this one to start the connection */
396         if (data->state != BIO_CONN_S_OK)
397             ret = (long)conn_state(b, data);
398         else
399             ret = 1;
400         break;
401     case BIO_C_GET_CONNECT:
402         if (ptr != NULL) {
403             pptr = (const char **)ptr;
404             if (num == 0) {
405                 *pptr = data->param_hostname;
406             } else if (num == 1) {
407                 *pptr = data->param_service;
408             } else if (num == 2) {
409                 *pptr = (const char *)BIO_ADDRINFO_address(data->addr_iter);
410             } else if (num == 3) {
411                 switch (BIO_ADDRINFO_family(data->addr_iter)) {
412 # ifdef AF_INET6
413                 case AF_INET6:
414                     ret = BIO_FAMILY_IPV6;
415                     break;
416 # endif
417                 case AF_INET:
418                     ret = BIO_FAMILY_IPV4;
419                     break;
420                 case 0:
421                     ret = data->connect_family;
422                     break;
423                 default:
424                     ret = -1;
425                     break;
426                 }
427             } else {
428                 ret = 0;
429             }
430         } else {
431             ret = 0;
432         }
433         break;
434     case BIO_C_SET_CONNECT:
435         if (ptr != NULL) {
436             b->init = 1;
437             if (num == 0) { /* BIO_set_conn_hostname */
438                 char *hold_service = data->param_service;
439                 /* We affect the hostname regardless.  However, the input
440                  * string might contain a host:service spec, so we must
441                  * parse it, which might or might not affect the service
442                  */
443
444                 OPENSSL_free(data->param_hostname);
445                 data->param_hostname = NULL;
446                 ret = BIO_parse_hostserv(ptr,
447                                          &data->param_hostname,
448                                          &data->param_service,
449                                          BIO_PARSE_PRIO_HOST);
450                 if (hold_service != data->param_service)
451                     OPENSSL_free(hold_service);
452             } else if (num == 1) { /* BIO_set_conn_port */
453                 OPENSSL_free(data->param_service);
454                 if ((data->param_service = OPENSSL_strdup(ptr)) == NULL)
455                     ret = 0;
456             } else if (num == 2) { /* BIO_set_conn_address */
457                 const BIO_ADDR *addr = (const BIO_ADDR *)ptr;
458                 char *host = BIO_ADDR_hostname_string(addr, 1);
459                 char *service = BIO_ADDR_service_string(addr, 1);
460
461                 ret = host != NULL && service != NULL;
462                 if (ret) {
463                     OPENSSL_free(data->param_hostname);
464                     data->param_hostname = host;
465                     OPENSSL_free(data->param_service);
466                     data->param_service = service;
467                     BIO_ADDRINFO_free(data->addr_first);
468                     data->addr_first = NULL;
469                     data->addr_iter = NULL;
470                 } else {
471                     OPENSSL_free(host);
472                     OPENSSL_free(service);
473                 }
474             } else if (num == 3) { /* BIO_set_conn_ip_family */
475                 data->connect_family = *(int *)ptr;
476             } else {
477                 ret = 0;
478             }
479         }
480         break;
481     case BIO_C_SET_NBIO:
482         if (num != 0)
483             data->connect_mode |= BIO_SOCK_NONBLOCK;
484         else
485             data->connect_mode &= ~BIO_SOCK_NONBLOCK;
486         break;
487     case BIO_C_SET_CONNECT_MODE:
488         data->connect_mode = (int)num;
489         break;
490     case BIO_C_GET_FD:
491         if (b->init) {
492             ip = (int *)ptr;
493             if (ip != NULL)
494                 *ip = b->num;
495             ret = b->num;
496         } else
497             ret = -1;
498         break;
499     case BIO_CTRL_GET_CLOSE:
500         ret = b->shutdown;
501         break;
502     case BIO_CTRL_SET_CLOSE:
503         b->shutdown = (int)num;
504         break;
505     case BIO_CTRL_PENDING:
506     case BIO_CTRL_WPENDING:
507         ret = 0;
508         break;
509     case BIO_CTRL_FLUSH:
510         break;
511     case BIO_CTRL_DUP:
512         {
513             dbio = (BIO *)ptr;
514             if (data->param_hostname)
515                 BIO_set_conn_hostname(dbio, data->param_hostname);
516             if (data->param_service)
517                 BIO_set_conn_port(dbio, data->param_service);
518             BIO_set_conn_ip_family(dbio, data->connect_family);
519             BIO_set_conn_mode(dbio, data->connect_mode);
520             /*
521              * FIXME: the cast of the function seems unlikely to be a good
522              * idea
523              */
524             (void)BIO_set_info_callback(dbio, data->info_callback);
525         }
526         break;
527     case BIO_CTRL_SET_CALLBACK:
528         ret = 0; /* use callback ctrl */
529         break;
530     case BIO_CTRL_GET_CALLBACK:
531         {
532             BIO_info_cb **fptr;
533
534             fptr = (BIO_info_cb **)ptr;
535             *fptr = data->info_callback;
536         }
537         break;
538     case BIO_CTRL_EOF:
539         ret = (b->flags & BIO_FLAGS_IN_EOF) != 0;
540         break;
541 # ifndef OPENSSL_NO_KTLS
542     case BIO_CTRL_SET_KTLS:
543         crypto_info = (ktls_crypto_info_t *)ptr;
544         ret = ktls_start(b->num, crypto_info, num);
545         if (ret)
546             BIO_set_ktls_flag(b, num);
547         break;
548     case BIO_CTRL_GET_KTLS_SEND:
549         return BIO_should_ktls_flag(b, 1) != 0;
550     case BIO_CTRL_GET_KTLS_RECV:
551         return BIO_should_ktls_flag(b, 0) != 0;
552     case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
553         BIO_set_ktls_ctrl_msg_flag(b);
554         data->record_type = num;
555         ret = 0;
556         break;
557     case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
558         BIO_clear_ktls_ctrl_msg_flag(b);
559         ret = 0;
560         break;
561 # endif
562     default:
563         ret = 0;
564         break;
565     }
566     return ret;
567 }
568
569 static long conn_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
570 {
571     long ret = 1;
572     BIO_CONNECT *data;
573
574     data = (BIO_CONNECT *)b->ptr;
575
576     switch (cmd) {
577     case BIO_CTRL_SET_CALLBACK:
578         {
579             data->info_callback = fp;
580         }
581         break;
582     default:
583         ret = 0;
584         break;
585     }
586     return ret;
587 }
588
589 static int conn_puts(BIO *bp, const char *str)
590 {
591     int n, ret;
592
593     n = strlen(str);
594     ret = conn_write(bp, str, n);
595     return ret;
596 }
597
598 BIO *BIO_new_connect(const char *str)
599 {
600     BIO *ret;
601
602     ret = BIO_new(BIO_s_connect());
603     if (ret == NULL)
604         return NULL;
605     if (BIO_set_conn_hostname(ret, str))
606         return ret;
607     BIO_free(ret);
608     return NULL;
609 }
610
611 #endif