bio_test.cc
Go to the documentation of this file.
1 /* Copyright (c) 2014, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <algorithm>
16 #include <string>
17 
18 #include <gtest/gtest.h>
19 
20 #include <openssl/bio.h>
21 #include <openssl/crypto.h>
22 #include <openssl/err.h>
23 #include <openssl/mem.h>
24 
25 #include "../internal.h"
26 #include "../test/test_util.h"
27 
28 #if !defined(OPENSSL_WINDOWS)
29 #include <arpa/inet.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <netinet/in.h>
33 #include <string.h>
34 #include <sys/socket.h>
35 #include <unistd.h>
36 #else
37 #include <io.h>
39 #include <winsock2.h>
40 #include <ws2tcpip.h>
42 #endif
43 
44 
45 #if !defined(OPENSSL_WINDOWS)
46 static int closesocket(int sock) { return close(sock); }
47 static std::string LastSocketError() { return strerror(errno); }
48 #else
50  char buf[DECIMAL_SIZE(int) + 1];
51  BIO_snprintf(buf, sizeof(buf), "%d", WSAGetLastError());
52  return buf;
53 }
54 #endif
55 
56 class ScopedSocket {
57  public:
58  explicit ScopedSocket(int sock) : sock_(sock) {}
61  }
62 
63  private:
64  const int sock_;
65 };
66 
67 TEST(BIOTest, SocketConnect) {
68  static const char kTestMessage[] = "test";
69  int listening_sock = -1;
70  socklen_t len = 0;
71  sockaddr_storage ss;
72  struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &ss;
73  struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
74  OPENSSL_memset(&ss, 0, sizeof(ss));
75 
76  ss.ss_family = AF_INET6;
77  listening_sock = socket(AF_INET6, SOCK_STREAM, 0);
78  ASSERT_NE(-1, listening_sock) << LastSocketError();
79  len = sizeof(*sin6);
80  ASSERT_EQ(1, inet_pton(AF_INET6, "::1", &sin6->sin6_addr))
81  << LastSocketError();
82  if (bind(listening_sock, (struct sockaddr *)sin6, sizeof(*sin6)) == -1) {
83  closesocket(listening_sock);
84 
85  ss.ss_family = AF_INET;
86  listening_sock = socket(AF_INET, SOCK_STREAM, 0);
87  ASSERT_NE(-1, listening_sock) << LastSocketError();
88  len = sizeof(*sin);
89  ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", &sin->sin_addr))
90  << LastSocketError();
91  ASSERT_EQ(0, bind(listening_sock, (struct sockaddr *)sin, sizeof(*sin)))
92  << LastSocketError();
93  }
94 
95  ScopedSocket listening_sock_closer(listening_sock);
96  ASSERT_EQ(0, listen(listening_sock, 1)) << LastSocketError();
97  ASSERT_EQ(0, getsockname(listening_sock, (struct sockaddr *)&ss, &len))
98  << LastSocketError();
99 
100  char hostname[80];
101  if (ss.ss_family == AF_INET6) {
102  BIO_snprintf(hostname, sizeof(hostname), "[::1]:%d",
103  ntohs(sin6->sin6_port));
104  } else if (ss.ss_family == AF_INET) {
105  BIO_snprintf(hostname, sizeof(hostname), "127.0.0.1:%d",
106  ntohs(sin->sin_port));
107  }
108 
109  // Connect to it with a connect BIO.
110  bssl::UniquePtr<BIO> bio(BIO_new_connect(hostname));
111  ASSERT_TRUE(bio);
112 
113  // Write a test message to the BIO.
114  ASSERT_EQ(static_cast<int>(sizeof(kTestMessage)),
115  BIO_write(bio.get(), kTestMessage, sizeof(kTestMessage)));
116 
117  // Accept the socket.
118  int sock = accept(listening_sock, (struct sockaddr *) &ss, &len);
119  ASSERT_NE(-1, sock) << LastSocketError();
120  ScopedSocket sock_closer(sock);
121 
122  // Check the same message is read back out.
123  char buf[sizeof(kTestMessage)];
124  ASSERT_EQ(static_cast<int>(sizeof(kTestMessage)),
125  recv(sock, buf, sizeof(buf), 0))
126  << LastSocketError();
127  EXPECT_EQ(Bytes(kTestMessage, sizeof(kTestMessage)), Bytes(buf, sizeof(buf)));
128 }
129 
130 TEST(BIOTest, Printf) {
131  // Test a short output, a very long one, and various sizes around
132  // 256 (the size of the buffer) to ensure edge cases are correct.
133  static const size_t kLengths[] = {5, 250, 251, 252, 253, 254, 1023};
134 
135  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
136  ASSERT_TRUE(bio);
137 
138  for (size_t length : kLengths) {
140 
141  std::string in(length, 'a');
142 
143  int ret = BIO_printf(bio.get(), "test %s", in.c_str());
144  ASSERT_GE(ret, 0);
145  EXPECT_EQ(5 + length, static_cast<size_t>(ret));
146 
147  const uint8_t *contents;
148  size_t len;
149  ASSERT_TRUE(BIO_mem_contents(bio.get(), &contents, &len));
150  EXPECT_EQ("test " + in,
151  std::string(reinterpret_cast<const char *>(contents), len));
152 
153  ASSERT_TRUE(BIO_reset(bio.get()));
154  }
155 }
156 
157 static const size_t kLargeASN1PayloadLen = 8000;
158 
161  std::vector<uint8_t> input;
162  // suffix_len is the number of zeros to append to |input|.
163  size_t suffix_len;
164  // expected_len, if |should_succeed| is true, is the expected length of the
165  // ASN.1 element.
166  size_t expected_len;
167  size_t max_len;
168 } kASN1TestParams[] = {
169  {true, {0x30, 2, 1, 2, 0, 0}, 0, 4, 100},
170  {false /* truncated */, {0x30, 3, 1, 2}, 0, 0, 100},
171  {false /* should be short len */, {0x30, 0x81, 1, 1}, 0, 0, 100},
172  {false /* zero padded */, {0x30, 0x82, 0, 1, 1}, 0, 0, 100},
173 
174  // Test a large payload.
175  {true,
176  {0x30, 0x82, kLargeASN1PayloadLen >> 8, kLargeASN1PayloadLen & 0xff},
180  {false /* max_len too short */,
181  {0x30, 0x82, kLargeASN1PayloadLen >> 8, kLargeASN1PayloadLen & 0xff},
185 
186  // Test an indefinite-length input.
187  {true,
188  {0x30, 0x80},
190  2 + kLargeASN1PayloadLen + 2,
192  {false /* max_len too short */,
193  {0x30, 0x80},
195  2 + kLargeASN1PayloadLen + 2,
196  2 + kLargeASN1PayloadLen + 1},
197 };
198 
199 class BIOASN1Test : public testing::TestWithParam<ASN1TestParam> {};
200 
201 TEST_P(BIOASN1Test, ReadASN1) {
202  const ASN1TestParam& param = GetParam();
203  std::vector<uint8_t> input = param.input;
204  input.resize(input.size() + param.suffix_len, 0);
205 
206  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(input.data(), input.size()));
207  ASSERT_TRUE(bio);
208 
209  uint8_t *out;
210  size_t out_len;
211  int ok = BIO_read_asn1(bio.get(), &out, &out_len, param.max_len);
212  if (!ok) {
213  out = nullptr;
214  }
215  bssl::UniquePtr<uint8_t> out_storage(out);
216 
217  ASSERT_EQ(param.should_succeed, (ok == 1));
218  if (param.should_succeed) {
219  EXPECT_EQ(Bytes(input.data(), param.expected_len), Bytes(out, out_len));
220  }
221 }
222 
224 
225 // Run through the tests twice, swapping |bio1| and |bio2|, for symmetry.
226 class BIOPairTest : public testing::TestWithParam<bool> {};
227 
228 TEST_P(BIOPairTest, TestPair) {
229  BIO *bio1, *bio2;
230  ASSERT_TRUE(BIO_new_bio_pair(&bio1, 10, &bio2, 10));
231  bssl::UniquePtr<BIO> free_bio1(bio1), free_bio2(bio2);
232 
233  if (GetParam()) {
234  std::swap(bio1, bio2);
235  }
236 
237  // Check initial states.
240 
241  // Data written in one end may be read out the other.
242  uint8_t buf[20];
243  EXPECT_EQ(5, BIO_write(bio1, "12345", 5));
245  ASSERT_EQ(5, BIO_read(bio2, buf, sizeof(buf)));
246  EXPECT_EQ(Bytes("12345"), Bytes(buf, 5));
248 
249  // Attempting to write more than 10 bytes will write partially.
250  EXPECT_EQ(10, BIO_write(bio1, "1234567890___", 13));
252  EXPECT_EQ(-1, BIO_write(bio1, "z", 1));
254  ASSERT_EQ(10, BIO_read(bio2, buf, sizeof(buf)));
255  EXPECT_EQ(Bytes("1234567890"), Bytes(buf, 10));
257 
258  // Unsuccessful reads update the read request.
259  EXPECT_EQ(-1, BIO_read(bio2, buf, 5));
262 
263  // The read request is clamped to the size of the buffer.
264  EXPECT_EQ(-1, BIO_read(bio2, buf, 20));
267 
268  // Data may be written and read in chunks.
269  EXPECT_EQ(5, BIO_write(bio1, "12345", 5));
271  EXPECT_EQ(5, BIO_write(bio1, "67890___", 8));
273  ASSERT_EQ(3, BIO_read(bio2, buf, 3));
274  EXPECT_EQ(Bytes("123"), Bytes(buf, 3));
276  ASSERT_EQ(7, BIO_read(bio2, buf, sizeof(buf)));
277  EXPECT_EQ(Bytes("4567890"), Bytes(buf, 7));
279 
280  // Successful reads reset the read request.
282 
283  // Test writes and reads starting in the middle of the ring buffer and
284  // wrapping to front.
285  EXPECT_EQ(8, BIO_write(bio1, "abcdefgh", 8));
287  ASSERT_EQ(3, BIO_read(bio2, buf, 3));
288  EXPECT_EQ(Bytes("abc"), Bytes(buf, 3));
290  EXPECT_EQ(5, BIO_write(bio1, "ijklm___", 8));
292  ASSERT_EQ(10, BIO_read(bio2, buf, sizeof(buf)));
293  EXPECT_EQ(Bytes("defghijklm"), Bytes(buf, 10));
295 
296  // Data may flow from both ends in parallel.
297  EXPECT_EQ(5, BIO_write(bio1, "12345", 5));
298  EXPECT_EQ(5, BIO_write(bio2, "67890", 5));
299  ASSERT_EQ(5, BIO_read(bio2, buf, sizeof(buf)));
300  EXPECT_EQ(Bytes("12345"), Bytes(buf, 5));
301  ASSERT_EQ(5, BIO_read(bio1, buf, sizeof(buf)));
302  EXPECT_EQ(Bytes("67890"), Bytes(buf, 5));
303 
304  // Closing the write end causes an EOF on the read half, after draining.
305  EXPECT_EQ(5, BIO_write(bio1, "12345", 5));
307  ASSERT_EQ(5, BIO_read(bio2, buf, sizeof(buf)));
308  EXPECT_EQ(Bytes("12345"), Bytes(buf, 5));
309  EXPECT_EQ(0, BIO_read(bio2, buf, sizeof(buf)));
310 
311  // A closed write end may not be written to.
313  EXPECT_EQ(-1, BIO_write(bio1, "_____", 5));
314 
318 
319  // The other end is still functional.
320  EXPECT_EQ(5, BIO_write(bio2, "12345", 5));
321  ASSERT_EQ(5, BIO_read(bio1, buf, sizeof(buf)));
322  EXPECT_EQ(Bytes("12345"), Bytes(buf, 5));
323 }
324 
BIO_read_asn1
#define BIO_read_asn1
Definition: boringssl_prefix_symbols.h:832
ASSERT_NE
#define ASSERT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2060
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
BIO_shutdown_wr
#define BIO_shutdown_wr
Definition: boringssl_prefix_symbols.h:863
Bytes
Definition: boringssl-with-bazel/src/crypto/test/test_util.h:38
AF_INET6
#define AF_INET6
Definition: ares_setup.h:208
bio_st
Definition: bio.h:822
BIO_should_write
#define BIO_should_write
Definition: boringssl_prefix_symbols.h:862
LastSocketError
static std::string LastSocketError()
Definition: bio_test.cc:47
check_version.warning
string warning
Definition: check_version.py:46
BIO_new_connect
#define BIO_new_connect
Definition: boringssl_prefix_symbols.h:816
bio.h
string.h
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
BIO_reset
#define BIO_reset
Definition: boringssl_prefix_symbols.h:834
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
ASN1TestParam::should_succeed
bool should_succeed
Definition: bio_test.cc:160
error_ref_leak.err
err
Definition: error_ref_leak.py:35
ASSERT_GE
#define ASSERT_GE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2072
u
OPENSSL_EXPORT pem_password_cb void * u
Definition: pem.h:351
BIO_write
#define BIO_write
Definition: boringssl_prefix_symbols.h:870
ScopedSocket::~ScopedSocket
~ScopedSocket()
Definition: bio_test.cc:59
BIO_read
#define BIO_read
Definition: boringssl_prefix_symbols.h:831
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
OPENSSL_memset
static void * OPENSSL_memset(void *dst, int c, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:835
ERR_get_error
#define ERR_get_error
Definition: boringssl_prefix_symbols.h:1419
BIO_printf
#define BIO_printf
Definition: boringssl_prefix_symbols.h:827
testing::TestWithParam
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1883
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
BIO_new_mem_buf
#define BIO_new_mem_buf
Definition: boringssl_prefix_symbols.h:820
kASN1TestParams
struct ASN1TestParam kASN1TestParams[]
TEST_P
TEST_P(BIOASN1Test, ReadASN1)
Definition: bio_test.cc:201
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
BIO_new_bio_pair
#define BIO_new_bio_pair
Definition: boringssl_prefix_symbols.h:815
SCOPED_TRACE
#define SCOPED_TRACE(message)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2264
ERR_GET_REASON
#define ERR_GET_REASON(packed_error)
Definition: err.h:171
sockaddr_in6
Definition: ares_ipv6.h:25
BIO_s_mem
#define BIO_s_mem
Definition: boringssl_prefix_symbols.h:839
INSTANTIATE_TEST_SUITE_P
INSTANTIATE_TEST_SUITE_P(All, BIOASN1Test, testing::ValuesIn(kASN1TestParams))
BIO_ctrl_get_read_request
#define BIO_ctrl_get_read_request
Definition: boringssl_prefix_symbols.h:780
ERR_GET_LIB
#define ERR_GET_LIB(packed_error)
Definition: err.h:166
ERR_LIB_BIO
@ ERR_LIB_BIO
Definition: err.h:308
err.h
crypto.h
std::swap
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:1226
close
#define close
Definition: test-fs.c:48
OPENSSL_MSVC_PRAGMA
OPENSSL_MSVC_PRAGMA(warning(disable:4702))
Definition: e_aes.c:69
TEST
TEST(BIOTest, SocketConnect)
Definition: bio_test.cc:67
ScopedSocket::ScopedSocket
ScopedSocket(int sock)
Definition: bio_test.cc:58
BIO_new
#define BIO_new
Definition: boringssl_prefix_symbols.h:814
BIO_R_BROKEN_PIPE
#define BIO_R_BROKEN_PIPE
Definition: bio.h:920
BIO_snprintf
#define BIO_snprintf
Definition: boringssl_prefix_symbols.h:864
BIOPairTest
Definition: bio_test.cc:226
push
int push(void *desc, unsigned char *buf, unsigned len)
Definition: bloaty/third_party/zlib/test/infcover.c:463
ScopedSocket::sock_
const int sock_
Definition: bio_test.cc:64
contents
string_view contents
Definition: elf.cc:597
testing::Values
internal::ValueArray< T... > Values(T... v)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:335
http2_test_server.listen
def listen(endpoint, test_case)
Definition: http2_test_server.py:87
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
BIOASN1Test
Definition: bio_test.cc:199
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
ASN1TestParam::expected_len
size_t expected_len
Definition: bio_test.cc:166
ok
bool ok
Definition: async_end2end_test.cc:197
ASN1TestParam::suffix_len
size_t suffix_len
Definition: bio_test.cc:163
input
std::string input
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:197
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
sockaddr_in6::sin6_addr
struct ares_in6_addr sin6_addr
Definition: ares_ipv6.h:30
DECIMAL_SIZE
#define DECIMAL_SIZE(type)
Definition: mem.h:124
ASN1TestParam::input
std::vector< uint8_t > input
Definition: bio_test.cc:161
kLargeASN1PayloadLen
static const size_t kLargeASN1PayloadLen
Definition: bio_test.cc:157
test_server.socket
socket
Definition: test_server.py:65
closesocket
static int closesocket(int sock)
Definition: bio_test.cc:46
mem.h
testing::ValuesIn
internal::ParamGenerator< typename std::iterator_traits< ForwardIterator >::value_type > ValuesIn(ForwardIterator begin, ForwardIterator end)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:297
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
ASN1TestParam
Definition: bio_test.cc:159
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
ScopedSocket
Definition: bio_test.cc:56
BIO_ctrl_get_write_guarantee
#define BIO_ctrl_get_write_guarantee
Definition: boringssl_prefix_symbols.h:781
ASN1TestParam::max_len
size_t max_len
Definition: bio_test.cc:167
errno.h
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2056
BIO_should_read
#define BIO_should_read
Definition: boringssl_prefix_symbols.h:860
BIO_mem_contents
#define BIO_mem_contents
Definition: boringssl_prefix_symbols.h:803


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:48