Fixed BACnet/SC secure connect VMAC, UUID, and initialization sequence (#1142)
* Refactored the BACnet/SC datalink initialization order by moving certificate file checks and hub connection registration to occur after datalink initialization * Replaced stdlib rand() with platform-specific cryptographically secure random functions (RtlGenRandom for Windows, getrandom for Linux, arc4random_buf for BSD) to generate UUID and VMAC addresses, preventing duplicates that broke connections * Enabled conditional debug output in BACnet/SC components when BUILD=debug is specified
This commit is contained in:
+24
-4
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Implementation of mutex abstraction used in BACNet secure connect.
|
||||
* @brief Implementation of port specific API used in BACNet secure connect.
|
||||
* @author Kirill Neznamov <kirill.neznamov@dsr-corporation.com>
|
||||
* @date August 2022
|
||||
* @copyright SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0
|
||||
@@ -14,10 +14,8 @@
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "bacnet/datalink/bsc/bsc-event.h"
|
||||
|
||||
#define DEBUG_BSC_EVENT 0
|
||||
|
||||
#undef DEBUG_PRINTF
|
||||
#if DEBUG_BSC_EVENT == 1
|
||||
#if DEBUG_BSC_EVENT
|
||||
#define DEBUG_PRINTF printf
|
||||
#else
|
||||
#undef DEBUG_ENABLED
|
||||
@@ -179,3 +177,25 @@ void bsc_wait_ms(int mseconds)
|
||||
{
|
||||
usleep(mseconds * 1000);
|
||||
}
|
||||
|
||||
void bsc_generate_random_vmac(BACNET_SC_VMAC_ADDRESS *p)
|
||||
{
|
||||
arc4random_buf(p->address, BVLC_SC_VMAC_SIZE);
|
||||
|
||||
/* According H.7.3 EUI-48 and Random-48 VMAC Address:
|
||||
The Random-48 VMAC is a 6-octet VMAC address in which the least
|
||||
significant 4 bits (Bit 3 to Bit 0) in the first octet shall be
|
||||
B'0010' (X'2'), and all other 44 bits are randomly selected to be
|
||||
0 or 1. */
|
||||
p->address[0] = (p->address[0] & 0xF0) | 0x02;
|
||||
|
||||
debug_printf_hex(
|
||||
0, p->address, BVLC_SC_VMAC_SIZE, "bsc_generate_random_vmac:");
|
||||
}
|
||||
|
||||
void bsc_generate_random_uuid(BACNET_SC_UUID *p)
|
||||
{
|
||||
arc4random_buf(p->uuid, BVLC_SC_UUID_SIZE);
|
||||
debug_printf_hex(
|
||||
0, p->uuid, BVLC_SC_UUID_SIZE, "bsc_generate_random_uuid:");
|
||||
}
|
||||
|
||||
@@ -14,10 +14,8 @@
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "websocket-global.h"
|
||||
|
||||
#define DEBUG_WEBSOCKET_CLIENT 0
|
||||
|
||||
#undef DEBUG_PRINTF
|
||||
#if DEBUG_WEBSOCKET_CLIENT == 1
|
||||
#if DEBUG_WEBSOCKET_CLIENT
|
||||
#define DEBUG_PRINTF debug_printf
|
||||
#else
|
||||
#undef DEBUG_ENABLED
|
||||
|
||||
@@ -15,10 +15,8 @@
|
||||
#include "websocket-global.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define DEBUG_WEBSOCKET_SERVER 0
|
||||
|
||||
#undef DEBUG_PRINTF
|
||||
#if DEBUG_WEBSOCKET_SERVER == 1
|
||||
#if DEBUG_WEBSOCKET_SERVER
|
||||
#define DEBUG_PRINTF debug_printf
|
||||
#else
|
||||
#undef DEBUG_ENABLED
|
||||
|
||||
+25
-4
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Implementation of mutex abstraction used in BACNet secure connect.
|
||||
* @brief Implementation of port specific API used in BACNet secure connect.
|
||||
* @author Kirill Neznamov <kirill.neznamov@dsr-corporation.com>
|
||||
* @date August 2022
|
||||
* @copyright SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0
|
||||
@@ -11,13 +11,12 @@
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/random.h>
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "bacnet/datalink/bsc/bsc-event.h"
|
||||
|
||||
#define DEBUG_BSC_EVENT 0
|
||||
|
||||
#undef DEBUG_PRINTF
|
||||
#if DEBUG_BSC_EVENT == 1
|
||||
#if DEBUG_BSC_EVENT
|
||||
#define DEBUG_PRINTF printf
|
||||
#else
|
||||
#undef DEBUG_ENABLED
|
||||
@@ -179,3 +178,25 @@ void bsc_wait_ms(int mseconds)
|
||||
{
|
||||
usleep(mseconds * 1000);
|
||||
}
|
||||
|
||||
void bsc_generate_random_vmac(BACNET_SC_VMAC_ADDRESS *p)
|
||||
{
|
||||
getrandom(p->address, BVLC_SC_VMAC_SIZE, 0);
|
||||
|
||||
/* According H.7.3 EUI-48 and Random-48 VMAC Address:
|
||||
The Random-48 VMAC is a 6-octet VMAC address in which the least
|
||||
significant 4 bits (Bit 3 to Bit 0) in the first octet shall be
|
||||
B'0010' (X'2'), and all other 44 bits are randomly selected to be
|
||||
0 or 1. */
|
||||
p->address[0] = (p->address[0] & 0xF0) | 0x02;
|
||||
|
||||
debug_printf_hex(
|
||||
0, p->address, BVLC_SC_VMAC_SIZE, "bsc_generate_random_vmac:");
|
||||
}
|
||||
|
||||
void bsc_generate_random_uuid(BACNET_SC_UUID *p)
|
||||
{
|
||||
getrandom(p->uuid, BVLC_SC_UUID_SIZE, 0);
|
||||
debug_printf_hex(
|
||||
0, p->uuid, BVLC_SC_UUID_SIZE, "bsc_generate_random_uuid:");
|
||||
}
|
||||
|
||||
@@ -15,10 +15,8 @@
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "websocket-global.h"
|
||||
|
||||
#define DEBUG_WEBSOCKET_CLIENT 0
|
||||
|
||||
#undef DEBUG_PRINTF
|
||||
#if DEBUG_WEBSOCKET_CLIENT == 1
|
||||
#if DEBUG_WEBSOCKET_CLIENT
|
||||
#define DEBUG_PRINTF debug_printf
|
||||
#else
|
||||
#undef DEBUG_ENABLED
|
||||
|
||||
@@ -16,10 +16,8 @@
|
||||
#include "websocket-global.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define DEBUG_WEBSOCKET_SERVER 0
|
||||
|
||||
#undef DEBUG_PRINTF
|
||||
#if DEBUG_WEBSOCKET_SERVER == 1
|
||||
#if DEBUG_WEBSOCKET_SERVER
|
||||
#define DEBUG_PRINTF debug_printf
|
||||
#else
|
||||
#undef DEBUG_ENABLED
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <string.h>
|
||||
/* BACnet Stack defines - first */
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "bacnet/basic/object/bacfile.h"
|
||||
|
||||
#ifndef FILE_RECORD_SIZE
|
||||
@@ -57,6 +58,8 @@ size_t bacfile_posix_file_size(const char *pathname)
|
||||
file_size = (size_t)file_position;
|
||||
}
|
||||
fclose(pFile);
|
||||
} else {
|
||||
debug_printf_stderr("Failed to open %s for reading!\n", pathname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +106,8 @@ size_t bacfile_posix_read_stream_data(
|
||||
(void)fseek(pFile, fileStartPosition, SEEK_SET);
|
||||
len = fread(fileData, 1, fileDataLen, pFile);
|
||||
fclose(pFile);
|
||||
} else {
|
||||
debug_printf_stderr("Failed to open %s for reading!\n", pathname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,6 +150,8 @@ size_t bacfile_posix_write_stream_data(
|
||||
}
|
||||
bytes_written = fwrite(fileData, fileDataLen, 1, pFile);
|
||||
fclose(pFile);
|
||||
} else {
|
||||
debug_printf_stderr("Failed to open %s for writing!\n", pathname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +211,8 @@ bool bacfile_posix_write_record_data(
|
||||
status = true;
|
||||
}
|
||||
fclose(pFile);
|
||||
} else {
|
||||
debug_printf_stderr("Failed to open %s for writing!\n", pathname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +259,8 @@ bool bacfile_posix_read_record_data(
|
||||
status = true;
|
||||
}
|
||||
fclose(pFile);
|
||||
} else {
|
||||
debug_printf_stderr("Failed to open %s for reading!\n", pathname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,5 +279,7 @@ void bacfile_posix_init(void)
|
||||
bacfile_read_record_data_callback_set(bacfile_posix_read_record_data);
|
||||
bacfile_file_size_callback_set(bacfile_posix_file_size);
|
||||
bacfile_file_size_set_callback_set(bacfile_posix_file_size_set);
|
||||
#elif defined(BACDL_BSC)
|
||||
#error BACFILE is not defined for BACnet/SC!
|
||||
#endif
|
||||
}
|
||||
|
||||
+23
-4
@@ -1,11 +1,12 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Implementation of mutex abstraction used in BACNet secure connect.
|
||||
* @brief Implementation of port specific API used in BACNet secure connect.
|
||||
* @author Kirill Neznamov <kirill.neznamov@dsr-corporation.com>
|
||||
* @date August 2022
|
||||
* @copyright SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <ntsecapi.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -13,10 +14,8 @@
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "bacnet/datalink/bsc/bsc-event.h"
|
||||
|
||||
#define DEBUG_BSC_EVENT 0
|
||||
|
||||
#undef DEBUG_PRINTF
|
||||
#if DEBUG_BSC_EVENT == 1
|
||||
#if DEBUG_BSC_EVENT
|
||||
#define DEBUG_PRINTF printf
|
||||
#else
|
||||
#undef DEBUG_ENABLED
|
||||
@@ -144,3 +143,23 @@ void bsc_wait_ms(int mseconds)
|
||||
{
|
||||
Sleep(mseconds);
|
||||
}
|
||||
|
||||
void bsc_generate_random_vmac(BACNET_SC_VMAC_ADDRESS *p)
|
||||
{
|
||||
// Use RtlGenRandom (SystemFunction036) for cryptographically secure random
|
||||
// bytes
|
||||
RtlGenRandom(p->address, BVLC_SC_VMAC_SIZE);
|
||||
|
||||
/* According H.7.3 EUI-48 and Random-48 VMAC Address */
|
||||
p->address[0] = (p->address[0] & 0xF0) | 0x02;
|
||||
|
||||
debug_printf_hex(
|
||||
0, p->address, BVLC_SC_VMAC_SIZE, "bsc_generate_random_vmac:");
|
||||
}
|
||||
|
||||
void bsc_generate_random_uuid(BACNET_SC_UUID *p)
|
||||
{
|
||||
RtlGenRandom(p->uuid, BVLC_SC_UUID_SIZE);
|
||||
debug_printf_hex(
|
||||
0, p->uuid, BVLC_SC_UUID_SIZE, "bsc_generate_random_uuid:");
|
||||
}
|
||||
|
||||
@@ -13,10 +13,8 @@
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "websocket-global.h"
|
||||
|
||||
#define DEBUG_WEBSOCKET_CLIENT 0
|
||||
|
||||
#undef DEBUG_PRINTF
|
||||
#if DEBUG_WEBSOCKET_CLIENT == 1
|
||||
#if DEBUG_WEBSOCKET_CLIENT
|
||||
#define DEBUG_PRINTF debug_printf
|
||||
#else
|
||||
#undef DEBUG_ENABLED
|
||||
|
||||
@@ -13,10 +13,8 @@
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "websocket-global.h"
|
||||
|
||||
#define DEBUG_WEBSOCKET_SERVER 0
|
||||
|
||||
#undef DEBUG_PRINTF
|
||||
#if DEBUG_WEBSOCKET_SERVER == 1
|
||||
#if DEBUG_WEBSOCKET_SERVER
|
||||
#define DEBUG_PRINTF debug_printf
|
||||
#else
|
||||
#undef DEBUG_ENABLED
|
||||
|
||||
Reference in New Issue
Block a user