[api] Fix potential buffer overflow in noise PSK base64 decode (#12395)
This commit is contained in:
committed by
Jonathan Swoboda
parent
1d13d18a16
commit
78b76045ce
@@ -1669,7 +1669,7 @@ bool APIConnection::send_noise_encryption_set_key_response(const NoiseEncryption
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Failed to clear encryption key");
|
||||
}
|
||||
} else if (base64_decode(msg.key, psk.data(), msg.key.size()) != psk.size()) {
|
||||
} else if (base64_decode(msg.key, psk.data(), psk.size()) != psk.size()) {
|
||||
ESP_LOGW(TAG, "Invalid encryption key length");
|
||||
} else if (!this->parent_->save_noise_psk(psk, true)) {
|
||||
ESP_LOGW(TAG, "Failed to save encryption key");
|
||||
|
||||
@@ -480,22 +480,13 @@ std::string base64_encode(const uint8_t *buf, size_t buf_len) {
|
||||
}
|
||||
|
||||
size_t base64_decode(const std::string &encoded_string, uint8_t *buf, size_t buf_len) {
|
||||
std::vector<uint8_t> decoded = base64_decode(encoded_string);
|
||||
if (decoded.size() > buf_len) {
|
||||
ESP_LOGW(TAG, "Base64 decode: buffer too small, truncating");
|
||||
decoded.resize(buf_len);
|
||||
}
|
||||
memcpy(buf, decoded.data(), decoded.size());
|
||||
return decoded.size();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> base64_decode(const std::string &encoded_string) {
|
||||
int in_len = encoded_string.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in = 0;
|
||||
size_t out = 0;
|
||||
uint8_t char_array_4[4], char_array_3[3];
|
||||
std::vector<uint8_t> ret;
|
||||
bool truncated = false;
|
||||
|
||||
// SAFETY: The loop condition checks is_base64() before processing each character.
|
||||
// This ensures base64_find_char() is only called on valid base64 characters,
|
||||
@@ -511,8 +502,13 @@ std::vector<uint8_t> base64_decode(const std::string &encoded_string) {
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (i = 0; (i < 3); i++)
|
||||
ret.push_back(char_array_3[i]);
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (out < buf_len) {
|
||||
buf[out++] = char_array_3[i];
|
||||
} else {
|
||||
truncated = true;
|
||||
}
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
@@ -528,10 +524,28 @@ std::vector<uint8_t> base64_decode(const std::string &encoded_string) {
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (j = 0; (j < i - 1); j++)
|
||||
ret.push_back(char_array_3[j]);
|
||||
for (j = 0; j < i - 1; j++) {
|
||||
if (out < buf_len) {
|
||||
buf[out++] = char_array_3[j];
|
||||
} else {
|
||||
truncated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (truncated) {
|
||||
ESP_LOGW(TAG, "Base64 decode: buffer too small, truncating");
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> base64_decode(const std::string &encoded_string) {
|
||||
// Calculate maximum decoded size: every 4 base64 chars = 3 bytes
|
||||
size_t max_len = ((encoded_string.size() + 3) / 4) * 3;
|
||||
std::vector<uint8_t> ret(max_len);
|
||||
size_t actual_len = base64_decode(encoded_string, ret.data(), max_len);
|
||||
ret.resize(actual_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user