]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/bio/bss_conn.c
Convert all {NAME}err() in crypto/ to their corresponding ERR_raise() call
[thirdparty/openssl.git] / crypto / bio / bss_conn.c
CommitLineData
b1322259 1/*
33388b44 2 * Copyright 1995-2020 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>
d02b48c6 12
706457b7 13#include "bio_local.h"
b1f79e7c 14#include "internal/ktls.h"
b00b2124 15
417be660 16#ifndef OPENSSL_NO_SOCK
0f113f3e
MC
17
18typedef struct bio_connect_st {
19 int state;
417be660 20 int connect_family;
0f113f3e 21 char *param_hostname;
417be660
RL
22 char *param_service;
23 int connect_mode;
b1f79e7c
JB
24# ifndef OPENSSL_NO_KTLS
25 unsigned char record_type;
26# endif
417be660
RL
27
28 BIO_ADDRINFO *addr_first;
29 const BIO_ADDRINFO *addr_iter;
0f113f3e
MC
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 */
fce78bd4 39 BIO_info_cb *info_callback;
0f113f3e 40} BIO_CONNECT;
d02b48c6 41
0e1c0612
UM
42static int conn_write(BIO *h, const char *buf, int num);
43static int conn_read(BIO *h, char *buf, int size);
44static int conn_puts(BIO *h, const char *str);
45static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
d02b48c6
RE
46static int conn_new(BIO *h);
47static int conn_free(BIO *data);
fce78bd4 48static long conn_callback_ctrl(BIO *h, int cmd, BIO_info_cb *);
d02b48c6
RE
49
50static int conn_state(BIO *b, BIO_CONNECT *c);
51static void conn_close_socket(BIO *data);
0f113f3e 52BIO_CONNECT *BIO_CONNECT_new(void);
d02b48c6
RE
53void BIO_CONNECT_free(BIO_CONNECT *a);
54
417be660
RL
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
181f5185 61#define BIO_CONN_S_CONNECT_ERROR 7
417be660 62
04f6b0fd 63static const BIO_METHOD methods_connectp = {
0f113f3e
MC
64 BIO_TYPE_CONNECT,
65 "socket connect",
3befffa3
MC
66 /* TODO: Convert to new style write function */
67 bwrite_conv,
0f113f3e 68 conn_write,
d07aee2c
MC
69 /* TODO: Convert to new style read function */
70 bread_conv,
0f113f3e
MC
71 conn_read,
72 conn_puts,
b4ff6622 73 NULL, /* conn_gets, */
0f113f3e
MC
74 conn_ctrl,
75 conn_new,
76 conn_free,
77 conn_callback_ctrl,
78};
d02b48c6 79
6b691a5c 80static int conn_state(BIO *b, BIO_CONNECT *c)
0f113f3e
MC
81{
82 int ret = -1, i;
fce78bd4 83 BIO_info_cb *cb = NULL;
0f113f3e
MC
84
85 if (c->info_callback != NULL)
86 cb = c->info_callback;
87
88 for (;;) {
89 switch (c->state) {
90 case BIO_CONN_S_BEFORE:
417be660 91 if (c->param_hostname == NULL && c->param_service == NULL) {
9311d0c4 92 ERR_raise(ERR_LIB_BIO, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED);
417be660
RL
93 ERR_add_error_data(4,
94 "hostname=", c->param_hostname,
95 " service=", c->param_service);
0f113f3e
MC
96 goto exit_loop;
97 }
417be660
RL
98 c->state = BIO_CONN_S_GET_ADDR;
99 break;
0f113f3e 100
417be660
RL
101 case BIO_CONN_S_GET_ADDR:
102 {
103 int family = AF_UNSPEC;
104 switch (c->connect_family) {
105 case BIO_FAMILY_IPV6:
106 if (1) { /* This is a trick we use to avoid bit rot.
107 * at least the "else" part will always be
108 * compiled.
109 */
110#ifdef AF_INET6
111 family = AF_INET6;
112 } else {
113#endif
9311d0c4 114 ERR_raise(ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY);
417be660
RL
115 goto exit_loop;
116 }
117 break;
118 case BIO_FAMILY_IPV4:
119 family = AF_INET;
120 break;
121 case BIO_FAMILY_IPANY:
122 family = AF_UNSPEC;
123 break;
124 default:
9311d0c4 125 ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY);
417be660 126 goto exit_loop;
0f113f3e 127 }
417be660
RL
128 if (BIO_lookup(c->param_hostname, c->param_service,
129 BIO_LOOKUP_CLIENT,
130 family, SOCK_STREAM, &c->addr_first) == 0)
131 goto exit_loop;
0f113f3e 132 }
417be660 133 if (c->addr_first == NULL) {
9311d0c4 134 ERR_raise(ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING);
0f113f3e
MC
135 goto exit_loop;
136 }
417be660 137 c->addr_iter = c->addr_first;
0f113f3e
MC
138 c->state = BIO_CONN_S_CREATE_SOCKET;
139 break;
140
141 case BIO_CONN_S_CREATE_SOCKET:
417be660
RL
142 ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
143 BIO_ADDRINFO_socktype(c->addr_iter),
144 BIO_ADDRINFO_protocol(c->addr_iter), 0);
b13fdc48 145 if (ret == (int)INVALID_SOCKET) {
ff988500
RS
146 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
147 "calling socket(%s, %s)",
148 c->param_hostname, c->param_service);
9311d0c4 149 ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
0f113f3e
MC
150 goto exit_loop;
151 }
152 b->num = ret;
0f113f3e 153 c->state = BIO_CONN_S_CONNECT;
0f113f3e
MC
154 break;
155
156 case BIO_CONN_S_CONNECT:
157 BIO_clear_retry_flags(b);
417be660
RL
158 ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter),
159 BIO_SOCK_KEEPALIVE | c->connect_mode);
0f113f3e 160 b->retry_reason = 0;
a043d0b9 161 if (ret == 0) {
0f113f3e
MC
162 if (BIO_sock_should_retry(ret)) {
163 BIO_set_retry_special(b);
164 c->state = BIO_CONN_S_BLOCKED_CONNECT;
165 b->retry_reason = BIO_RR_CONNECT;
417be660
RL
166 ERR_clear_error();
167 } else if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter))
168 != NULL) {
169 /*
170 * if there are more addresses to try, do that first
171 */
172 BIO_closesocket(b->num);
173 c->state = BIO_CONN_S_CREATE_SOCKET;
174 ERR_clear_error();
175 break;
0f113f3e 176 } else {
ff988500
RS
177 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
178 "calling connect(%s, %s)",
179 c->param_hostname, c->param_service);
181f5185
RL
180 c->state = BIO_CONN_S_CONNECT_ERROR;
181 break;
0f113f3e
MC
182 }
183 goto exit_loop;
417be660 184 } else {
0f113f3e 185 c->state = BIO_CONN_S_OK;
417be660 186 }
0f113f3e
MC
187 break;
188
189 case BIO_CONN_S_BLOCKED_CONNECT:
190 i = BIO_sock_error(b->num);
dc18e4dd 191 if (i != 0) {
0f113f3e 192 BIO_clear_retry_flags(b);
dc18e4dd
DDO
193 if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) != NULL) {
194 /*
195 * if there are more addresses to try, do that first
196 */
197 BIO_closesocket(b->num);
198 c->state = BIO_CONN_S_CREATE_SOCKET;
199 ERR_clear_error();
200 break;
201 }
ff988500
RS
202 ERR_raise_data(ERR_LIB_SYS, i,
203 "calling connect(%s, %s)",
204 c->param_hostname, c->param_service);
9311d0c4 205 ERR_raise(ERR_LIB_BIO, BIO_R_NBIO_CONNECT_ERROR);
0f113f3e
MC
206 ret = 0;
207 goto exit_loop;
208 } else
209 c->state = BIO_CONN_S_OK;
210 break;
211
181f5185 212 case BIO_CONN_S_CONNECT_ERROR:
9311d0c4 213 ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
181f5185
RL
214 ret = 0;
215 goto exit_loop;
216
0f113f3e
MC
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) {
75ebbd9a 226 if ((ret = cb((BIO *)b, c->state, ret)) == 0)
0f113f3e
MC
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:
26a7d938 236 return ret;
0f113f3e 237}
d02b48c6 238
6b691a5c 239BIO_CONNECT *BIO_CONNECT_new(void)
0f113f3e
MC
240{
241 BIO_CONNECT *ret;
242
f06080cb 243 if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
9311d0c4 244 ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
26a7d938 245 return NULL;
f06080cb 246 }
0f113f3e 247 ret->state = BIO_CONN_S_BEFORE;
417be660 248 ret->connect_family = BIO_FAMILY_IPANY;
26a7d938 249 return ret;
0f113f3e 250}
d02b48c6 251
6b691a5c 252void BIO_CONNECT_free(BIO_CONNECT *a)
0f113f3e 253{
e6e9170d
RS
254 if (a == NULL)
255 return;
b548a1f1 256 OPENSSL_free(a->param_hostname);
417be660
RL
257 OPENSSL_free(a->param_service);
258 BIO_ADDRINFO_free(a->addr_first);
0f113f3e
MC
259 OPENSSL_free(a);
260}
d02b48c6 261
04f6b0fd 262const BIO_METHOD *BIO_s_connect(void)
0f113f3e 263{
26a7d938 264 return &methods_connectp;
0f113f3e 265}
d02b48c6 266
6b691a5c 267static int conn_new(BIO *bi)
0f113f3e
MC
268{
269 bi->init = 0;
b13fdc48 270 bi->num = (int)INVALID_SOCKET;
0f113f3e
MC
271 bi->flags = 0;
272 if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL)
26a7d938 273 return 0;
0f113f3e 274 else
208fb891 275 return 1;
0f113f3e 276}
d02b48c6 277
6b691a5c 278static void conn_close_socket(BIO *bio)
0f113f3e
MC
279{
280 BIO_CONNECT *c;
281
282 c = (BIO_CONNECT *)bio->ptr;
b13fdc48 283 if (bio->num != (int)INVALID_SOCKET) {
0f113f3e
MC
284 /* Only do a shutdown if things were established */
285 if (c->state == BIO_CONN_S_OK)
286 shutdown(bio->num, 2);
417be660 287 BIO_closesocket(bio->num);
b13fdc48 288 bio->num = (int)INVALID_SOCKET;
0f113f3e
MC
289 }
290}
d02b48c6 291
6b691a5c 292static int conn_free(BIO *a)
0f113f3e
MC
293{
294 BIO_CONNECT *data;
295
296 if (a == NULL)
26a7d938 297 return 0;
0f113f3e
MC
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 }
208fb891 307 return 1;
0f113f3e
MC
308}
309
6b691a5c 310static int conn_read(BIO *b, char *out, int outl)
0f113f3e
MC
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)
26a7d938 319 return ret;
0f113f3e
MC
320 }
321
322 if (out != NULL) {
323 clear_socket_error();
b1f79e7c
JB
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);
0f113f3e
MC
330 BIO_clear_retry_flags(b);
331 if (ret <= 0) {
332 if (BIO_sock_should_retry(ret))
333 BIO_set_retry_read(b);
6d53ad6b
MC
334 else if (ret == 0)
335 b->flags |= BIO_FLAGS_IN_EOF;
0f113f3e
MC
336 }
337 }
26a7d938 338 return ret;
0f113f3e 339}
d02b48c6 340
0e1c0612 341static int conn_write(BIO *b, const char *in, int inl)
0f113f3e
MC
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)
26a7d938 350 return ret;
0f113f3e
MC
351 }
352
353 clear_socket_error();
b1f79e7c
JB
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);
0f113f3e
MC
364 BIO_clear_retry_flags(b);
365 if (ret <= 0) {
366 if (BIO_sock_should_retry(ret))
367 BIO_set_retry_write(b);
368 }
26a7d938 369 return ret;
0f113f3e 370}
d02b48c6 371
0e1c0612 372static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
0f113f3e
MC
373{
374 BIO *dbio;
375 int *ip;
4b72d5f8 376 const char **pptr = NULL;
0f113f3e
MC
377 long ret = 1;
378 BIO_CONNECT *data;
b1f79e7c 379# ifndef OPENSSL_NO_KTLS
4b09e192 380 ktls_crypto_info_t *crypto_info;
b1f79e7c 381# endif
0f113f3e
MC
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);
417be660
RL
390 BIO_ADDRINFO_free(data->addr_first);
391 data->addr_first = NULL;
0f113f3e
MC
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;
417be660
RL
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;
4b72d5f8 426 }
417be660
RL
427 } else {
428 ret = 0;
4b72d5f8
RL
429 }
430 } else {
4b72d5f8 431 ret = 0;
0f113f3e
MC
432 }
433 break;
434 case BIO_C_SET_CONNECT:
435 if (ptr != NULL) {
436 b->init = 1;
c0fff24e 437 if (num == 0) { /* BIO_set_conn_hostname */
417be660
RL
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 */
c0fff24e 443
b548a1f1 444 OPENSSL_free(data->param_hostname);
417be660
RL
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);
c0fff24e 452 } else if (num == 1) { /* BIO_set_conn_port */
417be660 453 OPENSSL_free(data->param_service);
c0fff24e
DDO
454 if ((data->param_service = OPENSSL_strdup(ptr)) == NULL)
455 ret = 0;
456 } else if (num == 2) { /* BIO_set_conn_address */
417be660 457 const BIO_ADDR *addr = (const BIO_ADDR *)ptr;
c0fff24e
DDO
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;
417be660 462 if (ret) {
c0fff24e
DDO
463 OPENSSL_free(data->param_hostname);
464 data->param_hostname = host;
465 OPENSSL_free(data->param_service);
466 data->param_service = service;
417be660
RL
467 BIO_ADDRINFO_free(data->addr_first);
468 data->addr_first = NULL;
469 data->addr_iter = NULL;
c0fff24e
DDO
470 } else {
471 OPENSSL_free(host);
472 OPENSSL_free(service);
417be660 473 }
c0fff24e 474 } else if (num == 3) { /* BIO_set_conn_ip_family */
417be660
RL
475 data->connect_family = *(int *)ptr;
476 } else {
477 ret = 0;
0f113f3e
MC
478 }
479 }
480 break;
481 case BIO_C_SET_NBIO:
417be660
RL
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;
0f113f3e
MC
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;
0f113f3e
MC
514 if (data->param_hostname)
515 BIO_set_conn_hostname(dbio, data->param_hostname);
417be660
RL
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);
0f113f3e
MC
520 /*
521 * FIXME: the cast of the function seems unlikely to be a good
522 * idea
523 */
fce78bd4 524 (void)BIO_set_info_callback(dbio, data->info_callback);
0f113f3e
MC
525 }
526 break;
527 case BIO_CTRL_SET_CALLBACK:
2722ff50 528 ret = 0; /* use callback ctrl */
0f113f3e
MC
529 break;
530 case BIO_CTRL_GET_CALLBACK:
531 {
fce78bd4 532 BIO_info_cb **fptr;
0f113f3e 533
fce78bd4 534 fptr = (BIO_info_cb **)ptr;
0f113f3e
MC
535 *fptr = data->info_callback;
536 }
537 break;
6d53ad6b
MC
538 case BIO_CTRL_EOF:
539 ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
540 break;
b1f79e7c
JB
541# ifndef OPENSSL_NO_KTLS
542 case BIO_CTRL_SET_KTLS:
4b09e192 543 crypto_info = (ktls_crypto_info_t *)ptr;
7f0f8824 544 ret = ktls_start(b->num, crypto_info, num);
b1f79e7c
JB
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);
550 case BIO_CTRL_GET_KTLS_RECV:
551 return BIO_should_ktls_flag(b, 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
0f113f3e
MC
562 default:
563 ret = 0;
564 break;
565 }
26a7d938 566 return ret;
0f113f3e 567}
d02b48c6 568
fce78bd4 569static long conn_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
0f113f3e
MC
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 {
fce78bd4 579 data->info_callback = fp;
0f113f3e
MC
580 }
581 break;
582 default:
583 ret = 0;
584 break;
585 }
26a7d938 586 return ret;
0f113f3e 587}
d3442bc7 588
0e1c0612 589static int conn_puts(BIO *bp, const char *str)
0f113f3e
MC
590{
591 int n, ret;
d02b48c6 592
0f113f3e
MC
593 n = strlen(str);
594 ret = conn_write(bp, str, n);
26a7d938 595 return ret;
0f113f3e 596}
d02b48c6 597
c45a48c1 598BIO *BIO_new_connect(const char *str)
0f113f3e
MC
599{
600 BIO *ret;
601
602 ret = BIO_new(BIO_s_connect());
603 if (ret == NULL)
26a7d938 604 return NULL;
0f113f3e 605 if (BIO_set_conn_hostname(ret, str))
26a7d938 606 return ret;
ca3a82c3 607 BIO_free(ret);
26a7d938 608 return NULL;
0f113f3e 609}
d02b48c6
RE
610
611#endif