mirror of
https://github.com/openssl/openssl.git
synced 2025-03-31 20:10:45 +08:00
Add support for streams to the quic-client fuzzer
Enable the quic-client fuzzer to accept and create new streams Reviewed-by: Hugo Landau <hlandau@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/22592)
This commit is contained in:
parent
d3dcf88cc5
commit
3fa274ca81
@ -43,13 +43,18 @@ int FuzzerInitialize(int *argc, char ***argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define HANDSHAKING 0
|
||||
#define READING 1
|
||||
#define WRITING 2
|
||||
#define HANDSHAKING 0
|
||||
#define READING 1
|
||||
#define WRITING 2
|
||||
#define ACCEPTING_STREAM 3
|
||||
#define CREATING_STREAM 4
|
||||
#define SWAPPING_STREAM 5
|
||||
|
||||
int FuzzerTestOneInput(const uint8_t *buf, size_t len)
|
||||
{
|
||||
SSL *client = NULL;
|
||||
SSL *client = NULL, *stream = NULL;
|
||||
SSL *allstreams[] = {NULL, NULL, NULL, NULL};
|
||||
size_t i, thisstream = 0, numstreams = 1;
|
||||
BIO *in;
|
||||
BIO *out;
|
||||
SSL_CTX *ctx;
|
||||
@ -57,6 +62,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
|
||||
struct in_addr ina = {0};
|
||||
struct timeval tv;
|
||||
int state = HANDSHAKING;
|
||||
uint8_t tmp[1024];
|
||||
int writelen = 0;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
@ -104,13 +111,40 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
|
||||
goto end;
|
||||
SSL_set_connect_state(client);
|
||||
|
||||
if (!SSL_set_incoming_stream_policy(client,
|
||||
SSL_INCOMING_STREAM_POLICY_ACCEPT,
|
||||
0))
|
||||
goto end;
|
||||
|
||||
allstreams[0] = stream = client;
|
||||
for (;;) {
|
||||
size_t size;
|
||||
uint64_t nxtpktms = 0;
|
||||
OSSL_TIME nxtpkt = ossl_time_zero(), nxttimeout;
|
||||
int isinf, ret;
|
||||
int isinf, ret = 0;
|
||||
|
||||
if (len >= 2) {
|
||||
if (len >= 5 && buf[0] == 0xff && buf[1] == 0xff) {
|
||||
switch (buf[2]) {
|
||||
case 0x00:
|
||||
if (state == READING)
|
||||
state = ACCEPTING_STREAM;
|
||||
break;
|
||||
case 0x01:
|
||||
if (state == READING)
|
||||
state = CREATING_STREAM;
|
||||
break;
|
||||
case 0x02:
|
||||
if (state == READING)
|
||||
state = SWAPPING_STREAM;
|
||||
break;
|
||||
default:
|
||||
/*ignore*/
|
||||
break;
|
||||
}
|
||||
len -= 3;
|
||||
buf += 3;
|
||||
}
|
||||
nxtpktms = buf[0] + (buf[1] << 8);
|
||||
nxtpkt = ossl_time_add(fake_now, ossl_ms2time(nxtpktms));
|
||||
len -= 2;
|
||||
@ -118,32 +152,70 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
uint8_t tmp[1024];
|
||||
int writelen = 0;
|
||||
|
||||
switch (state) {
|
||||
case HANDSHAKING:
|
||||
ret = SSL_do_handshake(client);
|
||||
ret = SSL_do_handshake(stream);
|
||||
if (ret == 1)
|
||||
state = READING;
|
||||
break;
|
||||
|
||||
case READING:
|
||||
ret = SSL_read(client, tmp, sizeof(tmp));
|
||||
ret = SSL_read(stream, tmp, sizeof(tmp));
|
||||
if (ret > 0) {
|
||||
state = WRITING;
|
||||
writelen = ret;
|
||||
assert(writelen <= sizeof(tmp));
|
||||
assert(writelen <= (int)sizeof(tmp));
|
||||
}
|
||||
break;
|
||||
|
||||
case WRITING:
|
||||
ret = SSL_write(client, tmp, writelen);
|
||||
ret = SSL_write(stream, tmp, writelen);
|
||||
if (ret > 0)
|
||||
state = READING;
|
||||
break;
|
||||
|
||||
case ACCEPTING_STREAM:
|
||||
state = READING;
|
||||
ret = 1;
|
||||
if (numstreams == OSSL_NELEM(allstreams)
|
||||
|| SSL_get_accept_stream_queue_len(client) == 0)
|
||||
break;
|
||||
thisstream = numstreams;
|
||||
stream = allstreams[numstreams++]
|
||||
= SSL_accept_stream(client, 0);
|
||||
if (stream == NULL)
|
||||
goto end;
|
||||
break;
|
||||
|
||||
case CREATING_STREAM:
|
||||
state = READING;
|
||||
ret = 1;
|
||||
if (numstreams == OSSL_NELEM(allstreams))
|
||||
break;
|
||||
stream = SSL_new_stream(client, 0);
|
||||
if (stream == NULL) {
|
||||
/* Ignore, and go back to the previous stream */
|
||||
stream = allstreams[thisstream];
|
||||
break;
|
||||
}
|
||||
thisstream = numstreams;
|
||||
allstreams[numstreams++] = stream;
|
||||
break;
|
||||
|
||||
case SWAPPING_STREAM:
|
||||
state = READING;
|
||||
ret = 1;
|
||||
if (numstreams == 1)
|
||||
break;
|
||||
if (++thisstream == numstreams)
|
||||
thisstream = 0;
|
||||
stream = allstreams[thisstream];
|
||||
break;
|
||||
}
|
||||
assert(stream != NULL);
|
||||
assert(thisstream < numstreams);
|
||||
if (ret <= 0) {
|
||||
switch (SSL_get_error(client, ret)) {
|
||||
switch (SSL_get_error(stream, ret)) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
break;
|
||||
@ -182,7 +254,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
|
||||
buf += size + 2;
|
||||
}
|
||||
end:
|
||||
SSL_free(client);
|
||||
for (i = 0; i < numstreams; i++)
|
||||
SSL_free(allstreams[i]);
|
||||
ERR_clear_error();
|
||||
SSL_CTX_free(ctx);
|
||||
BIO_ADDR_free(peer_addr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user