Compare commits
4 Commits
Author | SHA1 | Date |
---|---|---|
Cyberes | 8fae0cd5db | |
Cyberes | 09602b2745 | |
Cyberes | 06d0c28499 | |
Cyberes | 28603b2a2e |
|
@ -1,6 +1,7 @@
|
||||||
.idea
|
.idea
|
||||||
server/config.yml
|
server/config.yml
|
||||||
.vscode
|
.vscode
|
||||||
|
*.ino.cpp
|
||||||
|
|
||||||
# ---> Python
|
# ---> Python
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
|
|
|
@ -257,11 +257,10 @@ bool TeleClientUDP::notify(byte event, const char* payload)
|
||||||
if (wifi.connected())
|
if (wifi.connected())
|
||||||
{
|
{
|
||||||
#if SERVER_ENCRYPTION_ENABLE == 1
|
#if SERVER_ENCRYPTION_ENABLE == 1
|
||||||
char *orig_send_buf = netbuf.buffer();
|
unsigned int encrypted_len;
|
||||||
unsigned int orig_send_buf_len = netbuf.length();
|
unsigned char* encrypted_buf = encrypt_buffer(netbuf.buffer(), netbuf.length(), &encrypted_len);
|
||||||
unsigned char encrypted_buf[12 + orig_send_buf_len + 16];
|
bool wifi_send = wifi.send((const char *)encrypted_buf, encrypted_len);
|
||||||
encrypt_string((unsigned char *)orig_send_buf, orig_send_buf_len, encrypted_buf);
|
free(encrypted_buf);
|
||||||
if (!wifi.send((const char *)encrypted_buf, sizeof(encrypted_buf))) break;
|
|
||||||
#else
|
#else
|
||||||
if (!wifi.send(netbuf.buffer(), netbuf.length())) break;
|
if (!wifi.send(netbuf.buffer(), netbuf.length())) break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -270,11 +269,11 @@ bool TeleClientUDP::notify(byte event, const char* payload)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if SERVER_ENCRYPTION_ENABLE == 1
|
#if SERVER_ENCRYPTION_ENABLE == 1
|
||||||
char *orig_send_buf = netbuf.buffer();
|
unsigned int encrypted_len;
|
||||||
unsigned int orig_send_buf_len = netbuf.length();
|
unsigned char* encrypted_buf = encrypt_buffer(netbuf.buffer(), netbuf.length(), &encrypted_len);
|
||||||
unsigned char encrypted_buf[12 + orig_send_buf_len + 16];
|
bool cell_send = cell.send((const char *)encrypted_buf, encrypted_len);
|
||||||
encrypt_string((unsigned char *)orig_send_buf, orig_send_buf_len, encrypted_buf);
|
free(encrypted_buf);
|
||||||
if (!cell.send((const char *)encrypted_buf, sizeof(encrypted_buf))) break;
|
if (!cell_send) break;
|
||||||
#else
|
#else
|
||||||
if (!cell.send(netbuf.buffer(), netbuf.length())) break;
|
if (!cell.send(netbuf.buffer(), netbuf.length())) break;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -66,32 +66,10 @@ void decrypt_string(const unsigned char *input, size_t length, unsigned char *ou
|
||||||
size_t decryptedLength = length - sizeof(nonce) - chachaPoly.tagSize();
|
size_t decryptedLength = length - sizeof(nonce) - chachaPoly.tagSize();
|
||||||
chachaPoly.decrypt(output, input + sizeof(nonce), decryptedLength);
|
chachaPoly.decrypt(output, input + sizeof(nonce), decryptedLength);
|
||||||
|
|
||||||
// String decryptedString = "";
|
|
||||||
// for (size_t i = 0; i < decryptedLength; i++) {
|
|
||||||
// decryptedString += (char)output[i];
|
|
||||||
// }
|
|
||||||
// Serial.println(decryptedString);
|
|
||||||
|
|
||||||
const unsigned char *tagPtr = input + sizeof(nonce) + decryptedLength; // actual tag
|
const unsigned char *tagPtr = input + sizeof(nonce) + decryptedLength; // actual tag
|
||||||
uint8_t computedTag[16]; // computed tag
|
uint8_t computedTag[16]; // computed tag
|
||||||
chachaPoly.computeTag(computedTag, sizeof(computedTag));
|
chachaPoly.computeTag(computedTag, sizeof(computedTag));
|
||||||
|
|
||||||
// Serial.print("Tag: ");
|
|
||||||
// for (size_t i = 0; i < chachaPoly.tagSize(); i++) {
|
|
||||||
// Serial.print(tagPtr[i], HEX);
|
|
||||||
// Serial.print(" ");
|
|
||||||
// }
|
|
||||||
// Serial.println();
|
|
||||||
// Serial.print("Computed Tag: ");
|
|
||||||
// for (size_t i = 0; i < sizeof(computedTag); i++) {
|
|
||||||
// Serial.print(computedTag[i], HEX);
|
|
||||||
// Serial.print(" ");
|
|
||||||
// }
|
|
||||||
// Serial.println();
|
|
||||||
|
|
||||||
///// BEGIN TAG VERIFY
|
|
||||||
// The crypto library implementation of tag verification crashes.
|
|
||||||
|
|
||||||
// Can never match if the expected tag length is too long.
|
// Can never match if the expected tag length is too long.
|
||||||
if (chachaPoly.tagSize() > 16) {
|
if (chachaPoly.tagSize() > 16) {
|
||||||
Serial.println("[CHACHA] Authentication failed: expected tag length is too long");
|
Serial.println("[CHACHA] Authentication failed: expected tag length is too long");
|
||||||
|
@ -100,17 +78,28 @@ void decrypt_string(const unsigned char *input, size_t length, unsigned char *ou
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the tag and check it.
|
// Compute the tag and check it.
|
||||||
|
// The crypto library implementation of tag verification crashes.
|
||||||
bool equal = secure_compare(computedTag, tagPtr, chachaPoly.tagSize());
|
bool equal = secure_compare(computedTag, tagPtr, chachaPoly.tagSize());
|
||||||
clean(computedTag);
|
clean(computedTag);
|
||||||
|
|
||||||
if (!equal) {
|
if (!equal) {
|
||||||
Serial.println("[CHACHA] Authentication failed!");
|
Serial.println("[CHACHA] Authentication failed!");
|
||||||
output[0] = '\0';
|
output[0] = '\0';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
///// END TAG VERIFY
|
|
||||||
|
|
||||||
output[decryptedLength] = '\0';
|
output[decryptedLength] = '\0';
|
||||||
chachaPoly.clear();
|
chachaPoly.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char* encrypt_buffer(char* buf, unsigned int len, unsigned int* encrypted_len) {
|
||||||
|
// Increase the size of encrypted_buf to hold the nonce, the encrypted data, and the authentication tag.
|
||||||
|
unsigned char* encrypted_buf = (unsigned char*)malloc(12 + len + 16); // 12 bytes for nonce and 16 bytes for tag
|
||||||
|
if(!encrypted_buf) {
|
||||||
|
// handle error
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
encrypt_string((unsigned char *)buf, len, encrypted_buf);
|
||||||
|
*encrypted_len = 12 + len + 16;
|
||||||
|
return encrypted_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,3 +7,4 @@
|
||||||
void encrypt_string(const unsigned char *input, size_t length, unsigned char *output);
|
void encrypt_string(const unsigned char *input, size_t length, unsigned char *output);
|
||||||
void decrypt_string(const unsigned char *input, size_t length, unsigned char *output);
|
void decrypt_string(const unsigned char *input, size_t length, unsigned char *output);
|
||||||
void print_hex(const unsigned char *data, size_t length);
|
void print_hex(const unsigned char *data, size_t length);
|
||||||
|
unsigned char* encrypt_buffer(char* buf, unsigned int len, unsigned int* encrypted_len);
|
|
@ -62,6 +62,12 @@ PID_POLLING_INFO obdData[]= {
|
||||||
{PID_TIMING_ADVANCE, 2},
|
{PID_TIMING_ADVANCE, 2},
|
||||||
{PID_COOLANT_TEMP, 3},
|
{PID_COOLANT_TEMP, 3},
|
||||||
{PID_INTAKE_TEMP, 3},
|
{PID_INTAKE_TEMP, 3},
|
||||||
|
{PID_ODOMETER, 3},
|
||||||
|
{PID_DISTANCE, 3},
|
||||||
|
{PID_AMBIENT_TEMP, 2},
|
||||||
|
{PID_ENGINE_OIL_TEMP, 2},
|
||||||
|
{PID_FUEL_LEVEL, 1}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CBufferManager bufman;
|
CBufferManager bufman;
|
||||||
|
@ -1007,12 +1013,11 @@ void telemetry(void* inst)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SERVER_ENCRYPTION_ENABLE == 1
|
#if SERVER_ENCRYPTION_ENABLE == 1
|
||||||
char *orig_send_buf = store.buffer();
|
unsigned int encrypted_len;
|
||||||
unsigned int orig_send_buf_len = store.length();
|
unsigned char* encrypted_buf = encrypt_buffer(store.buffer(), store.length(), &encrypted_len);
|
||||||
// Increase the size of encrypted_buf to hold the nonce, the encrypted data, and the authentication tag.
|
bool transmit_success = teleClient.transmit((const char *)encrypted_buf, encrypted_len);
|
||||||
unsigned char encrypted_buf[12 + orig_send_buf_len + 16]; // 12 bytes for nonce and 16 bytes for tag
|
free(encrypted_buf);
|
||||||
encrypt_string((unsigned char *)orig_send_buf, orig_send_buf_len, encrypted_buf);
|
if (transmit_success) {
|
||||||
if (teleClient.transmit((const char *)encrypted_buf, sizeof(encrypted_buf))) {
|
|
||||||
#else
|
#else
|
||||||
if (teleClient.transmit(store.buffer(), store.length())) {
|
if (teleClient.transmit(store.buffer(), store.length())) {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -107,7 +107,7 @@ void CStorageRAM::header(const char* devid)
|
||||||
void CStorageRAM::tailer()
|
void CStorageRAM::tailer()
|
||||||
{
|
{
|
||||||
if (m_cache[m_cacheBytes - 1] == ',') m_cacheBytes--;
|
if (m_cache[m_cacheBytes - 1] == ',') m_cacheBytes--;
|
||||||
m_cacheBytes += sprintf(m_cache + m_cacheBytes, "*%X", (unsigned int)checksum(m_cache, m_cacheBytes));
|
m_cacheBytes += sprintf(m_cache + m_cacheBytes, "*%02X", (unsigned int)checksum(m_cache, m_cacheBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStorageRAM::untailer()
|
void CStorageRAM::untailer()
|
||||||
|
|
|
@ -84,21 +84,22 @@ func main() {
|
||||||
|
|
||||||
// Handle the message.
|
// Handle the message.
|
||||||
go func(addr *net.UDPAddr, buf []byte, n int) {
|
go func(addr *net.UDPAddr, buf []byte, n int) {
|
||||||
// Do the decryption.
|
|
||||||
var plaintext []byte
|
var plaintext []byte
|
||||||
if len(buf[:n]) > 0 {
|
shouldEncrypt := true
|
||||||
plaintext, err = encryption.Decrypt(key, buf[:n]) // Use only the part of the buffer that has data.
|
recievedContent := buf[:n]
|
||||||
|
if len(recievedContent) > 0 {
|
||||||
|
plaintext, err = encryption.Decrypt(key, recievedContent) // Use only the part of the buffer that has data.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rawHex := hex.EncodeToString(buf[:n])
|
logger.Warningf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf(`Error decrypting message: %s. Length: %d, Raw: "%s"`, err, len(recievedContent), recievedContent)))
|
||||||
logger.Warnf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf(`Error decrypting message: %s. Length: %d, Raw: "%s"`, err, len(rawHex), rawHex)))
|
plaintext = recievedContent // Don't bother with decryption.
|
||||||
plaintext = buf[:n] // Forward the raw message to the backend without bothering with decryption.
|
shouldEncrypt = false
|
||||||
if len(plaintext) > 0 {
|
} else {
|
||||||
logger.Warningf("Encryption failed, possibly recieved unencrypted message -- %s", plaintext)
|
logger.Infof(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, string(plaintext)))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If empty message.
|
// If empty message.
|
||||||
plaintext = buf[:n]
|
plaintext = recievedContent
|
||||||
|
shouldEncrypt = false
|
||||||
}
|
}
|
||||||
|
|
||||||
forwardAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", dest.Address, dest.Port))
|
forwardAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", dest.Address, dest.Port))
|
||||||
|
@ -107,14 +108,12 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new UDP address for listening to the backend server's response.
|
|
||||||
listenAddr, err := net.ResolveUDPAddr("udp", ":0") // Let the OS pick a free port.
|
listenAddr, err := net.ResolveUDPAddr("udp", ":0") // Let the OS pick a free port.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalln("Error resolving listen address:", err)
|
logger.Fatalln("Error resolving listen address:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new UDP listener for the backend server's response.
|
|
||||||
listenConn, err := net.ListenUDP("udp", listenAddr)
|
listenConn, err := net.ListenUDP("udp", listenAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalln("Error listening for backend response:", err)
|
logger.Fatalln("Error listening for backend response:", err)
|
||||||
|
@ -122,7 +121,6 @@ func main() {
|
||||||
}
|
}
|
||||||
defer listenConn.Close()
|
defer listenConn.Close()
|
||||||
|
|
||||||
// Dial the backend server without binding a local address.
|
|
||||||
forwardConn, err := net.DialUDP("udp", nil, forwardAddr)
|
forwardConn, err := net.DialUDP("udp", nil, forwardAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalln("Error dialing to forward address:", err)
|
logger.Fatalln("Error dialing to forward address:", err)
|
||||||
|
@ -145,12 +143,16 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt the backend's response.
|
var encryptedBackendResponse []byte
|
||||||
encryptedBackendResponse, err := encryption.Encrypt(key, backendResponse[:n])
|
if shouldEncrypt {
|
||||||
|
encryptedBackendResponse, err = encryption.Encrypt(key, backendResponse[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf("Error encrypting response: %s", err)))
|
logger.Errorf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf("Error encrypting response: %s", err)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
encryptedBackendResponse = backendResponse
|
||||||
|
}
|
||||||
|
|
||||||
// Forward the encrypted backend response to the client.
|
// Forward the encrypted backend response to the client.
|
||||||
_, err = conn.WriteToUDP(encryptedBackendResponse, addr)
|
_, err = conn.WriteToUDP(encryptedBackendResponse, addr)
|
||||||
|
@ -158,8 +160,6 @@ func main() {
|
||||||
logger.Errorf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf("Error forwarding response to client: %s", err)))
|
logger.Errorf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf("Error forwarding response to client: %s", err)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Infof(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, string(plaintext)))
|
|
||||||
}(addr, buf, n)
|
}(addr, buf, n)
|
||||||
}
|
}
|
||||||
}(port, dest)
|
}(port, dest)
|
||||||
|
|
Loading…
Reference in New Issue