It should be noted that the fingerprint mechanism itself, invented by us in this Extra Systems Cypher Net encryption system, serves as one of the mechanisms for protecting the central server from hacker attacks. Receiving a connection request from an abstract client (which may be an intruder), the server expects to immediately receive a correct fingerprint from it. If this does not happen, the server does not conduct any further conversations with such a client and immediately terminates the connection. Let us recall that since the fingerprint files are encrypted via RSA with the server's public key (only by name), which is not actually published anywhere, it is completely impossible to forge them.
Thus, with the help of such a simple mechanism, we also have protection here that cannot be hacked.
The validity of the fingerprint received by the server is checked by the check_finger_print procedure (which is called on the server in the dispatch_call procedure):
int check_finger_print(THREADDATA *thread_item) { unsigned char client_message[PACKED_VALUE_LENTH]; unsigned char encrypted_value[VALUE_LENTH], decrypted_value[VALUE_LENTH]; char local_hash[HARD_HASH_SIZE]; int my_socket; FINGERPRINT client_finger_print; my_socket = thread_item->thread_socket; if (socket_read_buffer(my_socket, client_message, PACKED_VALUE_LENTH) != PACKED_VALUE_LENTH) return 0; unpack_value(client_message, encrypted_value); long_power_mod(encrypted_value, decrypt_rsa_key.exponent, decrypt_rsa_key.modulus, decrypted_value); pack_value(decrypted_value, client_message); memcpy(&client_finger_print, client_message, sizeof(client_finger_print)); get_hard_hash(client_finger_print.mixed_item, sizeof(client_finger_print.mixed_item), local_hash); if (memcmp(client_finger_print.mixed_hash, local_hash, HARD_HASH_SIZE) != 0) return 0; get_fingerprint_items(&(thread_item->client_id), &(thread_item->server_id), &(thread_item->client_mode), &(thread_item->prolog_size), &client_finger_print); return 1; }
In addition to checking the validity of the client who has applied, check_finger_print, as can be easily seen from this code, performs a number of preparatory operations by calling the get_fingerprint_items procedure. With its help, from the fingerprint object, which has the structure
typedef struct finger_print { unsigned char mixed_item[ITEM_SIZE * 2 * 3]; unsigned char mixed_hash[HARD_HASH_SIZE]; } FINGERPRINT;
into a THREADDATA object, which has the structure
typedef struct thread_data { int thread_id; int thread_socket; PEERID client_id; PEERID server_id; int server_thread; char *buffer_to_send; int buf_size; int prolog_size; unsigned char client_mode; } THREADDATA;
the subscriber identifiers (client_id and server_id), the connection type (client_mode) and the prolog size (prolog_size) are extracted. All these parameters, by the way, are absolutely necessary for the connect_server procedure called on the central server (in the dispatch_call procedure) immediately after check_finger_print. In fact, the entire work of connect_server (as is easily seen from its code) is based exclusively on these four parameters.
The content of this page is also available in French, German, Ukrainian and Russian.
© Extra Systems, 2024 |