test_util_format.c (11575B)
1 /* Copyright (c) 2010-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 #include "orconfig.h" 5 #include "core/or/or.h" 6 7 #include "test/test.h" 8 9 #include "lib/crypt_ops/crypto_rand.h" 10 #include "lib/encoding/binascii.h" 11 12 static void 13 test_util_format_unaligned_accessors(void *ignored) 14 { 15 (void)ignored; 16 NONSTRING char buf[9] = "onionsoup"; // 6f6e696f6e736f7570 17 18 tt_u64_op(get_uint64(buf+1), OP_EQ, 19 tor_htonll(UINT64_C(0x6e696f6e736f7570))); 20 tt_uint_op(get_uint32(buf+1), OP_EQ, htonl(0x6e696f6e)); 21 tt_uint_op(get_uint16(buf+1), OP_EQ, htons(0x6e69)); 22 tt_uint_op(get_uint8(buf+1), OP_EQ, 0x6e); 23 24 set_uint8(buf+7, 0x61); 25 tt_mem_op(buf, OP_EQ, "onionsoap", 9); 26 27 set_uint16(buf+6, htons(0x746f)); 28 tt_mem_op(buf, OP_EQ, "onionstop", 9); 29 30 set_uint32(buf+1, htonl(0x78696465)); 31 tt_mem_op(buf, OP_EQ, "oxidestop", 9); 32 33 set_uint64(buf+1, tor_htonll(UINT64_C(0x6266757363617465))); 34 tt_mem_op(buf, OP_EQ, "obfuscate", 9); 35 done: 36 ; 37 } 38 39 static void 40 test_util_format_base64_encode(void *ignored) 41 { 42 (void)ignored; 43 int res; 44 int i; 45 char *src; 46 char *dst; 47 48 src = tor_malloc_zero(256); 49 dst = tor_malloc_zero(1000); 50 51 for (i=0;i<256;i++) { 52 src[i] = (char)i; 53 } 54 55 res = base64_encode(NULL, 1, src, 1, 0); 56 tt_int_op(res, OP_EQ, -1); 57 58 res = base64_encode(dst, 1, NULL, 1, 0); 59 tt_int_op(res, OP_EQ, -1); 60 61 res = base64_encode(dst, 1, src, 10, 0); 62 tt_int_op(res, OP_EQ, -1); 63 64 res = base64_encode(dst, SSIZE_MAX-1, src, 1, 0); 65 tt_int_op(res, OP_EQ, -1); 66 67 res = base64_encode(dst, SSIZE_MAX-1, src, 10, 0); 68 tt_int_op(res, OP_EQ, -1); 69 70 res = base64_encode(dst, 1000, src, 256, 0); 71 tt_int_op(res, OP_EQ, 344); 72 tt_str_op(dst, OP_EQ, "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh" 73 "8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH" 74 "SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3" 75 "BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeY" 76 "mZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wM" 77 "HCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp" 78 "6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="); 79 80 res = base64_encode(dst, 1000, src, 256, BASE64_ENCODE_MULTILINE); 81 tt_int_op(res, OP_EQ, 350); 82 tt_str_op(dst, OP_EQ, 83 "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4v\n" 84 "MDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5f\n" 85 "YGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P\n" 86 "kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/\n" 87 "wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v\n" 88 "8PHy8/T19vf4+fr7/P3+/w==\n"); 89 90 res = base64_encode(dst, 1000, src+1, 255, BASE64_ENCODE_MULTILINE); 91 tt_int_op(res, OP_EQ, 346); 92 93 for (i = 0;i<50;i++) { 94 src[i] = 0; 95 } 96 src[50] = (char)255; 97 src[51] = (char)255; 98 src[52] = (char)255; 99 src[53] = (char)255; 100 101 res = base64_encode(dst, 1000, src, 54, BASE64_ENCODE_MULTILINE); 102 tt_int_op(res, OP_EQ, 74); 103 104 res = base64_encode(dst, 1000, src+1, 53, BASE64_ENCODE_MULTILINE); 105 tt_int_op(res, OP_EQ, 74); 106 107 res = base64_encode(dst, 1000, src+2, 52, BASE64_ENCODE_MULTILINE); 108 tt_int_op(res, OP_EQ, 74); 109 110 res = base64_encode(dst, 1000, src+3, 51, BASE64_ENCODE_MULTILINE); 111 tt_int_op(res, OP_EQ, 70); 112 113 res = base64_encode(dst, 1000, src+4, 50, BASE64_ENCODE_MULTILINE); 114 tt_int_op(res, OP_EQ, 70); 115 116 res = base64_encode(dst, 1000, src+5, 49, BASE64_ENCODE_MULTILINE); 117 tt_int_op(res, OP_EQ, 70); 118 119 res = base64_encode(dst, 1000, src+6, 48, BASE64_ENCODE_MULTILINE); 120 tt_int_op(res, OP_EQ, 65); 121 122 res = base64_encode(dst, 1000, src+7, 47, BASE64_ENCODE_MULTILINE); 123 tt_int_op(res, OP_EQ, 65); 124 125 res = base64_encode(dst, 1000, src+8, 46, BASE64_ENCODE_MULTILINE); 126 tt_int_op(res, OP_EQ, 65); 127 128 done: 129 tor_free(src); 130 tor_free(dst); 131 } 132 133 static void 134 test_util_format_base64_decode_oddsize(void *ignored) 135 { 136 (void)ignored; 137 int res; 138 int i; 139 char *src; 140 char *dst, real_dst[7]; 141 char expected[] = {0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65}; 142 char real_src[] = "ZXhhbXBsZQ"; 143 char expected40[] = "testing40characteroddsizebase64encoding!"; 144 char src40[] = "dGVzdGluZzQwY2hhcmFjdGVyb2Rkc2l6ZWJhc2U2NGVuY29kaW5nIQ"; 145 char pad40[] = "dGVzdGluZzQwY2hhcmFjdGVyb2Rkc2l6ZWJhc2U2NGVuY29kaW5nIQ=="; 146 147 src = tor_malloc_zero(256); 148 dst = tor_malloc_zero(1000); 149 150 for (i=0;i<256;i++) { 151 src[i] = (char)i; 152 } 153 154 res = base64_decode(dst, 1, src, 5); 155 tt_int_op(res, OP_EQ, -1); 156 157 const char *s = "SGVsbG8gd29ybGQ"; 158 res = base64_decode(dst, 1000, s, strlen(s)); 159 tt_int_op(res, OP_EQ, 11); 160 tt_mem_op(dst, OP_EQ, "Hello world", 11); 161 162 s = "T3BhIG11bmRv"; 163 res = base64_decode(dst, 9, s, strlen(s)); 164 tt_int_op(res, OP_EQ, 9); 165 tt_mem_op(dst, OP_EQ, "Opa mundo", 9); 166 167 res = base64_decode(real_dst, sizeof(real_dst), real_src, 10); 168 tt_int_op(res, OP_EQ, 7); 169 tt_mem_op(real_dst, OP_EQ, expected, 7); 170 171 res = base64_decode(dst, 40, src40, strlen(src40)); 172 tt_int_op(res, OP_EQ, 40); 173 tt_mem_op(dst, OP_EQ, expected40, 40); 174 175 res = base64_decode(dst, 40, pad40, strlen(pad40)); 176 tt_int_op(res, OP_EQ, 40); 177 tt_mem_op(dst, OP_EQ, expected40, 40); 178 179 done: 180 tor_free(src); 181 tor_free(dst); 182 } 183 184 static void 185 test_util_format_base64_decode(void *ignored) 186 { 187 (void)ignored; 188 int res; 189 int i; 190 char *src; 191 char *dst, *real_dst; 192 uint8_t expected[] = {0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65}; 193 char real_src[] = "ZXhhbXBsZQ=="; 194 195 src = tor_malloc_zero(256); 196 dst = tor_malloc_zero(1000); 197 real_dst = tor_malloc_zero(10); 198 199 for (i=0;i<256;i++) { 200 src[i] = (char)i; 201 } 202 203 res = base64_decode(dst, 1, src, 100); 204 tt_int_op(res, OP_EQ, -1); 205 206 res = base64_decode(dst, 1, real_src, 10); 207 tt_int_op(res, OP_EQ, -1); 208 209 const char *s = "T3BhIG11bmRv"; 210 res = base64_decode(dst, 9, s, strlen(s)); 211 tt_int_op(res, OP_EQ, 9); 212 tt_mem_op(dst, OP_EQ, "Opa mundo", 9); 213 214 memset(dst, 0, 1000); 215 res = base64_decode(dst, 100, s, strlen(s)); 216 tt_int_op(res, OP_EQ, 9); 217 tt_mem_op(dst, OP_EQ, "Opa mundo", 9); 218 219 s = "SGVsbG8gd29ybGQ="; 220 res = base64_decode(dst, 100, s, strlen(s)); 221 tt_int_op(res, OP_EQ, 11); 222 tt_mem_op(dst, OP_EQ, "Hello world", 11); 223 224 res = base64_decode(real_dst, 10, real_src, 10); 225 tt_int_op(res, OP_EQ, 7); 226 tt_mem_op(real_dst, OP_EQ, expected, 7); 227 228 done: 229 tor_free(src); 230 tor_free(dst); 231 tor_free(real_dst); 232 } 233 234 static void 235 test_util_format_base16_decode(void *ignored) 236 { 237 (void)ignored; 238 int res; 239 int i; 240 char *src; 241 char *dst, *real_dst; 242 char expected[] = {0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65}; 243 char real_src[] = "6578616D706C65"; 244 245 src = tor_malloc_zero(256); 246 dst = tor_malloc_zero(1000); 247 real_dst = tor_malloc_zero(10); 248 249 for (i=0;i<256;i++) { 250 src[i] = (char)i; 251 } 252 253 res = base16_decode(dst, 3, src, 3); 254 tt_int_op(res, OP_EQ, -1); 255 256 res = base16_decode(dst, 1, src, 10); 257 tt_int_op(res, OP_EQ, -1); 258 259 res = base16_decode(dst, ((size_t)INT_MAX)+1, src, 10); 260 tt_int_op(res, OP_EQ, -1); 261 262 res = base16_decode(dst, 1000, "", 0); 263 tt_int_op(res, OP_EQ, 0); 264 265 res = base16_decode(dst, 1000, "aabc", 4); 266 tt_int_op(res, OP_EQ, 2); 267 tt_mem_op(dst, OP_EQ, "\xaa\xbc", 2); 268 269 res = base16_decode(dst, 1000, "aabcd", 6); 270 tt_int_op(res, OP_EQ, -1); 271 272 res = base16_decode(dst, 1000, "axxx", 4); 273 tt_int_op(res, OP_EQ, -1); 274 275 res = base16_decode(real_dst, 10, real_src, 14); 276 tt_int_op(res, OP_EQ, 7); 277 tt_mem_op(real_dst, OP_EQ, expected, 7); 278 279 done: 280 tor_free(src); 281 tor_free(dst); 282 tor_free(real_dst); 283 } 284 285 static void 286 test_util_format_base32_encode(void *arg) 287 { 288 (void) arg; 289 size_t real_dstlen = 32; 290 char *dst = tor_malloc_zero(real_dstlen); 291 292 /* Basic use case that doesn't require a source length correction. */ 293 { 294 /* Length of 10 bytes. */ 295 const char *src = "blahbleh12"; 296 size_t srclen = strlen(src); 297 /* Expected result encoded base32. This was created using python as 298 * such (and same goes for all test case.): 299 * 300 * b = bytes("blahbleh12", 'utf-8') 301 * base64.b32encode(b) 302 * (result in lower case) 303 */ 304 const char *expected = "mjwgc2dcnrswqmjs"; 305 306 base32_encode(dst, base32_encoded_size(srclen), src, srclen); 307 tt_mem_op(expected, OP_EQ, dst, strlen(expected)); 308 /* Encode but to a larger size destination. */ 309 memset(dst, 0, real_dstlen); 310 base32_encode(dst, real_dstlen, src, srclen); 311 tt_mem_op(expected, OP_EQ, dst, strlen(expected)); 312 } 313 314 /* Non multiple of 5 for the source buffer length. */ 315 { 316 /* Length of 8 bytes. */ 317 const char *expected = "mjwgc2dcnrswq"; 318 const char *src = "blahbleh"; 319 size_t srclen = strlen(src); 320 321 memset(dst, 0, real_dstlen); 322 base32_encode(dst, base32_encoded_size(srclen), src, srclen); 323 tt_mem_op(expected, OP_EQ, dst, strlen(expected)); 324 } 325 326 done: 327 tor_free(dst); 328 } 329 330 static void 331 test_util_format_base32_decode(void *arg) 332 { 333 (void) arg; 334 int ret; 335 size_t real_dstlen = 32; 336 char *dst = tor_malloc_zero(real_dstlen); 337 338 /* Basic use case. */ 339 { 340 /* Length of 10 bytes. */ 341 const char *expected = "blahbleh12"; 342 /* Expected result encoded base32. */ 343 const char *src = "mjwgc2dcnrswqmjs"; 344 345 ret = base32_decode(dst, strlen(expected), src, strlen(src)); 346 tt_int_op(ret, OP_EQ, 10); 347 tt_str_op(expected, OP_EQ, dst); 348 } 349 350 /* Non multiple of 5 for the source buffer length. */ 351 { 352 /* Length of 8 bytes. */ 353 const char *expected = "blahbleh"; 354 const char *src = "mjwgc2dcnrswq"; 355 356 ret = base32_decode(dst, strlen(expected), src, strlen(src)); 357 tt_int_op(ret, OP_EQ, 8); 358 tt_mem_op(expected, OP_EQ, dst, strlen(expected)); 359 } 360 361 /* Invalid values. */ 362 { 363 /* Invalid character '#'. */ 364 ret = base32_decode(dst, real_dstlen, "#abcde", 6); 365 tt_int_op(ret, OP_EQ, -1); 366 /* Make sure the destination buffer has been zeroed even on error. */ 367 tt_int_op(fast_mem_is_zero(dst, real_dstlen), OP_EQ, 1); 368 } 369 370 done: 371 tor_free(dst); 372 } 373 374 static void 375 test_util_format_encoded_size(void *arg) 376 { 377 (void)arg; 378 uint8_t inbuf[256]; 379 char outbuf[1024]; 380 unsigned i; 381 382 crypto_rand((char *)inbuf, sizeof(inbuf)); 383 for (i = 0; i <= sizeof(inbuf); ++i) { 384 /* XXXX (Once the return values are consistent, check them too.) */ 385 386 base32_encode(outbuf, sizeof(outbuf), (char *)inbuf, i); 387 /* The "+ 1" below is an API inconsistency. */ 388 tt_int_op(strlen(outbuf) + 1, OP_EQ, base32_encoded_size(i)); 389 390 base64_encode(outbuf, sizeof(outbuf), (char *)inbuf, i, 0); 391 tt_int_op(strlen(outbuf), OP_EQ, base64_encode_size(i, 0)); 392 tt_int_op(i, OP_LE, base64_decode_maxsize(strlen(outbuf))); 393 394 base64_encode(outbuf, sizeof(outbuf), (char *)inbuf, i, 395 BASE64_ENCODE_MULTILINE); 396 tt_int_op(strlen(outbuf), OP_EQ, 397 base64_encode_size(i, BASE64_ENCODE_MULTILINE)); 398 tt_int_op(i, OP_LE, base64_decode_maxsize(strlen(outbuf))); 399 } 400 401 done: 402 ; 403 } 404 405 struct testcase_t util_format_tests[] = { 406 { "unaligned_accessors", test_util_format_unaligned_accessors, 0, 407 NULL, NULL }, 408 { "base64_encode", test_util_format_base64_encode, 0, NULL, NULL }, 409 { "base64_decode_oddsize", test_util_format_base64_decode_oddsize, 0, 410 NULL, NULL }, 411 { "base64_decode", test_util_format_base64_decode, 0, NULL, NULL }, 412 { "base16_decode", test_util_format_base16_decode, 0, NULL, NULL }, 413 { "base32_encode", test_util_format_base32_encode, 0, 414 NULL, NULL }, 415 { "base32_decode", test_util_format_base32_decode, 0, 416 NULL, NULL }, 417 { "encoded_size", test_util_format_encoded_size, 0, NULL, NULL }, 418 END_OF_TESTCASES 419 };