aboutsummaryrefslogtreecommitdiff
path: root/crypto/bio
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/bio')
-rw-r--r--crypto/bio/bf_buff.c31
-rw-r--r--crypto/bio/bf_lbuf.c27
-rw-r--r--crypto/bio/bf_nbio.c17
-rw-r--r--crypto/bio/bf_null.c15
-rw-r--r--crypto/bio/bf_prefix.c207
-rw-r--r--crypto/bio/bf_readbuff.c291
-rw-r--r--crypto/bio/bio_addr.c (renamed from crypto/bio/b_addr.c)94
-rw-r--r--crypto/bio/bio_cb.c74
-rw-r--r--crypto/bio/bio_dump.c (renamed from crypto/bio/b_dump.c)37
-rw-r--r--crypto/bio/bio_err.c75
-rw-r--r--crypto/bio/bio_lib.c376
-rw-r--r--crypto/bio/bio_local.h13
-rw-r--r--crypto/bio/bio_meth.c8
-rw-r--r--crypto/bio/bio_print.c (renamed from crypto/bio/b_print.c)47
-rw-r--r--crypto/bio/bio_sock.c (renamed from crypto/bio/b_sock.c)106
-rw-r--r--crypto/bio/bio_sock2.c (renamed from crypto/bio/b_sock2.c)82
-rw-r--r--crypto/bio/bss_acpt.c51
-rw-r--r--crypto/bio/bss_bio.c28
-rw-r--r--crypto/bio/bss_conn.c120
-rw-r--r--crypto/bio/bss_core.c194
-rw-r--r--crypto/bio/bss_dgram.c178
-rw-r--r--crypto/bio/bss_fd.c12
-rw-r--r--crypto/bio/bss_file.c90
-rw-r--r--crypto/bio/bss_log.c11
-rw-r--r--crypto/bio/bss_mem.c45
-rw-r--r--crypto/bio/bss_null.c6
-rw-r--r--crypto/bio/bss_sock.c65
-rw-r--r--crypto/bio/build.info20
-rw-r--r--crypto/bio/ossl_core_bio.c124
29 files changed, 1809 insertions, 635 deletions
diff --git a/crypto/bio/bf_buff.c b/crypto/bio/bf_buff.c
index 51ae1f918d87..53bd02fe1416 100644
--- a/crypto/bio/bf_buff.c
+++ b/crypto/bio/bf_buff.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -25,10 +25,8 @@ static long buffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
static const BIO_METHOD methods_buffer = {
BIO_TYPE_BUFFER,
"buffer",
- /* TODO: Convert to new style write function */
bwrite_conv,
buffer_write,
- /* TODO: Convert to new style read function */
bread_conv,
buffer_read,
buffer_puts,
@@ -289,7 +287,9 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
break;
case BIO_C_SET_BUFF_READ_DATA:
if (num > ctx->ibuf_size) {
- p1 = OPENSSL_malloc((int)num);
+ if (num <= 0)
+ return 0;
+ p1 = OPENSSL_malloc((size_t)num);
if (p1 == NULL)
goto malloc_error;
OPENSSL_free(ctx->ibuf);
@@ -318,12 +318,14 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
p1 = ctx->ibuf;
p2 = ctx->obuf;
if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) {
- p1 = OPENSSL_malloc((int)num);
+ if (num <= 0)
+ return 0;
+ p1 = OPENSSL_malloc((size_t)num);
if (p1 == NULL)
goto malloc_error;
}
if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
- p2 = OPENSSL_malloc((int)num);
+ p2 = OPENSSL_malloc((size_t)num);
if (p2 == NULL) {
if (p1 != ctx->ibuf)
OPENSSL_free(p1);
@@ -381,8 +383,8 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
break;
case BIO_CTRL_DUP:
dbio = (BIO *)ptr;
- if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) ||
- !BIO_set_write_buffer_size(dbio, ctx->obuf_size))
+ if (BIO_set_read_buffer_size(dbio, ctx->ibuf_size) <= 0 ||
+ BIO_set_write_buffer_size(dbio, ctx->obuf_size) <= 0)
ret = 0;
break;
case BIO_CTRL_PEEK:
@@ -404,22 +406,15 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
}
return ret;
malloc_error:
- BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
static long buffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
- long ret = 1;
-
if (b->next_bio == NULL)
return 0;
- switch (cmd) {
- default:
- ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
- break;
- }
- return ret;
+ return BIO_callback_ctrl(b->next_bio, cmd, fp);
}
static int buffer_gets(BIO *b, char *buf, int size)
diff --git a/crypto/bio/bf_lbuf.c b/crypto/bio/bf_lbuf.c
index 72f9901813ea..6908e64d3652 100644
--- a/crypto/bio/bf_lbuf.c
+++ b/crypto/bio/bf_lbuf.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -30,10 +30,8 @@ static long linebuffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
static const BIO_METHOD methods_linebuffer = {
BIO_TYPE_LINEBUFFER,
"linebuffer",
- /* TODO: Convert to new style write function */
bwrite_conv,
linebuffer_write,
- /* TODO: Convert to new style read function */
bread_conv,
linebuffer_read,
linebuffer_puts,
@@ -60,12 +58,12 @@ static int linebuffer_new(BIO *bi)
BIO_LINEBUFFER_CTX *ctx;
if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL) {
- BIOerr(BIO_F_LINEBUFFER_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
ctx->obuf = OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE);
if (ctx->obuf == NULL) {
- BIOerr(BIO_F_LINEBUFFER_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ctx);
return 0;
}
@@ -232,10 +230,12 @@ static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
}
break;
case BIO_C_SET_BUFF_SIZE:
+ if (num > INT_MAX)
+ return 0;
obs = (int)num;
p = ctx->obuf;
if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) {
- p = OPENSSL_malloc((int)num);
+ p = OPENSSL_malloc((size_t)obs);
if (p == NULL)
goto malloc_error;
}
@@ -284,7 +284,7 @@ static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
break;
case BIO_CTRL_DUP:
dbio = (BIO *)ptr;
- if (!BIO_set_write_buffer_size(dbio, ctx->obuf_size))
+ if (BIO_set_write_buffer_size(dbio, ctx->obuf_size) <= 0)
ret = 0;
break;
default:
@@ -295,22 +295,15 @@ static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
}
return ret;
malloc_error:
- BIOerr(BIO_F_LINEBUFFER_CTRL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
static long linebuffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
- long ret = 1;
-
if (b->next_bio == NULL)
return 0;
- switch (cmd) {
- default:
- ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
- break;
- }
- return ret;
+ return BIO_callback_ctrl(b->next_bio, cmd, fp);
}
static int linebuffer_gets(BIO *b, char *buf, int size)
diff --git a/crypto/bio/bf_nbio.c b/crypto/bio/bf_nbio.c
index dd7011ab669f..f9ea1730ba31 100644
--- a/crypto/bio/bf_nbio.c
+++ b/crypto/bio/bf_nbio.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -34,10 +34,8 @@ typedef struct nbio_test_st {
static const BIO_METHOD methods_nbiof = {
BIO_TYPE_NBIO_TEST,
"non-blocking IO test filter",
- /* TODO: Convert to new style write function */
bwrite_conv,
nbiof_write,
- /* TODO: Convert to new style read function */
bread_conv,
nbiof_read,
nbiof_puts,
@@ -58,7 +56,7 @@ static int nbiof_new(BIO *bi)
NBIO_TEST *nt;
if ((nt = OPENSSL_zalloc(sizeof(*nt))) == NULL) {
- BIOerr(BIO_F_NBIOF_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
nt->lrn = -1;
@@ -173,16 +171,9 @@ static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
static long nbiof_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
- long ret = 1;
-
if (b->next_bio == NULL)
return 0;
- switch (cmd) {
- default:
- ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
- break;
- }
- return ret;
+ return BIO_callback_ctrl(b->next_bio, cmd, fp);
}
static int nbiof_gets(BIO *bp, char *buf, int size)
diff --git a/crypto/bio/bf_null.c b/crypto/bio/bf_null.c
index 48c6be692a5d..7add76a4ca5c 100644
--- a/crypto/bio/bf_null.c
+++ b/crypto/bio/bf_null.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -25,10 +25,8 @@ static long nullf_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
static const BIO_METHOD methods_nullf = {
BIO_TYPE_NULL_FILTER,
"NULL filter",
- /* TODO: Convert to new style write function */
bwrite_conv,
nullf_write,
- /* TODO: Convert to new style read function */
bread_conv,
nullf_read,
nullf_puts,
@@ -95,16 +93,9 @@ static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
static long nullf_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
- long ret = 1;
-
if (b->next_bio == NULL)
return 0;
- switch (cmd) {
- default:
- ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
- break;
- }
- return ret;
+ return BIO_callback_ctrl(b->next_bio, cmd, fp);
}
static int nullf_gets(BIO *bp, char *buf, int size)
diff --git a/crypto/bio/bf_prefix.c b/crypto/bio/bf_prefix.c
new file mode 100644
index 000000000000..872efa13b559
--- /dev/null
+++ b/crypto/bio/bf_prefix.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "bio_local.h"
+
+static int prefix_write(BIO *b, const char *out, size_t outl,
+ size_t *numwritten);
+static int prefix_read(BIO *b, char *buf, size_t size, size_t *numread);
+static int prefix_puts(BIO *b, const char *str);
+static int prefix_gets(BIO *b, char *str, int size);
+static long prefix_ctrl(BIO *b, int cmd, long arg1, void *arg2);
+static int prefix_create(BIO *b);
+static int prefix_destroy(BIO *b);
+static long prefix_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp);
+
+static const BIO_METHOD prefix_meth = {
+ BIO_TYPE_BUFFER,
+ "prefix",
+ prefix_write,
+ NULL,
+ prefix_read,
+ NULL,
+ prefix_puts,
+ prefix_gets,
+ prefix_ctrl,
+ prefix_create,
+ prefix_destroy,
+ prefix_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_prefix(void)
+{
+ return &prefix_meth;
+}
+
+typedef struct prefix_ctx_st {
+ char *prefix; /* Text prefix, given by user */
+ unsigned int indent; /* Indentation amount, given by user */
+
+ int linestart; /* flag to indicate we're at the line start */
+} PREFIX_CTX;
+
+static int prefix_create(BIO *b)
+{
+ PREFIX_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+ if (ctx == NULL)
+ return 0;
+
+ ctx->prefix = NULL;
+ ctx->indent = 0;
+ ctx->linestart = 1;
+ BIO_set_data(b, ctx);
+ BIO_set_init(b, 1);
+ return 1;
+}
+
+static int prefix_destroy(BIO *b)
+{
+ PREFIX_CTX *ctx = BIO_get_data(b);
+
+ OPENSSL_free(ctx->prefix);
+ OPENSSL_free(ctx);
+ return 1;
+}
+
+static int prefix_read(BIO *b, char *in, size_t size, size_t *numread)
+{
+ return BIO_read_ex(BIO_next(b), in, size, numread);
+}
+
+static int prefix_write(BIO *b, const char *out, size_t outl,
+ size_t *numwritten)
+{
+ PREFIX_CTX *ctx = BIO_get_data(b);
+
+ if (ctx == NULL)
+ return 0;
+
+ /*
+ * If no prefix is set or if it's empty, and no indentation amount is set,
+ * we've got nothing to do here
+ */
+ if ((ctx->prefix == NULL || *ctx->prefix == '\0')
+ && ctx->indent == 0) {
+ /*
+ * We do note if what comes next will be a new line, though, so we're
+ * prepared to handle prefix and indentation the next time around.
+ */
+ if (outl > 0)
+ ctx->linestart = (out[outl-1] == '\n');
+ return BIO_write_ex(BIO_next(b), out, outl, numwritten);
+ }
+
+ *numwritten = 0;
+
+ while (outl > 0) {
+ size_t i;
+ char c;
+
+ /*
+ * If we know that we're at the start of the line, output prefix and
+ * indentation.
+ */
+ if (ctx->linestart) {
+ size_t dontcare;
+
+ if (ctx->prefix != NULL
+ && !BIO_write_ex(BIO_next(b), ctx->prefix, strlen(ctx->prefix),
+ &dontcare))
+ return 0;
+ BIO_printf(BIO_next(b), "%*s", ctx->indent, "");
+ ctx->linestart = 0;
+ }
+
+ /* Now, go look for the next LF, or the end of the string */
+ for (i = 0, c = '\0'; i < outl && (c = out[i]) != '\n'; i++)
+ continue;
+ if (c == '\n')
+ i++;
+
+ /* Output what we found so far */
+ while (i > 0) {
+ size_t num = 0;
+
+ if (!BIO_write_ex(BIO_next(b), out, i, &num))
+ return 0;
+ out += num;
+ outl -= num;
+ *numwritten += num;
+ i -= num;
+ }
+
+ /* If we found a LF, what follows is a new line, so take note */
+ if (c == '\n')
+ ctx->linestart = 1;
+ }
+
+ return 1;
+}
+
+static long prefix_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 0;
+ PREFIX_CTX *ctx;
+
+ if (b == NULL || (ctx = BIO_get_data(b)) == NULL)
+ return -1;
+
+ switch (cmd) {
+ case BIO_CTRL_SET_PREFIX:
+ OPENSSL_free(ctx->prefix);
+ if (ptr == NULL) {
+ ctx->prefix = NULL;
+ ret = 1;
+ } else {
+ ctx->prefix = OPENSSL_strdup((const char *)ptr);
+ ret = ctx->prefix != NULL;
+ }
+ break;
+ case BIO_CTRL_SET_INDENT:
+ if (num >= 0) {
+ ctx->indent = (unsigned int)num;
+ ret = 1;
+ }
+ break;
+ case BIO_CTRL_GET_INDENT:
+ ret = (long)ctx->indent;
+ break;
+ default:
+ /* Commands that we intercept before passing them along */
+ switch (cmd) {
+ case BIO_C_FILE_SEEK:
+ case BIO_CTRL_RESET:
+ ctx->linestart = 1;
+ break;
+ }
+ if (BIO_next(b) != NULL)
+ ret = BIO_ctrl(BIO_next(b), cmd, num, ptr);
+ break;
+ }
+ return ret;
+}
+
+static long prefix_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
+{
+ return BIO_callback_ctrl(BIO_next(b), cmd, fp);
+}
+
+static int prefix_gets(BIO *b, char *buf, int size)
+{
+ return BIO_gets(BIO_next(b), buf, size);
+}
+
+static int prefix_puts(BIO *b, const char *str)
+{
+ return BIO_write(b, str, strlen(str));
+}
diff --git a/crypto/bio/bf_readbuff.c b/crypto/bio/bf_readbuff.c
new file mode 100644
index 000000000000..2409c9db97cc
--- /dev/null
+++ b/crypto/bio/bf_readbuff.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * This is a read only BIO filter that can be used to add BIO_tell() and
+ * BIO_seek() support to source/sink BIO's (such as a file BIO that uses stdin).
+ * It does this by caching ALL data read from the BIO source/sink into a
+ * resizable memory buffer.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "bio_local.h"
+#include "internal/cryptlib.h"
+
+#define DEFAULT_BUFFER_SIZE 4096
+
+static int readbuffer_write(BIO *h, const char *buf, int num);
+static int readbuffer_read(BIO *h, char *buf, int size);
+static int readbuffer_puts(BIO *h, const char *str);
+static int readbuffer_gets(BIO *h, char *str, int size);
+static long readbuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int readbuffer_new(BIO *h);
+static int readbuffer_free(BIO *data);
+static long readbuffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
+
+static const BIO_METHOD methods_readbuffer = {
+ BIO_TYPE_BUFFER,
+ "readbuffer",
+ bwrite_conv,
+ readbuffer_write,
+ bread_conv,
+ readbuffer_read,
+ readbuffer_puts,
+ readbuffer_gets,
+ readbuffer_ctrl,
+ readbuffer_new,
+ readbuffer_free,
+ readbuffer_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_readbuffer(void)
+{
+ return &methods_readbuffer;
+}
+
+static int readbuffer_new(BIO *bi)
+{
+ BIO_F_BUFFER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+ if (ctx == NULL)
+ return 0;
+ ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
+ ctx->ibuf = OPENSSL_zalloc(DEFAULT_BUFFER_SIZE);
+ if (ctx->ibuf == NULL) {
+ OPENSSL_free(ctx);
+ return 0;
+ }
+
+ bi->init = 1;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ return 1;
+}
+
+static int readbuffer_free(BIO *a)
+{
+ BIO_F_BUFFER_CTX *b;
+
+ if (a == NULL)
+ return 0;
+ b = (BIO_F_BUFFER_CTX *)a->ptr;
+ OPENSSL_free(b->ibuf);
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return 1;
+}
+
+static int readbuffer_resize(BIO_F_BUFFER_CTX *ctx, int sz)
+{
+ char *tmp;
+
+ /* Figure out how many blocks are required */
+ sz += (ctx->ibuf_off + DEFAULT_BUFFER_SIZE - 1);
+ sz = DEFAULT_BUFFER_SIZE * (sz / DEFAULT_BUFFER_SIZE);
+
+ /* Resize if the buffer is not big enough */
+ if (sz > ctx->ibuf_size) {
+ tmp = OPENSSL_realloc(ctx->ibuf, sz);
+ if (tmp == NULL)
+ return 0;
+ ctx->ibuf = tmp;
+ ctx->ibuf_size = sz;
+ }
+ return 1;
+}
+
+static int readbuffer_read(BIO *b, char *out, int outl)
+{
+ int i, num = 0;
+ BIO_F_BUFFER_CTX *ctx;
+
+ if (out == NULL || outl == 0)
+ return 0;
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return 0;
+ BIO_clear_retry_flags(b);
+
+ for (;;) {
+ i = ctx->ibuf_len;
+ /* If there is something in the buffer just read it. */
+ if (i != 0) {
+ if (i > outl)
+ i = outl;
+ memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i);
+ ctx->ibuf_off += i;
+ ctx->ibuf_len -= i;
+ num += i;
+ /* Exit if we have read the bytes required out of the buffer */
+ if (outl == i)
+ return num;
+ outl -= i;
+ out += i;
+ }
+
+ /* Only gets here if the buffer has been consumed */
+ if (!readbuffer_resize(ctx, outl))
+ return 0;
+
+ /* Do some buffering by reading from the next bio */
+ i = BIO_read(b->next_bio, ctx->ibuf + ctx->ibuf_off, outl);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ else
+ return num; /* i == 0 */
+ }
+ ctx->ibuf_len = i;
+ }
+}
+
+static int readbuffer_write(BIO *b, const char *in, int inl)
+{
+ return 0;
+}
+static int readbuffer_puts(BIO *b, const char *str)
+{
+ return 0;
+}
+
+static long readbuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO_F_BUFFER_CTX *ctx;
+ long ret = 1, sz;
+
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_EOF:
+ if (ctx->ibuf_len > 0)
+ return 0;
+ if (b->next_bio == NULL)
+ return 1;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+
+ case BIO_C_FILE_SEEK:
+ case BIO_CTRL_RESET:
+ sz = ctx->ibuf_off + ctx->ibuf_len;
+ /* Assume it can only seek backwards */
+ if (num < 0 || num > sz)
+ return 0;
+ ctx->ibuf_off = num;
+ ctx->ibuf_len = sz - num;
+ break;
+
+ case BIO_C_FILE_TELL:
+ case BIO_CTRL_INFO:
+ ret = (long)ctx->ibuf_off;
+ break;
+ case BIO_CTRL_PENDING:
+ ret = (long)ctx->ibuf_len;
+ if (ret == 0) {
+ if (b->next_bio == NULL)
+ return 0;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static long readbuffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
+{
+ if (b->next_bio == NULL)
+ return 0;
+ return BIO_callback_ctrl(b->next_bio, cmd, fp);
+}
+
+static int readbuffer_gets(BIO *b, char *buf, int size)
+{
+ BIO_F_BUFFER_CTX *ctx;
+ int num = 0, num_chars, found_newline;
+ char *p;
+ int i, j;
+
+ if (buf == NULL || size == 0)
+ return 0;
+ --size; /* the passed in size includes the terminator - so remove it here */
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+ if (ctx == NULL || b->next_bio == NULL)
+ return 0;
+ BIO_clear_retry_flags(b);
+
+ /* If data is already buffered then use this first */
+ if (ctx->ibuf_len > 0) {
+ p = ctx->ibuf + ctx->ibuf_off;
+ found_newline = 0;
+ for (num_chars = 0;
+ (num_chars < ctx->ibuf_len) && (num_chars < size);
+ num_chars++) {
+ *buf++ = p[num_chars];
+ if (p[num_chars] == '\n') {
+ found_newline = 1;
+ num_chars++;
+ break;
+ }
+ }
+ num += num_chars;
+ size -= num_chars;
+ ctx->ibuf_len -= num_chars;
+ ctx->ibuf_off += num_chars;
+ if (found_newline || size == 0) {
+ *buf = '\0';
+ return num;
+ }
+ }
+ /*
+ * If there is no buffered data left then read any remaining data from the
+ * next bio.
+ */
+
+ /* Resize if we have to */
+ if (!readbuffer_resize(ctx, 1 + size))
+ return 0;
+ /*
+ * Read more data from the next bio using BIO_read_ex:
+ * Note we cannot use BIO_gets() here as it does not work on a
+ * binary stream that contains 0x00. (Since strlen() will stop at
+ * any 0x00 not at the last read '\n' in a FILE bio).
+ * Also note that some applications open and close the file bio
+ * multiple times and need to read the next available block when using
+ * stdin - so we need to READ one byte at a time!
+ */
+ p = ctx->ibuf + ctx->ibuf_off;
+ for (i = 0; i < size; ++i) {
+ j = BIO_read(b->next_bio, p, 1);
+ if (j <= 0) {
+ BIO_copy_next_retry(b);
+ *buf = '\0';
+ return num > 0 ? num : j;
+ }
+ *buf++ = *p;
+ num++;
+ ctx->ibuf_off++;
+ if (*p == '\n')
+ break;
+ ++p;
+ }
+ *buf = '\0';
+ return num;
+}
diff --git a/crypto/bio/b_addr.c b/crypto/bio/bio_addr.c
index 0af7a330bc68..d462f424d3a4 100644
--- a/crypto/bio/b_addr.c
+++ b/crypto/bio/bio_addr.c
@@ -1,7 +1,7 @@
/*
- * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -11,6 +11,16 @@
# define _GNU_SOURCE
#endif
+/*
+ * VC configurations may define UNICODE, to indicate to the C RTL that
+ * WCHAR functions are preferred.
+ * This affects functions like gai_strerror(), which is implemented as
+ * an alias macro for gai_strerrorA() (which returns a const char *) or
+ * gai_strerrorW() (which returns a const WCHAR *). This source file
+ * assumes POSIX declarations, so prefer the non-UNICODE definitions.
+ */
+#undef UNICODE
+
#include <assert.h>
#include <string.h>
@@ -44,7 +54,7 @@ BIO_ADDR *BIO_ADDR_new(void)
BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
- BIOerr(BIO_F_BIO_ADDR_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -211,13 +221,12 @@ static int addr_strings(const BIO_ADDR *ap, int numeric,
flags)) != 0) {
# ifdef EAI_SYSTEM
if (ret == EAI_SYSTEM) {
- SYSerr(SYS_F_GETNAMEINFO, get_last_socket_error());
- BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling getnameinfo()");
} else
# endif
{
- BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
- ERR_add_error_data(1, gai_strerror(ret));
+ ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB, gai_strerror(ret));
}
return 0;
}
@@ -258,7 +267,7 @@ static int addr_strings(const BIO_ADDR *ap, int numeric,
OPENSSL_free(*service);
*service = NULL;
}
- BIOerr(BIO_F_ADDR_STRINGS, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -538,20 +547,25 @@ int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
*service = NULL;
} else {
*service = OPENSSL_strndup(p, pl);
- if (*service == NULL)
+ if (*service == NULL) {
+ if (h != NULL && host != NULL) {
+ OPENSSL_free(*host);
+ *host = NULL;
+ }
goto memerr;
+ }
}
}
return 1;
amb_err:
- BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_AMBIGUOUS_HOST_OR_SERVICE);
+ ERR_raise(ERR_LIB_BIO, BIO_R_AMBIGUOUS_HOST_OR_SERVICE);
return 0;
spec_err:
- BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_MALFORMED_HOST_OR_SERVICE);
+ ERR_raise(ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE);
return 0;
memerr:
- BIOerr(BIO_F_BIO_PARSE_HOSTSERV, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -570,7 +584,7 @@ static int addrinfo_wrap(int family, int socktype,
BIO_ADDRINFO **bai)
{
if ((*bai = OPENSSL_zalloc(sizeof(**bai))) == NULL) {
- BIOerr(BIO_F_ADDRINFO_WRAP, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -607,8 +621,6 @@ static int addrinfo_wrap(int family, int socktype,
DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init)
{
- if (!OPENSSL_init_crypto(0, NULL))
- return 0;
bio_lookup_lock = CRYPTO_THREAD_lock_new();
return bio_lookup_lock != NULL;
}
@@ -621,8 +633,8 @@ int BIO_lookup(const char *host, const char *service,
}
/*-
- * BIO_lookup_ex - look up the node and service you want to connect to.
- * @node: the node you want to connect to.
+ * BIO_lookup_ex - look up the host and service you want to connect to.
+ * @host: the host (or node, in case family == AF_UNIX) you want to connect to.
* @service: the service you want to connect to.
* @lookup_type: declare intent with the result, client or server.
* @family: the address family you want to use. Use AF_UNSPEC for any, or
@@ -635,7 +647,7 @@ int BIO_lookup(const char *host, const char *service,
* with 0 for the protocol)
* @res: Storage place for the resulting list of returned addresses
*
- * This will do a lookup of the node and service that you want to connect to.
+ * This will do a lookup of the host and service that you want to connect to.
* It returns a linked list of different addresses you can try to connect to.
*
* When no longer needed you should call BIO_ADDRINFO_free() to free the result.
@@ -660,7 +672,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
#endif
break;
default:
- BIOerr(BIO_F_BIO_LOOKUP_EX, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY);
return 0;
}
@@ -669,7 +681,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res))
return 1;
else
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
#endif
@@ -706,13 +718,14 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
# ifdef EAI_SYSTEM
case EAI_SYSTEM:
- SYSerr(SYS_F_GETADDRINFO, get_last_socket_error());
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling getaddrinfo()");
+ ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB);
break;
# endif
# ifdef EAI_MEMORY
case EAI_MEMORY:
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
break;
# endif
case 0:
@@ -727,8 +740,8 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
goto retry;
}
# endif
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB);
- ERR_add_error_data(1, gai_strerror(old_ret ? old_ret : gai_ret));
+ ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
+ gai_strerror(old_ret ? old_ret : gai_ret));
break;
}
} else {
@@ -769,12 +782,13 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
#endif
if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) {
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
- ret = 0;
- goto err;
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
+ return 0;
}
- CRYPTO_THREAD_write_lock(bio_lookup_lock);
+ if (!CRYPTO_THREAD_write_lock(bio_lookup_lock))
+ return 0;
+
he_fallback_address = INADDR_ANY;
if (host == NULL) {
he = &he_fallback;
@@ -788,7 +802,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
default:
/* We forgot to handle a lookup type! */
assert("We forgot to handle a lookup type!" == NULL);
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR);
ret = 0;
goto err;
}
@@ -810,12 +824,15 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
*/
# if defined(OPENSSL_SYS_VXWORKS)
/* h_errno doesn't exist on VxWorks */
- SYSerr(SYS_F_GETHOSTBYNAME, 1000 );
+ ERR_raise_data(ERR_LIB_SYS, 1000,
+ "calling gethostbyname()");
# else
- SYSerr(SYS_F_GETHOSTBYNAME, 1000 + h_errno);
+ ERR_raise_data(ERR_LIB_SYS, 1000 + h_errno,
+ "calling gethostbyname()");
# endif
#else
- SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError());
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling gethostbyname()");
#endif
ret = 0;
goto err;
@@ -861,15 +878,12 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
se = getservbyname(service, proto);
if (se == NULL) {
-#ifndef OPENSSL_SYS_WINDOWS
- SYSerr(SYS_F_GETSERVBYNAME, errno);
-#else
- SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError());
-#endif
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling getservbyname()");
goto err;
}
} else {
- BIOerr(BIO_F_BIO_LOOKUP_EX, BIO_R_MALFORMED_HOST_OR_SERVICE);
+ ERR_raise(ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE);
goto err;
}
}
@@ -911,7 +925,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
addrinfo_malloc_err:
BIO_ADDRINFO_free(*res);
*res = NULL;
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
ret = 0;
goto err;
}
diff --git a/crypto/bio/bio_cb.c b/crypto/bio/bio_cb.c
index a153100a8825..522a05369dc7 100644
--- a/crypto/bio/bio_cb.c
+++ b/crypto/bio/bio_cb.c
@@ -1,12 +1,14 @@
/*
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
+#define OPENSSL_SUPPRESS_DEPRECATED
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -14,25 +16,25 @@
#include "internal/cryptlib.h"
#include <openssl/err.h>
-long BIO_debug_callback(BIO *bio, int cmd, const char *argp,
- int argi, long argl, long ret)
+long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len,
+ int argi, long argl, int ret, size_t *processed)
{
BIO *b;
char buf[256];
char *p;
- long r = 1;
- int len, left;
+ int left;
+ size_t l = 0;
- if (BIO_CB_RETURN & cmd)
- r = ret;
+ if (processed != NULL)
+ l = *processed;
- len = BIO_snprintf(buf, sizeof(buf), "BIO[%p]: ", (void *)bio);
+ left = BIO_snprintf(buf, sizeof(buf), "BIO[%p]: ", (void *)bio);
/* Ignore errors and continue printing the other information. */
- if (len < 0)
- len = 0;
- p = buf + len;
- left = sizeof(buf) - len;
+ if (left < 0)
+ left = 0;
+ p = buf + left;
+ left = sizeof(buf) - left;
switch (cmd) {
case BIO_CB_FREE:
@@ -40,47 +42,47 @@ long BIO_debug_callback(BIO *bio, int cmd, const char *argp,
break;
case BIO_CB_READ:
if (bio->method->type & BIO_TYPE_DESCRIPTOR)
- BIO_snprintf(p, left, "read(%d,%lu) - %s fd=%d\n",
- bio->num, (unsigned long)argi,
+ BIO_snprintf(p, left, "read(%d,%zu) - %s fd=%d\n",
+ bio->num, len,
bio->method->name, bio->num);
else
- BIO_snprintf(p, left, "read(%d,%lu) - %s\n",
- bio->num, (unsigned long)argi, bio->method->name);
+ BIO_snprintf(p, left, "read(%d,%zu) - %s\n",
+ bio->num, len, bio->method->name);
break;
case BIO_CB_WRITE:
if (bio->method->type & BIO_TYPE_DESCRIPTOR)
- BIO_snprintf(p, left, "write(%d,%lu) - %s fd=%d\n",
- bio->num, (unsigned long)argi,
+ BIO_snprintf(p, left, "write(%d,%zu) - %s fd=%d\n",
+ bio->num, len,
bio->method->name, bio->num);
else
- BIO_snprintf(p, left, "write(%d,%lu) - %s\n",
- bio->num, (unsigned long)argi, bio->method->name);
+ BIO_snprintf(p, left, "write(%d,%zu) - %s\n",
+ bio->num, len, bio->method->name);
break;
case BIO_CB_PUTS:
BIO_snprintf(p, left, "puts() - %s\n", bio->method->name);
break;
case BIO_CB_GETS:
- BIO_snprintf(p, left, "gets(%lu) - %s\n", (unsigned long)argi,
+ BIO_snprintf(p, left, "gets(%zu) - %s\n", len,
bio->method->name);
break;
case BIO_CB_CTRL:
- BIO_snprintf(p, left, "ctrl(%lu) - %s\n", (unsigned long)argi,
+ BIO_snprintf(p, left, "ctrl(%d) - %s\n", argi,
bio->method->name);
break;
case BIO_CB_RETURN | BIO_CB_READ:
- BIO_snprintf(p, left, "read return %ld\n", ret);
+ BIO_snprintf(p, left, "read return %d processed: %zu\n", ret, l);
break;
case BIO_CB_RETURN | BIO_CB_WRITE:
- BIO_snprintf(p, left, "write return %ld\n", ret);
+ BIO_snprintf(p, left, "write return %d processed: %zu\n", ret, l);
break;
case BIO_CB_RETURN | BIO_CB_GETS:
- BIO_snprintf(p, left, "gets return %ld\n", ret);
+ BIO_snprintf(p, left, "gets return %d processed: %zu\n", ret, l);
break;
case BIO_CB_RETURN | BIO_CB_PUTS:
- BIO_snprintf(p, left, "puts return %ld\n", ret);
+ BIO_snprintf(p, left, "puts return %d processed: %zu\n", ret, l);
break;
case BIO_CB_RETURN | BIO_CB_CTRL:
- BIO_snprintf(p, left, "ctrl return %ld\n", ret);
+ BIO_snprintf(p, left, "ctrl return %d\n", ret);
break;
default:
BIO_snprintf(p, left, "bio callback - unknown type (%d)\n", cmd);
@@ -94,5 +96,19 @@ long BIO_debug_callback(BIO *bio, int cmd, const char *argp,
else
fputs(buf, stderr);
#endif
- return r;
+ return ret;
+}
+
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+long BIO_debug_callback(BIO *bio, int cmd, const char *argp,
+ int argi, long argl, long ret)
+{
+ size_t processed = 0;
+
+ if (ret > 0)
+ processed = (size_t)ret;
+ BIO_debug_callback_ex(bio, cmd, argp, (size_t)argi,
+ argi, argl, ret > 0 ? 1 : (int)ret, &processed);
+ return ret;
}
+#endif
diff --git a/crypto/bio/b_dump.c b/crypto/bio/bio_dump.c
index f175e244b233..04191a653054 100644
--- a/crypto/bio/b_dump.c
+++ b/crypto/bio/bio_dump.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -20,15 +20,16 @@
#define SPACE(buf, pos, n) (sizeof(buf) - (pos) > (n))
int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
- void *u, const char *s, int len)
+ void *u, const void *s, int len)
{
return BIO_dump_indent_cb(cb, u, s, len, 0);
}
int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
- void *u, const char *s, int len, int indent)
+ void *u, const void *v, int len, int indent)
{
- int ret = 0;
+ const unsigned char *s = v;
+ int res, ret = 0;
char buf[288 + 1];
int i, j, rows, n;
unsigned char ch;
@@ -46,12 +47,14 @@ int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
for (i = 0; i < rows; i++) {
n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "",
i * dump_width);
+ if (n < 0)
+ return -1;
for (j = 0; j < dump_width; j++) {
if (SPACE(buf, n, 3)) {
if (((i * dump_width) + j) >= len) {
strcpy(buf + n, " ");
} else {
- ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
+ ch = *(s + i * dump_width + j) & 0xff;
BIO_snprintf(buf + n, 4, "%02x%c", ch,
j == 7 ? '-' : ' ');
}
@@ -66,7 +69,7 @@ int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
if (((i * dump_width) + j) >= len)
break;
if (SPACE(buf, n, 1)) {
- ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
+ ch = *(s + i * dump_width + j) & 0xff;
#ifndef CHARSET_EBCDIC
buf[n++] = ((ch >= ' ') && (ch <= '~')) ? ch : '.';
#else
@@ -85,7 +88,10 @@ int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
* if this is the last call then update the ddt_dump thing so that we
* will move the selection point in the debug window
*/
- ret += cb((void *)buf, n, u);
+ res = cb((void *)buf, n, u);
+ if (res < 0)
+ return res;
+ ret += res;
}
return ret;
}
@@ -96,12 +102,12 @@ static int write_fp(const void *data, size_t len, void *fp)
return UP_fwrite(data, len, 1, fp);
}
-int BIO_dump_fp(FILE *fp, const char *s, int len)
+int BIO_dump_fp(FILE *fp, const void *s, int len)
{
return BIO_dump_cb(write_fp, fp, s, len);
}
-int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
+int BIO_dump_indent_fp(FILE *fp, const void *s, int len, int indent)
{
return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
}
@@ -112,19 +118,20 @@ static int write_bio(const void *data, size_t len, void *bp)
return BIO_write((BIO *)bp, (const char *)data, len);
}
-int BIO_dump(BIO *bp, const char *s, int len)
+int BIO_dump(BIO *bp, const void *s, int len)
{
return BIO_dump_cb(write_bio, bp, s, len);
}
-int BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
+int BIO_dump_indent(BIO *bp, const void *s, int len, int indent)
{
return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
}
-int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
+int BIO_hex_string(BIO *out, int indent, int width, const void *data,
int datalen)
{
+ const unsigned char *d = data;
int i, j = 0;
if (datalen < 1)
@@ -134,7 +141,7 @@ int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
if (i && !j)
BIO_printf(out, "%*s", indent, "");
- BIO_printf(out, "%02X:", data[i]);
+ BIO_printf(out, "%02X:", d[i]);
j = (j + 1) % width;
if (!j)
@@ -143,6 +150,6 @@ int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
if (i && !j)
BIO_printf(out, "%*s", indent, "");
- BIO_printf(out, "%02X", data[datalen - 1]);
+ BIO_printf(out, "%02X", d[datalen - 1]);
return 1;
}
diff --git a/crypto/bio/bio_err.c b/crypto/bio/bio_err.c
index 7aa9dabb2915..7a36c61148a7 100644
--- a/crypto/bio/bio_err.c
+++ b/crypto/bio/bio_err.c
@@ -1,8 +1,8 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -10,69 +10,10 @@
#include <openssl/err.h>
#include <openssl/bioerr.h>
+#include "crypto/bioerr.h"
#ifndef OPENSSL_NO_ERR
-static const ERR_STRING_DATA BIO_str_functs[] = {
- {ERR_PACK(ERR_LIB_BIO, BIO_F_ACPT_STATE, 0), "acpt_state"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_ADDRINFO_WRAP, 0), "addrinfo_wrap"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_ADDR_STRINGS, 0), "addr_strings"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT, 0), "BIO_accept"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT_EX, 0), "BIO_accept_ex"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT_NEW, 0), "BIO_ACCEPT_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ADDR_NEW, 0), "BIO_ADDR_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_BIND, 0), "BIO_bind"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CALLBACK_CTRL, 0), "BIO_callback_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CONNECT, 0), "BIO_connect"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CONNECT_NEW, 0), "BIO_CONNECT_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CTRL, 0), "BIO_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GETS, 0), "BIO_gets"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_HOST_IP, 0), "BIO_get_host_ip"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_NEW_INDEX, 0), "BIO_get_new_index"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_PORT, 0), "BIO_get_port"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LISTEN, 0), "BIO_listen"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LOOKUP, 0), "BIO_lookup"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LOOKUP_EX, 0), "BIO_lookup_ex"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_MAKE_PAIR, 0), "bio_make_pair"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_METH_NEW, 0), "BIO_meth_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW, 0), "BIO_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_DGRAM_SCTP, 0), "BIO_new_dgram_sctp"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_FILE, 0), "BIO_new_file"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_MEM_BUF, 0), "BIO_new_mem_buf"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NREAD, 0), "BIO_nread"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NREAD0, 0), "BIO_nread0"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NWRITE, 0), "BIO_nwrite"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NWRITE0, 0), "BIO_nwrite0"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_PARSE_HOSTSERV, 0), "BIO_parse_hostserv"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_PUTS, 0), "BIO_puts"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ, 0), "BIO_read"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ_EX, 0), "BIO_read_ex"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ_INTERN, 0), "bio_read_intern"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCKET, 0), "BIO_socket"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCKET_NBIO, 0), "BIO_socket_nbio"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCK_INFO, 0), "BIO_sock_info"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCK_INIT, 0), "BIO_sock_init"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE, 0), "BIO_write"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE_EX, 0), "BIO_write_ex"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE_INTERN, 0), "bio_write_intern"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BUFFER_CTRL, 0), "buffer_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_CONN_CTRL, 0), "conn_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_CONN_STATE, 0), "conn_state"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_NEW, 0), "dgram_sctp_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_READ, 0), "dgram_sctp_read"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_WRITE, 0), "dgram_sctp_write"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_DOAPR_OUTCH, 0), "doapr_outch"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_FILE_CTRL, 0), "file_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_FILE_READ, 0), "file_read"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_LINEBUFFER_CTRL, 0), "linebuffer_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_LINEBUFFER_NEW, 0), "linebuffer_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_MEM_WRITE, 0), "mem_write"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_NBIOF_NEW, 0), "nbiof_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_SLG_WRITE, 0), "slg_write"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_SSL_NEW, 0), "SSL_new"},
- {0, NULL}
-};
-
static const ERR_STRING_DATA BIO_str_reasons[] = {
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ACCEPT_ERROR), "accept error"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET),
@@ -82,6 +23,7 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BAD_FOPEN_MODE), "bad fopen mode"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BROKEN_PIPE), "broken pipe"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_ERROR), "connect error"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_TIMEOUT), "connect timeout"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),
"gethostbyname addr is not af inet"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETSOCKNAME_ERROR), "getsockname error"},
@@ -104,7 +46,8 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
"no hostname or service specified"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_DEFINED), "no port defined"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "no such file"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NULL_PARAMETER), "null parameter"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_ERROR), "transfer error"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_TIMEOUT), "transfer timeout"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_BIND_SOCKET),
"unable to bind socket"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_CREATE_SOCKET),
@@ -133,13 +76,11 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
#endif
-int ERR_load_BIO_strings(void)
+int ossl_err_load_BIO_strings(void)
{
#ifndef OPENSSL_NO_ERR
- if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) {
- ERR_load_strings_const(BIO_str_functs);
+ if (ERR_reason_error_string(BIO_str_reasons[0].error) == NULL)
ERR_load_strings_const(BIO_str_reasons);
- }
#endif
return 1;
}
diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c
index d2202e537b30..245a75afa1b8 100644
--- a/crypto/bio/bio_lib.c
+++ b/crypto/bio/bio_lib.c
@@ -1,26 +1,32 @@
/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
+#define OPENSSL_SUPPRESS_DEPRECATED
+
#include <stdio.h>
#include <errno.h>
#include <openssl/crypto.h>
+#include "internal/numbers.h"
#include "bio_local.h"
-#include "internal/cryptlib.h"
-
/*
* Helper macro for the callback to determine whether an operator expects a
* len parameter or not
*/
-#define HAS_LEN_OPER(o) ((o) == BIO_CB_READ || (o) == BIO_CB_WRITE || \
- (o) == BIO_CB_GETS)
+#define HAS_LEN_OPER(o) ((o) == BIO_CB_READ || (o) == BIO_CB_WRITE \
+ || (o) == BIO_CB_GETS)
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+# define HAS_CALLBACK(b) ((b)->callback != NULL || (b)->callback_ex != NULL)
+#else
+# define HAS_CALLBACK(b) ((b)->callback_ex != NULL)
+#endif
/*
* Helper function to work out whether to call the new style callback or the old
* one, and translate between the two.
@@ -29,14 +35,18 @@
* for the "long" used for "inret"
*/
static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len,
- int argi, long argl, long inret, size_t *processed)
+ int argi, long argl, long inret,
+ size_t *processed)
{
- long ret;
+ long ret = inret;
+#ifndef OPENSSL_NO_DEPRECATED_3_0
int bareoper;
if (b->callback_ex != NULL)
+#endif
return b->callback_ex(b, oper, argp, len, argi, argl, inret, processed);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
/* Strip off any BIO_CB_RETURN flag */
bareoper = oper & ~BIO_CB_RETURN;
@@ -64,19 +74,20 @@ static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len,
*processed = (size_t)ret;
ret = 1;
}
-
+#endif
return ret;
}
-BIO *BIO_new(const BIO_METHOD *method)
+BIO *BIO_new_ex(OSSL_LIB_CTX *libctx, const BIO_METHOD *method)
{
BIO *bio = OPENSSL_zalloc(sizeof(*bio));
if (bio == NULL) {
- BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return NULL;
}
+ bio->libctx = libctx;
bio->method = method;
bio->shutdown = 1;
bio->references = 1;
@@ -86,13 +97,13 @@ BIO *BIO_new(const BIO_METHOD *method)
bio->lock = CRYPTO_THREAD_lock_new();
if (bio->lock == NULL) {
- BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
goto err;
}
if (method->create != NULL && !method->create(bio)) {
- BIOerr(BIO_F_BIO_NEW, ERR_R_INIT_FAIL);
+ ERR_raise(ERR_LIB_BIO, ERR_R_INIT_FAIL);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
CRYPTO_THREAD_lock_free(bio->lock);
goto err;
@@ -107,6 +118,11 @@ err:
return NULL;
}
+BIO *BIO_new(const BIO_METHOD *method)
+{
+ return BIO_new_ex(NULL, method);
+}
+
int BIO_free(BIO *a)
{
int ret;
@@ -122,10 +138,10 @@ int BIO_free(BIO *a)
return 1;
REF_ASSERT_ISNT(ret < 0);
- if (a->callback != NULL || a->callback_ex != NULL) {
+ if (HAS_CALLBACK(a)) {
ret = (int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0, 0L, 1L, NULL);
if (ret <= 0)
- return ret;
+ return 0;
}
if ((a->method != NULL) && (a->method->destroy != NULL))
@@ -184,7 +200,7 @@ int BIO_up_ref(BIO *a)
REF_PRINT_COUNT("BIO", a);
REF_ASSERT_ISNT(i < 2);
- return ((i > 1) ? 1 : 0);
+ return i > 1;
}
void BIO_clear_flags(BIO *b, int flags)
@@ -202,6 +218,7 @@ void BIO_set_flags(BIO *b, int flags)
b->flags |= flags;
}
+#ifndef OPENSSL_NO_DEPRECATED_3_0
BIO_callback_fn BIO_get_callback(const BIO *b)
{
return b->callback;
@@ -211,6 +228,7 @@ void BIO_set_callback(BIO *b, BIO_callback_fn cb)
{
b->callback = cb;
}
+#endif
BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b)
{
@@ -252,19 +270,23 @@ static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes)
{
int ret;
- if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) {
- BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNSUPPORTED_METHOD);
+ if (b == NULL) {
+ ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+ if (b->method == NULL || b->method->bread == NULL) {
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
- if ((b->callback != NULL || b->callback_ex != NULL) &&
+ if (HAS_CALLBACK(b) &&
((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L,
NULL)) <= 0))
return ret;
if (!b->init) {
- BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNINITIALIZED);
- return -2;
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
+ return -1;
}
ret = b->method->bread(b, data, dlen, readbytes);
@@ -272,13 +294,13 @@ static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes)
if (ret > 0)
b->num_read += (uint64_t)*readbytes;
- if (b->callback != NULL || b->callback_ex != NULL)
+ if (HAS_CALLBACK(b))
ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, data,
dlen, 0, 0L, ret, readbytes);
/* Shouldn't happen */
if (ret > 0 && *readbytes > dlen) {
- BIOerr(BIO_F_BIO_READ_INTERN, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR);
return -1;
}
@@ -305,50 +327,50 @@ int BIO_read(BIO *b, void *data, int dlen)
int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes)
{
- int ret;
-
- ret = bio_read_intern(b, data, dlen, readbytes);
-
- if (ret > 0)
- ret = 1;
- else
- ret = 0;
-
- return ret;
+ return bio_read_intern(b, data, dlen, readbytes) > 0;
}
static int bio_write_intern(BIO *b, const void *data, size_t dlen,
size_t *written)
{
+ size_t local_written;
int ret;
+ if (written != NULL)
+ *written = 0;
+ /*
+ * b == NULL is not an error but just means that zero bytes are written.
+ * Do not raise an error here.
+ */
if (b == NULL)
return 0;
- if ((b->method == NULL) || (b->method->bwrite == NULL)) {
- BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNSUPPORTED_METHOD);
+ if (b->method == NULL || b->method->bwrite == NULL) {
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
- if ((b->callback != NULL || b->callback_ex != NULL) &&
+ if (HAS_CALLBACK(b) &&
((ret = (int)bio_call_callback(b, BIO_CB_WRITE, data, dlen, 0, 0L, 1L,
NULL)) <= 0))
return ret;
if (!b->init) {
- BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNINITIALIZED);
- return -2;
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
+ return -1;
}
- ret = b->method->bwrite(b, data, dlen, written);
+ ret = b->method->bwrite(b, data, dlen, &local_written);
if (ret > 0)
- b->num_write += (uint64_t)*written;
+ b->num_write += (uint64_t)local_written;
- if (b->callback != NULL || b->callback_ex != NULL)
+ if (HAS_CALLBACK(b))
ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, data,
- dlen, 0, 0L, ret, written);
+ dlen, 0, 0L, ret, &local_written);
+ if (written != NULL)
+ *written = local_written;
return ret;
}
@@ -357,13 +379,13 @@ int BIO_write(BIO *b, const void *data, int dlen)
size_t written;
int ret;
- if (dlen < 0)
+ if (dlen <= 0)
return 0;
ret = bio_write_intern(b, data, (size_t)dlen, &written);
if (ret > 0) {
- /* *written should always be <= dlen */
+ /* written should always be <= dlen */
ret = (int)written;
}
@@ -372,16 +394,8 @@ int BIO_write(BIO *b, const void *data, int dlen)
int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written)
{
- int ret;
-
- ret = bio_write_intern(b, data, dlen, written);
-
- if (ret > 0)
- ret = 1;
- else
- ret = 0;
-
- return ret;
+ return bio_write_intern(b, data, dlen, written) > 0
+ || (b != NULL && dlen == 0); /* order is important for *written */
}
int BIO_puts(BIO *b, const char *buf)
@@ -389,20 +403,24 @@ int BIO_puts(BIO *b, const char *buf)
int ret;
size_t written = 0;
- if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
- BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD);
+ if (b == NULL) {
+ ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+ if (b->method == NULL || b->method->bputs == NULL) {
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
- if (b->callback != NULL || b->callback_ex != NULL) {
+ if (HAS_CALLBACK(b)) {
ret = (int)bio_call_callback(b, BIO_CB_PUTS, buf, 0, 0, 0L, 1L, NULL);
if (ret <= 0)
return ret;
}
if (!b->init) {
- BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED);
- return -2;
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
+ return -1;
}
ret = b->method->bputs(b, buf);
@@ -413,13 +431,13 @@ int BIO_puts(BIO *b, const char *buf)
ret = 1;
}
- if (b->callback != NULL || b->callback_ex != NULL)
+ if (HAS_CALLBACK(b))
ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, buf, 0, 0,
0L, ret, &written);
if (ret > 0) {
if (written > INT_MAX) {
- BIOerr(BIO_F_BIO_PUTS, BIO_R_LENGTH_TOO_LONG);
+ ERR_raise(ERR_LIB_BIO, BIO_R_LENGTH_TOO_LONG);
ret = -1;
} else {
ret = (int)written;
@@ -434,25 +452,29 @@ int BIO_gets(BIO *b, char *buf, int size)
int ret;
size_t readbytes = 0;
- if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
- BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
+ if (b == NULL) {
+ ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+ if (b->method == NULL || b->method->bgets == NULL) {
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
if (size < 0) {
- BIOerr(BIO_F_BIO_GETS, BIO_R_INVALID_ARGUMENT);
- return 0;
+ ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
+ return -1;
}
- if (b->callback != NULL || b->callback_ex != NULL) {
+ if (HAS_CALLBACK(b)) {
ret = (int)bio_call_callback(b, BIO_CB_GETS, buf, size, 0, 0L, 1, NULL);
if (ret <= 0)
return ret;
}
if (!b->init) {
- BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
- return -2;
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
+ return -1;
}
ret = b->method->bgets(b, buf, size);
@@ -462,7 +484,7 @@ int BIO_gets(BIO *b, char *buf, int size)
ret = 1;
}
- if (b->callback != NULL || b->callback_ex != NULL)
+ if (HAS_CALLBACK(b))
ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, buf, size,
0, 0L, ret, &readbytes);
@@ -477,6 +499,37 @@ int BIO_gets(BIO *b, char *buf, int size)
return ret;
}
+int BIO_get_line(BIO *bio, char *buf, int size)
+{
+ int ret = 0;
+ char *ptr = buf;
+
+ if (buf == NULL) {
+ ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+ if (size <= 0) {
+ ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
+ return -1;
+ }
+ *buf = '\0';
+
+ if (bio == NULL) {
+ ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+ if (!bio->init) {
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
+ return -1;
+ }
+
+ while (size-- > 1 && (ret = BIO_read(bio, ptr, 1)) > 0)
+ if (*ptr++ == '\n')
+ break;
+ *ptr = '\0';
+ return ret > 0 || BIO_eof(bio) ? ptr - buf : ret;
+}
+
int BIO_indent(BIO *b, int indent, int max)
{
if (indent < 0)
@@ -512,14 +565,13 @@ long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
long ret;
if (b == NULL)
- return 0;
-
- if ((b->method == NULL) || (b->method->ctrl == NULL)) {
- BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
+ return -1;
+ if (b->method == NULL || b->method->ctrl == NULL) {
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
- if (b->callback != NULL || b->callback_ex != NULL) {
+ if (HAS_CALLBACK(b)) {
ret = bio_call_callback(b, BIO_CB_CTRL, parg, 0, cmd, larg, 1L, NULL);
if (ret <= 0)
return ret;
@@ -527,7 +579,7 @@ long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
ret = b->method->ctrl(b, cmd, larg, parg);
- if (b->callback != NULL || b->callback_ex != NULL)
+ if (HAS_CALLBACK(b))
ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, 0, cmd,
larg, ret, NULL);
@@ -539,15 +591,14 @@ long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
long ret;
if (b == NULL)
- return 0;
-
- if ((b->method == NULL) || (b->method->callback_ctrl == NULL)
- || (cmd != BIO_CTRL_SET_CALLBACK)) {
- BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD);
+ return -2;
+ if (b->method == NULL || b->method->callback_ctrl == NULL
+ || cmd != BIO_CTRL_SET_CALLBACK) {
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
- if (b->callback != NULL || b->callback_ex != NULL) {
+ if (HAS_CALLBACK(b)) {
ret = bio_call_callback(b, BIO_CB_CTRL, (void *)&fp, 0, cmd, 0, 1L,
NULL);
if (ret <= 0)
@@ -556,7 +607,7 @@ long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
ret = b->method->callback_ctrl(b, cmd, fp);
- if (b->callback != NULL || b->callback_ex != NULL)
+ if (HAS_CALLBACK(b))
ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, 0,
cmd, 0, ret, NULL);
@@ -570,12 +621,28 @@ long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
*/
size_t BIO_ctrl_pending(BIO *bio)
{
- return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
+ long ret = BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
+
+ if (ret < 0)
+ ret = 0;
+#if LONG_MAX > SIZE_MAX
+ if (ret > SIZE_MAX)
+ ret = SIZE_MAX;
+#endif
+ return (size_t)ret;
}
size_t BIO_ctrl_wpending(BIO *bio)
{
- return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
+ long ret = BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
+
+ if (ret < 0)
+ ret = 0;
+#if LONG_MAX > SIZE_MAX
+ if (ret > SIZE_MAX)
+ ret = SIZE_MAX;
+#endif
+ return (size_t)ret;
}
/* put the 'bio' on the end of b's list of operators */
@@ -649,8 +716,10 @@ BIO *BIO_find_type(BIO *bio, int type)
{
int mt, mask;
- if (bio == NULL)
+ if (bio == NULL) {
+ ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
+ }
mask = type & 0xff;
do {
if (bio->method != NULL) {
@@ -659,8 +728,9 @@ BIO *BIO_find_type(BIO *bio, int type)
if (!mask) {
if (mt & type)
return bio;
- } else if (mt == type)
+ } else if (mt == type) {
return bio;
+ }
}
bio = bio->next_bio;
} while (bio != NULL);
@@ -702,7 +772,9 @@ BIO *BIO_dup_chain(BIO *in)
for (bio = in; bio != NULL; bio = bio->next_bio) {
if ((new_bio = BIO_new(bio->method)) == NULL)
goto err;
+#ifndef OPENSSL_NO_DEPRECATED_3_0
new_bio->callback = bio->callback;
+#endif
new_bio->callback_ex = bio->callback_ex;
new_bio->cb_arg = bio->cb_arg;
new_bio->init = bio->init;
@@ -712,7 +784,7 @@ BIO *BIO_dup_chain(BIO *in)
/* This will let SSL_s_sock() work with stdin/stdout */
new_bio->num = bio->num;
- if (!BIO_dup_state(bio, (char *)new_bio)) {
+ if (BIO_dup_state(bio, (char *)new_bio) <= 0) {
BIO_free(new_bio);
goto err;
}
@@ -750,7 +822,7 @@ int BIO_set_ex_data(BIO *bio, int idx, void *data)
return CRYPTO_set_ex_data(&(bio->ex_data), idx, data);
}
-void *BIO_get_ex_data(BIO *bio, int idx)
+void *BIO_get_ex_data(const BIO *bio, int idx)
{
return CRYPTO_get_ex_data(&(bio->ex_data), idx);
}
@@ -784,3 +856,131 @@ void bio_cleanup(void)
CRYPTO_THREAD_lock_free(bio_type_lock);
bio_type_lock = NULL;
}
+
+/* Internal variant of the below BIO_wait() not calling BIOerr() */
+static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds)
+{
+#ifndef OPENSSL_NO_SOCK
+ int fd;
+#endif
+ long sec_diff;
+
+ if (max_time == 0) /* no timeout */
+ return 1;
+
+#ifndef OPENSSL_NO_SOCK
+ if (BIO_get_fd(bio, &fd) > 0) {
+ int ret = BIO_socket_wait(fd, BIO_should_read(bio), max_time);
+
+ if (ret != -1)
+ return ret;
+ }
+#endif
+ /* fall back to polling since no sockets are available */
+
+ sec_diff = (long)(max_time - time(NULL)); /* might overflow */
+ if (sec_diff < 0)
+ return 0; /* clearly timeout */
+
+ /* now take a nap at most the given number of milliseconds */
+ if (sec_diff == 0) { /* we are below the 1 seconds resolution of max_time */
+ if (nap_milliseconds > 1000)
+ nap_milliseconds = 1000;
+ } else { /* for sec_diff > 0, take min(sec_diff * 1000, nap_milliseconds) */
+ if ((unsigned long)sec_diff * 1000 < nap_milliseconds)
+ nap_milliseconds = (unsigned int)sec_diff * 1000;
+ }
+ ossl_sleep(nap_milliseconds);
+ return 1;
+}
+
+/*-
+ * Wait on (typically socket-based) BIO at most until max_time.
+ * Succeed immediately if max_time == 0.
+ * If sockets are not available support polling: succeed after waiting at most
+ * the number of nap_milliseconds in order to avoid a tight busy loop.
+ * Call BIOerr(...) on timeout or error.
+ * Returns -1 on error, 0 on timeout, and 1 on success.
+ */
+int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds)
+{
+ int rv = bio_wait(bio, max_time, nap_milliseconds);
+
+ if (rv <= 0)
+ ERR_raise(ERR_LIB_BIO,
+ rv == 0 ? BIO_R_TRANSFER_TIMEOUT : BIO_R_TRANSFER_ERROR);
+ return rv;
+}
+
+/*
+ * Connect via given BIO using BIO_do_connect() until success/timeout/error.
+ * Parameter timeout == 0 means no timeout, < 0 means exactly one try.
+ * For non-blocking and potentially even non-socket BIOs perform polling with
+ * the given density: between polls sleep nap_milliseconds using BIO_wait()
+ * in order to avoid a tight busy loop.
+ * Returns -1 on error, 0 on timeout, and 1 on success.
+ */
+int BIO_do_connect_retry(BIO *bio, int timeout, int nap_milliseconds)
+{
+ int blocking = timeout <= 0;
+ time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
+ int rv;
+
+ if (bio == NULL) {
+ ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+
+ if (nap_milliseconds < 0)
+ nap_milliseconds = 100;
+ BIO_set_nbio(bio, !blocking);
+
+ retry:
+ ERR_set_mark();
+ rv = BIO_do_connect(bio);
+
+ if (rv <= 0) { /* could be timeout or retryable error or fatal error */
+ int err = ERR_peek_last_error();
+ int reason = ERR_GET_REASON(err);
+ int do_retry = BIO_should_retry(bio); /* may be 1 only if !blocking */
+
+ if (ERR_GET_LIB(err) == ERR_LIB_BIO) {
+ switch (reason) {
+ case ERR_R_SYS_LIB:
+ /*
+ * likely retryable system error occurred, which may be
+ * EAGAIN (resource temporarily unavailable) some 40 secs after
+ * calling getaddrinfo(): Temporary failure in name resolution
+ * or a premature ETIMEDOUT, some 30 seconds after connect()
+ */
+ case BIO_R_CONNECT_ERROR:
+ case BIO_R_NBIO_CONNECT_ERROR:
+ /* some likely retryable connection error occurred */
+ (void)BIO_reset(bio); /* often needed to avoid retry failure */
+ do_retry = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ if (timeout >= 0 && do_retry) {
+ ERR_pop_to_mark();
+ /* will not actually wait if timeout == 0 (i.e., blocking BIO): */
+ rv = bio_wait(bio, max_time, nap_milliseconds);
+ if (rv > 0)
+ goto retry;
+ ERR_raise(ERR_LIB_BIO,
+ rv == 0 ? BIO_R_CONNECT_TIMEOUT : BIO_R_CONNECT_ERROR);
+ } else {
+ ERR_clear_last_mark();
+ rv = -1;
+ if (err == 0) /* missing error queue entry */
+ /* workaround: general error */
+ ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
+ }
+ } else {
+ ERR_clear_last_mark();
+ }
+
+ return rv;
+}
diff --git a/crypto/bio/bio_local.h b/crypto/bio/bio_local.h
index 8b2122129396..749e8f810c30 100644
--- a/crypto/bio/bio_local.h
+++ b/crypto/bio/bio_local.h
@@ -1,7 +1,7 @@
/*
- * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -9,7 +9,6 @@
#include "e_os.h"
#include "internal/sockets.h"
-#include "internal/refcount.h"
/* BEGIN BIO_ADDRINFO/BIO_ADDR stuff. */
@@ -30,7 +29,7 @@
# ifdef OSSL_INTERNAL_CRYPTLIB_H
# error internal/cryptlib.h included before bio_local.h
# endif
-# ifdef HEADER_BIO_H
+# ifdef OPENSSL_BIO_H
# error openssl/bio.h included before bio_local.h
# endif
@@ -88,6 +87,7 @@ union bio_addr_st {
#include "internal/cryptlib.h"
#include "internal/bio.h"
+#include "internal/refcount.h"
typedef struct bio_f_buffer_ctx_struct {
/*-
@@ -113,9 +113,12 @@ typedef struct bio_f_buffer_ctx_struct {
} BIO_F_BUFFER_CTX;
struct bio_st {
+ OSSL_LIB_CTX *libctx;
const BIO_METHOD *method;
/* bio, mode, argp, argi, argl, ret */
+#ifndef OPENSSL_NO_DEPRECATED_3_0
BIO_callback_fn callback;
+#endif
BIO_callback_fn_ex callback_ex;
char *cb_arg; /* first argument for the callback */
int init;
@@ -152,7 +155,7 @@ extern CRYPTO_RWLOCK *bio_type_lock;
void bio_sock_cleanup_int(void);
-#if BIO_FLAGS_UPLINK==0
+#if BIO_FLAGS_UPLINK_INTERNAL==0
/* Shortcut UPLINK calls on most platforms... */
# define UP_stdin stdin
# define UP_stdout stdout
diff --git a/crypto/bio/bio_meth.c b/crypto/bio/bio_meth.c
index da116461922e..469715ba09eb 100644
--- a/crypto/bio/bio_meth.c
+++ b/crypto/bio/bio_meth.c
@@ -1,7 +1,7 @@
/*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -25,7 +25,7 @@ int BIO_get_new_index(void)
int newval;
if (!RUN_ONCE(&bio_type_init, do_bio_type_init)) {
- BIOerr(BIO_F_BIO_GET_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return -1;
}
if (!CRYPTO_UP_REF(&bio_count, &newval, bio_type_lock))
@@ -40,7 +40,7 @@ BIO_METHOD *BIO_meth_new(int type, const char *name)
if (biom == NULL
|| (biom->name = OPENSSL_strdup(name)) == NULL) {
OPENSSL_free(biom);
- BIOerr(BIO_F_BIO_METH_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return NULL;
}
biom->type = type;
diff --git a/crypto/bio/b_print.c b/crypto/bio/bio_print.c
index 45d4e9f004b1..1934a6884251 100644
--- a/crypto/bio/b_print.c
+++ b/crypto/bio/bio_print.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -13,7 +13,7 @@
#include "crypto/ctype.h"
#include "internal/numbers.h"
#include <openssl/bio.h>
-#include <openssl/opensslconf.h>
+#include <openssl/configuration.h>
/*
* Copyright Patrick Powell 1995
@@ -344,7 +344,7 @@ _dopr(char **sbuffer,
break;
case 'w':
/* not supported yet, treat as next char */
- ch = *format++;
+ format++;
break;
default:
/* unknown, skip */
@@ -535,6 +535,10 @@ static LDOUBLE abs_val(LDOUBLE value)
LDOUBLE result = value;
if (value < 0)
result = -value;
+ if (result > 0 && result / 2 == result) /* INF */
+ result = 0;
+ else if (result != result) /* NAN */
+ result = 0;
return result;
}
@@ -590,6 +594,9 @@ fmtfp(char **sbuffer,
signvalue = '+';
else if (flags & DP_F_SPACE)
signvalue = ' ';
+ ufvalue = abs_val(fvalue);
+ if (ufvalue == 0 && fvalue != 0) /* INF or NAN? */
+ signvalue = '?';
/*
* G_FORMAT sometimes prints like E_FORMAT and sometimes like F_FORMAT
@@ -597,12 +604,12 @@ fmtfp(char **sbuffer,
* that from here on.
*/
if (style == G_FORMAT) {
- if (fvalue == 0.0) {
+ if (ufvalue == 0.0) {
realstyle = F_FORMAT;
- } else if (fvalue < 0.0001) {
+ } else if (ufvalue < 0.0001) {
realstyle = E_FORMAT;
- } else if ((max == 0 && fvalue >= 10)
- || (max > 0 && fvalue >= pow_10(max))) {
+ } else if ((max == 0 && ufvalue >= 10)
+ || (max > 0 && ufvalue >= pow_10(max))) {
realstyle = E_FORMAT;
} else {
realstyle = F_FORMAT;
@@ -612,9 +619,9 @@ fmtfp(char **sbuffer,
}
if (style != F_FORMAT) {
- tmpvalue = fvalue;
+ tmpvalue = ufvalue;
/* Calculate the exponent */
- if (fvalue != 0.0) {
+ if (ufvalue != 0.0) {
while (tmpvalue < 1) {
tmpvalue *= 10;
exp--;
@@ -638,6 +645,7 @@ fmtfp(char **sbuffer,
/*
* Should not happen. If we're in F_FORMAT then exp < max?
*/
+ (void)doapr_outch(sbuffer, buffer, currlen, maxlen, '\0');
return 0;
}
} else {
@@ -650,15 +658,16 @@ fmtfp(char **sbuffer,
}
}
if (realstyle == E_FORMAT)
- fvalue = tmpvalue;
+ ufvalue = tmpvalue;
}
- ufvalue = abs_val(fvalue);
+
/*
* By subtracting 65535 (2^16-1) we cancel the low order 15 bits
* of ULONG_MAX to avoid using imprecise floating point values.
*/
if (ufvalue >= (double)(ULONG_MAX - 65535) + 65536.0) {
/* Number too big */
+ (void)doapr_outch(sbuffer, buffer, currlen, maxlen, '\0');
return 0;
}
intpart = (unsigned long)ufvalue;
@@ -722,8 +731,10 @@ fmtfp(char **sbuffer,
tmpexp = (tmpexp / 10);
} while (tmpexp > 0 && eplace < (int)sizeof(econvert));
/* Exponent is huge!! Too big to print */
- if (tmpexp > 0)
+ if (tmpexp > 0) {
+ (void)doapr_outch(sbuffer, buffer, currlen, maxlen, '\0');
return 0;
+ }
/* Add a leading 0 for single digit exponents */
if (eplace == 1)
econvert[eplace++] = '0';
@@ -844,7 +855,7 @@ doapr_outch(char **sbuffer,
*maxlen += BUFFER_INC;
if (*buffer == NULL) {
if ((*buffer = OPENSSL_malloc(*maxlen)) == NULL) {
- BIOerr(BIO_F_DOAPR_OUTCH, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
if (*currlen > 0) {
@@ -855,9 +866,12 @@ doapr_outch(char **sbuffer,
*sbuffer = NULL;
} else {
char *tmpbuf;
+
tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
- if (tmpbuf == NULL)
+ if (tmpbuf == NULL) {
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
+ }
*buffer = tmpbuf;
}
}
@@ -949,6 +963,5 @@ int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
* been large enough.)
*/
return -1;
- else
- return (retlen <= INT_MAX) ? (int)retlen : -1;
+ return (retlen <= INT_MAX) ? (int)retlen : -1;
}
diff --git a/crypto/bio/b_sock.c b/crypto/bio/bio_sock.c
index df431e6d523d..84496de6f6bd 100644
--- a/crypto/bio/b_sock.c
+++ b/crypto/bio/bio_sock.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -9,7 +9,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include <errno.h>
#include "bio_local.h"
#ifndef OPENSSL_NO_SOCK
# define SOCKET_PROTOCOL IPPROTO_TCP
@@ -24,7 +23,26 @@
static int wsa_init_done = 0;
# endif
-# if OPENSSL_API_COMPAT < 0x10100000L
+# if defined __TANDEM
+# include <unistd.h>
+# include <sys/time.h> /* select */
+# if defined(OPENSSL_TANDEM_FLOSS)
+# include <floss.h(floss_select)>
+# endif
+# elif defined _WIN32
+# include <winsock.h> /* for type fd_set */
+# else
+# include <unistd.h>
+# if defined __VMS
+# include <sys/socket.h>
+# elif defined _HPUX_SOURCE
+# include <sys/time.h>
+# else
+# include <sys/select.h>
+# endif
+# endif
+
+# ifndef OPENSSL_NO_DEPRECATED_1_1_0
int BIO_get_host_ip(const char *str, unsigned char *ip)
{
BIO_ADDRINFO *res = NULL;
@@ -37,8 +55,7 @@ int BIO_get_host_ip(const char *str, unsigned char *ip)
size_t l;
if (BIO_ADDRINFO_family(res) != AF_INET) {
- BIOerr(BIO_F_BIO_GET_HOST_IP,
- BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
+ ERR_raise(ERR_LIB_BIO, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
} else if (BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), NULL, &l)) {
/*
* Because only AF_INET addresses will reach this far, we can assert
@@ -61,7 +78,7 @@ int BIO_get_port(const char *str, unsigned short *port_ptr)
int ret = 0;
if (str == NULL) {
- BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED);
+ ERR_raise(ERR_LIB_BIO, BIO_R_NO_PORT_DEFINED);
return 0;
}
@@ -70,8 +87,7 @@ int BIO_get_port(const char *str, unsigned short *port_ptr)
if (BIO_lookup(NULL, str, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
if (BIO_ADDRINFO_family(res) != AF_INET) {
- BIOerr(BIO_F_BIO_GET_PORT,
- BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET);
+ ERR_raise(ERR_LIB_BIO, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET);
} else {
*port_ptr = ntohs(BIO_ADDR_rawport(BIO_ADDRINFO_address(res)));
ret = 1;
@@ -103,7 +119,7 @@ int BIO_sock_error(int sock)
return j;
}
-# if OPENSSL_API_COMPAT < 0x10100000L
+# ifndef OPENSSL_NO_DEPRECATED_1_1_0
struct hostent *BIO_gethostbyname(const char *name)
{
/*
@@ -120,8 +136,6 @@ int BIO_sock_init(void)
static struct WSAData wsa_state;
if (!wsa_init_done) {
- int err;
-
wsa_init_done = 1;
memset(&wsa_state, 0, sizeof(wsa_state));
/*
@@ -131,9 +145,9 @@ int BIO_sock_init(void)
* probed at run-time with DSO_global_lookup.
*/
if (WSAStartup(0x0202, &wsa_state) != 0) {
- err = WSAGetLastError();
- SYSerr(SYS_F_WSASTARTUP, err);
- BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling wsastartup()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_WSASTARTUP);
return -1;
}
}
@@ -192,11 +206,12 @@ int BIO_socket_ioctl(int fd, long type, void *arg)
i = ioctlsocket(fd, type, ARG);
# endif /* __DJGPP__ */
if (i < 0)
- SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error());
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling ioctlsocket()");
return i;
}
-# if OPENSSL_API_COMPAT < 0x10100000L
+# ifndef OPENSSL_NO_DEPRECATED_1_1_0
int BIO_get_accept_socket(char *host, int bind_mode)
{
int s = INVALID_SOCKET;
@@ -207,7 +222,7 @@ int BIO_get_accept_socket(char *host, int bind_mode)
return INVALID_SOCKET;
if (BIO_sock_init() != 1)
- return INVALID_SOCKET;
+ goto err;
if (BIO_lookup(h, p, BIO_LOOKUP_SERVER, AF_UNSPEC, SOCK_STREAM, &res) != 0)
goto err;
@@ -243,8 +258,9 @@ int BIO_accept(int sock, char **ip_port)
ret = -2;
goto end;
}
- SYSerr(SYS_F_ACCEPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling accept()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_ACCEPT_ERROR);
goto end;
}
@@ -257,7 +273,7 @@ int BIO_accept(int sock, char **ip_port)
*ip_port = NULL;
if (*ip_port == NULL) {
- BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
BIO_closesocket(ret);
ret = (int)INVALID_SOCKET;
} else {
@@ -308,7 +324,8 @@ int BIO_socket_nbio(int s, int mode)
l = fcntl(s, F_GETFL, 0);
if (l == -1) {
- SYSerr(SYS_F_FCNTL, get_last_sys_error());
+ ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+ "calling fcntl()");
ret = -1;
} else {
# if defined(O_NONBLOCK)
@@ -326,12 +343,13 @@ int BIO_socket_nbio(int s, int mode)
ret = fcntl(s, F_SETFL, l);
if (ret < 0) {
- SYSerr(SYS_F_FCNTL, get_last_sys_error());
+ ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+ "calling fcntl()");
}
}
# else
/* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
- BIOerr(BIO_F_BIO_SOCKET_NBIO, ERR_R_PASSED_INVALID_ARGUMENT);
+ ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_INVALID_ARGUMENT);
# endif
return (ret == 0);
@@ -349,21 +367,53 @@ int BIO_sock_info(int sock,
ret = getsockname(sock, BIO_ADDR_sockaddr_noconst(info->addr),
&addr_len);
if (ret == -1) {
- SYSerr(SYS_F_GETSOCKNAME, get_last_socket_error());
- BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_ERROR);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling getsockname()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_GETSOCKNAME_ERROR);
return 0;
}
if ((size_t)addr_len > sizeof(*info->addr)) {
- BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS);
+ ERR_raise(ERR_LIB_BIO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS);
return 0;
}
}
break;
default:
- BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_UNKNOWN_INFO_TYPE);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNKNOWN_INFO_TYPE);
return 0;
}
return 1;
}
+/*
+ * Wait on fd at most until max_time; succeed immediately if max_time == 0.
+ * If for_read == 0 then assume to wait for writing, else wait for reading.
+ * Returns -1 on error, 0 on timeout, and 1 on success.
+ */
+int BIO_socket_wait(int fd, int for_read, time_t max_time)
+{
+ fd_set confds;
+ struct timeval tv;
+ time_t now;
+
+#ifdef _WIN32
+ if ((SOCKET)fd == INVALID_SOCKET)
+#else
+ if (fd < 0 || fd >= FD_SETSIZE)
#endif
+ return -1;
+ if (max_time == 0)
+ return 1;
+
+ now = time(NULL);
+ if (max_time < now)
+ return 0;
+
+ FD_ZERO(&confds);
+ openssl_fdset(fd, &confds);
+ tv.tv_usec = 0;
+ tv.tv_sec = (long)(max_time - now); /* might overflow */
+ return select(fd + 1, for_read ? &confds : NULL,
+ for_read ? NULL : &confds, NULL, &tv);
+}
+#endif /* !defined(OPENSSL_NO_SOCK) */
diff --git a/crypto/bio/b_sock2.c b/crypto/bio/bio_sock2.c
index 104ff31b0d2e..8bdad0c0b6ae 100644
--- a/crypto/bio/b_sock2.c
+++ b/crypto/bio/bio_sock2.c
@@ -1,7 +1,7 @@
/*
- * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -12,6 +12,7 @@
#include <errno.h>
#include "bio_local.h"
+#include "internal/ktls.h"
#include <openssl/err.h>
@@ -46,8 +47,9 @@ int BIO_socket(int domain, int socktype, int protocol, int options)
sock = socket(domain, socktype, protocol);
if (sock == -1) {
- SYSerr(SYS_F_SOCKET, get_last_socket_error());
- BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling socket()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
return INVALID_SOCKET;
}
@@ -79,7 +81,7 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options)
const int on = 1;
if (sock == -1) {
- BIOerr(BIO_F_BIO_CONNECT, BIO_R_INVALID_SOCKET);
+ ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_SOCKET);
return 0;
}
@@ -89,8 +91,9 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options)
if (options & BIO_SOCK_KEEPALIVE) {
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
(const void *)&on, sizeof(on)) != 0) {
- SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_KEEPALIVE);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling setsockopt()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_KEEPALIVE);
return 0;
}
}
@@ -98,8 +101,9 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options)
if (options & BIO_SOCK_NODELAY) {
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(const void *)&on, sizeof(on)) != 0) {
- SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_NODELAY);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling setsockopt()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_NODELAY);
return 0;
}
}
@@ -107,11 +111,21 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options)
if (connect(sock, BIO_ADDR_sockaddr(addr),
BIO_ADDR_sockaddr_size(addr)) == -1) {
if (!BIO_sock_should_retry(-1)) {
- SYSerr(SYS_F_CONNECT, get_last_socket_error());
- BIOerr(BIO_F_BIO_CONNECT, BIO_R_CONNECT_ERROR);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling connect()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
}
return 0;
}
+# ifndef OPENSSL_NO_KTLS
+ /*
+ * The new socket is created successfully regardless of ktls_enable.
+ * ktls_enable doesn't change any functionality of the socket, except
+ * changing the setsockopt to enable the processing of ktls_start.
+ * Thus, it is not a problem to call it for non-TLS sockets.
+ */
+ ktls_enable(sock);
+# endif
return 1;
}
@@ -138,7 +152,7 @@ int BIO_bind(int sock, const BIO_ADDR *addr, int options)
# endif
if (sock == -1) {
- BIOerr(BIO_F_BIO_BIND, BIO_R_INVALID_SOCKET);
+ ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_SOCKET);
return 0;
}
@@ -150,16 +164,18 @@ int BIO_bind(int sock, const BIO_ADDR *addr, int options)
if (options & BIO_SOCK_REUSEADDR) {
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(const void *)&on, sizeof(on)) != 0) {
- SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_REUSEADDR);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling setsockopt()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_REUSEADDR);
return 0;
}
}
# endif
if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) {
- SYSerr(SYS_F_BIND, get_last_socket_error());
- BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_BIND_SOCKET);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error() /* may be 0 */,
+ "calling bind()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_BIND_SOCKET);
return 0;
}
@@ -210,15 +226,16 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options)
socklen_t socktype_len = sizeof(socktype);
if (sock == -1) {
- BIOerr(BIO_F_BIO_LISTEN, BIO_R_INVALID_SOCKET);
+ ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_SOCKET);
return 0;
}
if (getsockopt(sock, SOL_SOCKET, SO_TYPE,
(void *)&socktype, &socktype_len) != 0
|| socktype_len != sizeof(socktype)) {
- SYSerr(SYS_F_GETSOCKOPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_LISTEN, BIO_R_GETTING_SOCKTYPE);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling getsockopt()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_GETTING_SOCKTYPE);
return 0;
}
@@ -228,8 +245,9 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options)
if (options & BIO_SOCK_KEEPALIVE) {
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
(const void *)&on, sizeof(on)) != 0) {
- SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_KEEPALIVE);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling setsockopt()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_KEEPALIVE);
return 0;
}
}
@@ -237,8 +255,9 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options)
if (options & BIO_SOCK_NODELAY) {
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(const void *)&on, sizeof(on)) != 0) {
- SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling setsockopt()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_NODELAY);
return 0;
}
}
@@ -253,8 +272,9 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options)
on = options & BIO_SOCK_V6_ONLY ? 1 : 0;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
(const void *)&on, sizeof(on)) != 0) {
- SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_LISTEN, BIO_R_LISTEN_V6_ONLY);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling setsockopt()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_LISTEN_V6_ONLY);
return 0;
}
}
@@ -264,8 +284,9 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options)
return 0;
if (socktype != SOCK_DGRAM && listen(sock, MAX_LISTEN) == -1) {
- SYSerr(SYS_F_LISTEN, get_last_socket_error());
- BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_LISTEN_SOCKET);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling listen()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_LISTEN_SOCKET);
return 0;
}
@@ -291,8 +312,9 @@ int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options)
BIO_ADDR_sockaddr_noconst(addr), &len);
if (accepted_sock == -1) {
if (!BIO_sock_should_retry(accepted_sock)) {
- SYSerr(SYS_F_ACCEPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_ACCEPT_EX, BIO_R_ACCEPT_ERROR);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling accept()");
+ ERR_raise(ERR_LIB_BIO, BIO_R_ACCEPT_ERROR);
}
return INVALID_SOCKET;
}
@@ -311,7 +333,7 @@ int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options)
*/
int BIO_closesocket(int sock)
{
- if (closesocket(sock) < 0)
+ if (sock < 0 || closesocket(sock) < 0)
return 0;
return 1;
}
diff --git a/crypto/bio/bss_acpt.c b/crypto/bio/bss_acpt.c
index 4461eae2333d..8870831039e9 100644
--- a/crypto/bio/bss_acpt.c
+++ b/crypto/bio/bss_acpt.c
@@ -1,12 +1,14 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
+#define OPENSSL_SUPPRESS_DEPRECATED
+
#include <stdio.h>
#include <errno.h>
#include "bio_local.h"
@@ -54,10 +56,8 @@ static void BIO_ACCEPT_free(BIO_ACCEPT *a);
static const BIO_METHOD methods_acceptp = {
BIO_TYPE_ACCEPT,
"socket accept",
- /* TODO: Convert to new style write function */
bwrite_conv,
acpt_write,
- /* TODO: Convert to new style read function */
bread_conv,
acpt_read,
acpt_puts,
@@ -93,7 +93,7 @@ static BIO_ACCEPT *BIO_ACCEPT_new(void)
BIO_ACCEPT *ret;
if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
- BIOerr(BIO_F_BIO_ACCEPT_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->accept_family = BIO_FAMILY_IPANY;
@@ -156,10 +156,10 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
switch (c->state) {
case ACPT_S_BEFORE:
if (c->param_addr == NULL && c->param_serv == NULL) {
- BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED);
- ERR_add_error_data(4,
- "hostname=", c->param_addr,
- " service=", c->param_serv);
+ ERR_raise_data(ERR_LIB_BIO,
+ BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED,
+ "hostname=%s, service=%s",
+ c->param_addr, c->param_serv);
goto exit_loop;
}
@@ -192,7 +192,7 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
family = AF_INET6;
} else {
#endif
- BIOerr(BIO_F_ACPT_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY);
goto exit_loop;
}
break;
@@ -203,7 +203,7 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
family = AF_UNSPEC;
break;
default:
- BIOerr(BIO_F_ACPT_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY);
goto exit_loop;
}
if (BIO_lookup(c->param_addr, c->param_serv, BIO_LOOKUP_SERVER,
@@ -211,26 +211,31 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
goto exit_loop;
}
if (c->addr_first == NULL) {
- BIOerr(BIO_F_ACPT_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
+ ERR_raise(ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING);
goto exit_loop;
}
- /* We're currently not iterating, but set this as preparation
- * for possible future development in that regard
- */
c->addr_iter = c->addr_first;
c->state = ACPT_S_CREATE_SOCKET;
break;
case ACPT_S_CREATE_SOCKET:
+ ERR_set_mark();
s = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
BIO_ADDRINFO_socktype(c->addr_iter),
BIO_ADDRINFO_protocol(c->addr_iter), 0);
if (s == (int)INVALID_SOCKET) {
- SYSerr(SYS_F_SOCKET, get_last_socket_error());
- ERR_add_error_data(4,
- "hostname=", c->param_addr,
- " service=", c->param_serv);
- BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
+ if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) != NULL) {
+ /*
+ * if there are more addresses to try, do that first
+ */
+ ERR_pop_to_mark();
+ break;
+ }
+ ERR_clear_last_mark();
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling socket(%s, %s)",
+ c->param_addr, c->param_serv);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
goto exit_loop;
}
c->accept_sock = s;
@@ -306,9 +311,11 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
if (bio == NULL)
goto exit_loop;
+ BIO_set_callback_ex(bio, BIO_get_callback_ex(b));
+#ifndef OPENSSL_NO_DEPRECATED_3_0
BIO_set_callback(bio, BIO_get_callback(b));
+#endif
BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
-
/*
* If the accept BIO has an bio_chain, we dup it and put the new
* socket at the end.
@@ -559,7 +566,7 @@ BIO *BIO_new_accept(const char *str)
ret = BIO_new(BIO_s_accept());
if (ret == NULL)
return NULL;
- if (BIO_set_accept_name(ret, str))
+ if (BIO_set_accept_name(ret, str) > 0)
return ret;
BIO_free(ret);
return NULL;
diff --git a/crypto/bio/bss_bio.c b/crypto/bio/bss_bio.c
index c97349e43282..7fa8778cae10 100644
--- a/crypto/bio/bss_bio.c
+++ b/crypto/bio/bss_bio.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -38,10 +38,8 @@ static void bio_destroy_pair(BIO *bio);
static const BIO_METHOD methods_biop = {
BIO_TYPE_BIO,
"BIO pair",
- /* TODO: Convert to new style write function */
bwrite_conv,
bio_write,
- /* TODO: Convert to new style read function */
bread_conv,
bio_read,
bio_puts,
@@ -286,7 +284,7 @@ static int bio_write(BIO *bio, const char *buf, int num_)
b->request = 0;
if (b->closed) {
/* we already closed */
- BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
+ ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE);
return -1;
}
@@ -362,7 +360,7 @@ static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
b->request = 0;
if (b->closed) {
- BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
+ ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE);
return -1;
}
@@ -427,10 +425,10 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
case BIO_C_SET_WRITE_BUF_SIZE:
if (b->peer) {
- BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
+ ERR_raise(ERR_LIB_BIO, BIO_R_IN_USE);
ret = 0;
} else if (num == 0) {
- BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
+ ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
ret = 0;
} else {
size_t new_size = num;
@@ -616,14 +614,14 @@ static int bio_make_pair(BIO *bio1, BIO *bio2)
b2 = bio2->ptr;
if (b1->peer != NULL || b2->peer != NULL) {
- BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
+ ERR_raise(ERR_LIB_BIO, BIO_R_IN_USE);
return 0;
}
if (b1->buf == NULL) {
b1->buf = OPENSSL_malloc(b1->size);
if (b1->buf == NULL) {
- BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
b1->len = 0;
@@ -633,7 +631,7 @@ static int bio_make_pair(BIO *bio1, BIO *bio2)
if (b2->buf == NULL) {
b2->buf = OPENSSL_malloc(b2->size);
if (b2->buf == NULL) {
- BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
b2->len = 0;
@@ -750,7 +748,7 @@ int BIO_nread0(BIO *bio, char **buf)
long ret;
if (!bio->init) {
- BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
return -2;
}
@@ -766,7 +764,7 @@ int BIO_nread(BIO *bio, char **buf, int num)
int ret;
if (!bio->init) {
- BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
return -2;
}
@@ -781,7 +779,7 @@ int BIO_nwrite0(BIO *bio, char **buf)
long ret;
if (!bio->init) {
- BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
return -2;
}
@@ -797,7 +795,7 @@ int BIO_nwrite(BIO *bio, char **buf, int num)
int ret;
if (!bio->init) {
- BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
return -2;
}
diff --git a/crypto/bio/bss_conn.c b/crypto/bio/bss_conn.c
index 807a82b23ba2..0d91f25fe70e 100644
--- a/crypto/bio/bss_conn.c
+++ b/crypto/bio/bss_conn.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -11,6 +11,7 @@
#include <errno.h>
#include "bio_local.h"
+#include "internal/ktls.h"
#ifndef OPENSSL_NO_SOCK
@@ -20,6 +21,9 @@ typedef struct bio_connect_st {
char *param_hostname;
char *param_service;
int connect_mode;
+# ifndef OPENSSL_NO_KTLS
+ unsigned char record_type;
+# endif
BIO_ADDRINFO *addr_first;
const BIO_ADDRINFO *addr_iter;
@@ -59,10 +63,8 @@ void BIO_CONNECT_free(BIO_CONNECT *a);
static const BIO_METHOD methods_connectp = {
BIO_TYPE_CONNECT,
"socket connect",
- /* TODO: Convert to new style write function */
bwrite_conv,
conn_write,
- /* TODO: Convert to new style read function */
bread_conv,
conn_read,
conn_puts,
@@ -85,10 +87,10 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
switch (c->state) {
case BIO_CONN_S_BEFORE:
if (c->param_hostname == NULL && c->param_service == NULL) {
- BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED);
- ERR_add_error_data(4,
- "hostname=", c->param_hostname,
- " service=", c->param_service);
+ ERR_raise_data(ERR_LIB_BIO,
+ BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED,
+ "hostname=%s service=%s",
+ c->param_hostname, c->param_service);
goto exit_loop;
}
c->state = BIO_CONN_S_GET_ADDR;
@@ -107,7 +109,7 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
family = AF_INET6;
} else {
#endif
- BIOerr(BIO_F_CONN_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY);
goto exit_loop;
}
break;
@@ -118,7 +120,7 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
family = AF_UNSPEC;
break;
default:
- BIOerr(BIO_F_CONN_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY);
goto exit_loop;
}
if (BIO_lookup(c->param_hostname, c->param_service,
@@ -127,7 +129,7 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
goto exit_loop;
}
if (c->addr_first == NULL) {
- BIOerr(BIO_F_CONN_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
+ ERR_raise(ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING);
goto exit_loop;
}
c->addr_iter = c->addr_first;
@@ -139,11 +141,10 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
BIO_ADDRINFO_socktype(c->addr_iter),
BIO_ADDRINFO_protocol(c->addr_iter), 0);
if (ret == (int)INVALID_SOCKET) {
- SYSerr(SYS_F_SOCKET, get_last_socket_error());
- ERR_add_error_data(4,
- "hostname=", c->param_hostname,
- " service=", c->param_service);
- BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling socket(%s, %s)",
+ c->param_hostname, c->param_service);
+ ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
goto exit_loop;
}
b->num = ret;
@@ -152,6 +153,7 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
case BIO_CONN_S_CONNECT:
BIO_clear_retry_flags(b);
+ ERR_set_mark();
ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter),
BIO_SOCK_KEEPALIVE | c->connect_mode);
b->retry_reason = 0;
@@ -160,7 +162,7 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
BIO_set_retry_special(b);
c->state = BIO_CONN_S_BLOCKED_CONNECT;
b->retry_reason = BIO_RR_CONNECT;
- ERR_clear_error();
+ ERR_pop_to_mark();
} else if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter))
!= NULL) {
/*
@@ -168,23 +170,27 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
*/
BIO_closesocket(b->num);
c->state = BIO_CONN_S_CREATE_SOCKET;
- ERR_clear_error();
+ ERR_pop_to_mark();
break;
} else {
- SYSerr(SYS_F_CONNECT, get_last_socket_error());
- ERR_add_error_data(4,
- "hostname=", c->param_hostname,
- " service=", c->param_service);
+ ERR_clear_last_mark();
+ ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+ "calling connect(%s, %s)",
+ c->param_hostname, c->param_service);
c->state = BIO_CONN_S_CONNECT_ERROR;
break;
}
goto exit_loop;
} else {
+ ERR_clear_last_mark();
c->state = BIO_CONN_S_OK;
}
break;
case BIO_CONN_S_BLOCKED_CONNECT:
+ /* wait for socket being writable, before querying BIO_sock_error */
+ if (BIO_socket_wait(b->num, 0, time(NULL)) == 0)
+ break;
i = BIO_sock_error(b->num);
if (i != 0) {
BIO_clear_retry_flags(b);
@@ -194,22 +200,30 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
*/
BIO_closesocket(b->num);
c->state = BIO_CONN_S_CREATE_SOCKET;
- ERR_clear_error();
break;
}
- SYSerr(SYS_F_CONNECT, i);
- ERR_add_error_data(4,
- "hostname=", c->param_hostname,
- " service=", c->param_service);
- BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR);
+ ERR_raise_data(ERR_LIB_SYS, i,
+ "calling connect(%s, %s)",
+ c->param_hostname, c->param_service);
+ ERR_raise(ERR_LIB_BIO, BIO_R_NBIO_CONNECT_ERROR);
ret = 0;
goto exit_loop;
- } else
+ } else {
c->state = BIO_CONN_S_OK;
+# ifndef OPENSSL_NO_KTLS
+ /*
+ * The new socket is created successfully regardless of ktls_enable.
+ * ktls_enable doesn't change any functionality of the socket, except
+ * changing the setsockopt to enable the processing of ktls_start.
+ * Thus, it is not a problem to call it for non-TLS sockets.
+ */
+ ktls_enable(b->num);
+# endif
+ }
break;
case BIO_CONN_S_CONNECT_ERROR:
- BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR);
+ ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
ret = 0;
goto exit_loop;
@@ -240,7 +254,7 @@ BIO_CONNECT *BIO_CONNECT_new(void)
BIO_CONNECT *ret;
if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
- BIOerr(BIO_F_BIO_CONNECT_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->state = BIO_CONN_S_BEFORE;
@@ -320,7 +334,12 @@ static int conn_read(BIO *b, char *out, int outl)
if (out != NULL) {
clear_socket_error();
- ret = readsocket(b->num, out, outl);
+# ifndef OPENSSL_NO_KTLS
+ if (BIO_get_ktls_recv(b))
+ ret = ktls_read_record(b->num, out, outl);
+ else
+# endif
+ ret = readsocket(b->num, out, outl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_sock_should_retry(ret))
@@ -345,7 +364,16 @@ static int conn_write(BIO *b, const char *in, int inl)
}
clear_socket_error();
- ret = writesocket(b->num, in, inl);
+# ifndef OPENSSL_NO_KTLS
+ if (BIO_should_ktls_ctrl_msg_flag(b)) {
+ ret = ktls_send_ctrl_message(b->num, data->record_type, in, inl);
+ if (ret >= 0) {
+ ret = inl;
+ BIO_clear_ktls_ctrl_msg_flag(b);
+ }
+ } else
+# endif
+ ret = writesocket(b->num, in, inl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_sock_should_retry(ret))
@@ -361,6 +389,9 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
const char **pptr = NULL;
long ret = 1;
BIO_CONNECT *data;
+# ifndef OPENSSL_NO_KTLS
+ ktls_crypto_info_t *crypto_info;
+# endif
data = (BIO_CONNECT *)b->ptr;
@@ -518,8 +549,29 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
}
break;
case BIO_CTRL_EOF:
- ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
+ ret = (b->flags & BIO_FLAGS_IN_EOF) != 0;
+ break;
+# ifndef OPENSSL_NO_KTLS
+ case BIO_CTRL_SET_KTLS:
+ crypto_info = (ktls_crypto_info_t *)ptr;
+ ret = ktls_start(b->num, crypto_info, num);
+ if (ret)
+ BIO_set_ktls_flag(b, num);
+ break;
+ case BIO_CTRL_GET_KTLS_SEND:
+ return BIO_should_ktls_flag(b, 1) != 0;
+ case BIO_CTRL_GET_KTLS_RECV:
+ return BIO_should_ktls_flag(b, 0) != 0;
+ case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
+ BIO_set_ktls_ctrl_msg_flag(b);
+ data->record_type = num;
+ ret = 0;
+ break;
+ case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
+ BIO_clear_ktls_ctrl_msg_flag(b);
+ ret = 0;
break;
+# endif
default:
ret = 0;
break;
diff --git a/crypto/bio/bss_core.c b/crypto/bio/bss_core.c
new file mode 100644
index 000000000000..7a84b20460c8
--- /dev/null
+++ b/crypto/bio/bss_core.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/core_dispatch.h>
+#include "bio_local.h"
+#include "internal/cryptlib.h"
+
+typedef struct {
+ OSSL_FUNC_BIO_read_ex_fn *c_bio_read_ex;
+ OSSL_FUNC_BIO_write_ex_fn *c_bio_write_ex;
+ OSSL_FUNC_BIO_gets_fn *c_bio_gets;
+ OSSL_FUNC_BIO_puts_fn *c_bio_puts;
+ OSSL_FUNC_BIO_ctrl_fn *c_bio_ctrl;
+ OSSL_FUNC_BIO_up_ref_fn *c_bio_up_ref;
+ OSSL_FUNC_BIO_free_fn *c_bio_free;
+} BIO_CORE_GLOBALS;
+
+static void bio_core_globals_free(void *vbcg)
+{
+ OPENSSL_free(vbcg);
+}
+
+static void *bio_core_globals_new(OSSL_LIB_CTX *ctx)
+{
+ return OPENSSL_zalloc(sizeof(BIO_CORE_GLOBALS));
+}
+
+static const OSSL_LIB_CTX_METHOD bio_core_globals_method = {
+ OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
+ bio_core_globals_new,
+ bio_core_globals_free,
+};
+
+static ossl_inline BIO_CORE_GLOBALS *get_globals(OSSL_LIB_CTX *libctx)
+{
+ return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_BIO_CORE_INDEX,
+ &bio_core_globals_method);
+}
+
+static int bio_core_read_ex(BIO *bio, char *data, size_t data_len,
+ size_t *bytes_read)
+{
+ BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);
+
+ if (bcgbl == NULL || bcgbl->c_bio_read_ex == NULL)
+ return 0;
+ return bcgbl->c_bio_read_ex(BIO_get_data(bio), data, data_len, bytes_read);
+}
+
+static int bio_core_write_ex(BIO *bio, const char *data, size_t data_len,
+ size_t *written)
+{
+ BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);
+
+ if (bcgbl == NULL || bcgbl->c_bio_write_ex == NULL)
+ return 0;
+ return bcgbl->c_bio_write_ex(BIO_get_data(bio), data, data_len, written);
+}
+
+static long bio_core_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+ BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);
+
+ if (bcgbl == NULL || bcgbl->c_bio_ctrl == NULL)
+ return -1;
+ return bcgbl->c_bio_ctrl(BIO_get_data(bio), cmd, num, ptr);
+}
+
+static int bio_core_gets(BIO *bio, char *buf, int size)
+{
+ BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);
+
+ if (bcgbl == NULL || bcgbl->c_bio_gets == NULL)
+ return -1;
+ return bcgbl->c_bio_gets(BIO_get_data(bio), buf, size);
+}
+
+static int bio_core_puts(BIO *bio, const char *str)
+{
+ BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);
+
+ if (bcgbl == NULL || bcgbl->c_bio_puts == NULL)
+ return -1;
+ return bcgbl->c_bio_puts(BIO_get_data(bio), str);
+}
+
+static int bio_core_new(BIO *bio)
+{
+ BIO_set_init(bio, 1);
+
+ return 1;
+}
+
+static int bio_core_free(BIO *bio)
+{
+ BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);
+
+ if (bcgbl == NULL)
+ return 0;
+
+ BIO_set_init(bio, 0);
+ bcgbl->c_bio_free(BIO_get_data(bio));
+
+ return 1;
+}
+
+static const BIO_METHOD corebiometh = {
+ BIO_TYPE_CORE_TO_PROV,
+ "BIO to Core filter",
+ bio_core_write_ex,
+ NULL,
+ bio_core_read_ex,
+ NULL,
+ bio_core_puts,
+ bio_core_gets,
+ bio_core_ctrl,
+ bio_core_new,
+ bio_core_free,
+ NULL,
+};
+
+const BIO_METHOD *BIO_s_core(void)
+{
+ return &corebiometh;
+}
+
+BIO *BIO_new_from_core_bio(OSSL_LIB_CTX *libctx, OSSL_CORE_BIO *corebio)
+{
+ BIO *outbio;
+ BIO_CORE_GLOBALS *bcgbl = get_globals(libctx);
+
+ /* Check the library context has been initialised with the callbacks */
+ if (bcgbl == NULL || (bcgbl->c_bio_write_ex == NULL && bcgbl->c_bio_read_ex == NULL))
+ return NULL;
+
+ if ((outbio = BIO_new_ex(libctx, BIO_s_core())) == NULL)
+ return NULL;
+
+ if (!bcgbl->c_bio_up_ref(corebio)) {
+ BIO_free(outbio);
+ return NULL;
+ }
+ BIO_set_data(outbio, corebio);
+ return outbio;
+}
+
+int ossl_bio_init_core(OSSL_LIB_CTX *libctx, const OSSL_DISPATCH *fns)
+{
+ BIO_CORE_GLOBALS *bcgbl = get_globals(libctx);
+
+ if (bcgbl == NULL)
+ return 0;
+
+ for (; fns->function_id != 0; fns++) {
+ switch (fns->function_id) {
+ case OSSL_FUNC_BIO_READ_EX:
+ if (bcgbl->c_bio_read_ex == NULL)
+ bcgbl->c_bio_read_ex = OSSL_FUNC_BIO_read_ex(fns);
+ break;
+ case OSSL_FUNC_BIO_WRITE_EX:
+ if (bcgbl->c_bio_write_ex == NULL)
+ bcgbl->c_bio_write_ex = OSSL_FUNC_BIO_write_ex(fns);
+ break;
+ case OSSL_FUNC_BIO_GETS:
+ if (bcgbl->c_bio_gets == NULL)
+ bcgbl->c_bio_gets = OSSL_FUNC_BIO_gets(fns);
+ break;
+ case OSSL_FUNC_BIO_PUTS:
+ if (bcgbl->c_bio_puts == NULL)
+ bcgbl->c_bio_puts = OSSL_FUNC_BIO_puts(fns);
+ break;
+ case OSSL_FUNC_BIO_CTRL:
+ if (bcgbl->c_bio_ctrl == NULL)
+ bcgbl->c_bio_ctrl = OSSL_FUNC_BIO_ctrl(fns);
+ break;
+ case OSSL_FUNC_BIO_UP_REF:
+ if (bcgbl->c_bio_up_ref == NULL)
+ bcgbl->c_bio_up_ref = OSSL_FUNC_BIO_up_ref(fns);
+ break;
+ case OSSL_FUNC_BIO_FREE:
+ if (bcgbl->c_bio_free == NULL)
+ bcgbl->c_bio_free = OSSL_FUNC_BIO_free(fns);
+ break;
+ }
+ }
+
+ return 1;
+}
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
index c87ba4d26508..4292d805a16a 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -1,7 +1,7 @@
/*
- * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -57,6 +57,8 @@ static int dgram_sctp_puts(BIO *h, const char *str);
static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int dgram_sctp_new(BIO *h);
static int dgram_sctp_free(BIO *data);
+static int dgram_sctp_wait_for_dry(BIO *b);
+static int dgram_sctp_msg_waiting(BIO *b);
# ifdef SCTP_AUTHENTICATION_EVENT
static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification
*snp);
@@ -70,10 +72,8 @@ static void get_current_time(struct timeval *t);
static const BIO_METHOD methods_dgramp = {
BIO_TYPE_DGRAM,
"datagram socket",
- /* TODO: Convert to new style write function */
bwrite_conv,
dgram_write,
- /* TODO: Convert to new style read function */
bread_conv,
dgram_read,
dgram_puts,
@@ -88,10 +88,8 @@ static const BIO_METHOD methods_dgramp = {
static const BIO_METHOD methods_dgramp_sctp = {
BIO_TYPE_DGRAM_SCTP,
"datagram sctp socket",
- /* TODO: Convert to new style write function */
bwrite_conv,
dgram_sctp_write,
- /* TODO: Convert to new style write function */
bread_conv,
dgram_sctp_read,
dgram_sctp_puts,
@@ -128,7 +126,7 @@ typedef struct bio_dgram_sctp_data_st {
struct bio_dgram_sctp_sndinfo sndinfo;
struct bio_dgram_sctp_rcvinfo rcvinfo;
struct bio_dgram_sctp_prinfo prinfo;
- void (*handle_notifications) (BIO *bio, void *context, void *buf);
+ BIO_dgram_sctp_notification_handler_fn handle_notifications;
void *notification_context;
int in_handshake;
int ccs_rcvd;
@@ -197,12 +195,6 @@ static void dgram_adjust_rcv_timeout(BIO *b)
{
# if defined(SO_RCVTIMEO)
bio_dgram_data *data = (bio_dgram_data *)b->ptr;
- union {
- size_t s;
- int i;
- } sz = {
- 0
- };
/* Is a timer active? */
if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
@@ -212,21 +204,21 @@ static void dgram_adjust_rcv_timeout(BIO *b)
# ifdef OPENSSL_SYS_WINDOWS
int timeout;
- sz.i = sizeof(timeout);
+ int sz = sizeof(timeout);
if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void *)&timeout, &sz.i) < 0) {
+ (void *)&timeout, &sz) < 0) {
perror("getsockopt");
} else {
data->socket_timeout.tv_sec = timeout / 1000;
data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
}
# else
- sz.i = sizeof(data->socket_timeout);
+ socklen_t sz = sizeof(data->socket_timeout);
if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- &(data->socket_timeout), (void *)&sz) < 0) {
+ &(data->socket_timeout), &sz) < 0) {
perror("getsockopt");
- } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0)
- OPENSSL_assert(sz.s <= sizeof(data->socket_timeout));
+ } else
+ OPENSSL_assert(sz <= sizeof(data->socket_timeout));
# endif
/* Get current time */
@@ -357,11 +349,11 @@ static int dgram_write(BIO *b, const char *in, int inl)
return ret;
}
-static long dgram_get_mtu_overhead(bio_dgram_data *data)
+static long dgram_get_mtu_overhead(BIO_ADDR *addr)
{
long ret;
- switch (BIO_ADDR_family(&data->peer)) {
+ switch (BIO_ADDR_family(addr)) {
case AF_INET:
/*
* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
@@ -373,7 +365,8 @@ static long dgram_get_mtu_overhead(bio_dgram_data *data)
{
# ifdef IN6_IS_ADDR_V4MAPPED
struct in6_addr tmp_addr;
- if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
+
+ if (BIO_ADDR_rawaddress(addr, &tmp_addr, NULL)
&& IN6_IS_ADDR_V4MAPPED(&tmp_addr))
/*
* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
@@ -500,11 +493,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
&sockopt_len)) < 0 || sockopt_val < 0) {
ret = 0;
} else {
- /*
- * we assume that the transport protocol is UDP and no IP
- * options are used.
- */
- data->mtu = sockopt_val - 8 - 20;
+ data->mtu = sockopt_val - dgram_get_mtu_overhead(&addr);
ret = data->mtu;
}
break;
@@ -516,11 +505,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
|| sockopt_val < 0) {
ret = 0;
} else {
- /*
- * we assume that the transport protocol is UDP and no IPV6
- * options are used.
- */
- data->mtu = sockopt_val - 8 - 40;
+ data->mtu = sockopt_val - dgram_get_mtu_overhead(&addr);
ret = data->mtu;
}
break;
@@ -534,7 +519,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
# endif
break;
case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
- ret = -dgram_get_mtu_overhead(data);
+ ret = -dgram_get_mtu_overhead(&data->peer);
switch (BIO_ADDR_family(&data->peer)) {
case AF_INET:
ret += 576;
@@ -609,19 +594,14 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
break;
case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
{
- union {
- size_t s;
- int i;
- } sz = {
- 0
- };
# ifdef OPENSSL_SYS_WINDOWS
+ int sz = 0;
int timeout;
struct timeval *tv = (struct timeval *)ptr;
- sz.i = sizeof(timeout);
+ sz = sizeof(timeout);
if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void *)&timeout, &sz.i) < 0) {
+ (void *)&timeout, &sz) < 0) {
perror("getsockopt");
ret = -1;
} else {
@@ -630,16 +610,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = sizeof(*tv);
}
# else
- sz.i = sizeof(struct timeval);
+ socklen_t sz = sizeof(struct timeval);
if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- ptr, (void *)&sz) < 0) {
+ ptr, &sz) < 0) {
perror("getsockopt");
ret = -1;
- } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
- OPENSSL_assert(sz.s <= sizeof(struct timeval));
- ret = (int)sz.s;
- } else
- ret = sz.i;
+ } else {
+ OPENSSL_assert(sz <= sizeof(struct timeval));
+ ret = (int)sz;
+ }
# endif
}
break;
@@ -666,19 +645,14 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
break;
case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
{
- union {
- size_t s;
- int i;
- } sz = {
- 0
- };
# ifdef OPENSSL_SYS_WINDOWS
+ int sz = 0;
int timeout;
struct timeval *tv = (struct timeval *)ptr;
- sz.i = sizeof(timeout);
+ sz = sizeof(timeout);
if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
- (void *)&timeout, &sz.i) < 0) {
+ (void *)&timeout, &sz) < 0) {
perror("getsockopt");
ret = -1;
} else {
@@ -687,16 +661,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = sizeof(*tv);
}
# else
- sz.i = sizeof(struct timeval);
+ socklen_t sz = sizeof(struct timeval);
if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
- ptr, (void *)&sz) < 0) {
+ ptr, &sz) < 0) {
perror("getsockopt");
ret = -1;
- } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
- OPENSSL_assert(sz.s <= sizeof(struct timeval));
- ret = (int)sz.s;
- } else
- ret = sz.i;
+ } else {
+ OPENSSL_assert(sz <= sizeof(struct timeval));
+ ret = (int)sz;
+ }
# endif
}
break;
@@ -780,7 +753,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
}
break;
case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
- ret = dgram_get_mtu_overhead(data);
+ ret = dgram_get_mtu_overhead(&data->peer);
break;
/*
@@ -845,8 +818,8 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
sizeof(struct sctp_authchunk));
if (ret < 0) {
BIO_vfree(bio);
- BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB);
- ERR_add_error_data(1, "Ensure SCTP AUTH chunks are enabled in kernel");
+ ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
+ "Ensure SCTP AUTH chunks are enabled in kernel");
return NULL;
}
auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
@@ -855,8 +828,8 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
sizeof(struct sctp_authchunk));
if (ret < 0) {
BIO_vfree(bio);
- BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB);
- ERR_add_error_data(1, "Ensure SCTP AUTH chunks are enabled in kernel");
+ ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
+ "Ensure SCTP AUTH chunks are enabled in kernel");
return NULL;
}
@@ -893,10 +866,9 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
if (!auth_data || !auth_forward) {
BIO_vfree(bio);
- BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB);
- ERR_add_error_data(1,
- "Ensure SCTP AUTH chunks are enabled on the "
- "underlying socket");
+ ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
+ "Ensure SCTP AUTH chunks are enabled on the "
+ "underlying socket");
return NULL;
}
@@ -960,7 +932,7 @@ static int dgram_sctp_new(BIO *bi)
bi->init = 0;
bi->num = 0;
if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) {
- BIOerr(BIO_F_DGRAM_SCTP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
# ifdef SCTP_PR_SCTP_NONE
@@ -1011,7 +983,6 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
int ret = 0, n = 0, i, optval;
socklen_t optlen;
bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
- union sctp_notification *snp;
struct msghdr msg;
struct iovec iov;
struct cmsghdr *cmsg;
@@ -1077,8 +1048,10 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
}
if (msg.msg_flags & MSG_NOTIFICATION) {
- snp = (union sctp_notification *)out;
- if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
+ union sctp_notification snp;
+
+ memcpy(&snp, out, sizeof(snp));
+ if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
# ifdef SCTP_EVENT
struct sctp_event event;
# else
@@ -1118,17 +1091,19 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
# endif
}
# ifdef SCTP_AUTHENTICATION_EVENT
- if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
- dgram_sctp_handle_auth_free_key_event(b, snp);
+ if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+ dgram_sctp_handle_auth_free_key_event(b, &snp);
# endif
if (data->handle_notifications != NULL)
data->handle_notifications(b, data->notification_context,
(void *)out);
+ memset(&snp, 0, sizeof(snp));
memset(out, 0, outl);
- } else
+ } else {
ret += n;
+ }
}
while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR)
&& (ret < outl));
@@ -1195,7 +1170,7 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
(socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
authchunks = OPENSSL_malloc(optlen);
if (authchunks == NULL) {
- BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return -1;
}
memset(authchunks, 0, optlen);
@@ -1215,7 +1190,7 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
OPENSSL_free(authchunks);
if (!auth_data || !auth_forward) {
- BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR);
+ ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
return -1;
}
@@ -1566,6 +1541,10 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
else
data->save_shutdown = 0;
break;
+ case BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY:
+ return dgram_sctp_wait_for_dry(b);
+ case BIO_CTRL_DGRAM_SCTP_MSG_WAITING:
+ return dgram_sctp_msg_waiting(b);
default:
/*
@@ -1578,11 +1557,8 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
}
int BIO_dgram_sctp_notification_cb(BIO *b,
- void (*handle_notifications) (BIO *bio,
- void
- *context,
- void *buf),
- void *context)
+ BIO_dgram_sctp_notification_handler_fn handle_notifications,
+ void *context)
{
bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
@@ -1610,6 +1586,11 @@ int BIO_dgram_sctp_notification_cb(BIO *b,
*/
int BIO_dgram_sctp_wait_for_dry(BIO *b)
{
+ return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY, 0, NULL);
+}
+
+static int dgram_sctp_wait_for_dry(BIO *b)
+{
int is_dry = 0;
int sockflags = 0;
int n, ret;
@@ -1768,6 +1749,11 @@ int BIO_dgram_sctp_wait_for_dry(BIO *b)
int BIO_dgram_sctp_msg_waiting(BIO *b)
{
+ return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_MSG_WAITING, 0, NULL);
+}
+
+static int dgram_sctp_msg_waiting(BIO *b)
+{
int n, sockflags;
union sctp_notification snp;
struct msghdr msg;
@@ -1907,22 +1893,22 @@ static void get_current_time(struct timeval *t)
{
# if defined(_WIN32)
SYSTEMTIME st;
- union {
- unsigned __int64 ul;
- FILETIME ft;
- } now;
+ unsigned __int64 now_ul;
+ FILETIME now_ft;
GetSystemTime(&st);
- SystemTimeToFileTime(&st, &now.ft);
+ SystemTimeToFileTime(&st, &now_ft);
+ now_ul = ((unsigned __int64)now_ft.dwHighDateTime << 32) | now_ft.dwLowDateTime;
# ifdef __MINGW32__
- now.ul -= 116444736000000000ULL;
+ now_ul -= 116444736000000000ULL;
# else
- now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
+ now_ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
# endif
- t->tv_sec = (long)(now.ul / 10000000);
- t->tv_usec = ((int)(now.ul % 10000000)) / 10;
+ t->tv_sec = (long)(now_ul / 10000000);
+ t->tv_usec = ((int)(now_ul % 10000000)) / 10;
# else
- gettimeofday(t, NULL);
+ if (gettimeofday(t, NULL) < 0)
+ perror("gettimeofday");
# endif
}
diff --git a/crypto/bio/bss_fd.c b/crypto/bio/bss_fd.c
index ccbe1626baf2..f756225edb21 100644
--- a/crypto/bio/bss_fd.c
+++ b/crypto/bio/bss_fd.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -60,10 +60,8 @@ int BIO_fd_should_retry(int s);
static const BIO_METHOD methods_fdp = {
BIO_TYPE_FD,
"file descriptor",
- /* TODO: Convert to new style write function */
bwrite_conv,
fd_write,
- /* TODO: Convert to new style read function */
bread_conv,
fd_read,
fd_puts,
@@ -94,7 +92,7 @@ static int fd_new(BIO *bi)
bi->init = 0;
bi->num = -1;
bi->ptr = NULL;
- bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */
+ bi->flags = BIO_FLAGS_UPLINK_INTERNAL; /* essentially redundant */
return 1;
}
@@ -107,7 +105,7 @@ static int fd_free(BIO *a)
UP_close(a->num);
}
a->init = 0;
- a->flags = BIO_FLAGS_UPLINK;
+ a->flags = BIO_FLAGS_UPLINK_INTERNAL;
}
return 1;
}
@@ -189,7 +187,7 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = 1;
break;
case BIO_CTRL_EOF:
- ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
+ ret = (b->flags & BIO_FLAGS_IN_EOF) != 0;
break;
default:
ret = 0;
diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c
index 1a70ce799404..0c57c1bfb474 100644
--- a/crypto/bio/bss_file.c
+++ b/crypto/bio/bss_file.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -42,10 +42,8 @@ static int file_free(BIO *data);
static const BIO_METHOD methods_filep = {
BIO_TYPE_FILE,
"FILE pointer",
- /* TODO: Convert to new style write function */
bwrite_conv,
file_write,
- /* TODO: Convert to new style read function */
bread_conv,
file_read,
file_puts,
@@ -66,16 +64,17 @@ BIO *BIO_new_file(const char *filename, const char *mode)
fp_flags |= BIO_FP_TEXT;
if (file == NULL) {
- SYSerr(SYS_F_FOPEN, get_last_sys_error());
- ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
+ ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+ "calling fopen(%s, %s)",
+ filename, mode);
if (errno == ENOENT
#ifdef ENXIO
|| errno == ENXIO
#endif
)
- BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
+ ERR_raise(ERR_LIB_BIO, BIO_R_NO_SUCH_FILE);
else
- BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
+ ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB);
return NULL;
}
if ((ret = BIO_new(BIO_s_file())) == NULL) {
@@ -83,8 +82,8 @@ BIO *BIO_new_file(const char *filename, const char *mode)
return NULL;
}
- BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
- * UPLINK */
+ /* we did fopen -> we disengage UPLINK */
+ BIO_clear_flags(ret, BIO_FLAGS_UPLINK_INTERNAL);
BIO_set_fp(ret, file, fp_flags);
return ret;
}
@@ -97,7 +96,7 @@ BIO *BIO_new_fp(FILE *stream, int close_flag)
return NULL;
/* redundant flag, left for documentation purposes */
- BIO_set_flags(ret, BIO_FLAGS_UPLINK);
+ BIO_set_flags(ret, BIO_FLAGS_UPLINK_INTERNAL);
BIO_set_fp(ret, stream, close_flag);
return ret;
}
@@ -112,7 +111,7 @@ static int file_new(BIO *bi)
bi->init = 0;
bi->num = 0;
bi->ptr = NULL;
- bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */
+ bi->flags = BIO_FLAGS_UPLINK_INTERNAL; /* default to UPLINK */
return 1;
}
@@ -122,12 +121,12 @@ static int file_free(BIO *a)
return 0;
if (a->shutdown) {
if ((a->init) && (a->ptr != NULL)) {
- if (a->flags & BIO_FLAGS_UPLINK)
+ if (a->flags & BIO_FLAGS_UPLINK_INTERNAL)
UP_fclose(a->ptr);
else
fclose(a->ptr);
a->ptr = NULL;
- a->flags = BIO_FLAGS_UPLINK;
+ a->flags = BIO_FLAGS_UPLINK_INTERNAL;
}
a->init = 0;
}
@@ -139,15 +138,16 @@ static int file_read(BIO *b, char *out, int outl)
int ret = 0;
if (b->init && (out != NULL)) {
- if (b->flags & BIO_FLAGS_UPLINK)
+ if (b->flags & BIO_FLAGS_UPLINK_INTERNAL)
ret = UP_fread(out, 1, (int)outl, b->ptr);
else
ret = fread(out, 1, (int)outl, (FILE *)b->ptr);
if (ret == 0
- && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) :
- ferror((FILE *)b->ptr)) {
- SYSerr(SYS_F_FREAD, get_last_sys_error());
- BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB);
+ && (b->flags & BIO_FLAGS_UPLINK_INTERNAL
+ ? UP_ferror((FILE *)b->ptr) : ferror((FILE *)b->ptr))) {
+ ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+ "calling fread()");
+ ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB);
ret = -1;
}
}
@@ -159,7 +159,7 @@ static int file_write(BIO *b, const char *in, int inl)
int ret = 0;
if (b->init && (in != NULL)) {
- if (b->flags & BIO_FLAGS_UPLINK)
+ if (b->flags & BIO_FLAGS_UPLINK_INTERNAL)
ret = UP_fwrite(in, (int)inl, 1, b->ptr);
else
ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr);
@@ -186,20 +186,20 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
switch (cmd) {
case BIO_C_FILE_SEEK:
case BIO_CTRL_RESET:
- if (b->flags & BIO_FLAGS_UPLINK)
+ if (b->flags & BIO_FLAGS_UPLINK_INTERNAL)
ret = (long)UP_fseek(b->ptr, num, 0);
else
ret = (long)fseek(fp, num, 0);
break;
case BIO_CTRL_EOF:
- if (b->flags & BIO_FLAGS_UPLINK)
+ if (b->flags & BIO_FLAGS_UPLINK_INTERNAL)
ret = (long)UP_feof(fp);
else
ret = (long)feof(fp);
break;
case BIO_C_FILE_TELL:
case BIO_CTRL_INFO:
- if (b->flags & BIO_FLAGS_UPLINK)
+ if (b->flags & BIO_FLAGS_UPLINK_INTERNAL)
ret = UP_ftell(b->ptr);
else
ret = ftell(fp);
@@ -209,22 +209,22 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
b->shutdown = (int)num & BIO_CLOSE;
b->ptr = ptr;
b->init = 1;
-# if BIO_FLAGS_UPLINK!=0
+# if BIO_FLAGS_UPLINK_INTERNAL!=0
# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
# define _IOB_ENTRIES 20
# endif
/* Safety net to catch purely internal BIO_set_fp calls */
-# if defined(_MSC_VER) && _MSC_VER>=1900
+# if (defined(_MSC_VER) && _MSC_VER>=1900) || defined(__BORLANDC__)
if (ptr == stdin || ptr == stdout || ptr == stderr)
- BIO_clear_flags(b, BIO_FLAGS_UPLINK);
+ BIO_clear_flags(b, BIO_FLAGS_UPLINK_INTERNAL);
# elif defined(_IOB_ENTRIES)
if ((size_t)ptr >= (size_t)stdin &&
(size_t)ptr < (size_t)(stdin + _IOB_ENTRIES))
- BIO_clear_flags(b, BIO_FLAGS_UPLINK);
+ BIO_clear_flags(b, BIO_FLAGS_UPLINK_INTERNAL);
# endif
# endif
# ifdef UP_fsetmod
- if (b->flags & BIO_FLAGS_UPLINK)
+ if (b->flags & BIO_FLAGS_UPLINK_INTERNAL)
UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b'));
else
# endif
@@ -235,6 +235,15 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
_setmode(fd, _O_TEXT);
else
_setmode(fd, _O_BINARY);
+ /*
+ * Reports show that ftell() isn't trustable in text mode.
+ * This has been confirmed as a bug in the Universal C RTL, see
+ * https://developercommunity.visualstudio.com/content/problem/425878/fseek-ftell-fail-in-text-mode-for-unix-style-text.html
+ * The suggested work-around from Microsoft engineering is to
+ * turn off buffering until the bug is resolved.
+ */
+ if ((num & BIO_FP_TEXT) != 0)
+ setvbuf((FILE *)ptr, NULL, _IONBF, 0);
# elif defined(OPENSSL_SYS_MSDOS)
int fd = fileno((FILE *)ptr);
/* Set correct text/binary mode */
@@ -270,7 +279,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
else if (num & BIO_FP_READ)
OPENSSL_strlcpy(p, "r", sizeof(p));
else {
- BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE);
+ ERR_raise(ERR_LIB_BIO, BIO_R_BAD_FOPEN_MODE);
ret = 0;
break;
}
@@ -285,16 +294,17 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
# endif
fp = openssl_fopen(ptr, p);
if (fp == NULL) {
- SYSerr(SYS_F_FOPEN, get_last_sys_error());
- ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
- BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
+ ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+ "calling fopen(%s, %s)",
+ (const char *)ptr, p);
+ ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB);
ret = 0;
break;
}
b->ptr = fp;
b->init = 1;
- BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
- * UPLINK */
+ /* we did fopen -> we disengage UPLINK */
+ BIO_clear_flags(b, BIO_FLAGS_UPLINK_INTERNAL);
break;
case BIO_C_GET_FILE_PTR:
/* the ptr parameter is actually a FILE ** in this case. */
@@ -310,12 +320,12 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
b->shutdown = (int)num;
break;
case BIO_CTRL_FLUSH:
- st = b->flags & BIO_FLAGS_UPLINK
+ st = b->flags & BIO_FLAGS_UPLINK_INTERNAL
? UP_fflush(b->ptr) : fflush((FILE *)b->ptr);
if (st == EOF) {
- SYSerr(SYS_F_FFLUSH, get_last_sys_error());
- ERR_add_error_data(1, "fflush()");
- BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
+ ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+ "calling fflush()");
+ ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB);
ret = 0;
}
break;
@@ -339,7 +349,7 @@ static int file_gets(BIO *bp, char *buf, int size)
int ret = 0;
buf[0] = '\0';
- if (bp->flags & BIO_FLAGS_UPLINK) {
+ if (bp->flags & BIO_FLAGS_UPLINK_INTERNAL) {
if (!UP_fgets(buf, size, bp->ptr))
goto err;
} else {
@@ -395,10 +405,8 @@ static int file_free(BIO *a)
static const BIO_METHOD methods_filep = {
BIO_TYPE_FILE,
"FILE pointer",
- /* TODO: Convert to new style write function */
bwrite_conv,
file_write,
- /* TODO: Convert to new style read function */
bread_conv,
file_read,
file_puts,
diff --git a/crypto/bio/bss_log.c b/crypto/bio/bss_log.c
index b9579faaa2a5..63b30e300fec 100644
--- a/crypto/bio/bss_log.c
+++ b/crypto/bio/bss_log.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -87,7 +87,6 @@ static void xcloselog(BIO *bp);
static const BIO_METHOD methods_slg = {
BIO_TYPE_MEM,
"syslog",
- /* TODO: Convert to new style write function */
bwrite_conv,
slg_write,
NULL, /* slg_write_old, */
@@ -196,8 +195,10 @@ static int slg_write(BIO *b, const char *in, int inl)
/* The default */
};
+ if (inl < 0)
+ return 0;
if ((buf = OPENSSL_malloc(inl + 1)) == NULL) {
- BIOerr(BIO_F_SLG_WRITE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(buf, in, inl);
@@ -280,7 +281,7 @@ static void xsyslog(BIO *bp, int priority, const char *string)
break;
}
- sprintf(pidbuf, "[%lu] ", GetCurrentProcessId());
+ BIO_snprintf(pidbuf, sizeof(pidbuf), "[%lu] ", GetCurrentProcessId());
lpszStrings[0] = pidbuf;
lpszStrings[1] = string;
diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c
index 2420b26553e0..9153c1f1cd81 100644
--- a/crypto/bio/bss_mem.c
+++ b/crypto/bio/bss_mem.c
@@ -1,7 +1,7 @@
/*
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -26,10 +26,8 @@ static int mem_buf_sync(BIO *h);
static const BIO_METHOD mem_method = {
BIO_TYPE_MEM,
"memory buffer",
- /* TODO: Convert to new style write function */
bwrite_conv,
mem_write,
- /* TODO: Convert to new style read function */
bread_conv,
mem_read,
mem_puts,
@@ -43,10 +41,8 @@ static const BIO_METHOD mem_method = {
static const BIO_METHOD secmem_method = {
BIO_TYPE_MEM,
"secure memory buffer",
- /* TODO: Convert to new style write function */
bwrite_conv,
mem_write,
- /* TODO: Convert to new style read function */
bread_conv,
mem_read,
mem_puts,
@@ -91,7 +87,7 @@ BIO *BIO_new_mem_buf(const void *buf, int len)
size_t sz;
if (buf == NULL) {
- BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
sz = (len < 0) ? strlen(buf) : (size_t)len;
@@ -176,6 +172,7 @@ static int mem_buf_free(BIO *a)
/*
* Reallocate memory buffer if read pointer differs
+ * NOT FOR RDONLY
*/
static int mem_buf_sync(BIO *b)
{
@@ -220,17 +217,17 @@ static int mem_write(BIO *b, const char *in, int inl)
int blen;
BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
- if (in == NULL) {
- BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER);
- goto end;
- }
if (b->flags & BIO_FLAGS_MEM_RDONLY) {
- BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO);
+ ERR_raise(ERR_LIB_BIO, BIO_R_WRITE_TO_READ_ONLY_BIO);
goto end;
}
BIO_clear_retry_flags(b);
if (inl == 0)
return 0;
+ if (in == NULL) {
+ ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
+ goto end;
+ }
blen = bbm->readp->length;
mem_buf_sync(b);
if (BUF_MEM_grow_clean(bbm->buf, blen + inl) == 0)
@@ -247,12 +244,18 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
long ret = 1;
char **pptr;
BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
- BUF_MEM *bm;
+ BUF_MEM *bm, *bo; /* bio_mem, bio_other */
+ long off, remain;
- if (b->flags & BIO_FLAGS_MEM_RDONLY)
+ if (b->flags & BIO_FLAGS_MEM_RDONLY) {
bm = bbm->buf;
- else
+ bo = bbm->readp;
+ } else {
bm = bbm->readp;
+ bo = bbm->buf;
+ }
+ off = (bm->data == bo->data) ? 0 : bm->data - bo->data;
+ remain = bm->length;
switch (cmd) {
case BIO_CTRL_RESET:
@@ -270,6 +273,18 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
}
}
break;
+ case BIO_C_FILE_SEEK:
+ if (num < 0 || num > off + remain)
+ return -1; /* Can't see outside of the current buffer */
+
+ bm->data = (num != 0) ? bo->data + num : bo->data;
+ bm->length = bo->length - num;
+ bm->max = bo->max - num;
+ off = num;
+ /* FALLTHRU */
+ case BIO_C_FILE_TELL:
+ ret = off;
+ break;
case BIO_CTRL_EOF:
ret = (long)(bm->length == 0);
break;
@@ -280,7 +295,7 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = (long)bm->length;
if (ptr != NULL) {
pptr = (char **)ptr;
- *pptr = (char *)bm->data;
+ *pptr = (char *)(bm->data);
}
break;
case BIO_C_SET_BUF_MEM:
diff --git a/crypto/bio/bss_null.c b/crypto/bio/bss_null.c
index e73ce7841d41..ba266f186c21 100644
--- a/crypto/bio/bss_null.c
+++ b/crypto/bio/bss_null.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -20,10 +20,8 @@ static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static const BIO_METHOD null_method = {
BIO_TYPE_NULL,
"NULL",
- /* TODO: Convert to new style write function */
bwrite_conv,
null_write,
- /* TODO: Convert to new style read function */
bread_conv,
null_read,
null_puts,
diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c
index 6251f3d46a17..f5d88102303a 100644
--- a/crypto/bio/bss_sock.c
+++ b/crypto/bio/bss_sock.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -11,6 +11,7 @@
#include <errno.h>
#include "bio_local.h"
#include "internal/cryptlib.h"
+#include "internal/ktls.h"
#ifndef OPENSSL_NO_SOCK
@@ -37,10 +38,8 @@ int BIO_sock_should_retry(int s);
static const BIO_METHOD methods_sockp = {
BIO_TYPE_SOCKET,
"socket",
- /* TODO: Convert to new style write function */
bwrite_conv,
sock_write,
- /* TODO: Convert to new style read function */
bread_conv,
sock_read,
sock_puts,
@@ -64,6 +63,17 @@ BIO *BIO_new_socket(int fd, int close_flag)
if (ret == NULL)
return NULL;
BIO_set_fd(ret, fd, close_flag);
+# ifndef OPENSSL_NO_KTLS
+ {
+ /*
+ * The new socket is created successfully regardless of ktls_enable.
+ * ktls_enable doesn't change any functionality of the socket, except
+ * changing the setsockopt to enable the processing of ktls_start.
+ * Thus, it is not a problem to call it for non-TLS sockets.
+ */
+ ktls_enable(fd);
+ }
+# endif
return ret;
}
@@ -96,7 +106,12 @@ static int sock_read(BIO *b, char *out, int outl)
if (out != NULL) {
clear_socket_error();
- ret = readsocket(b->num, out, outl);
+# ifndef OPENSSL_NO_KTLS
+ if (BIO_get_ktls_recv(b))
+ ret = ktls_read_record(b->num, out, outl);
+ else
+# endif
+ ret = readsocket(b->num, out, outl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_sock_should_retry(ret))
@@ -110,10 +125,20 @@ static int sock_read(BIO *b, char *out, int outl)
static int sock_write(BIO *b, const char *in, int inl)
{
- int ret;
+ int ret = 0;
clear_socket_error();
- ret = writesocket(b->num, in, inl);
+# ifndef OPENSSL_NO_KTLS
+ if (BIO_should_ktls_ctrl_msg_flag(b)) {
+ unsigned char record_type = (intptr_t)b->ptr;
+ ret = ktls_send_ctrl_message(b->num, record_type, in, inl);
+ if (ret >= 0) {
+ ret = inl;
+ BIO_clear_ktls_ctrl_msg_flag(b);
+ }
+ } else
+# endif
+ ret = writesocket(b->num, in, inl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_sock_should_retry(ret))
@@ -126,6 +151,9 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret = 1;
int *ip;
+# ifndef OPENSSL_NO_KTLS
+ ktls_crypto_info_t *crypto_info;
+# endif
switch (cmd) {
case BIO_C_SET_FD:
@@ -153,8 +181,29 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_CTRL_FLUSH:
ret = 1;
break;
+# ifndef OPENSSL_NO_KTLS
+ case BIO_CTRL_SET_KTLS:
+ crypto_info = (ktls_crypto_info_t *)ptr;
+ ret = ktls_start(b->num, crypto_info, num);
+ if (ret)
+ BIO_set_ktls_flag(b, num);
+ break;
+ case BIO_CTRL_GET_KTLS_SEND:
+ return BIO_should_ktls_flag(b, 1) != 0;
+ case BIO_CTRL_GET_KTLS_RECV:
+ return BIO_should_ktls_flag(b, 0) != 0;
+ case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
+ BIO_set_ktls_ctrl_msg_flag(b);
+ b->ptr = (void *)num;
+ ret = 0;
+ break;
+ case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
+ BIO_clear_ktls_ctrl_msg_flag(b);
+ ret = 0;
+ break;
+# endif
case BIO_CTRL_EOF:
- ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
+ ret = (b->flags & BIO_FLAGS_IN_EOF) != 0;
break;
default:
ret = 0;
diff --git a/crypto/bio/build.info b/crypto/bio/build.info
index d1e7d73c5509..b203ed5e63fe 100644
--- a/crypto/bio/build.info
+++ b/crypto/bio/build.info
@@ -1,8 +1,18 @@
LIBS=../../libcrypto
+
+# Base library
SOURCE[../../libcrypto]=\
bio_lib.c bio_cb.c bio_err.c \
- bss_mem.c bss_null.c bss_fd.c \
- bss_file.c bss_sock.c bss_conn.c \
- bf_null.c bf_buff.c b_print.c b_dump.c b_addr.c \
- b_sock.c b_sock2.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c \
- bss_dgram.c bio_meth.c bf_lbuf.c
+ bio_print.c bio_dump.c bio_addr.c \
+ bio_sock.c bio_sock2.c \
+ bio_meth.c ossl_core_bio.c
+
+# Source / sink implementations
+SOURCE[../../libcrypto]=\
+ bss_null.c bss_mem.c bss_bio.c bss_fd.c bss_file.c \
+ bss_sock.c bss_conn.c bss_acpt.c bss_dgram.c \
+ bss_log.c bss_core.c
+
+# Filters
+SOURCE[../../libcrypto]=\
+ bf_null.c bf_buff.c bf_lbuf.c bf_nbio.c bf_prefix.c bf_readbuff.c
diff --git a/crypto/bio/ossl_core_bio.c b/crypto/bio/ossl_core_bio.c
new file mode 100644
index 000000000000..328302ea34e6
--- /dev/null
+++ b/crypto/bio/ossl_core_bio.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/core.h>
+#include "bio_local.h"
+
+/*-
+ * Core BIO structure
+ * This is distinct from a BIO to prevent casting between the two which could
+ * lead to versioning problems.
+ */
+struct ossl_core_bio_st {
+ CRYPTO_REF_COUNT ref_cnt;
+ CRYPTO_RWLOCK *ref_lock;
+ BIO *bio;
+};
+
+static OSSL_CORE_BIO *core_bio_new(void)
+{
+ OSSL_CORE_BIO *cb = OPENSSL_malloc(sizeof(*cb));
+
+ if (cb == NULL || (cb->ref_lock = CRYPTO_THREAD_lock_new()) == NULL) {
+ OPENSSL_free(cb);
+ return NULL;
+ }
+ cb->ref_cnt = 1;
+ return cb;
+}
+
+int ossl_core_bio_up_ref(OSSL_CORE_BIO *cb)
+{
+ int ref = 0;
+
+ return CRYPTO_UP_REF(&cb->ref_cnt, &ref, cb->ref_lock);
+}
+
+int ossl_core_bio_free(OSSL_CORE_BIO *cb)
+{
+ int ref = 0, res = 1;
+
+ if (cb != NULL) {
+ CRYPTO_DOWN_REF(&cb->ref_cnt, &ref, cb->ref_lock);
+ if (ref <= 0) {
+ res = BIO_free(cb->bio);
+ CRYPTO_THREAD_lock_free(cb->ref_lock);
+ OPENSSL_free(cb);
+ }
+ }
+ return res;
+}
+
+OSSL_CORE_BIO *ossl_core_bio_new_from_bio(BIO *bio)
+{
+ OSSL_CORE_BIO *cb = core_bio_new();
+
+ if (cb == NULL || !BIO_up_ref(bio)) {
+ ossl_core_bio_free(cb);
+ return NULL;
+ }
+ cb->bio = bio;
+ return cb;
+}
+
+static OSSL_CORE_BIO *core_bio_new_from_new_bio(BIO *bio)
+{
+ OSSL_CORE_BIO *cb = NULL;
+
+ if (bio == NULL)
+ return NULL;
+ if ((cb = core_bio_new()) == NULL) {
+ BIO_free(bio);
+ return NULL;
+ }
+ cb->bio = bio;
+ return cb;
+}
+
+OSSL_CORE_BIO *ossl_core_bio_new_file(const char *filename, const char *mode)
+{
+ return core_bio_new_from_new_bio(BIO_new_file(filename, mode));
+}
+
+OSSL_CORE_BIO *ossl_core_bio_new_mem_buf(const void *buf, int len)
+{
+ return core_bio_new_from_new_bio(BIO_new_mem_buf(buf, len));
+}
+
+int ossl_core_bio_read_ex(OSSL_CORE_BIO *cb, void *data, size_t dlen,
+ size_t *readbytes)
+{
+ return BIO_read_ex(cb->bio, data, dlen, readbytes);
+}
+
+int ossl_core_bio_write_ex(OSSL_CORE_BIO *cb, const void *data, size_t dlen,
+ size_t *written)
+{
+ return BIO_write_ex(cb->bio, data, dlen, written);
+}
+
+int ossl_core_bio_gets(OSSL_CORE_BIO *cb, char *buf, int size)
+{
+ return BIO_gets(cb->bio, buf, size);
+}
+
+int ossl_core_bio_puts(OSSL_CORE_BIO *cb, const char *buf)
+{
+ return BIO_puts(cb->bio, buf);
+}
+
+long ossl_core_bio_ctrl(OSSL_CORE_BIO *cb, int cmd, long larg, void *parg)
+{
+ return BIO_ctrl(cb->bio, cmd, larg, parg);
+}
+
+int ossl_core_bio_vprintf(OSSL_CORE_BIO *cb, const char *format, va_list args)
+{
+ return BIO_vprintf(cb->bio, format, args);
+}