mirror of
https://github.com/esphome/esphome.git
synced 2026-10-07 03:16:37 +00:00
[api] Add zero-copy support for noise encryption key requests
This commit is contained in:
@@ -747,7 +747,7 @@ message NoiseEncryptionSetKeyRequest {
|
|||||||
option (source) = SOURCE_CLIENT;
|
option (source) = SOURCE_CLIENT;
|
||||||
option (ifdef) = "USE_API_NOISE";
|
option (ifdef) = "USE_API_NOISE";
|
||||||
|
|
||||||
bytes key = 1;
|
bytes key = 1 [(pointer_to_buffer) = true];
|
||||||
}
|
}
|
||||||
|
|
||||||
message NoiseEncryptionSetKeyResponse {
|
message NoiseEncryptionSetKeyResponse {
|
||||||
|
|||||||
@@ -1663,13 +1663,13 @@ bool APIConnection::send_noise_encryption_set_key_response(const NoiseEncryption
|
|||||||
resp.success = false;
|
resp.success = false;
|
||||||
|
|
||||||
psk_t psk{};
|
psk_t psk{};
|
||||||
if (msg.key.empty()) {
|
if (msg.key_len == 0) {
|
||||||
if (this->parent_->clear_noise_psk(true)) {
|
if (this->parent_->clear_noise_psk(true)) {
|
||||||
resp.success = true;
|
resp.success = true;
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "Failed to clear encryption key");
|
ESP_LOGW(TAG, "Failed to clear encryption key");
|
||||||
}
|
}
|
||||||
} else if (base64_decode(msg.key, psk.data(), psk.size()) != psk.size()) {
|
} else if (base64_decode(msg.key, msg.key_len, psk.data(), psk.size()) != psk.size()) {
|
||||||
ESP_LOGW(TAG, "Invalid encryption key length");
|
ESP_LOGW(TAG, "Invalid encryption key length");
|
||||||
} else if (!this->parent_->save_noise_psk(psk, true)) {
|
} else if (!this->parent_->save_noise_psk(psk, true)) {
|
||||||
ESP_LOGW(TAG, "Failed to save encryption key");
|
ESP_LOGW(TAG, "Failed to save encryption key");
|
||||||
|
|||||||
@@ -858,9 +858,12 @@ void SubscribeLogsResponse::calculate_size(ProtoSize &size) const {
|
|||||||
#ifdef USE_API_NOISE
|
#ifdef USE_API_NOISE
|
||||||
bool NoiseEncryptionSetKeyRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
|
bool NoiseEncryptionSetKeyRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
|
||||||
switch (field_id) {
|
switch (field_id) {
|
||||||
case 1:
|
case 1: {
|
||||||
this->key = value.as_string();
|
// Use raw data directly to avoid allocation
|
||||||
|
this->key = value.data();
|
||||||
|
this->key_len = value.size();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1054,11 +1054,12 @@ class SubscribeLogsResponse final : public ProtoMessage {
|
|||||||
class NoiseEncryptionSetKeyRequest final : public ProtoDecodableMessage {
|
class NoiseEncryptionSetKeyRequest final : public ProtoDecodableMessage {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t MESSAGE_TYPE = 124;
|
static constexpr uint8_t MESSAGE_TYPE = 124;
|
||||||
static constexpr uint8_t ESTIMATED_SIZE = 9;
|
static constexpr uint8_t ESTIMATED_SIZE = 19;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
const char *message_name() const override { return "noise_encryption_set_key_request"; }
|
const char *message_name() const override { return "noise_encryption_set_key_request"; }
|
||||||
#endif
|
#endif
|
||||||
std::string key{};
|
const uint8_t *key{nullptr};
|
||||||
|
uint16_t key_len{0};
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
void dump_to(std::string &out) const override;
|
void dump_to(std::string &out) const override;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1115,7 +1115,7 @@ void SubscribeLogsResponse::dump_to(std::string &out) const {
|
|||||||
void NoiseEncryptionSetKeyRequest::dump_to(std::string &out) const {
|
void NoiseEncryptionSetKeyRequest::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "NoiseEncryptionSetKeyRequest");
|
MessageDumpHelper helper(out, "NoiseEncryptionSetKeyRequest");
|
||||||
out.append(" key: ");
|
out.append(" key: ");
|
||||||
out.append(format_hex_pretty(reinterpret_cast<const uint8_t *>(this->key.data()), this->key.size()));
|
out.append(format_hex_pretty(this->key, this->key_len));
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
}
|
}
|
||||||
void NoiseEncryptionSetKeyResponse::dump_to(std::string &out) const { dump_field(out, "success", this->success); }
|
void NoiseEncryptionSetKeyResponse::dump_to(std::string &out) const { dump_field(out, "success", this->success); }
|
||||||
|
|||||||
@@ -473,10 +473,14 @@ 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) {
|
size_t base64_decode(const std::string &encoded_string, uint8_t *buf, size_t buf_len) {
|
||||||
int in_len = encoded_string.size();
|
return base64_decode(reinterpret_cast<const uint8_t *>(encoded_string.data()), encoded_string.size(), buf, buf_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t base64_decode(const uint8_t *encoded_data, size_t encoded_len, uint8_t *buf, size_t buf_len) {
|
||||||
|
size_t in_len = encoded_len;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
int in = 0;
|
size_t in = 0;
|
||||||
size_t out = 0;
|
size_t out = 0;
|
||||||
uint8_t char_array_4[4], char_array_3[3];
|
uint8_t char_array_4[4], char_array_3[3];
|
||||||
bool truncated = false;
|
bool truncated = false;
|
||||||
@@ -484,8 +488,8 @@ size_t base64_decode(const std::string &encoded_string, uint8_t *buf, size_t buf
|
|||||||
// SAFETY: The loop condition checks is_base64() before processing each character.
|
// SAFETY: The loop condition checks is_base64() before processing each character.
|
||||||
// This ensures base64_find_char() is only called on valid base64 characters,
|
// This ensures base64_find_char() is only called on valid base64 characters,
|
||||||
// preventing the edge case where invalid chars would return 0 (same as 'A').
|
// preventing the edge case where invalid chars would return 0 (same as 'A').
|
||||||
while (in_len-- && (encoded_string[in] != '=') && is_base64(encoded_string[in])) {
|
while (in_len-- && (encoded_data[in] != '=') && is_base64(encoded_data[in])) {
|
||||||
char_array_4[i++] = encoded_string[in];
|
char_array_4[i++] = encoded_data[in];
|
||||||
in++;
|
in++;
|
||||||
if (i == 4) {
|
if (i == 4) {
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
|
|||||||
@@ -855,6 +855,7 @@ std::string base64_encode(const std::vector<uint8_t> &buf);
|
|||||||
|
|
||||||
std::vector<uint8_t> base64_decode(const std::string &encoded_string);
|
std::vector<uint8_t> base64_decode(const std::string &encoded_string);
|
||||||
size_t base64_decode(std::string const &encoded_string, uint8_t *buf, size_t buf_len);
|
size_t base64_decode(std::string const &encoded_string, uint8_t *buf, size_t buf_len);
|
||||||
|
size_t base64_decode(const uint8_t *encoded_data, size_t encoded_len, uint8_t *buf, size_t buf_len);
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user