summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2016-09-05 17:26:58 +0100
committerMatt Caswell <matt@openssl.org>2016-10-28 09:48:54 +0100
commitd07aee2c7a33e77d97d8e13811af3637e3849cb2 (patch)
tree1c3452687dbd734f4e739713f29fbf770f5524dd
parent229bd12487f8576fc088dc4f641950ac33c62033 (diff)
Create BIO_read_ex() which handles size_t arguments
Also extend BIO_METHOD to be able to supply an implementation for the new BIO_read function. Reviewed-by: Richard Levitte <levitte@openssl.org>
-rw-r--r--crypto/asn1/bio_asn1.c2
-rw-r--r--crypto/bio/bf_buff.c2
-rw-r--r--crypto/bio/bf_lbuf.c2
-rw-r--r--crypto/bio/bf_nbio.c2
-rw-r--r--crypto/bio/bf_null.c2
-rw-r--r--crypto/bio/bio_err.c1
-rw-r--r--crypto/bio/bio_lcl.h3
-rw-r--r--crypto/bio/bio_lib.c118
-rw-r--r--crypto/bio/bio_meth.c33
-rw-r--r--crypto/bio/bss_acpt.c2
-rw-r--r--crypto/bio/bss_bio.c2
-rw-r--r--crypto/bio/bss_conn.c2
-rw-r--r--crypto/bio/bss_dgram.c2
-rw-r--r--crypto/bio/bss_fd.c2
-rw-r--r--crypto/bio/bss_file.c2
-rw-r--r--crypto/bio/bss_log.c1
-rw-r--r--crypto/bio/bss_mem.c4
-rw-r--r--crypto/bio/bss_null.c2
-rw-r--r--crypto/bio/bss_sock.c2
-rw-r--r--crypto/evp/bio_b64.c2
-rw-r--r--crypto/evp/bio_enc.c2
-rw-r--r--crypto/evp/bio_md.c2
-rw-r--r--crypto/evp/bio_ok.c2
-rw-r--r--include/internal/bio.h7
-rw-r--r--include/openssl/bio.h13
-rw-r--r--ssl/bio_ssl.c16
-rw-r--r--util/libcrypto.num5
27 files changed, 210 insertions, 25 deletions
diff --git a/crypto/asn1/bio_asn1.c b/crypto/asn1/bio_asn1.c
index d3cc108ed3..d270b3313d 100644
--- a/crypto/asn1/bio_asn1.c
+++ b/crypto/asn1/bio_asn1.c
@@ -79,6 +79,8 @@ static const BIO_METHOD methods_asn1 = {
BIO_TYPE_ASN1,
"asn1",
asn1_bio_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
asn1_bio_read,
asn1_bio_puts,
asn1_bio_gets,
diff --git a/crypto/bio/bf_buff.c b/crypto/bio/bf_buff.c
index b2a387b53a..fc0b8fa648 100644
--- a/crypto/bio/bf_buff.c
+++ b/crypto/bio/bf_buff.c
@@ -26,6 +26,8 @@ static const BIO_METHOD methods_buffer = {
BIO_TYPE_BUFFER,
"buffer",
buffer_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
buffer_read,
buffer_puts,
buffer_gets,
diff --git a/crypto/bio/bf_lbuf.c b/crypto/bio/bf_lbuf.c
index b3c2b5eeb6..c3b1a1ff3e 100644
--- a/crypto/bio/bf_lbuf.c
+++ b/crypto/bio/bf_lbuf.c
@@ -31,6 +31,8 @@ static const BIO_METHOD methods_linebuffer = {
BIO_TYPE_LINEBUFFER,
"linebuffer",
linebuffer_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
linebuffer_read,
linebuffer_puts,
linebuffer_gets,
diff --git a/crypto/bio/bf_nbio.c b/crypto/bio/bf_nbio.c
index 364d9fb5ae..32698432c6 100644
--- a/crypto/bio/bf_nbio.c
+++ b/crypto/bio/bf_nbio.c
@@ -35,6 +35,8 @@ static const BIO_METHOD methods_nbiof = {
BIO_TYPE_NBIO_TEST,
"non-blocking IO test filter",
nbiof_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
nbiof_read,
nbiof_puts,
nbiof_gets,
diff --git a/crypto/bio/bf_null.c b/crypto/bio/bf_null.c
index 0736b3f2fc..ed7bd98d75 100644
--- a/crypto/bio/bf_null.c
+++ b/crypto/bio/bf_null.c
@@ -28,6 +28,8 @@ static const BIO_METHOD methods_nullf = {
BIO_TYPE_NULL_FILTER,
"NULL filter",
nullf_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
nullf_read,
nullf_puts,
nullf_gets,
diff --git a/crypto/bio/bio_err.c b/crypto/bio/bio_err.c
index 98c90d6e52..21f7b4c0b9 100644
--- a/crypto/bio/bio_err.c
+++ b/crypto/bio/bio_err.c
@@ -44,6 +44,7 @@ static ERR_STRING_DATA BIO_str_functs[] = {
{ERR_FUNC(BIO_F_BIO_PARSE_HOSTSERV), "BIO_parse_hostserv"},
{ERR_FUNC(BIO_F_BIO_PUTS), "BIO_puts"},
{ERR_FUNC(BIO_F_BIO_READ), "BIO_read"},
+ {ERR_FUNC(BIO_F_BIO_READ_EX), "BIO_read_ex"},
{ERR_FUNC(BIO_F_BIO_SOCKET), "BIO_socket"},
{ERR_FUNC(BIO_F_BIO_SOCKET_NBIO), "BIO_socket_nbio"},
{ERR_FUNC(BIO_F_BIO_SOCK_INFO), "BIO_sock_info"},
diff --git a/crypto/bio/bio_lcl.h b/crypto/bio/bio_lcl.h
index 39178cf50a..d46f4e745c 100644
--- a/crypto/bio/bio_lcl.h
+++ b/crypto/bio/bio_lcl.h
@@ -114,7 +114,8 @@ typedef struct bio_f_buffer_ctx_struct {
struct bio_st {
const BIO_METHOD *method;
/* bio, mode, argp, argi, argl, ret */
- long (*callback) (struct bio_st *, int, const char *, int, long, long);
+ BIO_callback_fn callback;
+ BIO_callback_fn_ex callback_ex;
char *cb_arg; /* first argument for the callback */
int init;
int shutdown;
diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c
index 62392c3a52..c3633f255f 100644
--- a/crypto/bio/bio_lib.c
+++ b/crypto/bio/bio_lib.c
@@ -142,18 +142,26 @@ void BIO_set_flags(BIO *b, int flags)
b->flags |= flags;
}
-long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *,
- int, long, long) {
+BIO_callback_fn BIO_get_callback(const BIO *b)
+{
return b->callback;
}
-void BIO_set_callback(BIO *b,
- long (*cb) (struct bio_st *, int, const char *, int,
- long, long))
+void BIO_set_callback(BIO *b, BIO_callback_fn cb)
{
b->callback = cb;
}
+BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b)
+{
+ return b->callback_ex;
+}
+
+void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex cb)
+{
+ b->callback_ex = cb;
+}
+
void BIO_set_callback_arg(BIO *b, char *arg)
{
b->cb_arg = arg;
@@ -174,34 +182,104 @@ int BIO_method_type(const BIO *b)
return b->method->type;
}
+static int bio_call_callback(BIO *b, int oper, const char *argp, size_t len,
+ int argi, long argl, int inret, size_t *processed,
+ long *lret)
+{
+ long ret;
+ int bareoper;
+
+ if (b->callback_ex != NULL) {
+ return b->callback_ex(b, oper, argp, len, argi, argl, inret, processed,
+ lret);
+ }
+
+ /* Strip off the BIO_CB_RETURN flag */
+ bareoper = oper & ~BIO_CB_RETURN;
+ /*
+ * We have an old style callback, so we will have to do nasty casts and
+ * check for overflows.
+ */
+ if (bareoper == BIO_CB_READ || bareoper == BIO_CB_WRITE
+ || bareoper == BIO_CB_GETS) {
+ /* In this case |len| is set, and should be used instead of |argi| */
+ if (len > INT_MAX)
+ return 0;
+
+ argi = (int)len;
+
+ if (inret && (oper & BIO_CB_RETURN)) {
+ if (*processed > INT_MAX)
+ return 0;
+ inret = *processed;
+ }
+ }
+
+ ret = b->callback(b, oper, argp, argi, argl, inret);
+ if (bareoper == BIO_CB_CTRL)
+ return 1;
+
+ if (ret > INT_MAX || ret < INT_MIN)
+ return 0;
+
+ if (lret != NULL)
+ *lret = ret;
+
+ if (ret >= 0) {
+ *processed = (size_t)ret;
+ ret = 1;
+ }
+
+ return (int)ret;
+}
+
int BIO_read(BIO *b, void *out, int outl)
{
- int i;
- long (*cb) (BIO *, int, const char *, int, long, long);
+ size_t read;
+ int ret;
+
+ if (outl < 0)
+ return 0;
+
+ ret = BIO_read_ex(b, out, (size_t)outl, &read);
+
+ if (ret > 0) {
+ /* *read should always be <= outl */
+ ret = (int)read;
+ }
+
+ return ret;
+}
+
+int BIO_read_ex(BIO *b, void *out, size_t outl, size_t *read)
+{
+ int ret;
if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) {
- BIOerr(BIO_F_BIO_READ, BIO_R_UNSUPPORTED_METHOD);
+ BIOerr(BIO_F_BIO_READ_EX, BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
- cb = b->callback;
- if ((cb != NULL) &&
- ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0))
- return (i);
+ if ((b->callback != NULL || b->callback_ex != NULL) &&
+ ((ret = bio_call_callback(b, BIO_CB_READ, out, outl, 0, 0L, 1L, read,
+ NULL)) <= 0))
+ return ret;
if (!b->init) {
- BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED);
- return (-2);
+ BIOerr(BIO_F_BIO_READ_EX, BIO_R_UNINITIALIZED);
+ return -2;
}
- i = b->method->bread(b, out, outl);
+ ret = b->method->bread(b, out, outl, read);
- if (i > 0)
- b->num_read += (uint64_t)i;
+ if (ret > 0)
+ b->num_read += (uint64_t)*read;
- if (cb != NULL)
- i = (int)cb(b, BIO_CB_READ | BIO_CB_RETURN, out, outl, 0L, (long)i);
- return (i);
+ if (b->callback != NULL || b->callback_ex != NULL)
+ ret = bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, out, outl, 0,
+ 0L, ret, read, NULL);
+
+ return ret;
}
int BIO_write(BIO *b, const void *in, int inl)
diff --git a/crypto/bio/bio_meth.c b/crypto/bio/bio_meth.c
index c5f9f7e8e7..c10f8d01d1 100644
--- a/crypto/bio/bio_meth.c
+++ b/crypto/bio/bio_meth.c
@@ -63,12 +63,45 @@ int BIO_meth_set_write(BIO_METHOD *biom,
int (*BIO_meth_get_read(BIO_METHOD *biom)) (BIO *, char *, int)
{
+ return biom->bread_old;
+}
+
+int (*BIO_meth_get_read_ex(BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *)
+{
return biom->bread;
}
+/* Conversion for old style bread to new style */
+int bread_conv(BIO *bio, char *out, size_t outl, size_t *read)
+{
+ int ret;
+
+ if (outl > INT_MAX)
+ return 0;
+
+ ret = bio->method->bread_old(bio, out, (int)outl);
+
+ if (ret <= 0) {
+ *read = 0;
+ return ret;
+ }
+
+ *read = (size_t)ret;
+
+ return 1;
+}
+
int BIO_meth_set_read(BIO_METHOD *biom,
int (*bread) (BIO *, char *, int))
{
+ biom->bread_old = bread;
+ biom->bread = bread_conv;
+ return 1;
+}
+
+int BIO_meth_set_read_ex(BIO_METHOD *biom,
+ int (*bread) (BIO *, char *, size_t, size_t *))
+{
biom->bread = bread;
return 1;
}
diff --git a/crypto/bio/bss_acpt.c b/crypto/bio/bss_acpt.c
index 6fb971a50d..5151ff61c6 100644
--- a/crypto/bio/bss_acpt.c
+++ b/crypto/bio/bss_acpt.c
@@ -55,6 +55,8 @@ static const BIO_METHOD methods_acceptp = {
BIO_TYPE_ACCEPT,
"socket accept",
acpt_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
acpt_read,
acpt_puts,
NULL, /* connect_gets, */
diff --git a/crypto/bio/bss_bio.c b/crypto/bio/bss_bio.c
index de34f6bf37..ce775601f0 100644
--- a/crypto/bio/bss_bio.c
+++ b/crypto/bio/bss_bio.c
@@ -40,6 +40,8 @@ static const BIO_METHOD methods_biop = {
BIO_TYPE_BIO,
"BIO pair",
bio_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
bio_read,
bio_puts,
NULL /* no bio_gets */ ,
diff --git a/crypto/bio/bss_conn.c b/crypto/bio/bss_conn.c
index dfd0988dfb..eff3f68144 100644
--- a/crypto/bio/bss_conn.c
+++ b/crypto/bio/bss_conn.c
@@ -59,6 +59,8 @@ static const BIO_METHOD methods_connectp = {
BIO_TYPE_CONNECT,
"socket connect",
conn_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
conn_read,
conn_puts,
NULL, /* connect_gets, */
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
index 6dfcc9ba7b..6e5d482774 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -74,6 +74,8 @@ static const BIO_METHOD methods_dgramp = {
BIO_TYPE_DGRAM,
"datagram socket",
dgram_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
dgram_read,
dgram_puts,
NULL, /* dgram_gets, */
diff --git a/crypto/bio/bss_fd.c b/crypto/bio/bss_fd.c
index 1e56cb62df..78bbfd6f3b 100644
--- a/crypto/bio/bss_fd.c
+++ b/crypto/bio/bss_fd.c
@@ -60,6 +60,8 @@ int BIO_fd_should_retry(int s);
static const BIO_METHOD methods_fdp = {
BIO_TYPE_FD, "file descriptor",
fd_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
fd_read,
fd_puts,
fd_gets,
diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c
index 6af2d9cb87..00684ae640 100644
--- a/crypto/bio/bss_file.c
+++ b/crypto/bio/bss_file.c
@@ -52,6 +52,8 @@ static const BIO_METHOD methods_filep = {
BIO_TYPE_FILE,
"FILE pointer",
file_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
file_read,
file_puts,
file_gets,
diff --git a/crypto/bio/bss_log.c b/crypto/bio/bss_log.c
index 6cbde4d2fe..f262cc9d18 100644
--- a/crypto/bio/bss_log.c
+++ b/crypto/bio/bss_log.c
@@ -88,6 +88,7 @@ static const BIO_METHOD methods_slg = {
BIO_TYPE_MEM, "syslog",
slg_write,
NULL,
+ NULL,
slg_puts,
NULL,
slg_ctrl,
diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c
index 6dc075dc61..81f7fc6d9e 100644
--- a/crypto/bio/bss_mem.c
+++ b/crypto/bio/bss_mem.c
@@ -27,6 +27,8 @@ static const BIO_METHOD mem_method = {
BIO_TYPE_MEM,
"memory buffer",
mem_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
mem_read,
mem_puts,
mem_gets,
@@ -40,6 +42,8 @@ static const BIO_METHOD secmem_method = {
BIO_TYPE_MEM,
"secure memory buffer",
mem_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
mem_read,
mem_puts,
mem_gets,
diff --git a/crypto/bio/bss_null.c b/crypto/bio/bss_null.c
index e5c4adc874..90c9ee1618 100644
--- a/crypto/bio/bss_null.c
+++ b/crypto/bio/bss_null.c
@@ -23,6 +23,8 @@ static const BIO_METHOD null_method = {
BIO_TYPE_NULL,
"NULL",
null_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
null_read,
null_puts,
null_gets,
diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c
index 570e8985af..42f0f90b65 100644
--- a/crypto/bio/bss_sock.c
+++ b/crypto/bio/bss_sock.c
@@ -39,6 +39,8 @@ static const BIO_METHOD methods_sockp = {
BIO_TYPE_SOCKET,
"socket",
sock_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
sock_read,
sock_puts,
NULL, /* sock_gets, */
diff --git a/crypto/evp/bio_b64.c b/crypto/evp/bio_b64.c
index 32a884a711..2647be0233 100644
--- a/crypto/evp/bio_b64.c
+++ b/crypto/evp/bio_b64.c
@@ -49,6 +49,8 @@ typedef struct b64_struct {
static const BIO_METHOD methods_b64 = {
BIO_TYPE_BASE64, "base64 encoding",
b64_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
b64_read,
b64_puts,
NULL, /* b64_gets, */
diff --git a/crypto/evp/bio_enc.c b/crypto/evp/bio_enc.c
index 5a3beef97f..fff3e2735e 100644
--- a/crypto/evp/bio_enc.c
+++ b/crypto/evp/bio_enc.c
@@ -48,6 +48,8 @@ typedef struct enc_struct {
static const BIO_METHOD methods_enc = {
BIO_TYPE_CIPHER, "cipher",
enc_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
enc_read,
NULL, /* enc_puts, */
NULL, /* enc_gets, */
diff --git a/crypto/evp/bio_md.c b/crypto/evp/bio_md.c
index cd968ec2d4..7c61d0f3c0 100644
--- a/crypto/evp/bio_md.c
+++ b/crypto/evp/bio_md.c
@@ -34,6 +34,8 @@ static long md_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
static const BIO_METHOD methods_md = {
BIO_TYPE_MD, "message digest",
md_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
md_read,
NULL, /* md_puts, */
md_gets,
diff --git a/crypto/evp/bio_ok.c b/crypto/evp/bio_ok.c
index 7974b96311..0a15680c4b 100644
--- a/crypto/evp/bio_ok.c
+++ b/crypto/evp/bio_ok.c
@@ -110,6 +110,8 @@ typedef struct ok_struct {
static const BIO_METHOD methods_ok = {
BIO_TYPE_CIPHER, "reliable",
ok_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
ok_read,
NULL, /* ok_puts, */
NULL, /* ok_gets, */
diff --git a/include/internal/bio.h b/include/internal/bio.h
index 3b6a6ac4d2..f840bcd32c 100644
--- a/include/internal/bio.h
+++ b/include/internal/bio.h
@@ -13,7 +13,8 @@ struct bio_method_st {
int type;
const char *name;
int (*bwrite) (BIO *, const char *, int);
- int (*bread) (BIO *, char *, int);
+ int (*bread) (BIO *, char *, size_t, size_t *);
+ int (*bread_old) (BIO *, char *, int);
int (*bputs) (BIO *, const char *);
int (*bgets) (BIO *, char *, int);
long (*ctrl) (BIO *, int, long, void *);
@@ -24,3 +25,7 @@ struct bio_method_st {
void bio_free_ex_data(BIO *bio);
void bio_cleanup(void);
+
+
+/* Old style to new style BIO_METHOD conversion functions */
+int bread_conv(BIO *bio, char *out, size_t outl, size_t *read);
diff --git a/include/openssl/bio.h b/include/openssl/bio.h
index 9bc941b25f..b4b1e0acbc 100644
--- a/include/openssl/bio.h
+++ b/include/openssl/bio.h
@@ -239,8 +239,16 @@ void BIO_clear_flags(BIO *b, int flags);
typedef long (*BIO_callback_fn)(BIO *b, int oper, const char *argp, int argi,
long argl, long ret);
+typedef long (*BIO_callback_fn_ex)(BIO *b, int oper, const char *argp,
+ size_t len, int argi,
+ long argl, int ret, size_t *processed,
+ long *lret);
BIO_callback_fn BIO_get_callback(const BIO *b);
void BIO_set_callback(BIO *b, BIO_callback_fn callback);
+
+BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b);
+void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex callback);
+
char *BIO_get_callback_arg(const BIO *b);
void BIO_set_callback_arg(BIO *b, char *arg);
@@ -545,6 +553,7 @@ int BIO_get_shutdown(BIO *a);
void BIO_vfree(BIO *a);
int BIO_up_ref(BIO *a);
int BIO_read(BIO *b, void *data, int len);
+int BIO_read_ex(BIO *b, void *out, size_t outl, size_t *read);
int BIO_gets(BIO *bp, char *buf, int size);
int BIO_write(BIO *b, const void *data, int len);
int BIO_puts(BIO *bp, const char *buf);
@@ -737,8 +746,11 @@ int (*BIO_meth_get_write(BIO_METHOD *biom)) (BIO *, const char *, int);
int BIO_meth_set_write(BIO_METHOD *biom,
int (*write) (BIO *, const char *, int));
int (*BIO_meth_get_read(BIO_METHOD *biom)) (BIO *, char *, int);
+int (*BIO_meth_get_read_ex(BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *);
int BIO_meth_set_read(BIO_METHOD *biom,
int (*read) (BIO *, char *, int));
+int BIO_meth_set_read_ex(BIO_METHOD *biom,
+ int (*bread) (BIO *, char *, size_t, size_t *));
int (*BIO_meth_get_puts(BIO_METHOD *biom)) (BIO *, const char *);
int BIO_meth_set_puts(BIO_METHOD *biom,
int (*puts) (BIO *, const char *));
@@ -794,6 +806,7 @@ int ERR_load_BIO_strings(void);
# define BIO_F_BIO_PARSE_HOSTSERV 136
# define BIO_F_BIO_PUTS 110
# define BIO_F_BIO_READ 111
+# define BIO_F_BIO_READ_EX 105
# define BIO_F_BIO_SOCKET 140
# define BIO_F_BIO_SOCKET_NBIO 142
# define BIO_F_BIO_SOCK_INFO 141
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c
index 3dd09cf52d..59a04a3995 100644
--- a/ssl/bio_ssl.c
+++ b/ssl/bio_ssl.c
@@ -17,7 +17,7 @@
#include "ssl_locl.h"
static int ssl_write(BIO *h, const char *buf, int num);
-static int ssl_read(BIO *h, char *buf, int size);
+static int ssl_read(BIO *b, char *out, size_t outl, size_t *read);
static int ssl_puts(BIO *h, const char *str);
static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int ssl_new(BIO *h);
@@ -37,6 +37,7 @@ static const BIO_METHOD methods_sslp = {
BIO_TYPE_SSL, "ssl",
ssl_write,
ssl_read,
+ NULL,
ssl_puts,
NULL, /* ssl_gets, */
ssl_ctrl,
@@ -86,7 +87,7 @@ static int ssl_free(BIO *a)
return 1;
}
-static int ssl_read(BIO *b, char *out, int outl)
+static int ssl_read(BIO *b, char *out, size_t outl, size_t *read)
{
int ret = 1;
BIO_SSL *sb;
@@ -101,6 +102,9 @@ static int ssl_read(BIO *b, char *out, int outl)
BIO_clear_retry_flags(b);
+ if (outl > INT_MAX)
+ return -1;
+
ret = SSL_read(ssl, out, outl);
switch (SSL_get_error(ssl, ret)) {
@@ -154,7 +158,13 @@ static int ssl_read(BIO *b, char *out, int outl)
}
BIO_set_retry_reason(b, retry_reason);
- return (ret);
+
+ if (ret < 0)
+ return ret;
+
+ *read = (size_t)ret;
+
+ return 1;
}
static int ssl_write(BIO *b, const char *out, int outl)
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 21d46d27ba..0b7917b9f2 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4208,3 +4208,8 @@ OCSP_RESPID_set_by_key 4158 1_1_0a EXIST::FUNCTION:OCSP
OCSP_RESPID_match 4159 1_1_0a EXIST::FUNCTION:OCSP
ASN1_ITEM_lookup 4160 1_1_1 EXIST::FUNCTION:
ASN1_ITEM_get 4161 1_1_1 EXIST::FUNCTION:
+BIO_read_ex 4162 1_1_1 EXIST::FUNCTION:
+BIO_set_callback_ex 4163 1_1_1 EXIST::FUNCTION:
+BIO_get_callback_ex 4164 1_1_1 EXIST::FUNCTION:
+BIO_meth_set_read_ex 4165 1_1_1 EXIST::FUNCTION:
+BIO_meth_get_read_ex 4166 1_1_1 EXIST::FUNCTION: