1*a8c975d2Sderaadt /* $OpenBSD: test_sshbuf.c,v 1.2 2021/12/14 21:25:27 deraadt Exp $ */
229518ea0Sdjm /*
329518ea0Sdjm * Regress test for sshbuf.h buffer API
429518ea0Sdjm *
529518ea0Sdjm * Placed in the public domain
629518ea0Sdjm */
729518ea0Sdjm
829518ea0Sdjm #include <sys/types.h>
929518ea0Sdjm #include <stdio.h>
1029518ea0Sdjm #include <stdint.h>
1129518ea0Sdjm #include <stdlib.h>
1229518ea0Sdjm #include <string.h>
1329518ea0Sdjm
1429518ea0Sdjm #include "test_helper.h"
1529518ea0Sdjm
1629518ea0Sdjm #include "ssherr.h"
1729518ea0Sdjm #define SSHBUF_INTERNAL 1 /* access internals for testing */
1829518ea0Sdjm #include "sshbuf.h"
1929518ea0Sdjm
2029518ea0Sdjm void sshbuf_tests(void);
2129518ea0Sdjm
22*a8c975d2Sderaadt #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
23*a8c975d2Sderaadt
2429518ea0Sdjm void
sshbuf_tests(void)2529518ea0Sdjm sshbuf_tests(void)
2629518ea0Sdjm {
2729518ea0Sdjm struct sshbuf *p1;
2829518ea0Sdjm const u_char *cdp;
2929518ea0Sdjm u_char *dp;
3029518ea0Sdjm size_t sz;
3129518ea0Sdjm int r;
3229518ea0Sdjm
3329518ea0Sdjm TEST_START("allocate sshbuf");
3429518ea0Sdjm p1 = sshbuf_new();
3529518ea0Sdjm ASSERT_PTR_NE(p1, NULL);
3629518ea0Sdjm TEST_DONE();
3729518ea0Sdjm
3829518ea0Sdjm TEST_START("max size on fresh buffer");
3929518ea0Sdjm ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0);
4029518ea0Sdjm TEST_DONE();
4129518ea0Sdjm
4229518ea0Sdjm TEST_START("available on fresh buffer");
4329518ea0Sdjm ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0);
4429518ea0Sdjm TEST_DONE();
4529518ea0Sdjm
4629518ea0Sdjm TEST_START("len = 0 on empty buffer");
4729518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
4829518ea0Sdjm TEST_DONE();
4929518ea0Sdjm
5029518ea0Sdjm TEST_START("set valid max size");
5129518ea0Sdjm ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0);
5229518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536);
5329518ea0Sdjm TEST_DONE();
5429518ea0Sdjm
5529518ea0Sdjm TEST_START("available on limited buffer");
5629518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536);
5729518ea0Sdjm TEST_DONE();
5829518ea0Sdjm
5929518ea0Sdjm TEST_START("free");
6029518ea0Sdjm sshbuf_free(p1);
6129518ea0Sdjm TEST_DONE();
6229518ea0Sdjm
6329518ea0Sdjm TEST_START("consume on empty buffer");
6429518ea0Sdjm p1 = sshbuf_new();
6529518ea0Sdjm ASSERT_PTR_NE(p1, NULL);
6629518ea0Sdjm ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
6729518ea0Sdjm ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
6829518ea0Sdjm sshbuf_free(p1);
6929518ea0Sdjm TEST_DONE();
7029518ea0Sdjm
7129518ea0Sdjm TEST_START("consume_end on empty buffer");
7229518ea0Sdjm p1 = sshbuf_new();
7329518ea0Sdjm ASSERT_PTR_NE(p1, NULL);
7429518ea0Sdjm ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0);
7529518ea0Sdjm ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
7629518ea0Sdjm sshbuf_free(p1);
7729518ea0Sdjm TEST_DONE();
7829518ea0Sdjm
7929518ea0Sdjm TEST_START("reserve space");
8029518ea0Sdjm p1 = sshbuf_new();
8129518ea0Sdjm ASSERT_PTR_NE(p1, NULL);
8229518ea0Sdjm r = sshbuf_reserve(p1, 1, &dp);
8329518ea0Sdjm ASSERT_INT_EQ(r, 0);
8429518ea0Sdjm ASSERT_PTR_NE(dp, NULL);
8529518ea0Sdjm *dp = 0x11;
8629518ea0Sdjm r = sshbuf_reserve(p1, 3, &dp);
8729518ea0Sdjm ASSERT_INT_EQ(r, 0);
8829518ea0Sdjm ASSERT_PTR_NE(dp, NULL);
8929518ea0Sdjm *dp++ = 0x22;
9029518ea0Sdjm *dp++ = 0x33;
9129518ea0Sdjm *dp++ = 0x44;
9229518ea0Sdjm TEST_DONE();
9329518ea0Sdjm
9429518ea0Sdjm TEST_START("sshbuf_len on filled buffer");
9529518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
9629518ea0Sdjm TEST_DONE();
9729518ea0Sdjm
9829518ea0Sdjm TEST_START("sshbuf_ptr on filled buffer");
9929518ea0Sdjm cdp = sshbuf_ptr(p1);
10029518ea0Sdjm ASSERT_PTR_NE(cdp, NULL);
10129518ea0Sdjm ASSERT_U8_EQ(cdp[0], 0x11);
10229518ea0Sdjm ASSERT_U8_EQ(cdp[1], 0x22);
10329518ea0Sdjm ASSERT_U8_EQ(cdp[2], 0x33);
10429518ea0Sdjm ASSERT_U8_EQ(cdp[3], 0x44);
10529518ea0Sdjm TEST_DONE();
10629518ea0Sdjm
10729518ea0Sdjm TEST_START("consume on filled buffer");
10829518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
10929518ea0Sdjm ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
11029518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
11129518ea0Sdjm r = sshbuf_consume(p1, 64);
11229518ea0Sdjm ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
11329518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
11429518ea0Sdjm ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
11529518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
11629518ea0Sdjm cdp = sshbuf_ptr(p1);
11729518ea0Sdjm ASSERT_PTR_NE(p1, NULL);
11829518ea0Sdjm ASSERT_U8_EQ(cdp[0], 0x22);
11929518ea0Sdjm ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0);
12029518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
12129518ea0Sdjm cdp = sshbuf_ptr(p1);
12229518ea0Sdjm ASSERT_PTR_NE(p1, NULL);
12329518ea0Sdjm ASSERT_U8_EQ(cdp[0], 0x44);
12429518ea0Sdjm r = sshbuf_consume(p1, 2);
12529518ea0Sdjm ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
12629518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
12729518ea0Sdjm ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
12829518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
12929518ea0Sdjm r = sshbuf_consume(p1, 1);
13029518ea0Sdjm ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
13129518ea0Sdjm sshbuf_free(p1);
13229518ea0Sdjm TEST_DONE();
13329518ea0Sdjm
13429518ea0Sdjm TEST_START("consume_end on filled buffer");
13529518ea0Sdjm p1 = sshbuf_new();
13629518ea0Sdjm ASSERT_PTR_NE(p1, NULL);
13729518ea0Sdjm r = sshbuf_reserve(p1, 4, &dp);
13829518ea0Sdjm ASSERT_INT_EQ(r, 0);
13929518ea0Sdjm ASSERT_PTR_NE(dp, NULL);
14029518ea0Sdjm *dp++ = 0x11;
14129518ea0Sdjm *dp++ = 0x22;
14229518ea0Sdjm *dp++ = 0x33;
14329518ea0Sdjm *dp++ = 0x44;
14429518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
14529518ea0Sdjm r = sshbuf_consume_end(p1, 5);
14629518ea0Sdjm ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
14729518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
14829518ea0Sdjm ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0);
14929518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
15029518ea0Sdjm cdp = sshbuf_ptr(p1);
15129518ea0Sdjm ASSERT_PTR_NE(cdp, NULL);
15229518ea0Sdjm ASSERT_U8_EQ(*cdp, 0x11);
15329518ea0Sdjm r = sshbuf_consume_end(p1, 2);
15429518ea0Sdjm ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
15529518ea0Sdjm ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
15629518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
15729518ea0Sdjm sshbuf_free(p1);
15829518ea0Sdjm TEST_DONE();
15929518ea0Sdjm
16029518ea0Sdjm TEST_START("fill limited buffer");
16129518ea0Sdjm p1 = sshbuf_new();
16229518ea0Sdjm ASSERT_PTR_NE(p1, NULL);
16329518ea0Sdjm ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
16429518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
16529518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
16629518ea0Sdjm r = sshbuf_reserve(p1, 1223, &dp);
16729518ea0Sdjm ASSERT_INT_EQ(r, 0);
16829518ea0Sdjm ASSERT_PTR_NE(dp, NULL);
16929518ea0Sdjm memset(dp, 0xd7, 1223);
17029518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
17129518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
17229518ea0Sdjm r = sshbuf_reserve(p1, 1, &dp);
17329518ea0Sdjm ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
17429518ea0Sdjm ASSERT_PTR_EQ(dp, NULL);
17529518ea0Sdjm TEST_DONE();
17629518ea0Sdjm
17729518ea0Sdjm TEST_START("consume and force compaction");
17829518ea0Sdjm ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0);
17929518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
18029518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
18129518ea0Sdjm r = sshbuf_reserve(p1, 224, &dp);
18229518ea0Sdjm ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
18329518ea0Sdjm ASSERT_PTR_EQ(dp, NULL);
18429518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
18529518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
18629518ea0Sdjm r = sshbuf_reserve(p1, 223, &dp);
18729518ea0Sdjm ASSERT_INT_EQ(r, 0);
18829518ea0Sdjm ASSERT_PTR_NE(dp, NULL);
18929518ea0Sdjm memset(dp, 0x7d, 223);
19029518ea0Sdjm cdp = sshbuf_ptr(p1);
19129518ea0Sdjm ASSERT_PTR_NE(cdp, NULL);
19229518ea0Sdjm ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
19329518ea0Sdjm ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
19429518ea0Sdjm TEST_DONE();
19529518ea0Sdjm
19629518ea0Sdjm TEST_START("resize full buffer");
19729518ea0Sdjm r = sshbuf_set_max_size(p1, 1000);
19829518ea0Sdjm ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
19929518ea0Sdjm sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC);
20029518ea0Sdjm ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0);
20129518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
20229518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223);
20329518ea0Sdjm ASSERT_INT_EQ(sshbuf_len(p1), 1223);
20429518ea0Sdjm TEST_DONE();
20529518ea0Sdjm
20629518ea0Sdjm /* NB. uses sshbuf internals */
20729518ea0Sdjm TEST_START("alloc chunking");
20829518ea0Sdjm r = sshbuf_reserve(p1, 1, &dp);
20929518ea0Sdjm ASSERT_INT_EQ(r, 0);
21029518ea0Sdjm ASSERT_PTR_NE(dp, NULL);
21129518ea0Sdjm *dp = 0xff;
21229518ea0Sdjm cdp = sshbuf_ptr(p1);
21329518ea0Sdjm ASSERT_PTR_NE(cdp, NULL);
21429518ea0Sdjm ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
21529518ea0Sdjm ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
21629518ea0Sdjm ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1);
21729518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0);
21829518ea0Sdjm sshbuf_free(p1);
21929518ea0Sdjm TEST_DONE();
22029518ea0Sdjm
22129518ea0Sdjm TEST_START("reset buffer");
22229518ea0Sdjm p1 = sshbuf_new();
22329518ea0Sdjm ASSERT_PTR_NE(p1, NULL);
22429518ea0Sdjm ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
22529518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
22629518ea0Sdjm r = sshbuf_reserve(p1, 1223, &dp);
22729518ea0Sdjm ASSERT_INT_EQ(r, 0);
22829518ea0Sdjm ASSERT_PTR_NE(dp, NULL);
22929518ea0Sdjm memset(dp, 0xd7, 1223);
23029518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
23129518ea0Sdjm sshbuf_reset(p1);
23229518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
23329518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
23429518ea0Sdjm ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
23529518ea0Sdjm sshbuf_free(p1);
23629518ea0Sdjm TEST_DONE();
23729518ea0Sdjm }
238