/** Run unit tests for our secret-to-key passphrase hashing functionality. */ static void test_crypto_s2k_rfc2440(void *arg) { char buf[29]; char buf2[29]; char *buf3 = NULL; int i; (void)arg; memset(buf, 0, sizeof(buf)); memset(buf2, 0, sizeof(buf2)); buf3 = tor_malloc(65536); memset(buf3, 0, 65536); secret_to_key_rfc2440(buf+9, 20, "", 0, buf); crypto_digest(buf2+9, buf3, 1024); tt_mem_op(buf,OP_EQ, buf2, 29); memcpy(buf,"vrbacrda",8); memcpy(buf2,"vrbacrda",8); buf[8] = 96; buf2[8] = 96; secret_to_key_rfc2440(buf+9, 20, "12345678", 8, buf); for (i = 0; i < 65536; i += 16) { memcpy(buf3+i, "vrbacrda12345678", 16); } crypto_digest(buf2+9, buf3, 65536); tt_mem_op(buf,OP_EQ, buf2, 29); done: tor_free(buf3); }
/** Run unit tests for smartlist-of-digests functions. */ static void test_container_smartlist_digests(void *arg) { smartlist_t *sl = smartlist_new(); /* contains_digest */ (void)arg; smartlist_add(sl, tor_memdup("AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN)); smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN)); smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN)); tt_int_op(0,OP_EQ, smartlist_contains_digest(NULL, "AAAAAAAAAAAAAAAAAAAA")); tt_assert(smartlist_contains_digest(sl, "AAAAAAAAAAAAAAAAAAAA")); tt_assert(smartlist_contains_digest(sl, "\00090AAB2AAAAaasdAAAAA")); tt_int_op(0,OP_EQ, smartlist_contains_digest(sl, "\00090AAB2AAABaasdAAAAA")); /* sort digests */ smartlist_sort_digests(sl); tt_mem_op(smartlist_get(sl, 0),OP_EQ, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); tt_mem_op(smartlist_get(sl, 1),OP_EQ, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); tt_mem_op(smartlist_get(sl, 2),OP_EQ, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN); tt_int_op(3,OP_EQ, smartlist_len(sl)); /* uniq_digests */ smartlist_uniq_digests(sl); tt_int_op(2,OP_EQ, smartlist_len(sl)); tt_mem_op(smartlist_get(sl, 0),OP_EQ, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); tt_mem_op(smartlist_get(sl, 1),OP_EQ, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN); done: SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); smartlist_free(sl); }
static void test_util_format_unaligned_accessors(void *ignored) { (void)ignored; char buf[9] = "onionsoup"; // 6f6e696f6e736f7570 tt_u64_op(get_uint64(buf+1), OP_EQ, htonll(U64_LITERAL(0x6e696f6e736f7570))); tt_uint_op(get_uint32(buf+1), OP_EQ, htonl(0x6e696f6e)); tt_uint_op(get_uint16(buf+1), OP_EQ, htons(0x6e69)); tt_uint_op(get_uint8(buf+1), OP_EQ, 0x6e); set_uint8(buf+7, 0x61); tt_mem_op(buf, OP_EQ, "onionsoap", 9); set_uint16(buf+6, htons(0x746f)); tt_mem_op(buf, OP_EQ, "onionstop", 9); set_uint32(buf+1, htonl(0x78696465)); tt_mem_op(buf, OP_EQ, "oxidestop", 9); set_uint64(buf+1, htonll(U64_LITERAL(0x6266757363617465))); tt_mem_op(buf, OP_EQ, "obfuscate", 9); done: ; }
static void test_ntor_handshake(void *arg) { /* client-side */ ntor_handshake_state_t *c_state = NULL; uint8_t c_buf[NTOR_ONIONSKIN_LEN]; uint8_t c_keys[400]; /* server-side */ di_digest256_map_t *s_keymap=NULL; curve25519_keypair_t s_keypair; uint8_t s_buf[NTOR_REPLY_LEN]; uint8_t s_keys[400]; /* shared */ const curve25519_public_key_t *server_pubkey; uint8_t node_id[20] = "abcdefghijklmnopqrst"; (void) arg; /* Make the server some keys */ curve25519_secret_key_generate(&s_keypair.seckey, 0); curve25519_public_key_generate(&s_keypair.pubkey, &s_keypair.seckey); dimap_add_entry(&s_keymap, s_keypair.pubkey.public_key, &s_keypair); server_pubkey = &s_keypair.pubkey; /* client handshake 1. */ memset(c_buf, 0, NTOR_ONIONSKIN_LEN); tt_int_op(0, OP_EQ, onion_skin_ntor_create(node_id, server_pubkey, &c_state, c_buf)); /* server handshake */ memset(s_buf, 0, NTOR_REPLY_LEN); memset(s_keys, 0, 40); tt_int_op(0, OP_EQ, onion_skin_ntor_server_handshake(c_buf, s_keymap, NULL, node_id, s_buf, s_keys, 400)); /* client handshake 2 */ memset(c_keys, 0, 40); tt_int_op(0, OP_EQ, onion_skin_ntor_client_handshake(c_state, s_buf, c_keys, 400, NULL)); tt_mem_op(c_keys,OP_EQ, s_keys, 400); memset(s_buf, 0, 40); tt_mem_op(c_keys,OP_NE, s_buf, 40); /* Now try with a bogus server response. Zero input should trigger * All The Problems. */ memset(c_keys, 0, 400); memset(s_buf, 0, NTOR_REPLY_LEN); const char *msg = NULL; tt_int_op(-1, OP_EQ, onion_skin_ntor_client_handshake(c_state, s_buf, c_keys, 400, &msg)); tt_str_op(msg, OP_EQ, "Zero output from curve25519 handshake"); done: ntor_handshake_state_free(c_state); dimap_free(s_keymap, NULL); }
/** Perform SOCKS 5 authentication */ static void test_socks_5_no_authenticate(void *ptr) { SOCKS_TEST_INIT(); /*SOCKS 5 No Authentication */ ADD_DATA(buf,"\x05\x01\x00"); tt_assert(!fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks)); tt_int_op(2,OP_EQ, socks->replylen); tt_int_op(5,OP_EQ, socks->reply[0]); tt_int_op(SOCKS_NO_AUTH,OP_EQ, socks->reply[1]); tt_int_op(0,OP_EQ, buf_datalen(buf)); /*SOCKS 5 Send username/password anyway - pretend to be broken */ ADD_DATA(buf,"\x01\x02\x01\x01\x02\x01\x01"); tt_assert(!fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks)); tt_int_op(5,OP_EQ, socks->socks_version); tt_int_op(2,OP_EQ, socks->replylen); tt_int_op(1,OP_EQ, socks->reply[0]); tt_int_op(0,OP_EQ, socks->reply[1]); tt_int_op(2,OP_EQ, socks->usernamelen); tt_int_op(2,OP_EQ, socks->passwordlen); tt_mem_op("\x01\x01",OP_EQ, socks->username, 2); tt_mem_op("\x01\x01",OP_EQ, socks->password, 2); done: ; }
/* Test encoding and decoding service authorization cookies */ static void test_hs_auth_cookies(void *arg) { #define TEST_COOKIE_RAW ((const uint8_t *) "abcdefghijklmnop") #define TEST_COOKIE_ENCODED "YWJjZGVmZ2hpamtsbW5vcA" #define TEST_COOKIE_ENCODED_STEALTH "YWJjZGVmZ2hpamtsbW5vcB" #define TEST_COOKIE_ENCODED_INVALID "YWJjZGVmZ2hpamtsbW5vcD" char *encoded_cookie; uint8_t raw_cookie[REND_DESC_COOKIE_LEN]; rend_auth_type_t auth_type; char *err_msg; int re; (void)arg; /* Test that encoding gives the expected result */ encoded_cookie = rend_auth_encode_cookie(TEST_COOKIE_RAW, REND_BASIC_AUTH); tt_str_op(encoded_cookie, OP_EQ, TEST_COOKIE_ENCODED); tor_free(encoded_cookie); encoded_cookie = rend_auth_encode_cookie(TEST_COOKIE_RAW, REND_STEALTH_AUTH); tt_str_op(encoded_cookie, OP_EQ, TEST_COOKIE_ENCODED_STEALTH); tor_free(encoded_cookie); /* Decoding should give the original value */ re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED, raw_cookie, &auth_type, &err_msg); tt_assert(!re); tt_ptr_op(err_msg, OP_EQ, NULL); tt_mem_op(raw_cookie, OP_EQ, TEST_COOKIE_RAW, REND_DESC_COOKIE_LEN); tt_int_op(auth_type, OP_EQ, REND_BASIC_AUTH); memset(raw_cookie, 0, sizeof(raw_cookie)); re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED_STEALTH, raw_cookie, &auth_type, &err_msg); tt_assert(!re); tt_ptr_op(err_msg, OP_EQ, NULL); tt_mem_op(raw_cookie, OP_EQ, TEST_COOKIE_RAW, REND_DESC_COOKIE_LEN); tt_int_op(auth_type, OP_EQ, REND_STEALTH_AUTH); memset(raw_cookie, 0, sizeof(raw_cookie)); /* Decoding with padding characters should also work */ re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED "==", raw_cookie, NULL, &err_msg); tt_assert(!re); tt_ptr_op(err_msg, OP_EQ, NULL); tt_mem_op(raw_cookie, OP_EQ, TEST_COOKIE_RAW, REND_DESC_COOKIE_LEN); /* Decoding with an unknown type should fail */ re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED_INVALID, raw_cookie, &auth_type, &err_msg); tt_int_op(re, OP_LT, 0); tt_assert(err_msg); tor_free(err_msg); done: return; }
static void run_s2k_tests(const unsigned flags, const unsigned type, int speclen, const int keylen, int legacy) { uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN], buf3[S2K_MAXLEN]; int r; size_t sz; const char pw1[] = "You can't come in here unless you say swordfish!"; const char pw2[] = "Now, I give you one more guess."; r = secret_to_key_new(buf, sizeof(buf), &sz, pw1, strlen(pw1), flags); tt_int_op(r, OP_EQ, S2K_OKAY); tt_int_op(buf[0], OP_EQ, type); tt_int_op(sz, OP_EQ, keylen + speclen); if (legacy) { memmove(buf, buf+1, sz-1); --sz; --speclen; } tt_int_op(S2K_OKAY, OP_EQ, secret_to_key_check(buf, sz, pw1, strlen(pw1))); tt_int_op(S2K_BAD_SECRET, OP_EQ, secret_to_key_check(buf, sz, pw2, strlen(pw2))); /* Move key to buf2, and clear it. */ memset(buf3, 0, sizeof(buf3)); memcpy(buf2, buf+speclen, keylen); memset(buf+speclen, 0, sz - speclen); /* Derivekey should produce the same results. */ tt_int_op(S2K_OKAY, OP_EQ, secret_to_key_derivekey(buf3, keylen, buf, speclen, pw1, strlen(pw1))); tt_mem_op(buf2, OP_EQ, buf3, keylen); /* Derivekey with a longer output should fill the output. */ memset(buf2, 0, sizeof(buf2)); tt_int_op(S2K_OKAY, OP_EQ, secret_to_key_derivekey(buf2, sizeof(buf2), buf, speclen, pw1, strlen(pw1))); tt_mem_op(buf2, OP_NE, buf3, sizeof(buf2)); memset(buf3, 0, sizeof(buf3)); tt_int_op(S2K_OKAY, OP_EQ, secret_to_key_derivekey(buf3, sizeof(buf3), buf, speclen, pw1, strlen(pw1))); tt_mem_op(buf2, OP_EQ, buf3, sizeof(buf3)); tt_assert(!tor_mem_is_zero((char*)buf2+keylen, sizeof(buf2)-keylen)); done: ; }
static void test_ext_or_init_auth(void *arg) { or_options_t *options = get_options_mutable(); const char *fn; char *cp = NULL; struct stat st; char cookie0[32]; (void)arg; /* Check default filename location */ tor_free(options->DataDirectory); options->DataDirectory = tor_strdup("foo"); cp = get_ext_or_auth_cookie_file_name(); tt_str_op(cp, OP_EQ, "foo"PATH_SEPARATOR"extended_orport_auth_cookie"); tor_free(cp); /* Shouldn't be initialized already, or our tests will be a bit * meaningless */ ext_or_auth_cookie = tor_malloc_zero(32); tt_assert(tor_mem_is_zero((char*)ext_or_auth_cookie, 32)); /* Now make sure we use a temporary file */ fn = get_fname("ext_cookie_file"); options->ExtORPortCookieAuthFile = tor_strdup(fn); cp = get_ext_or_auth_cookie_file_name(); tt_str_op(cp, OP_EQ, fn); tor_free(cp); /* Test the initialization function with a broken write_bytes_to_file(). See if the problem is handled properly. */ MOCK(write_bytes_to_file, write_bytes_to_file_fail); tt_int_op(-1, OP_EQ, init_ext_or_cookie_authentication(1)); tt_int_op(ext_or_auth_cookie_is_set, OP_EQ, 0); UNMOCK(write_bytes_to_file); /* Now do the actual initialization. */ tt_int_op(0, OP_EQ, init_ext_or_cookie_authentication(1)); tt_int_op(ext_or_auth_cookie_is_set, OP_EQ, 1); cp = read_file_to_str(fn, RFTS_BIN, &st); tt_ptr_op(cp, OP_NE, NULL); tt_u64_op((uint64_t)st.st_size, OP_EQ, 64); tt_mem_op(cp,OP_EQ, "! Extended ORPort Auth Cookie !\x0a", 32); tt_mem_op(cp+32,OP_EQ, ext_or_auth_cookie, 32); memcpy(cookie0, ext_or_auth_cookie, 32); tt_assert(!tor_mem_is_zero((char*)ext_or_auth_cookie, 32)); /* Operation should be idempotent. */ tt_int_op(0, OP_EQ, init_ext_or_cookie_authentication(1)); tt_mem_op(cookie0,OP_EQ, ext_or_auth_cookie, 32); done: tor_free(cp); ext_orport_free_all(); }
/** Run unit tests for the onion handshake code. */ static void test_onion_handshake(void *arg) { /* client-side */ crypto_dh_t *c_dh = NULL; char c_buf[TAP_ONIONSKIN_CHALLENGE_LEN]; char c_keys[40]; /* server-side */ char s_buf[TAP_ONIONSKIN_REPLY_LEN]; char s_keys[40]; int i; /* shared */ crypto_pk_t *pk = NULL, *pk2 = NULL; (void)arg; pk = pk_generate(0); pk2 = pk_generate(1); /* client handshake 1. */ memset(c_buf, 0, TAP_ONIONSKIN_CHALLENGE_LEN); tt_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf)); for (i = 1; i <= 3; ++i) { crypto_pk_t *k1, *k2; if (i==1) { /* server handshake: only one key known. */ k1 = pk; k2 = NULL; } else if (i==2) { /* server handshake: try the right key first. */ k1 = pk; k2 = pk2; } else { /* server handshake: try the right key second. */ k1 = pk2; k2 = pk; } memset(s_buf, 0, TAP_ONIONSKIN_REPLY_LEN); memset(s_keys, 0, 40); tt_assert(! onion_skin_TAP_server_handshake(c_buf, k1, k2, s_buf, s_keys, 40)); /* client handshake 2 */ memset(c_keys, 0, 40); tt_assert(! onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40, NULL)); tt_mem_op(c_keys,OP_EQ, s_keys, 40); memset(s_buf, 0, 40); tt_mem_op(c_keys,OP_NE, s_buf, 40); } done: crypto_dh_free(c_dh); crypto_pk_free(pk); crypto_pk_free(pk2); }
static void test_ext_or_write_command(void *arg) { or_connection_t *c1; char *cp = NULL; char *buf = NULL; size_t sz; (void) arg; MOCK(connection_write_to_buf_impl_, connection_write_to_buf_impl_replacement); c1 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET); tt_assert(c1); /* Length too long */ tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 100, "X", 100000), OP_LT, 0); /* Empty command */ tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0x99, NULL, 0), OP_EQ, 0); cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz); tt_int_op(sz, OP_EQ, 4); tt_mem_op(cp, OP_EQ, "\x00\x99\x00\x00", 4); tor_free(cp); /* Medium command. */ tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0x99, "Wai\0Hello", 9), OP_EQ, 0); cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz); tt_int_op(sz, OP_EQ, 13); tt_mem_op(cp, OP_EQ, "\x00\x99\x00\x09Wai\x00Hello", 13); tor_free(cp); /* Long command */ buf = tor_malloc(65535); memset(buf, 'x', 65535); tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0xf00d, buf, 65535), OP_EQ, 0); cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz); tt_int_op(sz, OP_EQ, 65539); tt_mem_op(cp, OP_EQ, "\xf0\x0d\xff\xff", 4); tt_mem_op(cp+4, OP_EQ, buf, 65535); tor_free(cp); done: if (c1) connection_free_(TO_CONN(c1)); tor_free(cp); tor_free(buf); UNMOCK(connection_write_to_buf_impl_); }
static void test_util_format_base16_decode(void *ignored) { (void)ignored; int res; int i; char *src; char *dst, *real_dst; char expected[] = {0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65}; char real_src[] = "6578616D706C65"; src = tor_malloc_zero(256); dst = tor_malloc_zero(1000); real_dst = tor_malloc_zero(10); for (i=0;i<256;i++) { src[i] = (char)i; } res = base16_decode(dst, 3, src, 3); tt_int_op(res, OP_EQ, -1); res = base16_decode(dst, 1, src, 10); tt_int_op(res, OP_EQ, -1); res = base16_decode(dst, ((size_t)INT_MAX)+1, src, 10); tt_int_op(res, OP_EQ, -1); res = base16_decode(dst, 1000, "", 0); tt_int_op(res, OP_EQ, 0); res = base16_decode(dst, 1000, "aabc", 4); tt_int_op(res, OP_EQ, 2); tt_mem_op(dst, OP_EQ, "\xaa\xbc", 2); res = base16_decode(dst, 1000, "aabcd", 6); tt_int_op(res, OP_EQ, -1); res = base16_decode(dst, 1000, "axxx", 4); tt_int_op(res, OP_EQ, -1); res = base16_decode(real_dst, 10, real_src, 14); tt_int_op(res, OP_EQ, 7); tt_mem_op(real_dst, OP_EQ, expected, 7); done: tor_free(src); tor_free(dst); tor_free(real_dst); }
static void test_util_format_base64_decode(void *ignored) { (void)ignored; int res; int i; char *src; char *dst, *real_dst; uint8_t expected[] = {0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65}; char real_src[] = "ZXhhbXBsZQ=="; src = tor_malloc_zero(256); dst = tor_malloc_zero(1000); real_dst = tor_malloc_zero(10); for (i=0;i<256;i++) { src[i] = (char)i; } res = base64_decode(dst, 1, src, SIZE_T_CEILING); tt_int_op(res, OP_EQ, -1); res = base64_decode(dst, SIZE_T_CEILING+1, src, 10); tt_int_op(res, OP_EQ, -1); const char *s = "T3BhIG11bmRv"; res = base64_decode(dst, 9, s, strlen(s)); tt_int_op(res, OP_EQ, 9); tt_mem_op(dst, OP_EQ, "Opa mundo", 9); memset(dst, 0, 1000); res = base64_decode(dst, 100, s, strlen(s)); tt_int_op(res, OP_EQ, 9); tt_mem_op(dst, OP_EQ, "Opa mundo", 9); s = "SGVsbG8gd29ybGQ="; res = base64_decode(dst, 100, s, strlen(s)); tt_int_op(res, OP_EQ, 11); tt_mem_op(dst, OP_EQ, "Hello world", 11); res = base64_decode(real_dst, 10, real_src, 10); tt_int_op(res, OP_EQ, 7); tt_mem_op(real_dst, OP_EQ, expected, 7); done: tor_free(src); tor_free(dst); tor_free(real_dst); }
static void test_buffers_zlib_impl(int finalize_with_nil) { char *msg = NULL; char *contents = NULL; char *expanded = NULL; buf_t *buf = NULL; tor_zlib_state_t *zlib_state = NULL; size_t out_len, in_len; int done; buf = buf_new_with_capacity(128); /* will round up */ zlib_state = tor_zlib_new(1, ZLIB_METHOD, HIGH_COMPRESSION); msg = tor_malloc(512); crypto_rand(msg, 512); tt_int_op(write_to_buf_zlib(buf, zlib_state, msg, 128, 0), OP_EQ, 0); tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+128, 128, 0), OP_EQ, 0); tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+256, 256, 0), OP_EQ, 0); done = !finalize_with_nil; tt_int_op(write_to_buf_zlib(buf, zlib_state, "all done", 9, done), OP_EQ, 0); if (finalize_with_nil) { tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), OP_EQ, 0); } in_len = buf_datalen(buf); contents = tor_malloc(in_len); tt_int_op(fetch_from_buf(contents, in_len, buf), OP_EQ, 0); tt_int_op(0, OP_EQ, tor_gzip_uncompress(&expanded, &out_len, contents, in_len, ZLIB_METHOD, 1, LOG_WARN)); tt_int_op(out_len, OP_GE, 128); tt_mem_op(msg, OP_EQ, expanded, 128); tt_int_op(out_len, OP_GE, 512); tt_mem_op(msg, OP_EQ, expanded, 512); tt_int_op(out_len, OP_EQ, 512+9); tt_mem_op("all done", OP_EQ, expanded+512, 9); done: buf_free(buf); tor_zlib_free(zlib_state); tor_free(contents); tor_free(expanded); tor_free(msg); }
static void test_fast_handshake(void *arg) { /* tests for the obsolete "CREATE_FAST" handshake. */ (void) arg; fast_handshake_state_t *state = NULL; uint8_t client_handshake[CREATE_FAST_LEN]; uint8_t server_handshake[CREATED_FAST_LEN]; uint8_t s_keys[100], c_keys[100]; /* First, test an entire handshake. */ memset(client_handshake, 0, sizeof(client_handshake)); tt_int_op(0, OP_EQ, fast_onionskin_create(&state, client_handshake)); tt_assert(! tor_mem_is_zero((char*)client_handshake, sizeof(client_handshake))); tt_int_op(0, OP_EQ, fast_server_handshake(client_handshake, server_handshake, s_keys, 100)); const char *msg = NULL; tt_int_op(0, OP_EQ, fast_client_handshake(state, server_handshake, c_keys, 100, &msg)); tt_ptr_op(msg, OP_EQ, NULL); tt_mem_op(s_keys, OP_EQ, c_keys, 100); /* Now test a failing handshake. */ server_handshake[0] ^= 3; tt_int_op(-1, OP_EQ, fast_client_handshake(state, server_handshake, c_keys, 100, &msg)); tt_str_op(msg, OP_EQ, "Digest DOES NOT MATCH on fast handshake. " "Bug or attack."); done: fast_handshake_state_free(state); }
/** * Calling find_bridge_by_digest() when we have a bridge with a known * identity digest should return the bridge's information. */ static void test_bridges_find_bridge_by_digest_known(void *arg) { char digest1[DIGEST_LEN]; bridge_info_t *bridge; const char fingerprint[HEX_DIGEST_LEN] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; helper_add_bridges_to_bridgelist(arg); base16_decode(digest1, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN); bridge = find_bridge_by_digest(digest1); tt_ptr_op(bridge, OP_NE, NULL); /* We have to call bridge_get_rsa_id_digest() here because the bridge_info_t * struct is opaquely defined in bridges.h. */ const uint8_t *digest2 = bridge_get_rsa_id_digest(bridge); tt_mem_op((char*)digest2, OP_EQ, digest1, DIGEST_LEN); done: mark_bridge_list(); sweep_bridge_list(); }
/** Test destroy cell queue with no interference from other queues. */ static void test_cmux_destroy_cell_queue(void *arg) { circuitmux_t *cmux = NULL; channel_t *ch = NULL; circuit_t *circ = NULL; cell_queue_t *cq = NULL; packed_cell_t *pc = NULL; tor_libevent_cfg cfg; memset(&cfg, 0, sizeof(cfg)); tor_libevent_initialize(&cfg); scheduler_init(); #ifdef ENABLE_MEMPOOLS init_cell_pool(); #endif /* ENABLE_MEMPOOLS */ (void) arg; cmux = circuitmux_alloc(); tt_assert(cmux); ch = new_fake_channel(); ch->has_queued_writes = has_queued_writes; ch->wide_circ_ids = 1; circ = circuitmux_get_first_active_circuit(cmux, &cq); tt_assert(!circ); tt_assert(!cq); circuitmux_append_destroy_cell(ch, cmux, 100, 10); circuitmux_append_destroy_cell(ch, cmux, 190, 6); circuitmux_append_destroy_cell(ch, cmux, 30, 1); tt_int_op(circuitmux_num_cells(cmux), OP_EQ, 3); circ = circuitmux_get_first_active_circuit(cmux, &cq); tt_assert(!circ); tt_assert(cq); tt_int_op(cq->n, OP_EQ, 3); pc = cell_queue_pop(cq); tt_assert(pc); tt_mem_op(pc->body, OP_EQ, "\x00\x00\x00\x64\x04\x0a\x00\x00\x00", 9); packed_cell_free(pc); pc = NULL; tt_int_op(circuitmux_num_cells(cmux), OP_EQ, 2); done: circuitmux_free(cmux); channel_free(ch); packed_cell_free(pc); #ifdef ENABLE_MEMPOOLS free_cell_pool(); #endif /* ENABLE_MEMPOOLS */ }
static void test_routerkeys_rsa_ed_crosscert(void *arg) { (void)arg; ed25519_public_key_t ed; crypto_pk_t *rsa = pk_generate(2); uint8_t *cc = NULL; ssize_t cc_len; time_t expires_in = 1470846177; tt_int_op(0, OP_EQ, ed25519_public_from_base64(&ed, "ThisStringCanContainAnythingSoNoKeyHereNowX")); cc_len = tor_make_rsa_ed25519_crosscert(&ed, rsa, expires_in, &cc); tt_int_op(cc_len, OP_GT, 0); tt_int_op(cc_len, OP_GT, 37); /* key, expires, siglen */ tt_mem_op(cc, OP_EQ, ed.pubkey, 32); time_t expires_out = 3600 * ntohl(get_uint32(cc+32)); tt_int_op(expires_out, OP_GE, expires_in); tt_int_op(expires_out, OP_LE, expires_in + 3600); tt_int_op(cc_len, OP_EQ, 37 + get_uint8(cc+36)); tt_int_op(0, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed, expires_in - 10)); /* Now try after it has expired */ tt_int_op(-4, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed, expires_out + 1)); /* Truncated object */ tt_int_op(-2, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len - 2, rsa, &ed, expires_in - 10)); /* Key not as expected */ cc[0] ^= 3; tt_int_op(-3, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed, expires_in - 10)); cc[0] ^= 3; /* Bad signature */ cc[40] ^= 3; tt_int_op(-5, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed, expires_in - 10)); cc[40] ^= 3; /* Signature of wrong data */ cc[0] ^= 3; ed.pubkey[0] ^= 3; tt_int_op(-6, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed, expires_in - 10)); cc[0] ^= 3; ed.pubkey[0] ^= 3; done: crypto_pk_free(rsa); tor_free(cc); }
static void test_util_format_base32_encode(void *arg) { (void) arg; size_t real_dstlen = 32; char *dst = tor_malloc_zero(real_dstlen); /* Basic use case that doesn't require a source length correction. */ { /* Length of 10 bytes. */ const char *src = "blahbleh12"; size_t srclen = strlen(src); /* Expected result encoded base32. This was created using python as * such (and same goes for all test case.): * * b = bytes("blahbleh12", 'utf-8') * base64.b32encode(b) * (result in lower case) */ const char *expected = "mjwgc2dcnrswqmjs"; base32_encode(dst, base32_encoded_size(srclen), src, srclen); tt_mem_op(expected, OP_EQ, dst, strlen(expected)); /* Encode but to a larger size destination. */ memset(dst, 0, real_dstlen); base32_encode(dst, real_dstlen, src, srclen); tt_mem_op(expected, OP_EQ, dst, strlen(expected)); } /* Non multiple of 5 for the source buffer length. */ { /* Length of 8 bytes. */ const char *expected = "mjwgc2dcnrswq"; const char *src = "blahbleh"; size_t srclen = strlen(src); memset(dst, 0, real_dstlen); base32_encode(dst, base32_encoded_size(srclen), src, srclen); tt_mem_op(expected, OP_EQ, dst, strlen(expected)); } done: tor_free(dst); }
static void test_routerkeys_ed_key_create(void *arg) { (void)arg; tor_cert_t *cert = NULL; ed25519_keypair_t *kp1 = NULL, *kp2 = NULL; time_t now = time(NULL); /* This is a simple alias for 'make a new keypair' */ kp1 = ed_key_new(NULL, 0, 0, 0, 0, &cert); tt_assert(kp1); /* Create a new certificate signed by kp1. */ kp2 = ed_key_new(kp1, INIT_ED_KEY_NEEDCERT, now, 3600, 4, &cert); tt_assert(kp2); tt_assert(cert); tt_mem_op(&cert->signed_key, OP_EQ, &kp2->pubkey, sizeof(ed25519_public_key_t)); tt_assert(! cert->signing_key_included); tt_int_op(cert->valid_until, OP_GE, now); tt_int_op(cert->valid_until, OP_LE, now+7200); /* Create a new key-including certificate signed by kp1 */ ed25519_keypair_free(kp2); tor_cert_free(cert); cert = NULL; kp2 = NULL; kp2 = ed_key_new(kp1, (INIT_ED_KEY_NEEDCERT| INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT), now, 3600, 4, &cert); tt_assert(kp2); tt_assert(cert); tt_assert(cert->signing_key_included); tt_mem_op(&cert->signed_key, OP_EQ, &kp2->pubkey, sizeof(ed25519_public_key_t)); tt_mem_op(&cert->signing_key, OP_EQ, &kp1->pubkey, sizeof(ed25519_public_key_t)); done: ed25519_keypair_free(kp1); ed25519_keypair_free(kp2); tor_cert_free(cert); }
static void test_crypto_pwbox(void *arg) { uint8_t *boxed=NULL, *decoded=NULL; size_t len, dlen; unsigned i; const char msg[] = "This bunny reminds you that you still have a " "salamander in your sylladex. She is holding the bunny Dave got you. " "It’s sort of uncanny how similar they are, aside from the knitted " "enhancements. Seriously, what are the odds?? So weird."; const char pw[] = "I'm a night owl and a wise bird too"; const unsigned flags[] = { 0, S2K_FLAG_NO_SCRYPT, S2K_FLAG_LOW_MEM, S2K_FLAG_NO_SCRYPT|S2K_FLAG_LOW_MEM, S2K_FLAG_USE_PBKDF2 }; (void)arg; for (i = 0; i < ARRAY_LENGTH(flags); ++i) { tt_int_op(0, OP_EQ, crypto_pwbox(&boxed, &len, (const uint8_t*)msg, strlen(msg), pw, strlen(pw), flags[i])); tt_assert(boxed); tt_assert(len > 128+32); tt_int_op(0, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw))); tt_assert(decoded); tt_uint_op(dlen, OP_EQ, strlen(msg)); tt_mem_op(decoded, OP_EQ, msg, dlen); tor_free(decoded); tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw)-1)); boxed[len-1] ^= 1; tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw))); boxed[0] = 255; tt_int_op(UNPWBOX_CORRUPTED, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw))); tor_free(boxed); } done: tor_free(boxed); tor_free(decoded); }
static void test_util_format_base64_decode(void *ignored) { (void)ignored; int res; int i; char *src; char *dst; src = tor_malloc_zero(256); dst = tor_malloc_zero(1000); for (i=0;i<256;i++) { src[i] = (char)i; } res = base64_decode(dst, 1, src, SIZE_T_CEILING); tt_int_op(res, OP_EQ, -1); res = base64_decode(dst, SIZE_T_CEILING+1, src, 10); tt_int_op(res, OP_EQ, -1); const char *s = "T3BhIG11bmRv"; res = base64_decode(dst, 9, s, strlen(s)); tt_int_op(res, OP_EQ, 9); tt_mem_op(dst, OP_EQ, "Opa mundo", 9); memset(dst, 0, 1000); res = base64_decode(dst, 100, s, strlen(s)); tt_int_op(res, OP_EQ, 9); tt_mem_op(dst, OP_EQ, "Opa mundo", 9); s = "SGVsbG8gd29ybGQ="; res = base64_decode(dst, 100, s, strlen(s)); tt_int_op(res, OP_EQ, 11); tt_mem_op(dst, OP_EQ, "Hello world", 11); done: tor_free(src); tor_free(dst); }
/** Perform SOCKS 5 authentication and send data all in one go */ static void test_socks_5_authenticate_with_data(void *ptr) { SOCKS_TEST_INIT(); /* SOCKS 5 Negotiate username/password authentication */ ADD_DATA(buf, "\x05\x01\x02"); tt_assert(!fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks)); tt_int_op(2,OP_EQ, socks->replylen); tt_int_op(5,OP_EQ, socks->reply[0]); tt_int_op(SOCKS_USER_PASS,OP_EQ, socks->reply[1]); tt_int_op(5,OP_EQ, socks->socks_version); tt_int_op(0,OP_EQ, buf_datalen(buf)); /* SOCKS 5 Send username/password */ /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */ ADD_DATA(buf, "\x01\x02me\x03you\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11"); tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == 1); tt_int_op(5,OP_EQ, socks->socks_version); tt_int_op(2,OP_EQ, socks->replylen); tt_int_op(1,OP_EQ, socks->reply[0]); tt_int_op(0,OP_EQ, socks->reply[1]); tt_str_op("2.2.2.2",OP_EQ, socks->address); tt_int_op(4369,OP_EQ, socks->port); tt_int_op(2,OP_EQ, socks->usernamelen); tt_int_op(3,OP_EQ, socks->passwordlen); tt_mem_op("me",OP_EQ, socks->username, 2); tt_mem_op("you",OP_EQ, socks->password, 3); done: ; }
/** Perform supported SOCKS 4 commands */ static void test_socks_4_supported_commands(void *ptr) { SOCKS_TEST_INIT(); tt_int_op(0,OP_EQ, buf_datalen(buf)); /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4370 */ ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x03\x00"); tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == 1); tt_int_op(4,OP_EQ, socks->socks_version); tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */ tt_int_op(SOCKS_COMMAND_CONNECT,OP_EQ, socks->command); tt_str_op("2.2.2.3",OP_EQ, socks->address); tt_int_op(4370,OP_EQ, socks->port); tt_assert(socks->got_auth == 0); tt_assert(! socks->username); tt_int_op(0,OP_EQ, buf_datalen(buf)); socks_request_clear(socks); /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4369 with userid*/ ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x04me\x00"); tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == 1); tt_int_op(4,OP_EQ, socks->socks_version); tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */ tt_int_op(SOCKS_COMMAND_CONNECT,OP_EQ, socks->command); tt_str_op("2.2.2.4",OP_EQ, socks->address); tt_int_op(4370,OP_EQ, socks->port); tt_assert(socks->got_auth == 1); tt_assert(socks->username); tt_int_op(2,OP_EQ, socks->usernamelen); tt_mem_op("me",OP_EQ, socks->username, 2); tt_int_op(0,OP_EQ, buf_datalen(buf)); socks_request_clear(socks); /* SOCKS 4a Send RESOLVE [F0] request for torproject.org */ ADD_DATA(buf, "\x04\xF0\x01\x01\x00\x00\x00\x02me\x00torproject.org\x00"); tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == 1); tt_int_op(4,OP_EQ, socks->socks_version); tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */ tt_str_op("torproject.org",OP_EQ, socks->address); tt_int_op(0,OP_EQ, buf_datalen(buf)); done: ; }
/* Test connection_or_remove_from_ext_or_id_map and * connection_or_set_ext_or_identifier */ static void test_ext_or_id_map(void *arg) { or_connection_t *c1 = NULL, *c2 = NULL, *c3 = NULL; char *idp = NULL, *idp2 = NULL; (void)arg; /* pre-initialization */ tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx")); c1 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET); c2 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET); c3 = or_connection_new(CONN_TYPE_OR, AF_INET); tt_ptr_op(c1->ext_or_conn_id, OP_NE, NULL); tt_ptr_op(c2->ext_or_conn_id, OP_NE, NULL); tt_ptr_op(c3->ext_or_conn_id, OP_EQ, NULL); tt_ptr_op(c1, OP_EQ, connection_or_get_by_ext_or_id(c1->ext_or_conn_id)); tt_ptr_op(c2, OP_EQ, connection_or_get_by_ext_or_id(c2->ext_or_conn_id)); tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx")); idp = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN); /* Give c2 a new ID. */ connection_or_set_ext_or_identifier(c2); tt_mem_op(idp, OP_NE, c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN); idp2 = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN); tt_assert(!tor_digest_is_zero(idp2)); tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp)); tt_ptr_op(c2, OP_EQ, connection_or_get_by_ext_or_id(idp2)); /* Now remove it. */ connection_or_remove_from_ext_or_id_map(c2); tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp)); tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp2)); done: if (c1) connection_free_(TO_CONN(c1)); if (c2) connection_free_(TO_CONN(c2)); if (c3) connection_free_(TO_CONN(c3)); tor_free(idp); tor_free(idp2); connection_or_clear_ext_or_id_map(); }
static void test_routerkeys_cross_certify_tap(void *args) { (void)args; uint8_t *cc = NULL; int cc_len; ed25519_public_key_t master_key; crypto_pk_t *onion_key = pk_generate(2), *id_key = pk_generate(1); char digest[20]; char buf[128]; int n; tt_int_op(0, OP_EQ, ed25519_public_from_base64(&master_key, "IAlreadyWroteTestsForRouterdescsUsingTheseX")); cc = make_tap_onion_key_crosscert(onion_key, &master_key, id_key, &cc_len); tt_assert(cc); tt_assert(cc_len); n = crypto_pk_public_checksig(onion_key, buf, sizeof(buf), (char*)cc, cc_len); tt_int_op(n,OP_GT,0); tt_int_op(n,OP_EQ,52); crypto_pk_get_digest(id_key, digest); tt_mem_op(buf,OP_EQ,digest,20); tt_mem_op(buf+20,OP_EQ,master_key.pubkey,32); tt_int_op(0, OP_EQ, check_tap_onion_key_crosscert(cc, cc_len, onion_key, &master_key, (uint8_t*)digest)); done: tor_free(cc); crypto_pk_free(id_key); crypto_pk_free(onion_key); }
/** Perform SOCKS 5 authentication */ static void test_socks_5_authenticate(void *ptr) { SOCKS_TEST_INIT(); /* SOCKS 5 Negotiate username/password authentication */ ADD_DATA(buf, "\x05\x01\x02"); tt_assert(!fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks)); tt_int_op(2,OP_EQ, socks->replylen); tt_int_op(5,OP_EQ, socks->reply[0]); tt_int_op(SOCKS_USER_PASS,OP_EQ, socks->reply[1]); tt_int_op(5,OP_EQ, socks->socks_version); tt_int_op(0,OP_EQ, buf_datalen(buf)); /* SOCKS 5 Send username/password */ ADD_DATA(buf, "\x01\x02me\x08mypasswd"); tt_assert(!fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks)); tt_int_op(5,OP_EQ, socks->socks_version); tt_int_op(2,OP_EQ, socks->replylen); tt_int_op(1,OP_EQ, socks->reply[0]); tt_int_op(0,OP_EQ, socks->reply[1]); tt_int_op(2,OP_EQ, socks->usernamelen); tt_int_op(8,OP_EQ, socks->passwordlen); tt_mem_op("me",OP_EQ, socks->username, 2); tt_mem_op("mypasswd",OP_EQ, socks->password, 8); done: ; }
/** Run unit tests for our random number generation function and its wrappers. */ static void test_crypto_rng(void *arg) { int i, j, allok; char data1[100], data2[100]; double d; char *h=NULL; /* Try out RNG. */ (void)arg; tt_assert(! crypto_seed_rng()); crypto_rand(data1, 100); crypto_rand(data2, 100); tt_mem_op(data1,OP_NE, data2,100); allok = 1; for (i = 0; i < 100; ++i) { uint64_t big; char *host; j = crypto_rand_int(100); if (j < 0 || j >= 100) allok = 0; big = crypto_rand_uint64(UINT64_C(1)<<40); if (big >= (UINT64_C(1)<<40)) allok = 0; big = crypto_rand_uint64(UINT64_C(5)); if (big >= 5) allok = 0; d = crypto_rand_double(); tt_assert(d >= 0); tt_assert(d < 1.0); host = crypto_random_hostname(3,8,"www.",".onion"); if (strcmpstart(host,"www.") || strcmpend(host,".onion") || strlen(host) < 13 || strlen(host) > 18) allok = 0; tor_free(host); } /* Make sure crypto_random_hostname clips its inputs properly. */ h = crypto_random_hostname(20000, 9000, "www.", ".onion"); tt_assert(! strcmpstart(h,"www.")); tt_assert(! strcmpend(h,".onion")); tt_int_op(63+4+6, OP_EQ, strlen(h)); tt_assert(allok); done: tor_free(h); }
static void test_ext_or_cookie_auth_testvec(void *arg) { char *reply=NULL, *client_hash=NULL; size_t reply_len; char *mem_op_hex_tmp=NULL; const char client_nonce[] = "But when I look ahead up the whi"; (void)arg; ext_or_auth_cookie = tor_malloc_zero(32); memcpy(ext_or_auth_cookie, "Gliding wrapt in a brown mantle," , 32); ext_or_auth_cookie_is_set = 1; MOCK(crypto_rand, crypto_rand_return_tse_str); tt_int_op(0, OP_EQ, handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply, &reply_len)); tt_ptr_op(reply, OP_NE, NULL ); tt_uint_op(reply_len, OP_EQ, 64); tt_mem_op(reply+32,OP_EQ, "te road There is always another ", 32); /* HMACSHA256("Gliding wrapt in a brown mantle," * "ExtORPort authentication server-to-client hash" * "But when I look ahead up the write road There is always another "); */ test_memeq_hex(reply, "ec80ed6e546d3b36fdfc22fe1315416b" "029f1ade7610d910878b62eeb7403821"); /* HMACSHA256("Gliding wrapt in a brown mantle," * "ExtORPort authentication client-to-server hash" * "But when I look ahead up the write road There is always another "); * (Both values computed using Python CLI.) */ test_memeq_hex(client_hash, "ab391732dd2ed968cd40c087d1b1f25b" "33b3cd77ff79bd80c2074bbf438119a2"); done: UNMOCK(crypto_rand); tor_free(reply); tor_free(client_hash); tor_free(mem_op_hex_tmp); }
static void test_proto_line(void *arg) { (void)arg; char tmp[60]; buf_t *buf = buf_new(); #define S(str) str, sizeof(str)-1 const struct { const char *input; size_t input_len; size_t line_len; const char *output; int returnval; } cases[] = { { S("Hello world"), 0, NULL, 0 }, { S("Hello world\n"), 12, "Hello world\n", 1 }, { S("Hello world\nMore"), 12, "Hello world\n", 1 }, { S("\n oh hello world\nMore"), 1, "\n", 1 }, { S("Hello worpd\n\nMore"), 12, "Hello worpd\n", 1 }, { S("------------------------------------------------------------\n"), 0, NULL, -1 }, }; unsigned i; for (i = 0; i < ARRAY_LENGTH(cases); ++i) { buf_add(buf, cases[i].input, cases[i].input_len); memset(tmp, 0xfe, sizeof(tmp)); size_t sz = sizeof(tmp); int rv = buf_get_line(buf, tmp, &sz); tt_int_op(rv, OP_EQ, cases[i].returnval); if (rv == 1) { tt_int_op(sz, OP_LT, sizeof(tmp)); tt_mem_op(cases[i].output, OP_EQ, tmp, sz+1); tt_int_op(buf_datalen(buf), OP_EQ, cases[i].input_len - strlen(tmp)); tt_int_op(sz, OP_EQ, cases[i].line_len); } else { tt_int_op(buf_datalen(buf), OP_EQ, cases[i].input_len); // tt_int_op(sz, OP_EQ, sizeof(tmp)); } buf_clear(buf); } done: buf_free(buf); }
static void test_util_format_base32_decode(void *arg) { (void) arg; int ret; size_t real_dstlen = 32; char *dst = tor_malloc_zero(real_dstlen); /* Basic use case. */ { /* Length of 10 bytes. */ const char *expected = "blahbleh12"; /* Expected result encoded base32. */ const char *src = "mjwgc2dcnrswqmjs"; ret = base32_decode(dst, strlen(expected), src, strlen(src)); tt_int_op(ret, ==, 0); tt_str_op(expected, OP_EQ, dst); } /* Non multiple of 5 for the source buffer length. */ { /* Length of 8 bytes. */ const char *expected = "blahbleh"; const char *src = "mjwgc2dcnrswq"; ret = base32_decode(dst, strlen(expected), src, strlen(src)); tt_int_op(ret, ==, 0); tt_mem_op(expected, OP_EQ, dst, strlen(expected)); } /* Invalid values. */ { /* Invalid character '#'. */ ret = base32_decode(dst, real_dstlen, "#abcde", 6); tt_int_op(ret, ==, -1); /* Make sure the destination buffer has been zeroed even on error. */ tt_int_op(tor_mem_is_zero(dst, real_dstlen), ==, 1); } done: tor_free(dst); }