mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 15:50:51 +02:00
Merge pull request #10004 from julek-wolfssl/zd/21318
Add custom BIO callback dispatching
This commit is contained in:
@@ -1303,6 +1303,13 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bio->method != NULL && bio->method->ctrlCb != NULL) {
|
||||
long ret;
|
||||
WOLFSSL_MSG("Calling custom BIO ctrl pending callback");
|
||||
ret = bio->method->ctrlCb(bio, WOLFSSL_BIO_CTRL_PENDING, 0, NULL);
|
||||
return (ret < 0) ? 0 : (size_t)ret;
|
||||
}
|
||||
|
||||
if (bio->type == WOLFSSL_BIO_MD ||
|
||||
bio->type == WOLFSSL_BIO_BASE64) {
|
||||
/* these are wrappers only, get next bio */
|
||||
@@ -1713,6 +1720,11 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio)
|
||||
return WOLFSSL_BIO_ERROR;
|
||||
}
|
||||
|
||||
if (bio->method != NULL && bio->method->ctrlCb != NULL) {
|
||||
WOLFSSL_MSG("Calling custom BIO reset callback");
|
||||
return (int)bio->method->ctrlCb(bio, WOLFSSL_BIO_CTRL_RESET, 0, NULL);
|
||||
}
|
||||
|
||||
switch (bio->type) {
|
||||
#ifndef NO_FILESYSTEM
|
||||
case WOLFSSL_BIO_FILE:
|
||||
@@ -2016,6 +2028,13 @@ void* wolfSSL_BIO_get_data(WOLFSSL_BIO* bio)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void wolfSSL_BIO_set_init(WOLFSSL_BIO* bio, int init)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_BIO_set_init");
|
||||
if (bio != NULL)
|
||||
bio->init = (byte)(init != 0);
|
||||
}
|
||||
|
||||
/* If flag is 0 then blocking is set, if 1 then non blocking.
|
||||
* Always returns WOLFSSL_SUCCESS.
|
||||
*/
|
||||
@@ -2184,7 +2203,10 @@ int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p)
|
||||
|
||||
if (bio == NULL)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
|
||||
if (bio->method != NULL && bio->method->ctrlCb != NULL) {
|
||||
WOLFSSL_MSG("Calling custom BIO get mem data callback");
|
||||
return (int)bio->method->ctrlCb(bio, WOLFSSL_BIO_CTRL_INFO, 0, p);
|
||||
}
|
||||
mem_bio = bio;
|
||||
/* Return pointer from last memory BIO in chain */
|
||||
while (bio->next) {
|
||||
@@ -3620,15 +3642,6 @@ int wolfSSL_BIO_new_bio_pair(WOLFSSL_BIO **bio1_p, size_t writebuf1,
|
||||
|
||||
#ifdef OPENSSL_ALL
|
||||
|
||||
#ifndef NO_WOLFSSL_STUB
|
||||
void wolfSSL_BIO_set_init(WOLFSSL_BIO* bio, int init)
|
||||
{
|
||||
WOLFSSL_STUB("wolfSSL_BIO_set_init");
|
||||
(void)bio;
|
||||
(void)init;
|
||||
}
|
||||
#endif /* NO_WOLFSSL_STUB */
|
||||
|
||||
void wolfSSL_BIO_set_shutdown(WOLFSSL_BIO* bio, int shut)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_BIO_set_shutdown");
|
||||
|
||||
@@ -1466,5 +1466,217 @@ int test_wolfSSL_BIO_BIO_ring_read(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Custom BIO backing store for test_wolfSSL_BIO_custom_method */
|
||||
#if defined(OPENSSL_EXTRA)
|
||||
|
||||
static int custom_bio_destroyCalled = 0;
|
||||
|
||||
struct custom_bio_data {
|
||||
char buf[256];
|
||||
int len;
|
||||
byte createCalled:1;
|
||||
byte writeCalled:1;
|
||||
byte readCalled:1;
|
||||
byte putsCalled:1;
|
||||
byte getsCalled:1;
|
||||
byte ctrlCalled:1;
|
||||
};
|
||||
|
||||
static int custom_bio_createCb(WOLFSSL_BIO* bio)
|
||||
{
|
||||
struct custom_bio_data* data;
|
||||
data = (struct custom_bio_data*)XMALLOC(sizeof(*data), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
XMEMSET(data, 0, sizeof(*data));
|
||||
data->createCalled = 1;
|
||||
BIO_set_data(bio, data);
|
||||
BIO_set_init(bio, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int custom_bio_destroyCb(WOLFSSL_BIO* bio)
|
||||
{
|
||||
struct custom_bio_data* data = (struct custom_bio_data*)BIO_get_data(bio);
|
||||
if (data != NULL) {
|
||||
custom_bio_destroyCalled = 1;
|
||||
XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
BIO_set_data(bio, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int custom_bio_writeCb(WOLFSSL_BIO* bio, const char* in, int len)
|
||||
{
|
||||
struct custom_bio_data* data = (struct custom_bio_data*)BIO_get_data(bio);
|
||||
int avail;
|
||||
if (data == NULL || in == NULL || len <= 0)
|
||||
return -1;
|
||||
data->writeCalled = 1;
|
||||
avail = (int)sizeof(data->buf) - data->len;
|
||||
if (len > avail)
|
||||
len = avail;
|
||||
XMEMCPY(data->buf + data->len, in, (size_t)len);
|
||||
data->len += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int custom_bio_readCb(WOLFSSL_BIO* bio, char* out, int len)
|
||||
{
|
||||
struct custom_bio_data* data = (struct custom_bio_data*)BIO_get_data(bio);
|
||||
if (data == NULL || out == NULL || len <= 0)
|
||||
return -1;
|
||||
data->readCalled = 1;
|
||||
if (data->len == 0)
|
||||
return 0;
|
||||
if (len > data->len)
|
||||
len = data->len;
|
||||
XMEMCPY(out, data->buf, (size_t)len);
|
||||
/* shift remaining data */
|
||||
data->len -= len;
|
||||
if (data->len > 0)
|
||||
XMEMMOVE(data->buf, data->buf + len, (size_t)data->len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int custom_bio_putsCb(WOLFSSL_BIO* bio, const char* str)
|
||||
{
|
||||
struct custom_bio_data* data = (struct custom_bio_data*)BIO_get_data(bio);
|
||||
if (str == NULL || data == NULL)
|
||||
return -1;
|
||||
data->putsCalled = 1;
|
||||
return custom_bio_writeCb(bio, str, (int)XSTRLEN(str));
|
||||
}
|
||||
|
||||
static int custom_bio_getsCb(WOLFSSL_BIO* bio, char* buf, int sz)
|
||||
{
|
||||
struct custom_bio_data* data = (struct custom_bio_data*)BIO_get_data(bio);
|
||||
int i;
|
||||
int readLen;
|
||||
if (data == NULL || buf == NULL || sz <= 1)
|
||||
return -1;
|
||||
data->getsCalled = 1;
|
||||
if (data->len == 0)
|
||||
return 0;
|
||||
/* read up to newline or sz-1 bytes */
|
||||
readLen = (sz - 1 < data->len) ? sz - 1 : data->len;
|
||||
for (i = 0; i < readLen; i++) {
|
||||
buf[i] = data->buf[i];
|
||||
if (data->buf[i] == '\n') {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[i] = '\0';
|
||||
/* shift remaining data */
|
||||
data->len -= i;
|
||||
if (data->len > 0)
|
||||
XMEMMOVE(data->buf, data->buf + i, (size_t)data->len);
|
||||
return i;
|
||||
}
|
||||
|
||||
static long custom_bio_ctrlCb(WOLFSSL_BIO* bio, int cmd, long larg, void* parg)
|
||||
{
|
||||
struct custom_bio_data* data = (struct custom_bio_data*)BIO_get_data(bio);
|
||||
(void)larg;
|
||||
if (data == NULL)
|
||||
return -1;
|
||||
data->ctrlCalled = 1;
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_PENDING:
|
||||
return (long)data->len;
|
||||
case BIO_CTRL_RESET:
|
||||
data->len = 0;
|
||||
return WOLFSSL_SUCCESS;
|
||||
case BIO_CTRL_FLUSH:
|
||||
return 1;
|
||||
case BIO_CTRL_INFO:
|
||||
if (parg != NULL)
|
||||
*(char**)parg = data->buf;
|
||||
return (long)data->len;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
|
||||
int test_wolfSSL_BIO_custom_method(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(OPENSSL_EXTRA)
|
||||
BIO_METHOD* method = NULL;
|
||||
BIO* bio = NULL;
|
||||
struct custom_bio_data* data = NULL;
|
||||
char buf[256];
|
||||
char* memPtr = NULL;
|
||||
|
||||
/* Create custom method and set all callbacks */
|
||||
ExpectNotNull(method = BIO_meth_new(WOLFSSL_BIO_UNDEF, "custom_test"));
|
||||
ExpectIntEQ(BIO_meth_set_create(method, custom_bio_createCb),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(BIO_meth_set_destroy(method, custom_bio_destroyCb),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(BIO_meth_set_write(method, custom_bio_writeCb),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(BIO_meth_set_read(method, custom_bio_readCb),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(BIO_meth_set_puts(method, custom_bio_putsCb),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(BIO_meth_set_gets(method, custom_bio_getsCb),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(BIO_meth_set_ctrl(method, custom_bio_ctrlCb),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
/* Create BIO - should invoke createCb */
|
||||
ExpectNotNull(bio = BIO_new(method));
|
||||
ExpectNotNull(data = (struct custom_bio_data*)BIO_get_data(bio));
|
||||
ExpectTrue(data->createCalled);
|
||||
|
||||
/* write */
|
||||
ExpectIntEQ(BIO_write(bio, "hello", 5), 5);
|
||||
ExpectTrue(data->writeCalled);
|
||||
|
||||
/* ctrl_pending via ctrlCb */
|
||||
ExpectIntEQ((int)BIO_ctrl_pending(bio), 5);
|
||||
ExpectTrue(data->ctrlCalled);
|
||||
|
||||
/* read */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
ExpectIntEQ(BIO_read(bio, buf, 5), 5);
|
||||
ExpectBufEQ(buf, "hello", 5);
|
||||
ExpectTrue(data->readCalled);
|
||||
ExpectIntEQ((int)BIO_ctrl_pending(bio), 0);
|
||||
|
||||
/* puts */
|
||||
ExpectIntEQ(BIO_puts(bio, "world\nfoo"), 9);
|
||||
ExpectTrue(data->putsCalled);
|
||||
ExpectIntEQ((int)BIO_ctrl_pending(bio), 9);
|
||||
|
||||
/* gets - should read up to and including first newline */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
ExpectIntEQ(BIO_gets(bio, buf, (int)sizeof(buf)), 6);
|
||||
ExpectStrEQ(buf, "world\n");
|
||||
ExpectTrue(data->getsCalled);
|
||||
ExpectIntEQ((int)BIO_ctrl_pending(bio), 3);
|
||||
|
||||
/* get_mem_data via BIO_CTRL_INFO */
|
||||
ExpectIntEQ(BIO_get_mem_data(bio, &memPtr), 3);
|
||||
ExpectNotNull(memPtr);
|
||||
|
||||
/* reset via ctrlCb */
|
||||
ExpectIntEQ(BIO_reset(bio), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ((int)BIO_ctrl_pending(bio), 0);
|
||||
|
||||
/* free - should invoke destroyCb */
|
||||
custom_bio_destroyCalled = 0;
|
||||
BIO_free(bio);
|
||||
ExpectTrue(custom_bio_destroyCalled);
|
||||
BIO_meth_free(method);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#endif /* !NO_BIO */
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ int test_wolfSSL_BIO_reset(void);
|
||||
int test_wolfSSL_BIO_get_len(void);
|
||||
int test_wolfSSL_BIO(void);
|
||||
int test_wolfSSL_BIO_BIO_ring_read(void);
|
||||
int test_wolfSSL_BIO_custom_method(void);
|
||||
|
||||
#define TEST_OSSL_BIO_DECLS \
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_gets), \
|
||||
@@ -56,7 +57,8 @@ int test_wolfSSL_BIO_BIO_ring_read(void);
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_reset), \
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_get_len), \
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO), \
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_BIO_ring_read)
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_BIO_ring_read), \
|
||||
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_custom_method)
|
||||
|
||||
#define TEST_OSSL_BIO_TLS_DECLS \
|
||||
TEST_DECL_GROUP("ossl_bio_tls", test_wolfSSL_BIO_connect), \
|
||||
|
||||
Reference in New Issue
Block a user