diff --git a/core/federated/RTI/rti_lib.c b/core/federated/RTI/rti_lib.c index 80d1a7585..af2d45e2d 100644 --- a/core/federated/RTI/rti_lib.c +++ b/core/federated/RTI/rti_lib.c @@ -1378,57 +1378,67 @@ int receive_udp_message_and_set_up_clock_sync(int socket_id, uint16_t fed_id) { #ifdef __RTI_AUTH__ bool authenticate_federate(int socket) { - // Buffer for message type and federation RTI nonce. - size_t message_length = 1 + NONCE_LENGTH; - unsigned char rti_hello_buffer[message_length]; - rti_hello_buffer[0] = MSG_TYPE_RTI_NONCE; - unsigned char rti_nonce[NONCE_LENGTH]; - RAND_bytes(rti_nonce, NONCE_LENGTH); - memcpy(rti_hello_buffer + 1, rti_nonce, NONCE_LENGTH); - // Send RTI hello with RTI's random nonce. - write_to_socket(socket, message_length, rti_hello_buffer); - - // Check HMAC of received FED_RESPONSE message. + // Wait for MSG_TYPE_FED_NONCE from federate. + size_t fed_id_length = sizeof(uint16_t); + unsigned char buffer[1 + fed_id_length + NONCE_LENGTH]; + read_from_socket_errexit(socket, 1 + fed_id_length + NONCE_LENGTH, buffer, + "Failed to read MSG_TYPE_FED_NONCE"); + if (buffer[0] != MSG_TYPE_FED_NONCE) { + lf_print_error_and_exit( + "Received unexpected response %u from the FED (see net_common.h).", + buffer[0]); + } unsigned int hmac_length = SHA256_HMAC_LENGTH; size_t federation_id_length = strnlen(_f_rti->federation_id, 255); - size_t fed_id_length = sizeof(uint16_t); - - unsigned char received[1 + NONCE_LENGTH + fed_id_length + hmac_length]; - read_from_socket_errexit(socket, 1 + NONCE_LENGTH + fed_id_length + hmac_length, received, "Failed to read RTI response."); + // HMAC tag is created with MSG_TYPE, federate ID, received federate nonce. + unsigned char mac_buf[1 + fed_id_length + NONCE_LENGTH]; + mac_buf[0] = MSG_TYPE_RTI_RESPONSE; + memcpy(&mac_buf[1], &buffer[1], fed_id_length); + memcpy(&mac_buf[1 + fed_id_length], &buffer[1 + fed_id_length], NONCE_LENGTH); + unsigned char hmac_tag[hmac_length]; + unsigned char * ret = HMAC(EVP_sha256(), _f_rti->federation_id, + federation_id_length, mac_buf, 1 + fed_id_length + NONCE_LENGTH, + hmac_tag, &hmac_length); + if (ret == NULL) { + lf_print_error_and_exit("HMAC construction failed for MSG_TYPE_RTI_RESPONSE."); + } + // Make buffer for message type, RTI's nonce, and HMAC tag. + unsigned char sender[1 + NONCE_LENGTH + hmac_length]; + sender[0] = MSG_TYPE_RTI_RESPONSE; + unsigned char rti_nonce[NONCE_LENGTH]; + RAND_bytes(rti_nonce, NONCE_LENGTH); + memcpy(&sender[1], rti_nonce, NONCE_LENGTH); + memcpy(&sender[1 + NONCE_LENGTH], hmac_tag, hmac_length); + write_to_socket(socket, 1 + NONCE_LENGTH + hmac_length, sender); + + // Wait for MSG_TYPE_FED_RESPONSE + unsigned char received[1 + hmac_length]; + read_from_socket_errexit(socket, 1 + hmac_length, received, + "Failed to read federate response."); if (received[0] != MSG_TYPE_FED_RESPONSE) { - lf_print_error("Received unexpected response %u from the FED (see net_common.h).", - received[0]); + lf_print_error_and_exit( + "Received unexpected response %u from the federate (see net_common.h).", + received[0]); return false; } - - // Create tag to compare to received tag. - unsigned char buf_to_check[1 + fed_id_length + NONCE_LENGTH]; - buf_to_check[0] = MSG_TYPE_FED_RESPONSE; - memcpy(&buf_to_check[1], &received[1 + NONCE_LENGTH], fed_id_length); - memcpy(&buf_to_check[1 + fed_id_length], rti_nonce, NONCE_LENGTH); + // HMAC tag is created with MSG_TYPE_FED_RESPONSE and RTI's nonce. + unsigned char mac_buf2[1 + NONCE_LENGTH]; + mac_buf2[0] = MSG_TYPE_FED_RESPONSE; + memcpy(&mac_buf2[1], rti_nonce, NONCE_LENGTH); unsigned char rti_tag[hmac_length]; - HMAC(EVP_sha256(), _f_rti->federation_id, federation_id_length, buf_to_check, 1 + fed_id_length + NONCE_LENGTH, - rti_tag, &hmac_length); - + ret = HMAC(EVP_sha256(), _f_rti->federation_id, federation_id_length, + mac_buf2, 1 + NONCE_LENGTH, rti_tag, &hmac_length); + if (ret == NULL) { + lf_print_error_and_exit("HMAC construction failed for MSG_TYPE_FED_RESPONSE."); + } // Compare received tag and created tag. - if (memcmp(&received[1 + fed_id_length + NONCE_LENGTH], rti_tag, hmac_length) != 0) { + if (memcmp(&received[1], rti_tag, hmac_length) != 0) { // Federation IDs do not match. Send back a HMAC_DOES_NOT_MATCH message. lf_print_warning("HMAC authentication failed. Rejecting the federate."); send_reject(socket, HMAC_DOES_NOT_MATCH); return false; - } - else{ - LF_PRINT_LOG("HMAC verified."); - // HMAC tag is created with MSG_TYPE and received federate nonce. - unsigned char mac_buf[1 + NONCE_LENGTH]; - mac_buf[0] = MSG_TYPE_RTI_RESPONSE; - memcpy(&mac_buf[1], &received[1], NONCE_LENGTH); - // Buffer for message type and HMAC tag. - unsigned char sender[1 + hmac_length]; - sender[0] = MSG_TYPE_RTI_RESPONSE; - HMAC(EVP_sha256(), _f_rti->federation_id, federation_id_length, mac_buf, 1 + NONCE_LENGTH, - &sender[1], &hmac_length); - write_to_socket(socket, 1 + hmac_length, sender); + } else { + LF_PRINT_LOG("Federate's HMAC verified."); return true; } } @@ -1455,7 +1465,7 @@ void connect_to_federates(int socket_descriptor) { } } - // Send RTI hello when RTI -a option is on. + // Wait for the first message from the federate when RTI -a option is on. #ifdef __RTI_AUTH__ if (_f_rti->authentication_enabled) { if (!authenticate_federate(socket_id)) { diff --git a/core/federated/federate.c b/core/federated/federate.c index 7ab6db361..3a3b19893 100644 --- a/core/federated/federate.c +++ b/core/federated/federate.c @@ -914,65 +914,40 @@ void connect_to_federate(uint16_t remote_federate_id) { * @param rti_socket TCP socket for connection with the RTI. */ void perform_hmac_authentication(int rti_socket) { - unsigned char buffer[1 + NONCE_LENGTH]; - read_from_socket_errexit(rti_socket, 1 + NONCE_LENGTH, buffer, - "Failed to read RTI hello."); - if (buffer[0] != MSG_TYPE_RTI_NONCE) { - lf_print_error_and_exit( - "Received unexpected response %u from the RTI (see net_common.h).", - buffer[0]); - } + + // Send buffer including message type, federate ID, federate's nonce. + size_t fed_id_length = sizeof(uint16_t); + size_t message_length = 1 + fed_id_length + NONCE_LENGTH; + unsigned char fed_hello_buf[message_length]; + fed_hello_buf[0] = MSG_TYPE_FED_NONCE; + encode_uint16((uint16_t)_lf_my_fed_id, &fed_hello_buf[1]); + unsigned char fed_nonce[NONCE_LENGTH]; + RAND_bytes(fed_nonce, NONCE_LENGTH); + memcpy(&fed_hello_buf[1 + fed_id_length], fed_nonce, NONCE_LENGTH); + write_to_socket(rti_socket, message_length, fed_hello_buf); + + // Check HMAC of received FED_RESPONSE message. unsigned int hmac_length = SHA256_HMAC_LENGTH; size_t federation_id_length = strnlen(federation_metadata.federation_id, 255); - // HMAC tag is created with MSG_TYPE, federate ID, received rti nonce. - unsigned char mac_buf[1 + sizeof(uint16_t) + NONCE_LENGTH]; - mac_buf[0] = MSG_TYPE_FED_RESPONSE; - encode_uint16((uint16_t)_lf_my_fed_id, &mac_buf[1]); - memcpy(&mac_buf[1 + sizeof(uint16_t)], &buffer[1], NONCE_LENGTH); - unsigned char hmac_tag[hmac_length]; - unsigned char * ret = HMAC(EVP_sha256(), federation_metadata.federation_id, - federation_id_length, mac_buf, 1 + sizeof(uint16_t) + NONCE_LENGTH, - hmac_tag, &hmac_length); - if (ret == NULL) { - lf_print_error_and_exit("HMAC failure for MSG_TYPE_FED_RESPONSE."); - } - - // Buffer for message type, federate's nonce, federate ID, and HMAC tag. - unsigned char sender[1 + NONCE_LENGTH + sizeof(uint16_t) + hmac_length]; - sender[0] = MSG_TYPE_FED_RESPONSE; - unsigned char federate_nonce[NONCE_LENGTH]; - RAND_bytes(federate_nonce, NONCE_LENGTH); - int num_bytes = 1; - memcpy(&sender[num_bytes], federate_nonce, NONCE_LENGTH); - num_bytes += NONCE_LENGTH; - encode_uint16((uint16_t)_lf_my_fed_id, &sender[num_bytes]); - num_bytes += sizeof(uint16_t); - memcpy(&sender[num_bytes], hmac_tag, hmac_length); - num_bytes += hmac_length; - write_to_socket(rti_socket, num_bytes, sender); - - // Received MSG_TYPE_RTI_RESPONSE - unsigned char received[1 + hmac_length]; - read_from_socket_errexit(rti_socket, 1 + hmac_length, received, - "Failed to read RTI response."); + + unsigned char received[1 + NONCE_LENGTH + hmac_length]; + read_from_socket_errexit(rti_socket, 1 + NONCE_LENGTH + hmac_length, received, "Failed to read RTI response."); if (received[0] != MSG_TYPE_RTI_RESPONSE) { - lf_print_error_and_exit( - "Received unexpected response %u from the RTI (see net_common.h).", - received[0]); - } - // HMAC tag is created with MSG_TYPE and federate nonce. - unsigned char mac_buf2[1 + NONCE_LENGTH]; - mac_buf2[0] = MSG_TYPE_RTI_RESPONSE; - memcpy(&mac_buf2[1], federate_nonce, NONCE_LENGTH); + lf_print_error("Received unexpected response %u from the RTI (see net_common.h).", + received[0]); + } + // Create tag to compare to received tag. + unsigned char buf_to_check[1 + fed_id_length + NONCE_LENGTH]; + buf_to_check[0] = MSG_TYPE_RTI_RESPONSE; + encode_uint16((uint16_t)_lf_my_fed_id, &buf_to_check[1]); + memcpy(&buf_to_check[1 + fed_id_length], fed_nonce, NONCE_LENGTH); unsigned char fed_tag[hmac_length]; - ret = HMAC(EVP_sha256(), federation_metadata.federation_id, federation_id_length, - mac_buf2, 1 + NONCE_LENGTH, fed_tag, &hmac_length); - if (ret == NULL) { - lf_print_error_and_exit("HMAC failure for MSG_TYPE_RTI_RESPONSE."); - } + HMAC(EVP_sha256(), federation_metadata.federation_id, federation_id_length, buf_to_check, 1 + fed_id_length + NONCE_LENGTH, + fed_tag, &hmac_length); + // Compare received tag and created tag. - if (memcmp(&received[1], fed_tag, hmac_length) != 0) { - // Federation IDs do not match. Send back a MSG_TYPE_REJECT message. + if (memcmp(&received[1 + NONCE_LENGTH], fed_tag, hmac_length) != 0) { + // HMAC does not match. Send back a MSG_TYPE_REJECT message. lf_print_error("HMAC authentication failed."); unsigned char response[2]; response[0] = MSG_TYPE_REJECT; @@ -981,8 +956,19 @@ void perform_hmac_authentication(int rti_socket) { rti_socket, 2, response, "Federate failed to write MSG_TYPE_REJECT message on the socket."); close(rti_socket); - } else { + } + else { LF_PRINT_LOG("HMAC verified."); + // HMAC tag is created with MSG_TYPE_FED_RESPONSE and received federate nonce. + unsigned char mac_buf[1 + NONCE_LENGTH]; + mac_buf[0] = MSG_TYPE_FED_RESPONSE; + memcpy(&mac_buf[1], &received[1], NONCE_LENGTH); + // Buffer for message type and HMAC tag. + unsigned char sender[1 + hmac_length]; + sender[0] = MSG_TYPE_FED_RESPONSE; + HMAC(EVP_sha256(), federation_metadata.federation_id, federation_id_length, mac_buf, 1 + NONCE_LENGTH, + &sender[1], &hmac_length); + write_to_socket(rti_socket, 1 + hmac_length, sender); } } #endif diff --git a/include/core/federated/net_common.h b/include/core/federated/net_common.h index e7d331077..b0df4130d 100644 --- a/include/core/federated/net_common.h +++ b/include/core/federated/net_common.h @@ -330,40 +330,42 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /////////// Messages used for authenticated federation. /////////////// /** - * Byte identifying a message from an RTI to a federate containing - * RTI's 8-byte random nonce for HMAC-based authentication. The RTI sends this - * message to an incoming federate when TCP connection is established + * Byte identifying a message from a federate to an RTI containing + * federate's 8-byte random nonce for HMAC-based authentication. The federate sends this + * message to an incoming RTI when TCP connection is established * between the RTI and the federate. - * The next eight bytes are RTI's 8-byte nonce (RTI nonce). + * The message contains, in this order: + * * One byte equal to MSG_TYPE_FED_NONCE. + * * Two bytes (ushort) giving the federate ID. + * * Eight bytes for federate's nonce. */ -#define MSG_TYPE_RTI_NONCE 100 +#define MSG_TYPE_FED_NONCE 100 /** - * Byte identifying a message from federate to RTI as a response to the RTI Hello - * message. The federate sends this message to RTI for HMAC-based authentication. + * Byte identifying a message from RTI to federate as a response to the FED_NONCE + * message. The RTI sends this message to federate for HMAC-based authentication. * The message contains, in this order: - * * One byte equal to MSG_TYPE_FED_RESPONSE. - * * Eight bytes for federate's nonce. - * * Two bytes (ushort) giving the federate ID. + * * One byte equal to MSG_TYPE_RTI_RESPONSE. + * * Eight bytes for RTI's nonce. * * 32 bytes for HMAC tag based on SHA256. * The HMAC tag is composed of the following order: - * * One byte equal to MSG_TYPE_FED_RESPONSE. - * * Two bytes (ushort) giving the federate ID. - * * Eight bytes for received RTI's nonce. + * * One byte equal to MSG_TYPE_RTI_RESPONSE. + * * Two bytes (ushort) giving the received federate ID. + * * Eight bytes for received federate's nonce. */ -#define MSG_TYPE_FED_RESPONSE 101 +#define MSG_TYPE_RTI_RESPONSE 101 /** - * Byte identifying a message from RTI to a federate as a response to the FED_RESPONSE - * message. The RTI sends this message to federate for HMAC-based authentication. + * Byte identifying a message from federate to RTI as a response to the RTI_RESPONSE + * message. The federate sends this message to RTI for HMAC-based authentication. * The message contains, in this order: - * * One byte equal to MSG_TYPE_RTI_RESPONSE. + * * One byte equal to MSG_TYPE_FED_RESPONSE. * * 32 bytes for HMAC tag based on SHA256. * The HMAC tag is composed of the following order: - * * One byte equal to MSG_TYPE_RTI_RESPONSE. - * * Eight bytes for received federate's nonce. + * * One byte equal to MSG_TYPE_FED_RESPONSE. + * * Eight bytes for received RTI's nonce. */ -#define MSG_TYPE_RTI_RESPONSE 102 +#define MSG_TYPE_FED_RESPONSE 102 /** * The randomly created nonce size will be 8 bytes. diff --git a/lingua-franca-ref.txt b/lingua-franca-ref.txt index f5d2bf721..1f7391f92 100644 --- a/lingua-franca-ref.txt +++ b/lingua-franca-ref.txt @@ -1 +1 @@ -9acca40d53151aa79a5679ed1fcc675f3afb2e45 \ No newline at end of file +master