diff --git a/test/build.info b/test/build.info index 13653f9efa..2047cf29b8 100644 --- a/test/build.info +++ b/test/build.info @@ -63,7 +63,7 @@ IF[{- !$disabled{tests} -}] keymgmt_internal_test hexstr_test provider_status_test defltfips_test \ bio_readbuffer_test user_property_test pkcs7_test upcallstest \ provfetchtest prov_config_test rand_test ca_internals_test \ - bio_tfo_test + bio_tfo_test membio_test IF[{- !$disabled{'deprecated-3.0'} -}] PROGRAMS{noinst}=enginetest @@ -391,6 +391,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[bio_tfo_test]=../include ../apps/include .. DEPEND[bio_tfo_test]=../libcrypto libtestutil.a + SOURCE[membio_test]=membio_test.c + INCLUDE[membio_test]=../include ../apps/include .. + DEPEND[membio_test]=../libcrypto libtestutil.a + SOURCE[params_api_test]=params_api_test.c INCLUDE[params_api_test]=../include ../apps/include DEPEND[params_api_test]=../libcrypto libtestutil.a diff --git a/test/membio_test.c b/test/membio_test.c new file mode 100644 index 0000000000..d1b01061a9 --- /dev/null +++ b/test/membio_test.c @@ -0,0 +1,119 @@ +/* + * Copyright 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/bio.h> +#include "testutil.h" + +static int test_dgram(void) +{ + BIO *bio = BIO_new(BIO_s_dgram_mem()), *rbio = NULL; + int testresult = 0; + const char msg1[] = "12345656"; + const char msg2[] = "abcdefghijklmno"; + const char msg3[] = "ABCDEF"; + const char msg4[] = "FEDCBA"; + char buf[80]; + + if (!TEST_ptr(bio)) + goto err; + + rbio = BIO_new_mem_buf(msg1, sizeof(msg1)); + if (!TEST_ptr(rbio)) + goto err; + + /* Seeting the EOF return value on a non datagram mem BIO should be fine */ + if (!TEST_int_gt(BIO_set_mem_eof_return(rbio, 0), 0)) + goto err; + + /* Setting the EOF return value on a datagram mem BIO should fail */ + if (!TEST_int_le(BIO_set_mem_eof_return(bio, 0), 0)) + goto err; + + /* Write 4 dgrams */ + if (!TEST_int_eq(BIO_write(bio, msg1, sizeof(msg1)), sizeof(msg1))) + goto err; + if (!TEST_int_eq(BIO_write(bio, msg2, sizeof(msg2)), sizeof(msg2))) + goto err; + if (!TEST_int_eq(BIO_write(bio, msg3, sizeof(msg3)), sizeof(msg3))) + goto err; + if (!TEST_int_eq(BIO_write(bio, msg4, sizeof(msg4)), sizeof(msg4))) + goto err; + + /* Reading all 4 dgrams out again should all be the correct size */ + if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg1)) + || !TEST_mem_eq(buf, sizeof(msg1), msg1, sizeof(msg1)) + || !TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg2)) + || !TEST_mem_eq(buf, sizeof(msg2), msg2, sizeof(msg2)) + || !TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg3)) + || !TEST_mem_eq(buf, sizeof(msg3), msg3, sizeof(msg3)) + || !TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg4)) + || !TEST_mem_eq(buf, sizeof(msg4), msg4, sizeof(msg4))) + goto err; + + /* Interleaving writes and reads should be fine */ + if (!TEST_int_eq(BIO_write(bio, msg1, sizeof(msg1)), sizeof(msg1))) + goto err; + if (!TEST_int_eq(BIO_write(bio, msg2, sizeof(msg2)), sizeof(msg2))) + goto err; + if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg1)) + || !TEST_mem_eq(buf, sizeof(msg1), msg1, sizeof(msg1))) + goto err; + if (!TEST_int_eq(BIO_write(bio, msg3, sizeof(msg3)), sizeof(msg3))) + goto err; + if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg2)) + || !TEST_mem_eq(buf, sizeof(msg2), msg2, sizeof(msg2)) + || !TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg3)) + || !TEST_mem_eq(buf, sizeof(msg3), msg3, sizeof(msg3))) + goto err; + + /* + * Requesting less than the available data in a dgram should not impact the + * next packet. + */ + if (!TEST_int_eq(BIO_write(bio, msg1, sizeof(msg1)), sizeof(msg1))) + goto err; + if (!TEST_int_eq(BIO_write(bio, msg2, sizeof(msg2)), sizeof(msg2))) + goto err; + if (!TEST_int_eq(BIO_read(bio, buf, /* Short buffer */ 2), 2) + || !TEST_mem_eq(buf, 2, msg1, 2)) + goto err; + if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg2)) + || !TEST_mem_eq(buf, sizeof(msg2), msg2, sizeof(msg2))) + goto err; + + /* + * Writing a zero length datagram will return zero, but no datagrams will + * be written. Attempting to read when there are no datagrams to read should + * return a negative result, but not eof. Retry flags will be set. + */ + if (!TEST_int_eq(BIO_write(bio, NULL, 0), 0) + || !TEST_int_lt(BIO_read(bio, buf, sizeof(buf)), 0) + || !TEST_false(BIO_eof(bio)) + || !TEST_true(BIO_should_retry(bio))) + goto err; + + testresult = 1; + err: + BIO_free(rbio); + BIO_free(bio); + return testresult; +} + + +int setup_tests(void) +{ + if (!test_skip_common_options()) { + TEST_error("Error parsing test options\n"); + return 0; + } + + ADD_TEST(test_dgram); + + return 1; +} diff --git a/test/recipes/04-test_membio.t b/test/recipes/04-test_membio.t new file mode 100644 index 0000000000..58d1080fb8 --- /dev/null +++ b/test/recipes/04-test_membio.t @@ -0,0 +1,16 @@ +#! /usr/bin/env perl +# Copyright 2016-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 + +use strict; +use OpenSSL::Test; +use OpenSSL::Test::Simple; +use OpenSSL::Test::Utils; + +setup("test_membio"); + +simple_test("test_membio", "membio_test");