示例#1
0
文件: tor-resolve.c 项目: Zensin/tor
/** Set *<b>out</b> to a newly allocated SOCKS4a resolve request with
 * <b>username</b> and <b>hostname</b> as provided.  Return the number
 * of bytes in the request. */
static ssize_t
build_socks_resolve_request(char **out,
                            const char *username,
                            const char *hostname,
                            int reverse,
                            int version)
{
  size_t len = 0;
  tor_assert(out);
  tor_assert(username);
  tor_assert(hostname);

  if (version == 4) {
    len = 8 + strlen(username) + 1 + strlen(hostname) + 1;
    *out = tor_malloc(len);
    (*out)[0] = 4;      /* SOCKS version 4 */
    (*out)[1] = '\xF0'; /* Command: resolve. */
    set_uint16((*out)+2, htons(0)); /* port: 0. */
    set_uint32((*out)+4, htonl(0x00000001u)); /* addr: 0.0.0.1 */
    memcpy((*out)+8, username, strlen(username)+1);
    memcpy((*out)+8+strlen(username)+1, hostname, strlen(hostname)+1);
  } else if (version == 5) {
    int is_ip_address;
    tor_addr_t addr;
    size_t addrlen;
    int ipv6;
    is_ip_address = tor_addr_parse(&addr, hostname) != -1;
    if (!is_ip_address && reverse) {
      log_err(LD_GENERAL, "Tried to do a reverse lookup on a non-IP!");
      return -1;
    }
    ipv6 = reverse && tor_addr_family(&addr) == AF_INET6;
    addrlen = reverse ? (ipv6 ? 16 : 4) : 1 + strlen(hostname);
    len = 6 + addrlen;
    *out = tor_malloc(len);
    (*out)[0] = 5; /* SOCKS version 5 */
    (*out)[1] = reverse ? '\xF1' : '\xF0'; /* RESOLVE_PTR or RESOLVE */
    (*out)[2] = 0; /* reserved. */
    if (reverse) {
      (*out)[3] = ipv6 ? 4 : 1;
      if (ipv6)
        memcpy((*out)+4, tor_addr_to_in6_addr8(&addr), 16);
      else
        set_uint32((*out)+4, tor_addr_to_ipv4n(&addr));
    } else {
      (*out)[3] = 3;
      (*out)[4] = (char)(uint8_t)(addrlen - 1);
      memcpy((*out)+5, hostname, addrlen - 1);
    }
    set_uint16((*out)+4+addrlen, 0); /* port */
  } else {
    tor_assert(0);
  }

  return len;
}
示例#2
0
/** Set *<b>out</b> to a newly allocated SOCKS4a resolve request with
 * <b>username</b> and <b>hostname</b> as provided.  Return the number
 * of bytes in the request. */
static int
build_socks_connect_request(char **out,
                            const char *username,
                            const char *hostname,
                            int reverse,
                            int version)
{
  size_t len = 0;
  assert(out);
  assert(username);
  assert(hostname);

  if (version == 4) {
    len = 8 + strlen(username) + 1 + strlen(hostname) + 1;
    *out = malloc(len);
    (*out)[0] = 4;      /* SOCKS version 4 */
    (*out)[1] = '\x01'; /* Command: connect. */
    set_uint16((*out)+2, htons(80)); /* port: 80. */
    set_uint32((*out)+4, htonl(0x00000001u)); /* addr: 0.0.0.1 */
    memcpy((*out)+8, username, strlen(username)+1);
    memcpy((*out)+8+strlen(username)+1, hostname, strlen(hostname)+1);
  } else if (version == 5) {
    int is_ip_address;
    struct in_addr in;
    size_t addrlen;
    is_ip_address = inet_aton(hostname, &in);
    if (!is_ip_address && reverse) {
      fprintf(stderr,"Tried to do a reverse lookup on a non-IP!\n");
      return -1;
    }
    addrlen = is_ip_address ? 4 : 1 + strlen(hostname);
    len = 6 + addrlen;
    *out = malloc(len);
    (*out)[0] = 5; /* SOCKS version 5 */
    (*out)[1] = '\x01'; /* connect. */
    (*out)[2] = 0; /* reserved. */
    (*out)[3] = is_ip_address ? 1 : 3;
    if (is_ip_address) {
      set_uint32((*out)+4, in.s_addr);
    } else {
      (*out)[4] = (char)(uint8_t)(addrlen - 1);
      memcpy((*out)+5, hostname, addrlen - 1);
    }
    set_uint16((*out)+4+addrlen, htons(80)); /* port */
  } else {
    assert(0);
  }

  return len;
}
示例#3
0
/** Set *<b>out</b> to a newly allocated SOCKS4a resolve request with
 * <b>username</b> and <b>hostname</b> as provided.  Return the number
 * of bytes in the request. */
static int
build_socks_resolve_request(char **out,
                            const char *username,
                            const char *hostname,
                            int reverse,
                            int version)
{
  size_t len = 0;
  tor_assert(out);
  tor_assert(username);
  tor_assert(hostname);

  if (version == 4) {
    len = 8 + strlen(username) + 1 + strlen(hostname) + 1;
    *out = tor_malloc(len);
    (*out)[0] = 4;      /* SOCKS version 4 */
    (*out)[1] = '\xF0'; /* Command: resolve. */
    set_uint16((*out)+2, htons(0)); /* port: 0. */
    set_uint32((*out)+4, htonl(0x00000001u)); /* addr: 0.0.0.1 */
    memcpy((*out)+8, username, strlen(username)+1);
    memcpy((*out)+8+strlen(username)+1, hostname, strlen(hostname)+1);
  } else if (version == 5) {
    int is_ip_address;
    struct in_addr in;
    size_t addrlen;
    is_ip_address = tor_inet_aton(hostname, &in);
    if (!is_ip_address && reverse) {
      log_err(LD_GENERAL, "Tried to do a reverse lookup on a non-IP!");
      return -1;
    }
    addrlen = reverse ? 4 : 1 + strlen(hostname);
    len = 6 + addrlen;
    *out = tor_malloc(len);
    (*out)[0] = 5; /* SOCKS version 5 */
    (*out)[1] = reverse ? '\xF1' : '\xF0'; /* RESOLVE_PTR or RESOLVE */
    (*out)[2] = 0; /* reserved. */
    (*out)[3] = reverse ? 1 : 3;
    if (reverse) {
      set_uint32((*out)+4, in.s_addr);
    } else {
      (*out)[4] = (char)(uint8_t)(addrlen - 1);
      memcpy((*out)+5, hostname, addrlen - 1);
    }
    set_uint16((*out)+4+addrlen, 0); /* port */
  } else {
    tor_assert(0);
  }

  return len;
}
示例#4
0
文件: metabuilder.c 项目: snnw/gvfs
static void
write_metadata_for_file (GString *out,
			 MetaFile *file,
			 GList **stringvs,
			 GHashTable *strings,
			 GHashTable *key_hash)
{
  GList *l;
  MetaData *data;
  guint32 key;

  g_assert (file->metadata_pointer != 0);
  set_uint32 (out, file->metadata_pointer, out->len);

  append_uint32 (out, g_list_length (file->data), NULL);

  for (l = file->data; l != NULL; l = l->next)
    {
      data = l->data;

      key = GPOINTER_TO_UINT (g_hash_table_lookup (key_hash, data->key));
      if (data->is_list)
	key |= KEY_IS_LIST_MASK;
      append_uint32 (out, key, NULL);
      if (data->is_list)
	append_stringv (out, data->values, stringvs);
      else
	append_string (out, data->value, strings);
    }
}
示例#5
0
文件: metabuilder.c 项目: snnw/gvfs
static void
stringv_block_end (GString *out,
		   GHashTable *string_block,
		   GList *stringv_block)
{
  guint32 table_offset;
  StringvInfo *info;
  GList *l, *s;


  for (l = stringv_block; l != NULL; l = l->next)
    {
      info = l->data;

      table_offset = out->len;

      append_uint32 (out, g_list_length (info->strings), NULL);
      for (s = info->strings; s != NULL; s = s->next)
	append_string (out, s->data, string_block);

      set_uint32 (out, info->offset, table_offset);

      g_free (info);
    }

  g_list_free (stringv_block);

  /* Pad to 32bit */
  while (out->len % 4 != 0)
    g_string_append_c (out, 0);
}
示例#6
0
文件: metabuilder.c 项目: snnw/gvfs
static void
string_block_end (GString *out,
		  GHashTable *string_block)
{
  char *string;
  GList *offsets, *l;
  guint32 string_offset, offset;
  GHashTableIter iter;

  g_hash_table_iter_init (&iter, string_block);
  while (g_hash_table_iter_next (&iter,
				 (gpointer *)&string,
				 (gpointer *)&offsets))
    {
      string_offset = out->len;
      g_string_append_len (out, string, strlen (string) + 1);
      for (l = offsets; l != NULL; l = l->next)
	{
	  offset = GPOINTER_TO_UINT (l->data);
	  set_uint32 (out, offset, string_offset);
	}
    }

  g_hash_table_destroy (string_block);

  /* Pad to 32bit */
  while (out->len % 4 != 0)
    g_string_append_c (out, 0);
}
示例#7
0
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:
  ;
}
示例#8
0
int
do_rtpg(int fd, void* resp, long resplen, unsigned int timeout)
{
	struct rtpg_command	cmd;
	struct sg_io_hdr	hdr;
	unsigned char		sense[SENSE_BUFF_LEN];

	memset(&cmd, 0, sizeof(cmd));
	cmd.op			= OPERATION_CODE_RTPG;
	rtpg_command_set_service_action(&cmd);
	set_uint32(cmd.length, resplen);
	PRINT_HEX((unsigned char *) &cmd, sizeof(cmd));

	memset(&hdr, 0, sizeof(hdr));
	hdr.interface_id	= 'S';
	hdr.cmdp		= (unsigned char *) &cmd;
	hdr.cmd_len		= sizeof(cmd);
	hdr.dxfer_direction	= SG_DXFER_FROM_DEV;
	hdr.dxferp		= resp;
	hdr.dxfer_len		= resplen;
	hdr.mx_sb_len		= sizeof(sense);
	hdr.sbp			= sense;
	hdr.timeout		= get_prio_timeout(timeout, SGIO_TIMEOUT);

	if (ioctl(fd, SG_IO, &hdr) < 0)
		return -RTPG_RTPG_FAILED;

	if (scsi_error(&hdr)) {
		PRINT_DEBUG("do_rtpg: SCSI error!\n");
		return -RTPG_RTPG_FAILED;
	}
	PRINT_HEX(resp, resplen);

	return 0;
}
示例#9
0
文件: vlsctlc.c 项目: stiartsly/vdht
static
int _vlsctlc_pack_cmd(struct vlsctlc* lsctlc, void* buf, int len)
{
    struct vlsctlc_pack_cmd_desc* desc = lsctlc_pack_cmd_desc;
    void* len_addr = NULL;
    int ret = 0;
    int tsz = 0;
    int bsz = 0;

    vassert(lsctlc);
    vassert(buf);
    vassert(len > 0);

    set_uint8(buf + tsz, VLSCTL_VERSION);
    tsz += sizeof(uint8_t);
    set_uint8(buf + tsz, (uint8_t)lsctlc->type);
    tsz += sizeof(uint8_t);
    set_uint16(len_addr = buf + tsz, 0);
    tsz += sizeof(uint16_t);
    set_uint32(buf + tsz, VLSCTL_MAGIC);
    tsz += sizeof(uint32_t);

    for (; desc->cmd; desc++) {
        ret = desc->cmd(lsctlc, buf + tsz, len - tsz);
        if (ret < 0) {
            return -1;
        }
        bsz += ret;
        tsz += ret;
    }
    *(uint16_t*)len_addr = (uint16_t)bsz;
    return tsz;
}
示例#10
0
/** Pack global_id and circ_id; set *tag to the result. (See note on
 * cpuworker_main for wire format.) */
static void
tag_pack(uint8_t *tag, uint64_t chan_id, circid_t circ_id)
{
  /*XXXX RETHINK THIS WHOLE MESS !!!! !NM NM NM NM*/
  /*XXXX DOUBLEPLUSTHIS!!!! AS AS AS AS*/
  set_uint64(tag, chan_id);
  set_uint32(tag+8, circ_id);
}
示例#11
0
文件: vlsctlc.c 项目: stiartsly/vdht
static
int _aux_vlsctlc_pack_vaddr(void* buf, int len, struct vsockaddr_in* addr)
{
    int tsz = 0;

    vassert(addr);
    vassert(buf);
    vassert(len > 0);

    tsz += sizeof(uint16_t); // skip family;
    set_uint16(buf + tsz, addr->addr.sin_port);
    tsz += sizeof(int16_t);
    set_uint32(buf + tsz, addr->addr.sin_addr.s_addr);
    tsz += sizeof(uint32_t);
    set_uint32(buf + tsz, addr->type);
    tsz += sizeof(uint32_t);

    return tsz;
}
示例#12
0
static void
update_difference(int ipv6, uint8_t *d,
                  const tor_addr_t *a, const tor_addr_t *b)
{
  const int n_bytes = ipv6 ? 16 : 4;
  uint8_t a_tmp[4], b_tmp[4];
  const uint8_t *ba, *bb;
  int i;

  if (ipv6) {
    ba = tor_addr_to_in6_addr8(a);
    bb = tor_addr_to_in6_addr8(b);
  } else {
    set_uint32(a_tmp, tor_addr_to_ipv4n(a));
    set_uint32(b_tmp, tor_addr_to_ipv4n(b));
    ba = a_tmp; bb = b_tmp;
  }

  for (i = 0; i < n_bytes; ++i) {
    d[i] |= ba[i] ^ bb[i];
  }
}
示例#13
0
文件: metabuilder.c 项目: snnw/gvfs
static void
write_children (GString *out,
		MetaBuilder *builder)
{
  GHashTable *strings;
  MetaFile *child, *file;
  GList *l;
  GList *files;

  files = g_list_prepend (NULL, builder->root);

  while (files != NULL)
    {
      file = files->data;
      files = g_list_remove_link (files, files);

      if (file->children == NULL)
	continue; /* No children, skip file */

      strings = string_block_begin ();

      if (file->children_pointer != 0)
	set_uint32 (out, file->children_pointer, out->len);

      append_uint32 (out, g_list_length (file->children), NULL);

      for (l = file->children; l != NULL; l = l->next)
	{
	  child = l->data;

	  /* No mtime, children or metadata, no need for this
	     to be in the file */
	  if (child->last_changed == 0 &&
	      child->children == NULL &&
	      child->data == NULL)
	    continue;

	  append_string (out, child->name, strings);
	  append_uint32 (out, 0, &child->children_pointer);
	  append_uint32 (out, 0, &child->metadata_pointer);
	  append_time_t (out, child->last_changed, builder);

	  if (file->children)
	    files = g_list_append (files, child);
	}

      string_block_end (out, strings);
    }
}
示例#14
0
文件: metabuilder.c 项目: snnw/gvfs
static gboolean
create_new_journal (const char *filename, guint32 random_tag)
{
  char *journal_name;
  guint32 size_offset;
  GString *out;
  gsize pos;
  gboolean res;

  journal_name = get_journal_filename (filename, random_tag);

  out = g_string_new (NULL);

  /* HEADER */
  g_string_append_c (out, 0xda);
  g_string_append_c (out, 0x1a);
  g_string_append_c (out, 'j');
  g_string_append_c (out, 'o');
  g_string_append_c (out, 'u');
  g_string_append_c (out, 'r');

  /* VERSION */
  g_string_append_c (out, MAJOR_JOURNAL_VERSION);
  g_string_append_c (out, MINOR_JOURNAL_VERSION);

  append_uint32 (out, random_tag, NULL);
  append_uint32 (out, 0, &size_offset);
  append_uint32 (out, 0, NULL); /* Num entries, none so far */

  pos = out->len;

  g_string_set_size (out, NEW_JOURNAL_SIZE);
  memset (out->str + pos, 0, out->len - pos);

  set_uint32 (out, size_offset, out->len);

  res = g_file_set_contents (journal_name,
			     out->str, out->len,
			     NULL);

  g_free (journal_name);
  g_string_free (out, TRUE);

  return res;
}
示例#15
0
static int
build_socks5_resolve_ptr_request(char **out, const void *_addr)
{
  size_t len;
  const struct in_addr *addr=_addr;

  len = 12;
  *out = malloc(len);
  (*out)[0] = 5;      /* SOCKS version 5 */
  (*out)[1] = '\xF1'; /* Command: reverse resolve.
                         see doc/socks-extensions.txt*/
  (*out)[2] = '\x00'; /* RSV */
  (*out)[3] = '\x01'; /* ATYP: IP V4 address: X'01' */

  set_uint32((*out)+4, addr->s_addr);/*IP*/
  set_uint16((*out)+4+4, 0); /* port */

  return len;
}
示例#16
0
/* Return a srv object that is built with the construction:
 *    SRV = SHA3-256("shared-random" | INT_8(reveal_num) |
 *                   INT_4(version) | HASHED_REVEALS | previous_SRV)
 * This function cannot fail. */
static sr_srv_t *
generate_srv(const char *hashed_reveals, uint64_t reveal_num,
             const sr_srv_t *previous_srv)
{
  char msg[DIGEST256_LEN + SR_SRV_MSG_LEN] = {0};
  size_t offset = 0;
  sr_srv_t *srv;

  tor_assert(hashed_reveals);

  /* Add the invariant token. */
  memcpy(msg, SR_SRV_TOKEN, SR_SRV_TOKEN_LEN);
  offset += SR_SRV_TOKEN_LEN;
  set_uint64(msg + offset, tor_htonll(reveal_num));
  offset += sizeof(uint64_t);
  set_uint32(msg + offset, htonl(SR_PROTO_VERSION));
  offset += sizeof(uint32_t);
  memcpy(msg + offset, hashed_reveals, DIGEST256_LEN);
  offset += DIGEST256_LEN;
  if (previous_srv != NULL) {
    memcpy(msg + offset, previous_srv->value, sizeof(previous_srv->value));
  }

  /* Ok we have our message and key for the HMAC computation, allocate our
   * srv object and do the last step. */
  srv = tor_malloc_zero(sizeof(*srv));
  crypto_digest256((char *) srv->value, msg, sizeof(msg), SR_DIGEST_ALG);
  srv->num_reveals = reveal_num;

  {
    /* Debugging. */
    char srv_hash_encoded[SR_SRV_VALUE_BASE64_LEN + 1];
    sr_srv_encode(srv_hash_encoded, sizeof(srv_hash_encoded), srv);
    log_info(LD_DIR, "SR: Generated SRV: %s", srv_hash_encoded);
  }
  return srv;
}
示例#17
0
文件: onion.c 项目: BwRy/Astoria
/** Format the EXTEND{,2} cell in <b>cell_in</b>, storing its relay payload in
 * <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
 * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
 * RELAY_PAYLOAD_SIZE bytes available.  Return 0 on success, -1 on failure. */
int
extend_cell_format(uint8_t *command_out, uint16_t *len_out,
                   uint8_t *payload_out, const extend_cell_t *cell_in)
{
  uint8_t *p, *eop;
  if (check_extend_cell(cell_in) < 0)
    return -1;

  p = payload_out;
  eop = payload_out + RELAY_PAYLOAD_SIZE;

  memset(p, 0, RELAY_PAYLOAD_SIZE);

  switch (cell_in->cell_type) {
  case RELAY_COMMAND_EXTEND:
    {
      *command_out = RELAY_COMMAND_EXTEND;
      *len_out = 6 + TAP_ONIONSKIN_CHALLENGE_LEN + DIGEST_LEN;
      set_uint32(p, tor_addr_to_ipv4n(&cell_in->orport_ipv4.addr));
      set_uint16(p+4, ntohs(cell_in->orport_ipv4.port));
      if (cell_in->create_cell.handshake_type == ONION_HANDSHAKE_TYPE_NTOR) {
        memcpy(p+6, NTOR_CREATE_MAGIC, 16);
        memcpy(p+22, cell_in->create_cell.onionskin, NTOR_ONIONSKIN_LEN);
      } else {
        memcpy(p+6, cell_in->create_cell.onionskin,
               TAP_ONIONSKIN_CHALLENGE_LEN);
      }
      memcpy(p+6+TAP_ONIONSKIN_CHALLENGE_LEN, cell_in->node_id, DIGEST_LEN);
    }
    break;
  case RELAY_COMMAND_EXTEND2:
    {
      uint8_t n = 2;
      *command_out = RELAY_COMMAND_EXTEND2;

      *p++ = n; /* 2 identifiers */
      *p++ = SPECTYPE_IPV4; /* First is IPV4. */
      *p++ = 6; /* It's 6 bytes long. */
      set_uint32(p, tor_addr_to_ipv4n(&cell_in->orport_ipv4.addr));
      set_uint16(p+4, htons(cell_in->orport_ipv4.port));
      p += 6;
      *p++ = SPECTYPE_LEGACY_ID; /* Next is an identity digest. */
      *p++ = 20; /* It's 20 bytes long */
      memcpy(p, cell_in->node_id, DIGEST_LEN);
      p += 20;

      /* Now we can send the handshake */
      set_uint16(p, htons(cell_in->create_cell.handshake_type));
      set_uint16(p+2, htons(cell_in->create_cell.handshake_len));
      p += 4;

      if (cell_in->create_cell.handshake_len > eop - p)
        return -1;

      memcpy(p, cell_in->create_cell.onionskin,
             cell_in->create_cell.handshake_len);

      p += cell_in->create_cell.handshake_len;
      *len_out = p - payload_out;
    }
    break;
  default:
    return -1;
  }

  return 0;
}
示例#18
0
/**
 * Make an authenticated passphrase-encrypted blob to encode the
 * <b>input_len</b> bytes in <b>input</b> using the passphrase
 * <b>secret</b> of <b>secret_len</b> bytes.  Allocate a new chunk of memory
 * to hold the encrypted data, and store a pointer to that memory in
 * *<b>out</b>, and its size in <b>outlen_out</b>.  Use <b>s2k_flags</b> as an
 * argument to the passphrase-hashing function.
 */
int
crypto_pwbox(uint8_t **out, size_t *outlen_out,
             const uint8_t *input, size_t input_len,
             const char *secret, size_t secret_len,
             unsigned s2k_flags)
{
  uint8_t *result = NULL, *encrypted_portion;
  size_t encrypted_len = 128 * CEIL_DIV(input_len+4, 128);
  ssize_t result_len;
  int spec_len;
  uint8_t keys[CIPHER_KEY_LEN + DIGEST256_LEN];
  pwbox_encoded_t *enc = NULL;
  ssize_t enc_len;

  crypto_cipher_t *cipher;
  int rv;

  enc = pwbox_encoded_new();

  pwbox_encoded_setlen_skey_header(enc, S2K_MAXLEN);

  spec_len = secret_to_key_make_specifier(
                                      pwbox_encoded_getarray_skey_header(enc),
                                      S2K_MAXLEN,
                                      s2k_flags);
  if (BUG(spec_len < 0 || spec_len > S2K_MAXLEN))
    goto err;
  pwbox_encoded_setlen_skey_header(enc, spec_len);
  enc->header_len = spec_len;

  crypto_rand((char*)enc->iv, sizeof(enc->iv));

  pwbox_encoded_setlen_data(enc, encrypted_len);
  encrypted_portion = pwbox_encoded_getarray_data(enc);

  set_uint32(encrypted_portion, htonl((uint32_t)input_len));
  memcpy(encrypted_portion+4, input, input_len);

  /* Now that all the data is in position, derive some keys, encrypt, and
   * digest */
  const int s2k_rv = secret_to_key_derivekey(keys, sizeof(keys),
                              pwbox_encoded_getarray_skey_header(enc),
                              spec_len,
                              secret, secret_len);
  if (BUG(s2k_rv < 0))
    goto err;

  cipher = crypto_cipher_new_with_iv((char*)keys, (char*)enc->iv);
  crypto_cipher_crypt_inplace(cipher, (char*)encrypted_portion, encrypted_len);
  crypto_cipher_free(cipher);

  result_len = pwbox_encoded_encoded_len(enc);
  if (BUG(result_len < 0))
    goto err;
  result = tor_malloc(result_len);
  enc_len = pwbox_encoded_encode(result, result_len, enc);
  if (BUG(enc_len < 0))
    goto err;
  tor_assert(enc_len == result_len);

  crypto_hmac_sha256((char*) result + result_len - 32,
                     (const char*)keys + CIPHER_KEY_LEN,
                     DIGEST256_LEN,
                     (const char*)result,
                     result_len - 32);

  *out = result;
  *outlen_out = result_len;
  rv = 0;
  goto out;

 err:
  /* LCOV_EXCL_START

     This error case is often unreachable if we're correctly coded, unless
     somebody adds a new error case somewhere, or unless you're building
     without scrypto support.

       - make_specifier can't fail, unless S2K_MAX_LEN is too short.
       - secret_to_key_derivekey can't really fail unless we're missing
         scrypt, or the underlying function fails, or we pass it a bogus
         algorithm or parameters.
       - pwbox_encoded_encoded_len can't fail unless we're using trunnel
         incorrectly.
       - pwbox_encoded_encode can't fail unless we're using trunnel wrong,
         or it's buggy.
   */
  tor_free(result);
  rv = -1;
  /* LCOV_EXCL_STOP */
 out:
  pwbox_encoded_free(enc);
  memwipe(keys, 0, sizeof(keys));
  return rv;
}
示例#19
0
文件: onion.c 项目: ageis/tor
/** Format the EXTEND{,2} cell in <b>cell_in</b>, storing its relay payload in
 * <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
 * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
 * RELAY_PAYLOAD_SIZE bytes available.  Return 0 on success, -1 on failure. */
int
extend_cell_format(uint8_t *command_out, uint16_t *len_out,
                   uint8_t *payload_out, const extend_cell_t *cell_in)
{
  uint8_t *p;
  if (check_extend_cell(cell_in) < 0)
    return -1;

  p = payload_out;

  memset(p, 0, RELAY_PAYLOAD_SIZE);

  switch (cell_in->cell_type) {
  case RELAY_COMMAND_EXTEND:
    {
      *command_out = RELAY_COMMAND_EXTEND;
      *len_out = 6 + TAP_ONIONSKIN_CHALLENGE_LEN + DIGEST_LEN;
      set_uint32(p, tor_addr_to_ipv4n(&cell_in->orport_ipv4.addr));
      set_uint16(p+4, htons(cell_in->orport_ipv4.port));
      if (cell_in->create_cell.handshake_type == ONION_HANDSHAKE_TYPE_NTOR) {
        memcpy(p+6, NTOR_CREATE_MAGIC, 16);
        memcpy(p+22, cell_in->create_cell.onionskin, NTOR_ONIONSKIN_LEN);
      } else {
        memcpy(p+6, cell_in->create_cell.onionskin,
               TAP_ONIONSKIN_CHALLENGE_LEN);
      }
      memcpy(p+6+TAP_ONIONSKIN_CHALLENGE_LEN, cell_in->node_id, DIGEST_LEN);
    }
    break;
  case RELAY_COMMAND_EXTEND2:
    {
      uint8_t n_specifiers = 2;
      *command_out = RELAY_COMMAND_EXTEND2;
      extend2_cell_body_t *cell = extend2_cell_body_new();
      link_specifier_t *ls;
      {
        /* IPv4 specifier first. */
        ls = link_specifier_new();
        extend2_cell_body_add_ls(cell, ls);
        ls->ls_type = LS_IPV4;
        ls->ls_len = 6;
        ls->un_ipv4_addr = tor_addr_to_ipv4h(&cell_in->orport_ipv4.addr);
        ls->un_ipv4_port = cell_in->orport_ipv4.port;
      }
      {
        /* Then RSA id */
        ls = link_specifier_new();
        extend2_cell_body_add_ls(cell, ls);
        ls->ls_type = LS_LEGACY_ID;
        ls->ls_len = DIGEST_LEN;
        memcpy(ls->un_legacy_id, cell_in->node_id, DIGEST_LEN);
      }
      if (should_include_ed25519_id_extend_cells(NULL, get_options()) &&
          !ed25519_public_key_is_zero(&cell_in->ed_pubkey)) {
        /* Then, maybe, the ed25519 id! */
        ++n_specifiers;
        ls = link_specifier_new();
        extend2_cell_body_add_ls(cell, ls);
        ls->ls_type = LS_ED25519_ID;
        ls->ls_len = 32;
        memcpy(ls->un_ed25519_id, cell_in->ed_pubkey.pubkey, 32);
      }
      cell->n_spec = n_specifiers;

      /* Now, the handshake */
      cell->create2 = create2_cell_body_new();
      cell->create2->handshake_type = cell_in->create_cell.handshake_type;
      cell->create2->handshake_len = cell_in->create_cell.handshake_len;
      create2_cell_body_setlen_handshake_data(cell->create2,
                                         cell_in->create_cell.handshake_len);
      memcpy(create2_cell_body_getarray_handshake_data(cell->create2),
             cell_in->create_cell.onionskin,
             cell_in->create_cell.handshake_len);

      ssize_t len_encoded = extend2_cell_body_encode(
                             payload_out, RELAY_PAYLOAD_SIZE,
                             cell);
      extend2_cell_body_free(cell);
      if (len_encoded < 0 || len_encoded > UINT16_MAX)
        return -1;
      *len_out = (uint16_t) len_encoded;
    }
    break;
  default:
    return -1;
  }

  return 0;
}
示例#20
0
文件: metabuilder.c 项目: snnw/gvfs
static GString *
metadata_create_static (MetaBuilder *builder,
			guint32 *random_tag_out)
{
  GString *out;
  GHashTable *hash, *key_hash;
  GHashTableIter iter;
  char *key;
  GList *keys, *l;
  GHashTable *strings;
  guint32 index;
  guint32 attributes_pointer;
  gint64 time_t_min;
  gint64 time_t_max;
  guint32 random_tag, root_name;

  out = g_string_new (NULL);

  /* HEADER */
  g_string_append_c (out, 0xda);
  g_string_append_c (out, 0x1a);
  g_string_append_c (out, 'm');
  g_string_append_c (out, 'e');
  g_string_append_c (out, 't');
  g_string_append_c (out, 'a');

  /* VERSION */
  g_string_append_c (out, MAJOR_VERSION);
  g_string_append_c (out, MINOR_VERSION);

  append_uint32 (out, 0, NULL); /* Rotated */
  random_tag = g_random_int ();
  *random_tag_out = random_tag;
  append_uint32 (out, random_tag, NULL);
  append_uint32 (out, 0, &builder->root_pointer);
  append_uint32 (out, 0, &attributes_pointer);

  time_t_min = 0;
  time_t_max = 0;
  metafile_collect_times (builder->root, &time_t_min, &time_t_max);

  /* Store the base as the min value in use minus one so that
     0 is free to mean "not defined" */
  time_t_min = time_t_min - 1;

  /* Pick the base as the minimum, unless that leads to
     a 32bit overflow */
  if (time_t_max - time_t_min > G_MAXUINT32)
    time_t_min = time_t_max - G_MAXUINT32;
  builder->time_t_base = time_t_min;
  append_int64 (out, builder->time_t_base);

  /* Collect and sort all used keys */
  hash = g_hash_table_new (g_str_hash, g_str_equal);
  metafile_collect_keywords (builder->root, hash);
  g_hash_table_iter_init (&iter, hash);
  keys = NULL;
  while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL))
    keys = g_list_prepend (keys, key);
  g_hash_table_destroy (hash);
  keys = g_list_sort (keys, (GCompareFunc)strcmp);

  /* Write keys to file and collect mapping for keys */
  set_uint32 (out, attributes_pointer, out->len);
  key_hash = g_hash_table_new (g_str_hash, g_str_equal);
  strings = string_block_begin ();
  append_uint32 (out, g_list_length (keys), NULL);
  for (l = keys, index = 0; l != NULL; l = l->next, index++)
    {
      key = l->data;
      append_string (out, key, strings);
      g_hash_table_insert (key_hash, key, GUINT_TO_POINTER (index));
    }
  string_block_end (out, strings);

  /* update root pointer */
  set_uint32 (out, builder->root_pointer, out->len);

  /* Root name */
  append_uint32 (out, 0, &root_name);

  /* Root child pointer */
  append_uint32 (out, 0, &builder->root->children_pointer);

  /* Root metadata pointer */
  append_uint32 (out, 0, &builder->root->metadata_pointer);

  /* Root last changed */
  append_uint32 (out, builder->root->last_changed, NULL);

  /* Root name */
  set_uint32 (out, root_name, out->len);
  g_string_append_len (out, "/", 2);

  /* Pad to 32bit */
  while (out->len % 4 != 0)
    g_string_append_c (out, 0);

  write_children (out, builder);
  write_metadata (out, builder, key_hash);

  g_hash_table_destroy (key_hash);
  g_list_free (keys);

  return out;
}