1 /* $OpenBSD: test_sshbuf.c,v 1.2 2021/12/14 21:25:27 deraadt Exp $ */ 2 /* 3 * Regress test for sshbuf.h buffer API 4 * 5 * Placed in the public domain 6 */ 7 8 #define SSHBUF_INTERNAL 1 /* access internals for testing */ 9 #include "includes.h" 10 11 #include <sys/types.h> 12 #include <stdio.h> 13 #ifdef HAVE_STDINT_H 14 # include <stdint.h> 15 #endif 16 #include <stdlib.h> 17 #include <string.h> 18 19 #include "../test_helper/test_helper.h" 20 21 #include "ssherr.h" 22 #include "sshbuf.h" 23 24 void sshbuf_tests(void); 25 26 #ifndef roundup 27 #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) 28 #endif 29 30 void 31 sshbuf_tests(void) 32 { 33 struct sshbuf *p1; 34 const u_char *cdp; 35 u_char *dp; 36 size_t sz; 37 int r; 38 39 TEST_START("allocate sshbuf"); 40 p1 = sshbuf_new(); 41 ASSERT_PTR_NE(p1, NULL); 42 TEST_DONE(); 43 44 TEST_START("max size on fresh buffer"); 45 ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0); 46 TEST_DONE(); 47 48 TEST_START("available on fresh buffer"); 49 ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0); 50 TEST_DONE(); 51 52 TEST_START("len = 0 on empty buffer"); 53 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 54 TEST_DONE(); 55 56 TEST_START("set valid max size"); 57 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0); 58 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536); 59 TEST_DONE(); 60 61 TEST_START("available on limited buffer"); 62 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536); 63 TEST_DONE(); 64 65 TEST_START("free"); 66 sshbuf_free(p1); 67 TEST_DONE(); 68 69 TEST_START("consume on empty buffer"); 70 p1 = sshbuf_new(); 71 ASSERT_PTR_NE(p1, NULL); 72 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0); 73 ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE); 74 sshbuf_free(p1); 75 TEST_DONE(); 76 77 TEST_START("consume_end on empty buffer"); 78 p1 = sshbuf_new(); 79 ASSERT_PTR_NE(p1, NULL); 80 ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0); 81 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE); 82 sshbuf_free(p1); 83 TEST_DONE(); 84 85 TEST_START("reserve space"); 86 p1 = sshbuf_new(); 87 ASSERT_PTR_NE(p1, NULL); 88 r = sshbuf_reserve(p1, 1, &dp); 89 ASSERT_INT_EQ(r, 0); 90 ASSERT_PTR_NE(dp, NULL); 91 *dp = 0x11; 92 r = sshbuf_reserve(p1, 3, &dp); 93 ASSERT_INT_EQ(r, 0); 94 ASSERT_PTR_NE(dp, NULL); 95 *dp++ = 0x22; 96 *dp++ = 0x33; 97 *dp++ = 0x44; 98 TEST_DONE(); 99 100 TEST_START("sshbuf_len on filled buffer"); 101 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 102 TEST_DONE(); 103 104 TEST_START("sshbuf_ptr on filled buffer"); 105 cdp = sshbuf_ptr(p1); 106 ASSERT_PTR_NE(cdp, NULL); 107 ASSERT_U8_EQ(cdp[0], 0x11); 108 ASSERT_U8_EQ(cdp[1], 0x22); 109 ASSERT_U8_EQ(cdp[2], 0x33); 110 ASSERT_U8_EQ(cdp[3], 0x44); 111 TEST_DONE(); 112 113 TEST_START("consume on filled buffer"); 114 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 115 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0); 116 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 117 r = sshbuf_consume(p1, 64); 118 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 119 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 120 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0); 121 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3); 122 cdp = sshbuf_ptr(p1); 123 ASSERT_PTR_NE(p1, NULL); 124 ASSERT_U8_EQ(cdp[0], 0x22); 125 ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0); 126 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); 127 cdp = sshbuf_ptr(p1); 128 ASSERT_PTR_NE(p1, NULL); 129 ASSERT_U8_EQ(cdp[0], 0x44); 130 r = sshbuf_consume(p1, 2); 131 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 132 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); 133 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0); 134 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 135 r = sshbuf_consume(p1, 1); 136 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 137 sshbuf_free(p1); 138 TEST_DONE(); 139 140 TEST_START("consume_end on filled buffer"); 141 p1 = sshbuf_new(); 142 ASSERT_PTR_NE(p1, NULL); 143 r = sshbuf_reserve(p1, 4, &dp); 144 ASSERT_INT_EQ(r, 0); 145 ASSERT_PTR_NE(dp, NULL); 146 *dp++ = 0x11; 147 *dp++ = 0x22; 148 *dp++ = 0x33; 149 *dp++ = 0x44; 150 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 151 r = sshbuf_consume_end(p1, 5); 152 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 153 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 154 ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0); 155 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); 156 cdp = sshbuf_ptr(p1); 157 ASSERT_PTR_NE(cdp, NULL); 158 ASSERT_U8_EQ(*cdp, 0x11); 159 r = sshbuf_consume_end(p1, 2); 160 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 161 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0); 162 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 163 sshbuf_free(p1); 164 TEST_DONE(); 165 166 TEST_START("fill limited buffer"); 167 p1 = sshbuf_new(); 168 ASSERT_PTR_NE(p1, NULL); 169 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0); 170 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); 171 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223); 172 r = sshbuf_reserve(p1, 1223, &dp); 173 ASSERT_INT_EQ(r, 0); 174 ASSERT_PTR_NE(dp, NULL); 175 memset(dp, 0xd7, 1223); 176 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223); 177 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0); 178 r = sshbuf_reserve(p1, 1, &dp); 179 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 180 ASSERT_PTR_EQ(dp, NULL); 181 TEST_DONE(); 182 183 TEST_START("consume and force compaction"); 184 ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0); 185 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000); 186 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223); 187 r = sshbuf_reserve(p1, 224, &dp); 188 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 189 ASSERT_PTR_EQ(dp, NULL); 190 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000); 191 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223); 192 r = sshbuf_reserve(p1, 223, &dp); 193 ASSERT_INT_EQ(r, 0); 194 ASSERT_PTR_NE(dp, NULL); 195 memset(dp, 0x7d, 223); 196 cdp = sshbuf_ptr(p1); 197 ASSERT_PTR_NE(cdp, NULL); 198 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000); 199 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223); 200 TEST_DONE(); 201 202 TEST_START("resize full buffer"); 203 r = sshbuf_set_max_size(p1, 1000); 204 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 205 sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC); 206 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0); 207 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz); 208 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223); 209 ASSERT_INT_EQ(sshbuf_len(p1), 1223); 210 TEST_DONE(); 211 212 /* NB. uses sshbuf internals */ 213 TEST_START("alloc chunking"); 214 r = sshbuf_reserve(p1, 1, &dp); 215 ASSERT_INT_EQ(r, 0); 216 ASSERT_PTR_NE(dp, NULL); 217 *dp = 0xff; 218 cdp = sshbuf_ptr(p1); 219 ASSERT_PTR_NE(cdp, NULL); 220 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000); 221 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223); 222 ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1); 223 ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0); 224 sshbuf_free(p1); 225 TEST_DONE(); 226 227 TEST_START("reset buffer"); 228 p1 = sshbuf_new(); 229 ASSERT_PTR_NE(p1, NULL); 230 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0); 231 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); 232 r = sshbuf_reserve(p1, 1223, &dp); 233 ASSERT_INT_EQ(r, 0); 234 ASSERT_PTR_NE(dp, NULL); 235 memset(dp, 0xd7, 1223); 236 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223); 237 sshbuf_reset(p1); 238 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); 239 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 240 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223); 241 sshbuf_free(p1); 242 TEST_DONE(); 243 } 244