mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 19:13:13 +00:00
controller: Add reading PAA cert from spiffs partition
This commit is contained in:
@@ -7,10 +7,12 @@ if (CONFIG_ESP_MATTER_CONTROLLER_ENABLE)
|
||||
endif()
|
||||
|
||||
if (NOT CONFIG_ESP_MATTER_COMMISSIONER_ENABLE)
|
||||
list(APPEND exclude_srcs_list esp_matter_commissioner.cpp esp_matter_controller_pairing_command.cpp)
|
||||
list(APPEND exclude_srcs_list esp_matter_commissioner.cpp
|
||||
esp_matter_controller_pairing_command.cpp
|
||||
esp_matter_attestation_trust_store.cpp)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRC_DIRS ${src_dirs_list}
|
||||
EXCLUDE_SRCS ${exclude_srcs_list}
|
||||
INCLUDE_DIRS ${include_dirs_list}
|
||||
REQUIRES chip esp_matter esp_matter_console json_parser)
|
||||
REQUIRES chip esp_matter esp_matter_console json_parser spiffs)
|
||||
|
||||
@@ -20,4 +20,23 @@ menu "ESP Matter Controller"
|
||||
help
|
||||
Maximum number of active device the commissioner supports.
|
||||
|
||||
choice ESP_MATTER_COMMISSIONER_ATTESTATION_TRUST_STORE
|
||||
prompt "Attestation Trust Store"
|
||||
depends on ESP_MATTER_COMMISSIONER_ENABLE
|
||||
default TEST_ATTESTATION_TRUST_STORE
|
||||
help
|
||||
This option determines where the commissioner reads PAA trust root certificate.
|
||||
|
||||
config TEST_ATTESTATION_TRUST_STORE
|
||||
bool "Attestation Trust Store - Test"
|
||||
help
|
||||
Use the two hardcoded PAA certificates(Chip-Test-PAA-FFF1-Cert&Chip-Test-PAA-NoVID-Cert) in the firmware.
|
||||
|
||||
config SPIFFS_ATTESTATION_TRUST_STORE
|
||||
bool "Attestation Trust Store - Spiffs"
|
||||
help
|
||||
Read the PAA root certificates from the spiffs partition
|
||||
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
// Copyright 2023 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
|
||||
#include <esp_check.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_matter_attestation_trust_store.h>
|
||||
#include <esp_spiffs.h>
|
||||
|
||||
const char TAG[] = "spiffs_attestation";
|
||||
|
||||
namespace chip {
|
||||
namespace Credentials {
|
||||
|
||||
static const char *get_filename_extension(const char *filename)
|
||||
{
|
||||
const char *dot = strrchr(filename, '.');
|
||||
if (!dot || dot == filename) {
|
||||
return "";
|
||||
}
|
||||
return dot + 1;
|
||||
}
|
||||
|
||||
paa_der_cert_iterator::paa_der_cert_iterator(const char *path)
|
||||
{
|
||||
strncpy(m_path, path, strnlen(path, 16));
|
||||
m_path[15] = 0;
|
||||
m_dir = opendir(path);
|
||||
if (!m_dir) {
|
||||
ESP_LOGE(TAG, "Failed to open the directory");
|
||||
return;
|
||||
}
|
||||
m_count = 0;
|
||||
m_index = 0;
|
||||
dirent *entry = NULL;
|
||||
while ((entry = readdir(m_dir)) != NULL) {
|
||||
const char *extension = get_filename_extension(entry->d_name);
|
||||
if (strncmp(extension, "der", strlen("der")) == 0) {
|
||||
m_count++;
|
||||
}
|
||||
}
|
||||
if (m_count == 0) {
|
||||
ESP_LOGE(TAG, "No DER file in the directory");
|
||||
closedir(m_dir);
|
||||
m_dir = NULL;
|
||||
} else {
|
||||
rewinddir(m_dir);
|
||||
}
|
||||
}
|
||||
|
||||
bool paa_der_cert_iterator::next(paa_der_cert_t &item)
|
||||
{
|
||||
dirent *entry = NULL;
|
||||
if (m_index >= m_count) {
|
||||
return false;
|
||||
}
|
||||
while ((entry = readdir(m_dir)) != NULL) {
|
||||
const char *extension = get_filename_extension(entry->d_name);
|
||||
if (strncmp(extension, "der", strlen("der")) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!entry) {
|
||||
return false;
|
||||
}
|
||||
m_index++;
|
||||
char filename[280] = {0};
|
||||
snprintf(filename, sizeof(filename), "%s/%s", m_path, entry->d_name);
|
||||
FILE *file = fopen(filename, "rb");
|
||||
if (file == nullptr) {
|
||||
item.m_len = 0;
|
||||
return true;
|
||||
}
|
||||
item.m_len = fread(item.m_buffer, sizeof(uint8_t), kMaxDERCertLength, file);
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
void paa_der_cert_iterator::release()
|
||||
{
|
||||
if (m_dir) {
|
||||
closedir(m_dir);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t spiffs_attestation_trust_store::init()
|
||||
{
|
||||
esp_vfs_spiffs_conf_t conf = {
|
||||
.base_path = "/paa", .partition_label = nullptr, .max_files = 5, .format_if_mount_failed = false};
|
||||
ESP_RETURN_ON_ERROR(esp_vfs_spiffs_register(&conf), TAG, "Failed to initialize SPIFFS");
|
||||
size_t total = 0, used = 0;
|
||||
ESP_RETURN_ON_ERROR(esp_spiffs_info(conf.partition_label, &total, &used), TAG, "Failed to get SPIFFS info");
|
||||
ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
|
||||
m_is_initialized = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
CHIP_ERROR spiffs_attestation_trust_store::GetProductAttestationAuthorityCert(const ByteSpan &skid,
|
||||
MutableByteSpan &outPaaDerBuffer) const
|
||||
{
|
||||
if (m_is_initialized) {
|
||||
paa_der_cert_iterator iter("/paa");
|
||||
paa_der_cert_t paa_cert;
|
||||
while (iter.next(paa_cert)) {
|
||||
if (paa_cert.m_len == 0) {
|
||||
continue;
|
||||
}
|
||||
uint8_t skid_buf[Crypto::kSubjectKeyIdentifierLength] = {0};
|
||||
MutableByteSpan skid_span{skid_buf};
|
||||
if (CHIP_NO_ERROR !=
|
||||
Crypto::ExtractSKIDFromX509Cert(ByteSpan{paa_cert.m_buffer, paa_cert.m_len}, skid_span)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skid.data_equal(skid_span)) {
|
||||
return CopySpanToMutableSpan(ByteSpan{paa_cert.m_buffer, paa_cert.m_len}, outPaaDerBuffer);
|
||||
}
|
||||
}
|
||||
return CHIP_ERROR_CA_CERT_NOT_FOUND;
|
||||
}
|
||||
return CHIP_ERROR_INCORRECT_STATE;
|
||||
}
|
||||
|
||||
const AttestationTrustStore *get_attestation_trust_store()
|
||||
{
|
||||
// TODO: Fetch the PAA certificates from DCL
|
||||
#if CONFIG_TEST_ATTESTATION_TRUST_STORE
|
||||
return GetTestAttestationTrustStore();
|
||||
#elif CONFIG_SPIFFS_ATTESTATION_TRUST_STORE
|
||||
spiffs_attestation_trust_store::get_instance().init();
|
||||
return &spiffs_attestation_trust_store::get_instance();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Credentials
|
||||
} // namespace chip
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright 2023 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <credentials/CHIPCert.h>
|
||||
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
|
||||
#include <dirent.h>
|
||||
#include <esp_err.h>
|
||||
#include <lib/support/IntrusiveList.h>
|
||||
|
||||
namespace chip {
|
||||
namespace Credentials {
|
||||
|
||||
typedef struct paa_der_cert {
|
||||
uint8_t m_buffer[kMaxDERCertLength] = {0};
|
||||
size_t m_len = 0;
|
||||
} paa_der_cert_t;
|
||||
|
||||
class paa_der_cert_iterator {
|
||||
public:
|
||||
paa_der_cert_iterator(const char *path);
|
||||
~paa_der_cert_iterator() { release(); };
|
||||
size_t count() { return m_count; }
|
||||
bool next(paa_der_cert_t &item);
|
||||
void release();
|
||||
|
||||
private:
|
||||
DIR *m_dir = NULL;
|
||||
char m_path[16] = {0};
|
||||
size_t m_count = 0;
|
||||
size_t m_index = 0;
|
||||
};
|
||||
|
||||
class spiffs_attestation_trust_store : public AttestationTrustStore {
|
||||
public:
|
||||
spiffs_attestation_trust_store(spiffs_attestation_trust_store &other) = delete;
|
||||
void operator=(const spiffs_attestation_trust_store &) = delete;
|
||||
|
||||
static spiffs_attestation_trust_store &get_instance()
|
||||
{
|
||||
static spiffs_attestation_trust_store instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
CHIP_ERROR GetProductAttestationAuthorityCert(const ByteSpan &skid,
|
||||
MutableByteSpan &outPaaDerBuffer) const override;
|
||||
|
||||
esp_err_t init();
|
||||
|
||||
private:
|
||||
bool m_is_initialized = false;
|
||||
spiffs_attestation_trust_store() {}
|
||||
};
|
||||
|
||||
const AttestationTrustStore *get_attestation_trust_store();
|
||||
|
||||
} // namespace Credentials
|
||||
} // namespace chip
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
|
||||
#include <crypto/CHIPCryptoPAL.h>
|
||||
#include <esp_heap_caps.h>
|
||||
#include <esp_matter_attestation_trust_store.h>
|
||||
#include <esp_matter_commissioner.h>
|
||||
#include <esp_matter_controller_pairing_command.h>
|
||||
#include <lib/support/TestGroupData.h>
|
||||
@@ -119,8 +120,7 @@ esp_err_t init(uint16_t commissioner_port)
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// TODO: Root Store using spiffs
|
||||
const Credentials::AttestationTrustStore *testingRootStore = Credentials::GetTestAttestationTrustStore();
|
||||
const Credentials::AttestationTrustStore *testingRootStore = Credentials::get_attestation_trust_store();
|
||||
SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore));
|
||||
|
||||
Platform::ScopedMemoryBuffer<uint8_t> noc;
|
||||
|
||||
@@ -4,5 +4,7 @@ idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES ${PRIV_REQUIRES_LIST})
|
||||
|
||||
spiffs_create_partition_image(paa_cert ${CMAKE_SOURCE_DIR}/paa_cert FLASH_IN_PROJECT)
|
||||
|
||||
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 14)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-DLWIP_IPV6_SCOPES=0" "-DCHIP_HAVE_CONFIG_H")
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -6,4 +6,4 @@ otadata, data, ota, , 0x2000
|
||||
phy_init, data, phy, , 0x1000,
|
||||
ota_0, app, ota_0, 0x20000, 0x1E0000,
|
||||
ota_1, app, ota_1, 0x200000, 0x1E0000,
|
||||
fctry, data, nvs, 0x3E0000, 0x6000
|
||||
paa_cert, data, spiffs, , 0x20000
|
||||
|
||||
|
Reference in New Issue
Block a user