Ejemplo n.º 1
0
static void
test_util_format_base16_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 = 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_CEILING+2, src, 10);
    tt_int_op(res, OP_EQ, -1);

done:
    tor_free(src);
    tor_free(dst);
}
Ejemplo n.º 2
0
static smartlist_t *
descbr_get_digests_mock(void)
{
  char digest[DIGEST_LEN], *tmp;
  int len;
  smartlist_t *list = NULL;

  if (!disable_descbr) {
    /* Just pretend we have only the two hard-coded digests listed above */
    list = smartlist_new();
    len = base16_decode(digest, DIGEST_LEN,
                        descbr_digest_1_str, strlen(descbr_digest_1_str));
    tt_int_op(len, OP_EQ, DIGEST_LEN);
    tmp = tor_malloc(DIGEST_LEN);
    memcpy(tmp, digest, DIGEST_LEN);
    smartlist_add(list, tmp);
    len = base16_decode(digest, DIGEST_LEN,
                        descbr_digest_2_str, strlen(descbr_digest_2_str));
    tt_int_op(len, OP_EQ, DIGEST_LEN);
    tmp = tor_malloc(DIGEST_LEN);
    memcpy(tmp, digest, DIGEST_LEN);
    smartlist_add(list, tmp);
  }

 done:
  return list;
}
Ejemplo n.º 3
0
static smartlist_t *
cert_dl_status_auth_ids_mock(void)
{
  char digest[DIGEST_LEN], *tmp;
  int len;
  smartlist_t *list = NULL;

  /* Just pretend we have only the two hard-coded digests listed above */
  list = smartlist_new();
  len = base16_decode(digest, DIGEST_LEN,
                      auth_id_digest_1_str, strlen(auth_id_digest_1_str));
  tt_int_op(len, OP_EQ, DIGEST_LEN);
  tmp = tor_malloc(DIGEST_LEN);
  memcpy(tmp, digest, DIGEST_LEN);
  smartlist_add(list, tmp);
  len = base16_decode(digest, DIGEST_LEN,
                      auth_id_digest_2_str, strlen(auth_id_digest_2_str));
  tt_int_op(len, OP_EQ, DIGEST_LEN);
  tmp = tor_malloc(DIGEST_LEN);
  memcpy(tmp, digest, DIGEST_LEN);
  smartlist_add(list, tmp);

 done:
  return list;
}
Ejemplo n.º 4
0
static void
test_crypto_pbkdf2_vectors(void *arg)
{
  char *mem_op_hex_tmp = NULL;
  uint8_t spec[64], out[64];
  (void)arg;

  /* Test vectors from RFC6070, section 2 */
  base16_decode((char*)spec, sizeof(spec),
                "73616c74" "00" , 10);
  memset(out, 0x00, sizeof(out));
  tt_int_op(20, OP_EQ,
            secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
  test_memeq_hex(out, "0c60c80f961f0e71f3a9b524af6012062fe037a6");

  base16_decode((char*)spec, sizeof(spec),
                "73616c74" "01" , 10);
  memset(out, 0x00, sizeof(out));
  tt_int_op(20, OP_EQ,
            secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
  test_memeq_hex(out, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957");

  base16_decode((char*)spec, sizeof(spec),
                "73616c74" "0C" , 10);
  memset(out, 0x00, sizeof(out));
  tt_int_op(20, OP_EQ,
            secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
  test_memeq_hex(out, "4b007901b765489abead49d926f721d065a429c1");

  /* This is the very slow one here.  When enabled, it accounts for roughly
   * half the time spent in test-slow. */
  /*
  base16_decode((char*)spec, sizeof(spec),
                "73616c74" "18" , 10);
  memset(out, 0x00, sizeof(out));
  tt_int_op(20, OP_EQ,
            secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
  test_memeq_hex(out, "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984");
  */

  base16_decode((char*)spec, sizeof(spec),
                "73616c7453414c5473616c7453414c5473616c745"
                "3414c5473616c7453414c5473616c74" "0C" , 74);
  memset(out, 0x00, sizeof(out));
  tt_int_op(25, OP_EQ,
            secret_to_key_compute_key(out, 25, spec, 37,
                                      "passwordPASSWORDpassword", 24, 1));
  test_memeq_hex(out, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038");

  base16_decode((char*)spec, sizeof(spec),
                "7361006c74" "0c" , 12);
  memset(out, 0x00, sizeof(out));
  tt_int_op(16, OP_EQ,
            secret_to_key_compute_key(out, 16, spec, 6, "pass\0word", 9, 1));
  test_memeq_hex(out, "56fa6aa75548099dcc37d7f03425e0c3");

 done:
  tor_free(mem_op_hex_tmp);
}
Ejemplo n.º 5
0
static smartlist_t *
cert_dl_status_sks_for_auth_id_mock(const char *digest)
{
  smartlist_t *list = NULL;
  char sk[DIGEST_LEN];
  char digest_str[HEX_DIGEST_LEN+1];
  char *tmp;
  int len;

  tt_assert(digest != NULL);
  base16_encode(digest_str, HEX_DIGEST_LEN + 1,
                digest, DIGEST_LEN);
  digest_str[HEX_DIGEST_LEN] = '\0';

  /*
   * Build a list of two hard-coded digests, depending on what we
   * were just passed.
   */
  if (strcmp(digest_str, auth_id_digest_1_str) == 0) {
    list = smartlist_new();
    len = base16_decode(sk, DIGEST_LEN,
                        auth_1_sk_1_str, strlen(auth_1_sk_1_str));
    tt_int_op(len, OP_EQ, DIGEST_LEN);
    tmp = tor_malloc(DIGEST_LEN);
    memcpy(tmp, sk, DIGEST_LEN);
    smartlist_add(list, tmp);
    len = base16_decode(sk, DIGEST_LEN,
                        auth_1_sk_2_str, strlen(auth_1_sk_2_str));
    tt_int_op(len, OP_EQ, DIGEST_LEN);
    tmp = tor_malloc(DIGEST_LEN);
    memcpy(tmp, sk, DIGEST_LEN);
    smartlist_add(list, tmp);
  } else if (strcmp(digest_str, auth_id_digest_2_str) == 0) {
    list = smartlist_new();
    len = base16_decode(sk, DIGEST_LEN,
                        auth_2_sk_1_str, strlen(auth_2_sk_1_str));
    tt_int_op(len, OP_EQ, DIGEST_LEN);
    tmp = tor_malloc(DIGEST_LEN);
    memcpy(tmp, sk, DIGEST_LEN);
    smartlist_add(list, tmp);
    len = base16_decode(sk, DIGEST_LEN,
                        auth_2_sk_2_str, strlen(auth_2_sk_2_str));
    tt_int_op(len, OP_EQ, DIGEST_LEN);
    tmp = tor_malloc(DIGEST_LEN);
    memcpy(tmp, sk, DIGEST_LEN);
    smartlist_add(list, tmp);
  }

 done:
  return list;
}
Ejemplo n.º 6
0
/**
 * 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();
}
Ejemplo n.º 7
0
/**
 * Calling get_configured_bridge_by_exact_addr_port_digest() with a digest that
 * we do have, and an addr:port pair we do have, should return the bridge.
 */
static void
test_bridges_get_configured_bridge_by_exact_addr_port_digest_both(void *arg)
{
  char digest[DIGEST_LEN];
  bridge_info_t *bridge;
  const char fingerprint[HEX_DIGEST_LEN] =
    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
  tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
  uint16_t port = 4444;
  char ret_addr[16];
  int ret;

  helper_add_bridges_to_bridgelist(arg);

  base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN);
  ret = tor_addr_parse(addr, "4.4.4.4");
  tt_int_op(ret, OP_EQ, 2); // it returns the address family on success

  bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, digest);
  tt_ptr_op(bridge, OP_NE, NULL);

  tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0);
  tt_str_op("4.4.4.4", OP_EQ, ret_addr);

 done:
  tor_free(addr);

  mark_bridge_list();
  sweep_bridge_list();
}
Ejemplo n.º 8
0
/**
 * Calling get_configured_bridge_by_exact_addr_port_digest() with a digest that
 * we do have, and an addr:port pair we don't have, should return NULL.
 */
static void
test_bridges_get_configured_bridge_by_exact_addr_port_digest_donly(void *arg)
{
  char digest[DIGEST_LEN];
  bridge_info_t *bridge;
  const char fingerprint[HEX_DIGEST_LEN] =
    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
  tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
  uint16_t port = 11111;
  int ret;

  helper_add_bridges_to_bridgelist(arg);

  // We don't actually have a bridge with this addr:port pair
  base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN);
  ret = tor_addr_parse(addr, "111.111.111.111");
  tt_int_op(ret, OP_EQ, 2); // it returns the address family on success

  bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, digest);
  tt_ptr_op(bridge, OP_EQ, NULL);

 done:
  tor_free(addr);

  mark_bridge_list();
  sweep_bridge_list();
}
Ejemplo n.º 9
0
/** Decode the hashed, base64'd passwords stored in <b>passwords</b>.
 * Return a smartlist of acceptable passwords (unterminated strings of
 * length S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN) on success, or NULL on
 * failure.
 */
smartlist_t *
decode_hashed_passwords(config_line_t *passwords)
{
  char decoded[64];
  config_line_t *cl;
  smartlist_t *sl = smartlist_new();

  tor_assert(passwords);

  for (cl = passwords; cl; cl = cl->next) {
    const char *hashed = cl->value;

    if (!strcmpstart(hashed, "16:")) {
      if (base16_decode(decoded, sizeof(decoded), hashed+3, strlen(hashed+3))
                        != S2K_RFC2440_SPECIFIER_LEN + DIGEST_LEN
          || strlen(hashed+3) != (S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN)*2) {
        goto err;
      }
    } else {
        if (base64_decode(decoded, sizeof(decoded), hashed, strlen(hashed))
            != S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN) {
          goto err;
        }
    }
    smartlist_add(sl,
                  tor_memdup(decoded, S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN));
  }

  return sl;

 err:
  SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
  smartlist_free(sl);
  return NULL;
}
Ejemplo n.º 10
0
static chunk_t *
b16_dec(const chunk_t *inp)
{
  chunk_t *ch = chunk_new(CEIL_DIV(inp->len, 2));
  int r = base16_decode((char *)ch->buf, ch->len, (char *)inp->buf, inp->len);
  if (r >= 0) {
    ch->len = r;
  } else {
    chunk_free(ch);
  }
  return ch;
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
/**
 * Locate the start of "urn:bitprint:" indications and extract
 * the SHA1 and TTH out of it, placing them in the supplied buffers.
 *
 * @return whether we successfully extracted the bitprint, i.e. the two
 * hashes.
 */
bool
urn_get_bitprint(const char *buf, size_t size,
	struct sha1 *sha1, struct tth *tth)
{
	static const char prefix[] = "urn:bitprint:";
	size_t len;
	const char *p;
	bool base16_tth = FALSE;

	g_assert(0 == size || NULL != buf);
	g_assert(sha1);
	g_assert(tth);

	/*
	 * Because some clueless sites list magnets with hexadecimal-encoded
	 * values, we attempt to parse both base32 and base16 encoded hashes.
	 *
	 * Note that we expect both hashes to be similarily encoded.
	 */

	if (size < CONST_STRLEN(prefix) + BITPRINT_BASE32_SIZE)
		return FALSE;
	p = is_strcaseprefix(buf, prefix);
	if (NULL == p)
		return FALSE;
	if (!parse_base32_sha1(p, SHA1_BASE32_SIZE, sha1)) {
		if (
			size >= CONST_STRLEN(prefix) + BITPRINT_BASE16_SIZE &&
			parse_base16_sha1(p, SHA1_BASE16_SIZE, sha1)
		) {
			p += SHA1_BASE16_SIZE;
			base16_tth = TRUE;		/* SHA1 was hexa, expects TTH as hexa */
		} else {
			return FALSE;
		}
	} else {
		p += SHA1_BASE32_SIZE;
	}
	if ('.' != *p++) {
		return FALSE;
	}
	if (base16_tth) {
		len = base16_decode(tth, sizeof *tth, p, TTH_BASE16_SIZE);
	} else {
		len = base32_decode(tth, sizeof *tth, p, TTH_BASE32_SIZE);
	}
	if (len != TTH_RAW_SIZE) {
		return FALSE;
	}
	return TRUE;
}
Ejemplo n.º 13
0
/** Parse the string <b>s</b> to create a set of routerset entries, and add
 * them to <b>target</b>.  In log messages, refer to the string as
 * <b>description</b>.  Return 0 on success, -1 on failure.
 *
 * Three kinds of elements are allowed in routersets: nicknames, IP address
 * patterns, and fingerprints.  They may be surrounded by optional space, and
 * must be separated by commas.
 */
int
routerset_parse(routerset_t *target, const char *s, const char *description)
{
  int r = 0;
  int added_countries = 0;
  char *countryname;
  smartlist_t *list = smartlist_new();
  int malformed_list;
  smartlist_split_string(list, s, ",",
                         SPLIT_SKIP_SPACE | SPLIT_IGNORE_BLANK, 0);
  SMARTLIST_FOREACH_BEGIN(list, char *, nick) {
      addr_policy_t *p;
      /* if it doesn't pass our validation, assume it's malformed */
      malformed_list = 1;
      if (is_legal_hexdigest(nick)) {
        char d[DIGEST_LEN];
        if (*nick == '$')
          ++nick;
        log_debug(LD_CONFIG, "Adding identity %s to %s", nick, description);
        base16_decode(d, sizeof(d), nick, HEX_DIGEST_LEN);
        digestmap_set(target->digests, d, (void*)1);
      } else if (is_legal_nickname(nick)) {
        log_debug(LD_CONFIG, "Adding nickname %s to %s", nick, description);
        strmap_set_lc(target->names, nick, (void*)1);
      } else if ((countryname = routerset_get_countryname(nick)) != NULL) {
        log_debug(LD_CONFIG, "Adding country %s to %s", nick,
                  description);
        smartlist_add(target->country_names, countryname);
        added_countries = 1;
      } else if ((strchr(nick,'.') || strchr(nick, ':') ||  strchr(nick, '*'))
                 && (p = router_parse_addr_policy_item_from_string(
                                     nick, ADDR_POLICY_REJECT,
                                     &malformed_list))) {
        /* IPv4 addresses contain '.', IPv6 addresses contain ':',
         * and wildcard addresses contain '*'. */
        log_debug(LD_CONFIG, "Adding address %s to %s", nick, description);
        smartlist_add(target->policies, p);
      } else if (malformed_list) {
        log_warn(LD_CONFIG, "Entry '%s' in %s is malformed. Discarding entire"
                 " list.", nick, description);
        r = -1;
        tor_free(nick);
        SMARTLIST_DEL_CURRENT(list, nick);
      } else {
        log_notice(LD_CONFIG, "Entry '%s' in %s is ignored. Using the"
                   " remainder of the list.", nick, description);
        tor_free(nick);
        SMARTLIST_DEL_CURRENT(list, nick);
      }
  } SMARTLIST_FOREACH_END(nick);
Ejemplo n.º 14
0
/**
  Decode a hexadecimal notation into a NULL-terminated string.

  A convenience wrapper around @base16_decode, this function will return
  a NULL-terminated string containing the decoded binary data that the $src
  buffer represents.

  On success, returns a pointer to the newly-allocated string.  The caller is
  responsible for memory management from then on.

  On failure, returns NULL and sets errno appropriately:

    - **`EINVAL`** - $len is too small (0 or below).
    - **`EILSEQ`** - An illegal character was found in the input $src.

  **Note:** because the returned NULL-terminated string is the _raw data_,
  you must be careful when using this on hex strings that represent binary
  data that may have literal '\0' bytes in them.  This function will happily
  decode them into premature NULL-terminators, leaving you with short data
  strings.
 */
char* base16_decodestr(const char *src, size_t len)
{
	assert(src);
	errno = EINVAL;
	if (len <= 0) return NULL;

	size_t dlen = len / 2;
	char *dst = vmalloc(sizeof(char) * (dlen + 1));

	int rc = base16_decode(dst, dlen, src, len);
	if (rc < 0) {
		free(dst);
		return NULL;
	}

	dst[rc] = '\0';
	return dst;
}
Ejemplo n.º 15
0
/** Generate a vote_routerstatus_t for a router with identity digest
 * <b>digest_in_hex</b>. */
static vote_routerstatus_t *
gen_vote_routerstatus_for_tests(const char *digest_in_hex, int is_guard)
{
  int retval;
  vote_routerstatus_t *vrs = NULL;
  routerstatus_t *rs;

  vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
  rs = &vrs->status;

  { /* Useful information for tests */
    char digest_tmp[DIGEST_LEN];

    /* Guard or not? */
    rs->is_possible_guard = is_guard;

    /* Fill in the fpr */
    tt_int_op(strlen(digest_in_hex), ==, HEX_DIGEST_LEN);
    retval = base16_decode(digest_tmp, sizeof(digest_tmp),
                           digest_in_hex, HEX_DIGEST_LEN);
    tt_int_op(retval, ==, 0);
    memcpy(rs->identity_digest, digest_tmp, DIGEST_LEN);
  }

  { /* Misc info (maybe not used in tests) */
    vrs->version = tor_strdup("0.1.2.14");
    strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
    memset(rs->descriptor_digest, 78, DIGEST_LEN);
    rs->addr = 0x99008801;
    rs->or_port = 443;
    rs->dir_port = 8000;
    /* all flags but running cleared */
    rs->is_flagged_running = 1;
    vrs->has_measured_bw = 1;
    rs->has_bandwidth = 1;
  }

  return vrs;

 done:
  vote_routerstatus_free(vrs);

  return NULL;
}
Ejemplo n.º 16
0
/**
 * Validate SHA1 starting in NUL-terminated `buf' as a proper base16 encoding
 * of a SHA1 hash, and write decoded value in `retval'.
 *
 * The SHA1 typically comes from HTTP or magnet URIs, made by people who do
 * not follow the specs which says a magnet must hold a base32-encoded SHA1.
 *
 * @return TRUE if the SHA1 was valid and properly decoded, FALSE on error.
 */
bool
parse_base16_sha1(const char *buf, size_t size, struct sha1 *sha1)
{
	struct sha1 raw;
	size_t len;

	if (!sha1) {
		sha1 = &raw;
	}

	if (size < SHA1_BASE16_SIZE)
		return FALSE;

	len = base16_decode(sha1->data, SHA1_RAW_SIZE, buf, SHA1_BASE16_SIZE);
	if (SHA1_RAW_SIZE != len)
		return FALSE;

	return TRUE;
}
Ejemplo n.º 17
0
/** Parse the string <b>s</b> to create a set of routerset entries, and add
 * them to <b>target</b>.  In log messages, refer to the string as
 * <b>description</b>.  Return 0 on success, -1 on failure.
 *
 * Three kinds of elements are allowed in routersets: nicknames, IP address
 * patterns, and fingerprints.  They may be surrounded by optional space, and
 * must be separated by commas.
 */
int
routerset_parse(routerset_t *target, const char *s, const char *description)
{
  int r = 0;
  int added_countries = 0;
  char *countryname;
  smartlist_t *list = smartlist_new();
  smartlist_split_string(list, s, ",",
                         SPLIT_SKIP_SPACE | SPLIT_IGNORE_BLANK, 0);
  SMARTLIST_FOREACH_BEGIN(list, char *, nick) {
      addr_policy_t *p;
      if (is_legal_hexdigest(nick)) {
        char d[DIGEST_LEN];
        if (*nick == '$')
          ++nick;
        log_debug(LD_CONFIG, "Adding identity %s to %s", nick, description);
        base16_decode(d, sizeof(d), nick, HEX_DIGEST_LEN);
        digestmap_set(target->digests, d, (void*)1);
      } else if (is_legal_nickname(nick)) {
        log_debug(LD_CONFIG, "Adding nickname %s to %s", nick, description);
        strmap_set_lc(target->names, nick, (void*)1);
      } else if ((countryname = routerset_get_countryname(nick)) != NULL) {
        log_debug(LD_CONFIG, "Adding country %s to %s", nick,
                  description);
        smartlist_add(target->country_names, countryname);
        added_countries = 1;
      } else if ((strchr(nick,'.') || strchr(nick, '*')) &&
                 (p = router_parse_addr_policy_item_from_string(
                                     nick, ADDR_POLICY_REJECT))) {
        log_debug(LD_CONFIG, "Adding address %s to %s", nick, description);
        smartlist_add(target->policies, p);
      } else {
        log_warn(LD_CONFIG, "Entry '%s' in %s is malformed.", nick,
                 description);
        r = -1;
        tor_free(nick);
        SMARTLIST_DEL_CURRENT(list, nick);
      }
  } SMARTLIST_FOREACH_END(nick);
Ejemplo n.º 18
0
/**
 * Decrypts a string(str struct).
 * 
 * @param encoded - the string that needs to be decrypted
 * @returns - the decoded string.Memory allocation takes place in this
 * 				function.
 */
str thig_decrypt(str encoded)
{
	str src;
	str my_text={0,0},dec_text={0,0};
	cipherInstance ci2 = ci;

#ifdef USE_BASE64
	src = base64_decode(encoded);
#else
	src = base16_decode(encoded);
#endif
	if (!src.len) return dec_text;

	my_text = src;
	dec_text.s = pkg_malloc(my_text.len);
	if (!dec_text.s){
		LOG(L_ERR,"ERR:"M_NAME":decrypt: error allocating %d bytes\n",my_text.len);
		goto error;		
	}
	dec_text.len = my_text.len;
	
	printstr("String bef :",my_text);

	if (blockDecrypt(&ci2,&ki,(unsigned char*)my_text.s,my_text.len*8,(unsigned char*)dec_text.s) != my_text.len*8){
		LOG(L_ERR,"DBG:"M_NAME":decrypt: Error in encryption phase\n");
		goto error;
	}
	while(dec_text.s[dec_text.len-1]==0 && dec_text.len>0)
		dec_text.len--;
	printstr("String aft :",dec_text);
	if (src.s) pkg_free(src.s);
	return dec_text;
error:
	if (src.s) pkg_free(src.s);
	if (dec_text.s) pkg_free(dec_text.s);
	dec_text.s = 0;dec_text.len=0;
	return dec_text;	
}
Ejemplo n.º 19
0
/**
 * Parse IB SRP root path byte-string value
 *
 * @v rp_comp		Root path component string
 * @v default_value	Default value to use if component string is empty
 * @ret value		Value
 */
static int ib_srp_parse_byte_string ( const char *rp_comp, uint8_t *bytes,
				      unsigned int size_flags ) {
	size_t size = ( size_flags & ~IB_SRP_PARSE_FLAG_MASK );
	size_t rp_comp_len = strlen ( rp_comp );
	int decoded_size;

	/* Allow optional components to be empty */
	if ( ( rp_comp_len == 0 ) &&
	     ( size_flags & IB_SRP_PARSE_OPTIONAL ) )
		return 0;

	/* Check string length */
	if ( rp_comp_len != ( 2 * size ) )
		return -EINVAL_BYTE_STRING_LEN;

	/* Parse byte string */
	decoded_size = base16_decode ( rp_comp, bytes );
	if ( decoded_size < 0 )
		return decoded_size;
	assert ( decoded_size == size );

	return 0;
}
Ejemplo n.º 20
0
/** Called when we get an AUTHENTICATE message.  Check whether the
 * authentication is valid, and if so, update the connection's state to
 * OPEN.  Reply with DONE or ERROR.
 */
int
handle_control_authenticate(control_connection_t *conn, uint32_t len,
                            const char *body)
{
  int used_quoted_string = 0;
  const or_options_t *options = get_options();
  const char *errstr = "Unknown error";
  char *password;
  size_t password_len;
  const char *cp;
  int i;
  int bad_cookie=0, bad_password=0;
  smartlist_t *sl = NULL;

  if (!len) {
    password = tor_strdup("");
    password_len = 0;
  } else if (TOR_ISXDIGIT(body[0])) {
    cp = body;
    while (TOR_ISXDIGIT(*cp))
      ++cp;
    i = (int)(cp - body);
    tor_assert(i>0);
    password_len = i/2;
    password = tor_malloc(password_len + 1);
    if (base16_decode(password, password_len+1, body, i)
                      != (int) password_len) {
      connection_write_str_to_buf(
            "551 Invalid hexadecimal encoding.  Maybe you tried a plain text "
            "password?  If so, the standard requires that you put it in "
            "double quotes.\r\n", conn);
      connection_mark_for_close(TO_CONN(conn));
      tor_free(password);
      return 0;
    }
  } else {
    if (!decode_escaped_string(body, len, &password, &password_len)) {
      connection_write_str_to_buf("551 Invalid quoted string.  You need "
            "to put the password in double quotes.\r\n", conn);
      connection_mark_for_close(TO_CONN(conn));
      return 0;
    }
    used_quoted_string = 1;
  }

  if (conn->safecookie_client_hash != NULL) {
    /* The controller has chosen safe cookie authentication; the only
     * acceptable authentication value is the controller-to-server
     * response. */

    tor_assert(authentication_cookie_is_set);

    if (password_len != DIGEST256_LEN) {
      log_warn(LD_CONTROL,
               "Got safe cookie authentication response with wrong length "
               "(%d)", (int)password_len);
      errstr = "Wrong length for safe cookie response.";
      goto err;
    }

    if (tor_memneq(conn->safecookie_client_hash, password, DIGEST256_LEN)) {
      log_warn(LD_CONTROL,
               "Got incorrect safe cookie authentication response");
      errstr = "Safe cookie response did not match expected value.";
      goto err;
    }

    tor_free(conn->safecookie_client_hash);
    goto ok;
  }

  if (!options->CookieAuthentication && !options->HashedControlPassword &&
      !options->HashedControlSessionPassword) {
    /* if Tor doesn't demand any stronger authentication, then
     * the controller can get in with anything. */
    goto ok;
  }

  if (options->CookieAuthentication) {
    int also_password = options->HashedControlPassword != NULL ||
      options->HashedControlSessionPassword != NULL;
    if (password_len != AUTHENTICATION_COOKIE_LEN) {
      if (!also_password) {
        log_warn(LD_CONTROL, "Got authentication cookie with wrong length "
                 "(%d)", (int)password_len);
        errstr = "Wrong length on authentication cookie.";
        goto err;
      }
      bad_cookie = 1;
    } else if (tor_memneq(authentication_cookie, password, password_len)) {
      if (!also_password) {
        log_warn(LD_CONTROL, "Got mismatched authentication cookie");
        errstr = "Authentication cookie did not match expected value.";
        goto err;
      }
      bad_cookie = 1;
    } else {
      goto ok;
    }
  }

  if (options->HashedControlPassword ||
      options->HashedControlSessionPassword) {
    int bad = 0;
    smartlist_t *sl_tmp;
    char received[DIGEST_LEN];
    int also_cookie = options->CookieAuthentication;
    sl = smartlist_new();
    if (options->HashedControlPassword) {
      sl_tmp = decode_hashed_passwords(options->HashedControlPassword);
      if (!sl_tmp)
        bad = 1;
      else {
        smartlist_add_all(sl, sl_tmp);
        smartlist_free(sl_tmp);
      }
    }
    if (options->HashedControlSessionPassword) {
      sl_tmp = decode_hashed_passwords(options->HashedControlSessionPassword);
      if (!sl_tmp)
        bad = 1;
      else {
        smartlist_add_all(sl, sl_tmp);
        smartlist_free(sl_tmp);
      }
    }
    if (bad) {
      if (!also_cookie) {
        log_warn(LD_BUG,
                 "Couldn't decode HashedControlPassword: invalid base16");
        errstr="Couldn't decode HashedControlPassword value in configuration.";
        goto err;
      }
      bad_password = 1;
      SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
      smartlist_free(sl);
      sl = NULL;
    } else {
      SMARTLIST_FOREACH(sl, char *, expected,
      {
        secret_to_key_rfc2440(received,DIGEST_LEN,
                              password,password_len,expected);
        if (tor_memeq(expected + S2K_RFC2440_SPECIFIER_LEN,
                      received, DIGEST_LEN))
          goto ok;
      });
Ejemplo n.º 21
0
/** Called when we get an AUTHCHALLENGE command. */
int
handle_control_authchallenge(control_connection_t *conn, uint32_t len,
                             const char *body)
{
  const char *cp = body;
  char *client_nonce;
  size_t client_nonce_len;
  char server_hash[DIGEST256_LEN];
  char server_hash_encoded[HEX_DIGEST256_LEN+1];
  char server_nonce[SAFECOOKIE_SERVER_NONCE_LEN];
  char server_nonce_encoded[(2*SAFECOOKIE_SERVER_NONCE_LEN) + 1];

  cp += strspn(cp, " \t\n\r");
  if (!strcasecmpstart(cp, "SAFECOOKIE")) {
    cp += strlen("SAFECOOKIE");
  } else {
    connection_write_str_to_buf("513 AUTHCHALLENGE only supports SAFECOOKIE "
                                "authentication\r\n", conn);
    connection_mark_for_close(TO_CONN(conn));
    return -1;
  }

  if (!authentication_cookie_is_set) {
    connection_write_str_to_buf("515 Cookie authentication is disabled\r\n",
                                conn);
    connection_mark_for_close(TO_CONN(conn));
    return -1;
  }

  cp += strspn(cp, " \t\n\r");
  if (*cp == '"') {
    const char *newcp =
      decode_escaped_string(cp, len - (cp - body),
                            &client_nonce, &client_nonce_len);
    if (newcp == NULL) {
      connection_write_str_to_buf("513 Invalid quoted client nonce\r\n",
                                  conn);
      connection_mark_for_close(TO_CONN(conn));
      return -1;
    }
    cp = newcp;
  } else {
    size_t client_nonce_encoded_len = strspn(cp, "0123456789ABCDEFabcdef");

    client_nonce_len = client_nonce_encoded_len / 2;
    client_nonce = tor_malloc_zero(client_nonce_len);

    if (base16_decode(client_nonce, client_nonce_len,
                      cp, client_nonce_encoded_len)
                      != (int) client_nonce_len) {
      connection_write_str_to_buf("513 Invalid base16 client nonce\r\n",
                                  conn);
      connection_mark_for_close(TO_CONN(conn));
      tor_free(client_nonce);
      return -1;
    }

    cp += client_nonce_encoded_len;
  }

  cp += strspn(cp, " \t\n\r");
  if (*cp != '\0' ||
      cp != body + len) {
    connection_write_str_to_buf("513 Junk at end of AUTHCHALLENGE command\r\n",
                                conn);
    connection_mark_for_close(TO_CONN(conn));
    tor_free(client_nonce);
    return -1;
  }
  crypto_rand(server_nonce, SAFECOOKIE_SERVER_NONCE_LEN);

  /* Now compute and send the server-to-controller response, and the
   * server's nonce. */
  tor_assert(authentication_cookie != NULL);

  {
    size_t tmp_len = (AUTHENTICATION_COOKIE_LEN +
                      client_nonce_len +
                      SAFECOOKIE_SERVER_NONCE_LEN);
    char *tmp = tor_malloc_zero(tmp_len);
    char *client_hash = tor_malloc_zero(DIGEST256_LEN);
    memcpy(tmp, authentication_cookie, AUTHENTICATION_COOKIE_LEN);
    memcpy(tmp + AUTHENTICATION_COOKIE_LEN, client_nonce, client_nonce_len);
    memcpy(tmp + AUTHENTICATION_COOKIE_LEN + client_nonce_len,
           server_nonce, SAFECOOKIE_SERVER_NONCE_LEN);

    crypto_hmac_sha256(server_hash,
                       SAFECOOKIE_SERVER_TO_CONTROLLER_CONSTANT,
                       strlen(SAFECOOKIE_SERVER_TO_CONTROLLER_CONSTANT),
                       tmp,
                       tmp_len);

    crypto_hmac_sha256(client_hash,
                       SAFECOOKIE_CONTROLLER_TO_SERVER_CONSTANT,
                       strlen(SAFECOOKIE_CONTROLLER_TO_SERVER_CONSTANT),
                       tmp,
                       tmp_len);

    conn->safecookie_client_hash = client_hash;

    tor_free(tmp);
  }

  base16_encode(server_hash_encoded, sizeof(server_hash_encoded),
                server_hash, sizeof(server_hash));
  base16_encode(server_nonce_encoded, sizeof(server_nonce_encoded),
                server_nonce, sizeof(server_nonce));

  connection_printf_to_buf(conn,
                           "250 AUTHCHALLENGE SERVERHASH=%s "
                           "SERVERNONCE=%s\r\n",
                           server_hash_encoded,
                           server_nonce_encoded);

  tor_free(client_nonce);
  return 0;
}
Ejemplo n.º 22
0
/** Run unit tests for our SHA-1 functionality */
static void
test_crypto_sha(void)
{
  crypto_digest_t *d1 = NULL, *d2 = NULL;
  int i;
  char key[160];
  char digest[32];
  char data[50];
  char d_out1[DIGEST_LEN], d_out2[DIGEST256_LEN];
  char *mem_op_hex_tmp=NULL;

  /* Test SHA-1 with a test vector from the specification. */
  i = crypto_digest(data, "abc", 3);
  test_memeq_hex(data, "A9993E364706816ABA3E25717850C26C9CD0D89D");
  tt_int_op(i, ==, 0);

  /* Test SHA-256 with a test vector from the specification. */
  i = crypto_digest256(data, "abc", 3, DIGEST_SHA256);
  test_memeq_hex(data, "BA7816BF8F01CFEA414140DE5DAE2223B00361A3"
                       "96177A9CB410FF61F20015AD");
  tt_int_op(i, ==, 0);

  /* Test HMAC-SHA-1 with test cases from RFC2202. */

  /* Case 1. */
  memset(key, 0x0b, 20);
  crypto_hmac_sha1(digest, key, 20, "Hi There", 8);
  test_streq(hex_str(digest, 20),
             "B617318655057264E28BC0B6FB378C8EF146BE00");
  /* Case 2. */
  crypto_hmac_sha1(digest, "Jefe", 4, "what do ya want for nothing?", 28);
  test_streq(hex_str(digest, 20),
             "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79");

  /* Case 4. */
  base16_decode(key, 25,
                "0102030405060708090a0b0c0d0e0f10111213141516171819", 50);
  memset(data, 0xcd, 50);
  crypto_hmac_sha1(digest, key, 25, data, 50);
  test_streq(hex_str(digest, 20),
             "4C9007F4026250C6BC8414F9BF50C86C2D7235DA");

  /* Case 5. */
  memset(key, 0xaa, 80);
  crypto_hmac_sha1(digest, key, 80,
                   "Test Using Larger Than Block-Size Key - Hash Key First",
                   54);
  test_streq(hex_str(digest, 20),
             "AA4AE5E15272D00E95705637CE8A3B55ED402112");

  /* Test HMAC-SHA256 with test cases from wikipedia and RFC 4231 */

  /* Case empty (wikipedia) */
  crypto_hmac_sha256(digest, "", 0, "", 0);
  test_streq(hex_str(digest, 32),
           "B613679A0814D9EC772F95D778C35FC5FF1697C493715653C6C712144292C5AD");

  /* Case quick-brown (wikipedia) */
  crypto_hmac_sha256(digest, "key", 3,
                     "The quick brown fox jumps over the lazy dog", 43);
  test_streq(hex_str(digest, 32),
           "F7BC83F430538424B13298E6AA6FB143EF4D59A14946175997479DBC2D1A3CD8");

  /* "Test Case 1" from RFC 4231 */
  memset(key, 0x0b, 20);
  crypto_hmac_sha256(digest, key, 20, "Hi There", 8);
  test_memeq_hex(digest,
                 "b0344c61d8db38535ca8afceaf0bf12b"
                 "881dc200c9833da726e9376c2e32cff7");

  /* "Test Case 2" from RFC 4231 */
  memset(key, 0x0b, 20);
  crypto_hmac_sha256(digest, "Jefe", 4, "what do ya want for nothing?", 28);
  test_memeq_hex(digest,
                 "5bdcc146bf60754e6a042426089575c7"
                 "5a003f089d2739839dec58b964ec3843");

  /* "Test case 3" from RFC 4231 */
  memset(key, 0xaa, 20);
  memset(data, 0xdd, 50);
  crypto_hmac_sha256(digest, key, 20, data, 50);
  test_memeq_hex(digest,
                 "773ea91e36800e46854db8ebd09181a7"
                 "2959098b3ef8c122d9635514ced565fe");

  /* "Test case 4" from RFC 4231 */
  base16_decode(key, 25,
                "0102030405060708090a0b0c0d0e0f10111213141516171819", 50);
  memset(data, 0xcd, 50);
  crypto_hmac_sha256(digest, key, 25, data, 50);
  test_memeq_hex(digest,
                 "82558a389a443c0ea4cc819899f2083a"
                 "85f0faa3e578f8077a2e3ff46729665b");

  /* "Test case 5" from RFC 4231 */
  memset(key, 0x0c, 20);
  crypto_hmac_sha256(digest, key, 20, "Test With Truncation", 20);
  test_memeq_hex(digest,
                 "a3b6167473100ee06e0c796c2955552b");

  /* "Test case 6" from RFC 4231 */
  memset(key, 0xaa, 131);
  crypto_hmac_sha256(digest, key, 131,
                     "Test Using Larger Than Block-Size Key - Hash Key First",
                     54);
  test_memeq_hex(digest,
                 "60e431591ee0b67f0d8a26aacbf5b77f"
                 "8e0bc6213728c5140546040f0ee37f54");

  /* "Test case 7" from RFC 4231 */
  memset(key, 0xaa, 131);
  crypto_hmac_sha256(digest, key, 131,
                     "This is a test using a larger than block-size key and a "
                     "larger than block-size data. The key needs to be hashed "
                     "before being used by the HMAC algorithm.", 152);
  test_memeq_hex(digest,
                 "9b09ffa71b942fcb27635fbcd5b0e944"
                 "bfdc63644f0713938a7f51535c3a35e2");

  /* Incremental digest code. */
  d1 = crypto_digest_new();
  test_assert(d1);
  crypto_digest_add_bytes(d1, "abcdef", 6);
  d2 = crypto_digest_dup(d1);
  test_assert(d2);
  crypto_digest_add_bytes(d2, "ghijkl", 6);
  crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
  crypto_digest(d_out2, "abcdefghijkl", 12);
  test_memeq(d_out1, d_out2, DIGEST_LEN);
  crypto_digest_assign(d2, d1);
  crypto_digest_add_bytes(d2, "mno", 3);
  crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
  crypto_digest(d_out2, "abcdefmno", 9);
  test_memeq(d_out1, d_out2, DIGEST_LEN);
  crypto_digest_get_digest(d1, d_out1, sizeof(d_out1));
  crypto_digest(d_out2, "abcdef", 6);
  test_memeq(d_out1, d_out2, DIGEST_LEN);
  crypto_digest_free(d1);
  crypto_digest_free(d2);

  /* Incremental digest code with sha256 */
  d1 = crypto_digest256_new(DIGEST_SHA256);
  test_assert(d1);
  crypto_digest_add_bytes(d1, "abcdef", 6);
  d2 = crypto_digest_dup(d1);
  test_assert(d2);
  crypto_digest_add_bytes(d2, "ghijkl", 6);
  crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
  crypto_digest256(d_out2, "abcdefghijkl", 12, DIGEST_SHA256);
  test_memeq(d_out1, d_out2, DIGEST_LEN);
  crypto_digest_assign(d2, d1);
  crypto_digest_add_bytes(d2, "mno", 3);
  crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
  crypto_digest256(d_out2, "abcdefmno", 9, DIGEST_SHA256);
  test_memeq(d_out1, d_out2, DIGEST_LEN);
  crypto_digest_get_digest(d1, d_out1, sizeof(d_out1));
  crypto_digest256(d_out2, "abcdef", 6, DIGEST_SHA256);
  test_memeq(d_out1, d_out2, DIGEST_LEN);

 done:
  if (d1)
    crypto_digest_free(d1);
  if (d2)
    crypto_digest_free(d2);
  tor_free(mem_op_hex_tmp);
}
Ejemplo n.º 23
0
/** Run unit tests for misc crypto formatting functionality (base64, base32,
 * fingerprints, etc) */
static void
test_crypto_formats(void)
{
  char *data1 = NULL, *data2 = NULL, *data3 = NULL;
  int i, j, idx;

  data1 = tor_malloc(1024);
  data2 = tor_malloc(1024);
  data3 = tor_malloc(1024);
  test_assert(data1 && data2 && data3);

  /* Base64 tests */
  memset(data1, 6, 1024);
  for (idx = 0; idx < 10; ++idx) {
    i = base64_encode(data2, 1024, data1, idx);
    test_assert(i >= 0);
    j = base64_decode(data3, 1024, data2, i);
    test_eq(j,idx);
    test_memeq(data3, data1, idx);
  }

  strlcpy(data1, "Test string that contains 35 chars.", 1024);
  strlcat(data1, " 2nd string that contains 35 chars.", 1024);

  i = base64_encode(data2, 1024, data1, 71);
  test_assert(i >= 0);
  j = base64_decode(data3, 1024, data2, i);
  test_eq(j, 71);
  test_streq(data3, data1);
  test_assert(data2[i] == '\0');

  crypto_rand(data1, DIGEST_LEN);
  memset(data2, 100, 1024);
  digest_to_base64(data2, data1);
  test_eq(BASE64_DIGEST_LEN, strlen(data2));
  test_eq(100, data2[BASE64_DIGEST_LEN+2]);
  memset(data3, 99, 1024);
  test_eq(digest_from_base64(data3, data2), 0);
  test_memeq(data1, data3, DIGEST_LEN);
  test_eq(99, data3[DIGEST_LEN+1]);

  test_assert(digest_from_base64(data3, "###") < 0);

  /* Encoding SHA256 */
  crypto_rand(data2, DIGEST256_LEN);
  memset(data2, 100, 1024);
  digest256_to_base64(data2, data1);
  test_eq(BASE64_DIGEST256_LEN, strlen(data2));
  test_eq(100, data2[BASE64_DIGEST256_LEN+2]);
  memset(data3, 99, 1024);
  test_eq(digest256_from_base64(data3, data2), 0);
  test_memeq(data1, data3, DIGEST256_LEN);
  test_eq(99, data3[DIGEST256_LEN+1]);

  /* Base32 tests */
  strlcpy(data1, "5chrs", 1024);
  /* bit pattern is:  [35 63 68 72 73] ->
   *        [00110101 01100011 01101000 01110010 01110011]
   * By 5s: [00110 10101 10001 10110 10000 11100 10011 10011]
   */
  base32_encode(data2, 9, data1, 5);
  test_streq(data2, "gvrwq4tt");

  strlcpy(data1, "\xFF\xF5\x6D\x44\xAE\x0D\x5C\xC9\x62\xC4", 1024);
  base32_encode(data2, 30, data1, 10);
  test_streq(data2, "772w2rfobvomsywe");

  /* Base16 tests */
  strlcpy(data1, "6chrs\xff", 1024);
  base16_encode(data2, 13, data1, 6);
  test_streq(data2, "3663687273FF");

  strlcpy(data1, "f0d678affc000100", 1024);
  i = base16_decode(data2, 8, data1, 16);
  test_eq(i,0);
  test_memeq(data2, "\xf0\xd6\x78\xaf\xfc\x00\x01\x00",8);

  /* now try some failing base16 decodes */
  test_eq(-1, base16_decode(data2, 8, data1, 15)); /* odd input len */
  test_eq(-1, base16_decode(data2, 7, data1, 16)); /* dest too short */
  strlcpy(data1, "f0dz!8affc000100", 1024);
  test_eq(-1, base16_decode(data2, 8, data1, 16));

  tor_free(data1);
  tor_free(data2);
  tor_free(data3);

  /* Add spaces to fingerprint */
  {
    data1 = tor_strdup("ABCD1234ABCD56780000ABCD1234ABCD56780000");
    test_eq(strlen(data1), 40);
    data2 = tor_malloc(FINGERPRINT_LEN+1);
    add_spaces_to_fp(data2, FINGERPRINT_LEN+1, data1);
    test_streq(data2, "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000");
    tor_free(data1);
    tor_free(data2);
  }

 done:
  tor_free(data1);
  tor_free(data2);
  tor_free(data3);
}
Ejemplo n.º 24
0
static void
test_crypto_scrypt_vectors(void *arg)
{
  char *mem_op_hex_tmp = NULL;
  uint8_t spec[64], out[64];

  (void)arg;
#ifndef HAVE_LIBSCRYPT_H
  if (1)
    tt_skip();
#endif

  /* Test vectors from
     http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00 section 11.

     Note that the names of 'r' and 'N' are switched in that section. Or
     possibly in libscrypt.
  */

  base16_decode((char*)spec, sizeof(spec),
                "0400", 4);
  memset(out, 0x00, sizeof(out));
  tt_int_op(64, OP_EQ,
            secret_to_key_compute_key(out, 64, spec, 2, "", 0, 2));
  test_memeq_hex(out,
                 "77d6576238657b203b19ca42c18a0497"
                 "f16b4844e3074ae8dfdffa3fede21442"
                 "fcd0069ded0948f8326a753a0fc81f17"
                 "e8d3e0fb2e0d3628cf35e20c38d18906");

  base16_decode((char*)spec, sizeof(spec),
                "4e61436c" "0A34", 12);
  memset(out, 0x00, sizeof(out));
  tt_int_op(64, OP_EQ,
            secret_to_key_compute_key(out, 64, spec, 6, "password", 8, 2));
  test_memeq_hex(out,
                 "fdbabe1c9d3472007856e7190d01e9fe"
                 "7c6ad7cbc8237830e77376634b373162"
                 "2eaf30d92e22a3886ff109279d9830da"
                 "c727afb94a83ee6d8360cbdfa2cc0640");

  base16_decode((char*)spec, sizeof(spec),
                "536f6469756d43686c6f72696465" "0e30", 32);
  memset(out, 0x00, sizeof(out));
  tt_int_op(64, OP_EQ,
            secret_to_key_compute_key(out, 64, spec, 16,
                                      "pleaseletmein", 13, 2));
  test_memeq_hex(out,
                 "7023bdcb3afd7348461c06cd81fd38eb"
                 "fda8fbba904f8e3ea9b543f6545da1f2"
                 "d5432955613f0fcf62d49705242a9af9"
                 "e61e85dc0d651e40dfcf017b45575887");

  base16_decode((char*)spec, sizeof(spec),
                "536f6469756d43686c6f72696465" "1430", 32);
  memset(out, 0x00, sizeof(out));
  tt_int_op(64, OP_EQ,
            secret_to_key_compute_key(out, 64, spec, 16,
                                      "pleaseletmein", 13, 2));
  test_memeq_hex(out,
                 "2101cb9b6a511aaeaddbbe09cf70f881"
                 "ec568d574a2ffd4dabe5ee9820adaa47"
                 "8e56fd8f4ba5d09ffa1c6d927c40f4c3"
                 "37304049e8a952fbcbf45c6fa77a41a4");

 done:
  tor_free(mem_op_hex_tmp);
}
Ejemplo n.º 25
0
/**
 * Helper function to parse out a line in the measured bandwidth file
 * into a measured_bw_line_t output structure.
 *
 * If <b>line_is_after_headers</b> is true, then if we encounter an incomplete
 * bw line, return -1 and warn, since we are after the headers and we should
 * only parse bw lines. Return 0 otherwise.
 *
 * If <b>line_is_after_headers</b> is false then it means that we are not past
 * the header block yet. If we encounter an incomplete bw line, return -1 but
 * don't warn since there could be additional header lines coming. If we
 * encounter a proper bw line, return 0 (and we got past the headers).
 *
 * If the line contains "vote=0", stop parsing it, and return -1, so that the
 * line is ignored during voting.
 */
STATIC int
measured_bw_line_parse(measured_bw_line_t *out, const char *orig_line,
                       int line_is_after_headers)
{
  char *line = tor_strdup(orig_line);
  char *cp = line;
  int got_bw = 0;
  int got_node_id = 0;
  char *strtok_state; /* lame sauce d'jour */

  if (strlen(line) == 0) {
    log_warn(LD_DIRSERV, "Empty line in bandwidth file");
    tor_free(line);
    return -1;
  }

  /* Remove end of line character, so that is not part of the token */
  if (line[strlen(line) - 1] == '\n') {
    line[strlen(line) - 1] = '\0';
  }

  cp = tor_strtok_r(cp, " \t", &strtok_state);

  if (!cp) {
    log_warn(LD_DIRSERV, "Invalid line in bandwidth file: %s",
             escaped(orig_line));
    tor_free(line);
    return -1;
  }

  if (orig_line[strlen(orig_line)-1] != '\n') {
    log_warn(LD_DIRSERV, "Incomplete line in bandwidth file: %s",
             escaped(orig_line));
    tor_free(line);
    return -1;
  }

  do {
    // If the line contains vote=0, ignore it.
    if (strcmpstart(cp, "vote=0") == 0) {
      log_debug(LD_DIRSERV, "Ignoring bandwidth file line that contains "
                "vote=0: %s",escaped(orig_line));
      tor_free(line);
      return -1;
    } else if (strcmpstart(cp, "bw=") == 0) {
      int parse_ok = 0;
      char *endptr;
      if (got_bw) {
        log_warn(LD_DIRSERV, "Double bw= in bandwidth file line: %s",
                 escaped(orig_line));
        tor_free(line);
        return -1;
      }
      cp+=strlen("bw=");

      out->bw_kb = tor_parse_long(cp, 10, 0, LONG_MAX, &parse_ok, &endptr);
      if (!parse_ok || (*endptr && !TOR_ISSPACE(*endptr))) {
        log_warn(LD_DIRSERV, "Invalid bandwidth in bandwidth file line: %s",
                 escaped(orig_line));
        tor_free(line);
        return -1;
      }
      got_bw=1;
    } else if (strcmpstart(cp, "node_id=$") == 0) {
      if (got_node_id) {
        log_warn(LD_DIRSERV, "Double node_id= in bandwidth file line: %s",
                 escaped(orig_line));
        tor_free(line);
        return -1;
      }
      cp+=strlen("node_id=$");

      if (strlen(cp) != HEX_DIGEST_LEN ||
          base16_decode(out->node_id, DIGEST_LEN,
                        cp, HEX_DIGEST_LEN) != DIGEST_LEN) {
        log_warn(LD_DIRSERV, "Invalid node_id in bandwidth file line: %s",
                 escaped(orig_line));
        tor_free(line);
        return -1;
      }
      strlcpy(out->node_hex, cp, sizeof(out->node_hex));
      got_node_id=1;
    }
  } while ((cp = tor_strtok_r(NULL, " \t", &strtok_state)));

  if (got_bw && got_node_id) {
    tor_free(line);
    return 0;
  } else if (line_is_after_headers == 0) {
    /* There could be additional header lines, therefore do not give warnings
     * but returns -1 since it's not a complete bw line. */
    log_debug(LD_DIRSERV, "Missing bw or node_id in bandwidth file line: %s",
             escaped(orig_line));
    tor_free(line);
    return -1;
  } else {
    log_warn(LD_DIRSERV, "Incomplete line in bandwidth file: %s",
             escaped(orig_line));
    tor_free(line);
    return -1;
  }
}
Ejemplo n.º 26
0
ya_result
output_stream_decode_base16(output_stream* os, const char * string, u32 length)
{
    const char *string_start = string;
    u32 needle = 0;
    ya_result return_code = OK;
    char buffer[64];
    u8 buffer_bin[32];

    /*    ------------------------------------------------------------    */

    while(length-- > 0)
    {
        char c = *string++;

        if(isspace(c))
        {
            continue;
        }

        buffer[needle++] = c;
        if(needle == sizeof (buffer))
        {
            if(FAIL(return_code = base16_decode(buffer, needle, buffer_bin)))
            {
                return return_code;
            }
            if(FAIL(return_code = output_stream_write(os, buffer_bin, return_code)))
            {
                return return_code;
            }

            needle = 0;
        }
    }

    if(needle > 0)
    {
        if((needle & 1) != 0)
        {
            return PARSEB16_ERROR;
        }

        if(FAIL(return_code = base16_decode(buffer, needle, buffer_bin)))
        {
            return return_code;
        }

        if(FAIL(return_code = output_stream_write(os, buffer_bin, return_code)))
        {
            return return_code;
        }
    }

    /* return the number of bytes read, instead of the last write size
     * this way something can be done about the input.
     *
     * alternatively we could just return "success"
     */

    return string - string_start;
}
Ejemplo n.º 27
0
/**
 * Construct MAC address for Honeywell VM3
 *
 * @v smsc95xx		SMSC95xx device
 * @v hw_addr		Hardware address to fill in
 * @ret rc		Return status code
 */
static int smsc95xx_fetch_mac_vm3 ( struct smsc95xx_device *smsc95xx,
				    uint8_t *hw_addr ) {
	struct smbios_structure structure;
	struct smbios_system_information system;
	struct {
		char manufacturer[ 10 /* "Honeywell" + NUL */ ];
		char product[ 4 /* "VM3" + NUL */ ];
		char mac[ base16_encoded_len ( ETH_ALEN ) + 1 /* NUL */ ];
	} strings;
	int len;
	int rc;

	/* Find system information */
	if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_SYSTEM_INFORMATION, 0,
					    &structure ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not find system "
		       "information: %s\n", smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Read system information */
	if ( ( rc = read_smbios_structure ( &structure, &system,
					    sizeof ( system ) ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not read system "
		       "information: %s\n", smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* NUL-terminate all strings to be fetched */
	memset ( &strings, 0, sizeof ( strings ) );

	/* Fetch system manufacturer name */
	len = read_smbios_string ( &structure, system.manufacturer,
				   strings.manufacturer,
				   ( sizeof ( strings.manufacturer ) - 1 ) );
	if ( len < 0 ) {
		rc = len;
		DBGC ( smsc95xx, "SMSC95XX %p could not read manufacturer "
		       "name: %s\n", smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Fetch system product name */
	len = read_smbios_string ( &structure, system.product, strings.product,
				   ( sizeof ( strings.product ) - 1 ) );
	if ( len < 0 ) {
		rc = len;
		DBGC ( smsc95xx, "SMSC95XX %p could not read product name: "
		       "%s\n", smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Ignore non-VM3 devices */
	if ( ( strcmp ( strings.manufacturer, "Honeywell" ) != 0 ) ||
	     ( strcmp ( strings.product, "VM3" ) != 0 ) )
		return -ENOTTY;

	/* Find OEM strings */
	if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_OEM_STRINGS, 0,
					    &structure ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not find OEM strings: %s\n",
		       smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Fetch MAC address */
	len = read_smbios_string ( &structure, SMSC95XX_VM3_OEM_STRING_MAC,
				   strings.mac, ( sizeof ( strings.mac ) - 1 ));
	if ( len < 0 ) {
		rc = len;
		DBGC ( smsc95xx, "SMSC95XX %p could not read OEM string: %s\n",
		       smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Sanity check */
	if ( len != ( ( int ) ( sizeof ( strings.mac ) - 1 ) ) ) {
		DBGC ( smsc95xx, "SMSC95XX %p invalid MAC address \"%s\"\n",
		       smsc95xx, strings.mac );
		return -EINVAL;
	}

	/* Decode MAC address */
	len = base16_decode ( strings.mac, hw_addr, ETH_ALEN );
	if ( len < 0 ) {
		rc = len;
		DBGC ( smsc95xx, "SMSC95XX %p invalid MAC address \"%s\"\n",
		       smsc95xx, strings.mac );
		return rc;
	}

	DBGC ( smsc95xx, "SMSC95XX %p using VM3 MAC %s\n",
	       smsc95xx, eth_ntoa ( hw_addr ) );
	return 0;
}
Ejemplo n.º 28
0
/**
 * Parse extended build information (git's commit string + dirtyness)
 * from a version string, starting at the first byte after the build number.
 *
 * A typical extended build information would look like:
 *
 *		-g5c02b-dirty
 *
 * The hexadecimal string after "-g" points to the leading git commit ID.
 * The "-dirty" indication is present when the binary was built with
 * uncommitted changes.
 *
 * @returns TRUE if we parsed the extended build information properly, FALSE
 * if we were not facing a proper extension.
 */
static bool
version_ext_parse(const char *str, version_ext_t *vext)
{
	const char *v;
	const char *e;
	size_t commit_len;
	char commit[SHA1_BASE16_SIZE + 1];

	v = is_strprefix(str, "-g");
	if (NULL == v) {
		/*
		 * There may not be any git tag, but there may be a dirty indication.
		 */

		e = is_strprefix(str, "dirty");
		if (e != NULL) {
			vext->dirty = TRUE;
			return TRUE;
		} else if (' ' == *str || '\0' == *str) {
			return TRUE;
		}
		return FALSE;
	}

	/*
	 * Compute the length of the hexadecimal string, up to the next '-' or
	 * the next ' ' or the end of the string.
	 */

	e = strchr(v, ' ');
	if (e != NULL) {
		const char *d;
		d = strchr(v, '-');
		if (NULL == d || d > e) {
			commit_len = e - v;		/* '-' before ' ' or no '-' at all */
		} else {
			commit_len = d - v;		/* '-' after ' ' */
			e = d;
		}
	} else {
		e = strchr(v, '-');
		if (e != NULL) {
			commit_len = e - v;
		} else {
			commit_len = strlen(v);
		}
	}

	if (commit_len > SHA1_BASE16_SIZE)
		return FALSE;

	vext->commit_len = commit_len;

	memset(commit, '0', sizeof commit - 1);
	commit[SHA1_BASE16_SIZE] = '\0';
	memcpy(commit, v, commit_len);

	ZERO(&vext->commit);
	(void) base16_decode(vext->commit.data, sizeof vext->commit,
		commit, SHA1_BASE16_SIZE);

	if (e != NULL && is_strprefix(e, "-dirty")) {
		vext->dirty = TRUE;
	} else {
		vext->dirty = FALSE;
	}

	return TRUE;
}