Skip to content

Commit 578735e

Browse files
Merge pull request #7169 from julek-wolfssl/gh/7160
BIO_BIO: BIO_{write|read} on a BIO pair should wrap around ring buffer
2 parents a13d107 + 4f1d777 commit 578735e

3 files changed

Lines changed: 87 additions & 26 deletions

File tree

src/bio.c

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,31 @@ static int wolfSSL_BIO_BASE64_read(WOLFSSL_BIO* bio, void* buf, int len)
7070
*/
7171
static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
7272
{
73-
int sz;
73+
int sz1;
74+
int sz2;
7475
char* pt;
7576

76-
sz = wolfSSL_BIO_nread(bio, &pt, len);
77+
if (buf == NULL || len == 0)
78+
return 0;
7779

78-
if (sz > 0) {
79-
XMEMCPY(buf, pt, sz);
80+
sz1 = wolfSSL_BIO_nread(bio, &pt, len);
81+
if (sz1 > 0) {
82+
XMEMCPY(buf, pt, sz1);
83+
buf = (char*)buf + sz1;
84+
len -= sz1;
85+
if (len > 0) {
86+
/* try again to see if maybe we wrapped around the ring buffer */
87+
sz2 = wolfSSL_BIO_nread(bio, &pt, len);
88+
if (sz2 > 0) {
89+
XMEMCPY(buf, pt, sz2);
90+
sz1 += sz2;
91+
}
92+
}
8093
}
94+
if (sz1 == 0)
95+
sz1 = -1;
8196

82-
return sz;
97+
return sz1;
8398
}
8499

85100
#ifndef WOLFSSL_BIO_RESIZE_THRESHOLD
@@ -470,35 +485,47 @@ static int wolfSSL_BIO_SSL_write(WOLFSSL_BIO* bio, const void* data,
470485
}
471486
#endif /* WOLFCRYPT_ONLY */
472487

473-
474488
/* Writes to a WOLFSSL_BIO_BIO type.
475489
*
476490
* returns the amount written on success
477491
*/
478492
static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data,
479493
int len)
480494
{
481-
int sz;
495+
int sz1;
496+
int sz2;
482497
char* buf;
483498

484499
WOLFSSL_ENTER("wolfSSL_BIO_BIO_write");
485500

486501
/* adding in sanity checks for static analysis tools */
487-
if (bio == NULL || data == NULL) {
488-
return BAD_FUNC_ARG;
489-
}
490-
491-
sz = wolfSSL_BIO_nwrite(bio, &buf, len);
502+
if (bio == NULL || data == NULL || len == 0)
503+
return 0;
492504

493-
/* test space for write */
494-
if (sz <= 0) {
505+
sz1 = wolfSSL_BIO_nwrite(bio, &buf, len);
506+
if (sz1 == 0) {
495507
WOLFSSL_MSG("No room left to write");
496-
return sz;
508+
return WOLFSSL_BIO_ERROR;
509+
}
510+
if (sz1 < 0) {
511+
WOLFSSL_MSG("Error in wolfSSL_BIO_nwrite");
512+
return sz1;
513+
}
514+
XMEMCPY(buf, data, sz1);
515+
data = (char*)data + sz1;
516+
len -= sz1;
517+
518+
if (len > 0) {
519+
/* try again to see if maybe we wrapped around the ring buffer */
520+
sz2 = wolfSSL_BIO_nwrite(bio, &buf, len);
521+
if (sz2 > 0) {
522+
XMEMCPY(buf, data, sz2);
523+
sz1 += sz2;
524+
}
497525
}
498526

499-
XMEMCPY(buf, data, sz);
500527

501-
return sz;
528+
return sz1;
502529
}
503530

504531

@@ -907,7 +934,7 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz)
907934
char* c;
908935
int cSz;
909936
cSz = wolfSSL_BIO_nread0(bio, &c);
910-
if (cSz == 0) {
937+
if (cSz <= 0) {
911938
ret = 0; /* Nothing to read */
912939
buf[0] = '\0';
913940
break;
@@ -1297,7 +1324,7 @@ int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf)
12971324

12981325
if (bio == NULL || buf == NULL) {
12991326
WOLFSSL_MSG("NULL argument passed in");
1300-
return 0;
1327+
return -2;
13011328
}
13021329

13031330
/* if paired read from pair */
@@ -1314,7 +1341,7 @@ int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf)
13141341
}
13151342
}
13161343

1317-
return 0;
1344+
return -2;
13181345
}
13191346

13201347

@@ -1343,7 +1370,7 @@ int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num)
13431370

13441371
/* get amount able to read and set buffer pointer */
13451372
sz = wolfSSL_BIO_nread0(bio, buf);
1346-
if (sz == 0) {
1373+
if (sz < 0) {
13471374
return WOLFSSL_BIO_ERROR;
13481375
}
13491376

tests/api.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36801,19 +36801,22 @@ static int test_wolfSSL_Tls12_Key_Logging_test(void)
3680136801
/* clean up keylog file */
3680236802
ExpectTrue((fp = XFOPEN("./MyKeyLog.txt", "w")) != XBADFILE);
3680336803
if (fp != XBADFILE) {
36804+
XFFLUSH(fp);
3680436805
XFCLOSE(fp);
3680536806
fp = XBADFILE;
3680636807
}
3680736808

3680836809
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
3680936810
&server_cbf, NULL), TEST_SUCCESS);
36811+
XSLEEP_MS(100);
3681036812

3681136813
/* check if the keylog file exists */
3681236814

3681336815
char buff[300] = {0};
3681436816
int found = 0;
3681536817

3681636818
ExpectTrue((fp = XFOPEN("./MyKeyLog.txt", "r")) != XBADFILE);
36819+
XFFLUSH(fp); /* Just to make sure any buffers get flushed */
3681736820

3681836821
while (EXPECT_SUCCESS() && XFGETS(buff, (int)sizeof(buff), fp) != NULL) {
3681936822
if (0 == strncmp(buff,"CLIENT_RANDOM ", sizeof("CLIENT_RANDOM ")-1)) {
@@ -39231,12 +39234,12 @@ static int test_wolfSSL_BIO(void)
3923139234
for (i = 0; i < 20; i++) {
3923239235
ExpectIntEQ((int)bufPt[i], i);
3923339236
}
39234-
ExpectIntEQ(BIO_nread(bio2, &bufPt, 1), WOLFSSL_BIO_ERROR);
39237+
ExpectIntEQ(BIO_nread(bio2, &bufPt, 1), 0);
3923539238
ExpectIntEQ(BIO_nread(bio1, &bufPt, (int)BIO_ctrl_pending(bio1)), 8);
3923639239
for (i = 0; i < 8; i++) {
3923739240
ExpectIntEQ((int)bufPt[i], i);
3923839241
}
39239-
ExpectIntEQ(BIO_nread(bio1, &bufPt, 1), WOLFSSL_BIO_ERROR);
39242+
ExpectIntEQ(BIO_nread(bio1, &bufPt, 1), 0);
3924039243
ExpectIntEQ(BIO_ctrl_reset_read_request(bio1), 1);
3924139244

3924239245
/* new pair */
@@ -39245,7 +39248,7 @@ static int test_wolfSSL_BIO(void)
3924539248
bio2 = NULL;
3924639249
ExpectIntEQ(BIO_make_bio_pair(bio1, bio3), WOLFSSL_SUCCESS);
3924739250
ExpectIntEQ((int)BIO_ctrl_pending(bio3), 0);
39248-
ExpectIntEQ(BIO_nread(bio3, &bufPt, 10), WOLFSSL_BIO_ERROR);
39251+
ExpectIntEQ(BIO_nread(bio3, &bufPt, 10), 0);
3924939252

3925039253
/* test wrap around... */
3925139254
ExpectIntEQ(BIO_reset(bio1), 0);
@@ -39293,7 +39296,7 @@ static int test_wolfSSL_BIO(void)
3929339296
/* test reset on data in bio1 write buffer */
3929439297
ExpectIntEQ(BIO_reset(bio1), 0);
3929539298
ExpectIntEQ((int)BIO_ctrl_pending(bio3), 0);
39296-
ExpectIntEQ(BIO_nread(bio3, &bufPt, 3), WOLFSSL_BIO_ERROR);
39299+
ExpectIntEQ(BIO_nread(bio3, &bufPt, 3), 0);
3929739300
ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20);
3929839301
ExpectIntEQ((int)BIO_ctrl(bio1, BIO_CTRL_INFO, 0, &p), 20);
3929939302
ExpectNotNull(p);
@@ -39408,6 +39411,35 @@ static int test_wolfSSL_BIO(void)
3940839411
return EXPECT_RESULT();
3940939412
}
3941039413

39414+
static int test_wolfSSL_BIO_BIO_ring_read(void)
39415+
{
39416+
EXPECT_DECLS;
39417+
#if defined(OPENSSL_ALL)
39418+
BIO* bio1 = NULL;
39419+
BIO* bio2 = NULL;
39420+
byte data[50];
39421+
byte tmp[50];
39422+
39423+
XMEMSET(data, 42, sizeof(data));
39424+
39425+
39426+
ExpectIntEQ(BIO_new_bio_pair(&bio1, sizeof(data), &bio2, sizeof(data)),
39427+
SSL_SUCCESS);
39428+
39429+
ExpectIntEQ(BIO_write(bio1, data, 40), 40);
39430+
ExpectIntEQ(BIO_read(bio1, tmp, 20), -1);
39431+
ExpectIntEQ(BIO_read(bio2, tmp, 20), 20);
39432+
ExpectBufEQ(tmp, data, 20);
39433+
ExpectIntEQ(BIO_write(bio1, data, 20), 20);
39434+
ExpectIntEQ(BIO_read(bio2, tmp, 40), 40);
39435+
ExpectBufEQ(tmp, data, 40);
39436+
39437+
BIO_free(bio1);
39438+
BIO_free(bio2);
39439+
#endif
39440+
return EXPECT_RESULT();
39441+
}
39442+
3941139443
#endif /* !NO_BIO */
3941239444

3941339445

@@ -69722,6 +69754,7 @@ TEST_CASE testCases[] = {
6972269754
TEST_DECL(test_wolfSSL_PEM_file_RSAPrivateKey),
6972369755
#ifndef NO_BIO
6972469756
TEST_DECL(test_wolfSSL_BIO),
69757+
TEST_DECL(test_wolfSSL_BIO_BIO_ring_read),
6972569758
TEST_DECL(test_wolfSSL_PEM_read_bio),
6972669759
TEST_DECL(test_wolfSSL_PEM_bio_RSAKey),
6972769760
TEST_DECL(test_wolfSSL_PEM_bio_DSAKey),

tests/unit.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@
217217
int _z = (int)(z); \
218218
int _w = ((_x) && (_y)) ? XMEMCMP(_x, _y, _z) : -1; \
219219
Expect(_w op 0, ("%s " #op " %s for %s", #x, #y, #z), \
220-
("\"%p\" " #er " \"%p\" for \"%d\"", _x, _y, _z));\
220+
("\"%p\" " #er " \"%p\" for \"%d\"", \
221+
(const void *)_x, (const void *)_y, _z)); \
221222
} \
222223
} while(0)
223224

0 commit comments

Comments
 (0)