diff --git a/esphome/components/nfc/ndef_message.cpp b/esphome/components/nfc/ndef_message.cpp index d7d134aedb..461856d377 100644 --- a/esphome/components/nfc/ndef_message.cpp +++ b/esphome/components/nfc/ndef_message.cpp @@ -44,6 +44,11 @@ NdefMessage::NdefMessage(std::vector &data) { index += id_length; } + if ((data.begin() + index > data.end()) || (data.begin() + index + payload_length > data.end())) { + ESP_LOGE(TAG, "Corrupt record encountered; NdefMessage constructor aborting"); + break; + } + std::vector payload_data(data.begin() + index, data.begin() + index + payload_length); std::unique_ptr record; diff --git a/esphome/components/nfc/ndef_record.h b/esphome/components/nfc/ndef_record.h index 27083fdaca..20542bf24b 100644 --- a/esphome/components/nfc/ndef_record.h +++ b/esphome/components/nfc/ndef_record.h @@ -42,8 +42,8 @@ class NdefRecord { virtual const std::string &get_payload() const { return this->payload_; }; virtual std::vector get_encoded_payload() { - std::vector empty_payload; - return empty_payload; + std::vector payload(this->payload_.begin(), this->payload_.end()); + return payload; }; protected: diff --git a/esphome/components/nfc/nfc.cpp b/esphome/components/nfc/nfc.cpp index 09dbdcfe94..b7c7215028 100644 --- a/esphome/components/nfc/nfc.cpp +++ b/esphome/components/nfc/nfc.cpp @@ -89,18 +89,18 @@ uint32_t get_mifare_classic_buffer_size(uint32_t message_length) { } bool mifare_classic_is_first_block(uint8_t block_num) { - if (block_num < 128) { - return (block_num % 4 == 0); + if (block_num < MIFARE_CLASSIC_BLOCKS_PER_SECT_LOW * MIFARE_CLASSIC_16BLOCK_SECT_START) { + return (block_num % MIFARE_CLASSIC_BLOCKS_PER_SECT_LOW == 0); } else { - return (block_num % 16 == 0); + return (block_num % MIFARE_CLASSIC_BLOCKS_PER_SECT_HIGH == 0); } } bool mifare_classic_is_trailer_block(uint8_t block_num) { - if (block_num < 128) { - return ((block_num + 1) % 4 == 0); + if (block_num < MIFARE_CLASSIC_BLOCKS_PER_SECT_LOW * MIFARE_CLASSIC_16BLOCK_SECT_START) { + return ((block_num + 1) % MIFARE_CLASSIC_BLOCKS_PER_SECT_LOW == 0); } else { - return ((block_num + 1) % 16 == 0); + return ((block_num + 1) % MIFARE_CLASSIC_BLOCKS_PER_SECT_HIGH == 0); } } diff --git a/esphome/components/nfc/nfc.h b/esphome/components/nfc/nfc.h index 1a4e8f1c1d..d4d66f970f 100644 --- a/esphome/components/nfc/nfc.h +++ b/esphome/components/nfc/nfc.h @@ -14,6 +14,9 @@ namespace nfc { static const uint8_t MIFARE_CLASSIC_BLOCK_SIZE = 16; static const uint8_t MIFARE_CLASSIC_LONG_TLV_SIZE = 4; static const uint8_t MIFARE_CLASSIC_SHORT_TLV_SIZE = 2; +static const uint8_t MIFARE_CLASSIC_BLOCKS_PER_SECT_LOW = 4; +static const uint8_t MIFARE_CLASSIC_BLOCKS_PER_SECT_HIGH = 16; +static const uint8_t MIFARE_CLASSIC_16BLOCK_SECT_START = 32; static const uint8_t MIFARE_ULTRALIGHT_PAGE_SIZE = 4; static const uint8_t MIFARE_ULTRALIGHT_READ_SIZE = 4; @@ -30,10 +33,18 @@ static const uint8_t TAG_TYPE_UNKNOWN = 99; // Mifare Commands static const uint8_t MIFARE_CMD_AUTH_A = 0x60; static const uint8_t MIFARE_CMD_AUTH_B = 0x61; +static const uint8_t MIFARE_CMD_HALT = 0x50; static const uint8_t MIFARE_CMD_READ = 0x30; static const uint8_t MIFARE_CMD_WRITE = 0xA0; static const uint8_t MIFARE_CMD_WRITE_ULTRALIGHT = 0xA2; +// Mifare Ack/Nak +static const uint8_t MIFARE_CMD_ACK = 0x0A; +static const uint8_t MIFARE_CMD_NAK_INVALID_XFER_BUFF_VALID = 0x00; +static const uint8_t MIFARE_CMD_NAK_CRC_ERROR_XFER_BUFF_VALID = 0x01; +static const uint8_t MIFARE_CMD_NAK_INVALID_XFER_BUFF_INVALID = 0x04; +static const uint8_t MIFARE_CMD_NAK_CRC_ERROR_XFER_BUFF_INVALID = 0x05; + static const char *const MIFARE_CLASSIC = "Mifare Classic"; static const char *const NFC_FORUM_TYPE_2 = "NFC Forum Type 2"; static const char *const ERROR = "Error"; diff --git a/esphome/components/pn532/pn532_mifare_classic.cpp b/esphome/components/pn532/pn532_mifare_classic.cpp index 17d7aa123c..943f8c5519 100644 --- a/esphome/components/pn532/pn532_mifare_classic.cpp +++ b/esphome/components/pn532/pn532_mifare_classic.cpp @@ -52,7 +52,13 @@ std::unique_ptr PN532::read_mifare_classic_tag_(std::vector(uid, nfc::MIFARE_CLASSIC); + } + return make_unique(uid, nfc::MIFARE_CLASSIC, buffer); }