Пример #1
0
static int handle_send_initial(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
{
    Onion *onion = (Onion *)object;

    if (length > ONION_MAX_PACKET_SIZE) {
        return 1;
    }

    if (length <= 1 + SEND_1) {
        return 1;
    }

    change_symmetric_key(onion);

    uint8_t plain[ONION_MAX_PACKET_SIZE];
    uint8_t shared_key[crypto_box_BEFORENMBYTES];
    get_shared_key(&onion->shared_keys_1, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
    int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
                                     length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), plain);

    if (len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)) {
        return 1;
    }

    return onion_send_1(onion, plain, len, source, packet + 1);
}
Пример #2
0
//Begin ClientCode
int main(int argc, char ** argv)
{

#ifdef CSEC_VERIFY
  assume_string("clientID");
  assume_string("serverID");
  assume_string("port_ascii");

  // Assumption that the corresponding argv fields indeed contains the correct ids:
  readenvL(argv[1], strlen(argv[1]), "clientID");
  readenvL(argv[2], strlen(argv[2]), "serverID");
  readenvL(argv[3], strlen(argv[3]), "port_ascii");
#endif

  RPCstate clState;

  clState.end = CLIENT;

  if (parseargs(argc,argv,&clState))
  {
#ifdef VERBOSE
    fprintf(stdout, "Usage: client clientAddress serverAddress [port] request\n");
#endif
    exit(-1);
  }

#ifdef VERBOSE
  printf("Client: Now connecting to ");
  print_text_buffer(clState.other,clState.other_len);
  printf(", port %d.\n", clState.port);
  fflush(stdout);
#endif
  // Getting arguments
  if (socket_connect(&(clState.conn_fd),(char*) clState.other, clState.other_len, clState.port))
    return -1;
  clState.k_ab = get_shared_key(clState.self, clState.self_len, clState.other, clState.other_len, &(clState.k_ab_len));
  clState.k = mk_session_key(&(clState.k_len));
  clState.response = NULL;

#ifdef CSEC_VERIFY
  event3("client_begin", clState.self, clState.self_len, clState.other, clState.other_len, clState.request, clState.request_len);
#endif

  /* Send request */
  if (send_request(&clState) < 0) return -1;

  /* Receive response */
  if (recv_response(&clState) < 0) return -1;

#ifdef CSEC_VERIFY
  event4("client_accept", clState.self, clState.self_len, clState.other, clState.other_len,
                          clState.request, clState.request_len, clState.response, clState.response_len);
#endif

  return 0;
}
Пример #3
0
static int handle_send_2(void *object, IP_Port source, const uint8_t *packet, uint16_t length)
{
    Onion *onion = object;

    if (length > ONION_MAX_PACKET_SIZE)
        return 1;

    if (length <= 1 + SEND_3)
        return 1;

    change_symmetric_key(onion);

    uint8_t plain[ONION_MAX_PACKET_SIZE];
    uint8_t shared_key[crypto_box_BEFORENMBYTES];
    get_shared_key(&onion->shared_keys_3, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
    int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
                                     length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2), plain);

    if (len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2 + crypto_box_MACBYTES))
        return 1;

    if (len <= SIZE_IPPORT) {
        return 1;
    }

    if (plain[SIZE_IPPORT] != NET_PACKET_ANNOUNCE_REQUEST &&
            plain[SIZE_IPPORT] != NET_PACKET_ONION_DATA_REQUEST) {
        return 1;
    }

    IP_Port send_to;

    if (ipport_unpack(&send_to, plain, len, 0) == -1)
        return 1;

    uint8_t data[ONION_MAX_PACKET_SIZE];
    memcpy(data, plain + SIZE_IPPORT, len - SIZE_IPPORT);
    uint16_t data_len = (len - SIZE_IPPORT);
    uint8_t *ret_part = data + (len - SIZE_IPPORT);
    new_nonce(ret_part);
    uint8_t ret_data[RETURN_2 + SIZE_IPPORT];
    ipport_pack(ret_data, &source);
    memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_2), RETURN_2);
    len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
                                 ret_part + crypto_box_NONCEBYTES);

    if (len != RETURN_3 - crypto_box_NONCEBYTES)
        return 1;

    data_len += RETURN_3;

    if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len)
        return 1;

    return 0;
}
Пример #4
0
static int handle_send_1(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
{
    Onion *onion = (Onion *)object;

    if (length > ONION_MAX_PACKET_SIZE) {
        return 1;
    }

    if (length <= 1 + SEND_2) {
        return 1;
    }

    change_symmetric_key(onion);

    uint8_t plain[ONION_MAX_PACKET_SIZE];
    uint8_t shared_key[crypto_box_BEFORENMBYTES];
    get_shared_key(&onion->shared_keys_2, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
    int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
                                     length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1), plain);

    if (len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1 + crypto_box_MACBYTES)) {
        return 1;
    }

    IP_Port send_to;

    if (ipport_unpack(&send_to, plain, len, 0) == -1) {
        return 1;
    }

    uint8_t data[ONION_MAX_PACKET_SIZE];
    data[0] = NET_PACKET_ONION_SEND_2;
    memcpy(data + 1, packet + 1, crypto_box_NONCEBYTES);
    memcpy(data + 1 + crypto_box_NONCEBYTES, plain + SIZE_IPPORT, len - SIZE_IPPORT);
    uint16_t data_len = 1 + crypto_box_NONCEBYTES + (len - SIZE_IPPORT);
    uint8_t *ret_part = data + data_len;
    new_nonce(ret_part);
    uint8_t ret_data[RETURN_1 + SIZE_IPPORT];
    ipport_pack(ret_data, &source);
    memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_1), RETURN_1);
    len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
                                 ret_part + crypto_box_NONCEBYTES);

    if (len != RETURN_2 - crypto_box_NONCEBYTES) {
        return 1;
    }

    data_len += crypto_box_NONCEBYTES + len;

    if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len) {
        return 1;
    }

    return 0;
}
Пример #5
0
unsigned char * get_shared_key_proxy(size_t * len)
{
  mute();
  unsigned char * ret = get_shared_key(len);
  unmute();

  stack_ptr("get_key");
  StoreBuf(&ret);

  readenv(ret, len, "keyAB");
  return ret;
}
Пример #6
0
static int handle_announce_request(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
{
    Onion_Announce *onion_a = (Onion_Announce *)object;

    if (length != ANNOUNCE_REQUEST_SIZE_RECV) {
        return 1;
    }

    const uint8_t *packet_public_key = packet + 1 + CRYPTO_NONCE_SIZE;
    uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
    get_shared_key(&onion_a->shared_keys_recv, shared_key, onion_a->dht->self_secret_key, packet_public_key);

    uint8_t plain[ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE +
                  ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
    int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
                                     ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH +
                                     CRYPTO_MAC_SIZE, plain);

    if ((uint32_t)len != sizeof(plain)) {
        return 1;
    }

    uint8_t ping_id1[ONION_PING_ID_SIZE];
    generate_ping_id(onion_a, unix_time(), packet_public_key, source, ping_id1);

    uint8_t ping_id2[ONION_PING_ID_SIZE];
    generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet_public_key, source, ping_id2);

    int index = -1;

    uint8_t *data_public_key = plain + ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE;

    if (crypto_memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0
            || crypto_memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) {
        index = add_to_entries(onion_a, source, packet_public_key, data_public_key,
                               packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3));
    } else {
        index = in_entries(onion_a, plain + ONION_PING_ID_SIZE);
    }

    /*Respond with a announce response packet*/
    Node_format nodes_list[MAX_SENT_NODES];
    unsigned int num_nodes = get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, 0,
                             LAN_ip(source.ip) == 0, 1);
    uint8_t nonce[CRYPTO_NONCE_SIZE];
    random_nonce(nonce);

    uint8_t pl[1 + ONION_PING_ID_SIZE + sizeof(nodes_list)];

    if (index == -1) {
        pl[0] = 0;
        memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE);
    } else {
        if (public_key_cmp(onion_a->entries[index].public_key, packet_public_key) == 0) {
            if (public_key_cmp(onion_a->entries[index].data_public_key, data_public_key) != 0) {
                pl[0] = 0;
                memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE);
            } else {
                pl[0] = 2;
                memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE);
            }
        } else {
            pl[0] = 1;
            memcpy(pl + 1, onion_a->entries[index].data_public_key, CRYPTO_PUBLIC_KEY_SIZE);
        }
    }

    int nodes_length = 0;

    if (num_nodes != 0) {
        nodes_length = pack_nodes(pl + 1 + ONION_PING_ID_SIZE, sizeof(nodes_list), nodes_list, num_nodes);

        if (nodes_length <= 0) {
            return 1;
        }
    }

    uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE];
    len = encrypt_data_symmetric(shared_key, nonce, pl, 1 + ONION_PING_ID_SIZE + nodes_length,
                                 data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE);

    if (len != 1 + ONION_PING_ID_SIZE + nodes_length + CRYPTO_MAC_SIZE) {
        return 1;
    }

    data[0] = NET_PACKET_ANNOUNCE_RESPONSE;
    memcpy(data + 1, plain + ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
           ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
    memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, CRYPTO_NONCE_SIZE);

    if (send_onion_response(onion_a->net, source, data,
                            1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len,
                            packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3)) == -1) {
        return 1;
    }

    return 0;
}