From bf27627bd09c7ba1215d513efe7e427165c6cf68 Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Tue, 17 Jan 2023 15:43:07 +0800 Subject: [PATCH] controller: Add reading PAA cert from spiffs partition --- .../esp_matter_controller/CMakeLists.txt | 6 +- components/esp_matter_controller/Kconfig | 19 +++ .../esp_matter_attestation_trust_store.cpp | 147 ++++++++++++++++++ .../esp_matter_attestation_trust_store.h | 70 +++++++++ .../esp_matter_commissioner.cpp | 4 +- examples/controller/main/CMakeLists.txt | 2 + .../paa_cert/Chip-Test-PAA-FFF1-Cert.der | Bin 0 -> 449 bytes .../paa_cert/Chip-Test-PAA-NoVID-Cert.der | Bin 0 -> 405 bytes examples/controller/paa_cert/DCL-ESP-Cert.der | Bin 0 -> 524 bytes examples/controller/partitions.csv | 2 +- 10 files changed, 245 insertions(+), 5 deletions(-) create mode 100644 components/esp_matter_controller/esp_matter_attestation_trust_store.cpp create mode 100644 components/esp_matter_controller/esp_matter_attestation_trust_store.h create mode 100644 examples/controller/paa_cert/Chip-Test-PAA-FFF1-Cert.der create mode 100644 examples/controller/paa_cert/Chip-Test-PAA-NoVID-Cert.der create mode 100644 examples/controller/paa_cert/DCL-ESP-Cert.der diff --git a/components/esp_matter_controller/CMakeLists.txt b/components/esp_matter_controller/CMakeLists.txt index 742261fe7..a0dffa673 100644 --- a/components/esp_matter_controller/CMakeLists.txt +++ b/components/esp_matter_controller/CMakeLists.txt @@ -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) diff --git a/components/esp_matter_controller/Kconfig b/components/esp_matter_controller/Kconfig index 776f07a64..10ec8f30b 100644 --- a/components/esp_matter_controller/Kconfig +++ b/components/esp_matter_controller/Kconfig @@ -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 diff --git a/components/esp_matter_controller/esp_matter_attestation_trust_store.cpp b/components/esp_matter_controller/esp_matter_attestation_trust_store.cpp new file mode 100644 index 000000000..25eef3127 --- /dev/null +++ b/components/esp_matter_controller/esp_matter_attestation_trust_store.cpp @@ -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 +#include +#include +#include +#include + +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 diff --git a/components/esp_matter_controller/esp_matter_attestation_trust_store.h b/components/esp_matter_controller/esp_matter_attestation_trust_store.h new file mode 100644 index 000000000..407dbdede --- /dev/null +++ b/components/esp_matter_controller/esp_matter_attestation_trust_store.h @@ -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 +#include +#include +#include +#include + +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 diff --git a/components/esp_matter_controller/esp_matter_commissioner.cpp b/components/esp_matter_controller/esp_matter_commissioner.cpp index c4179073c..40af94724 100644 --- a/components/esp_matter_controller/esp_matter_commissioner.cpp +++ b/components/esp_matter_controller/esp_matter_commissioner.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -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 noc; diff --git a/examples/controller/main/CMakeLists.txt b/examples/controller/main/CMakeLists.txt index a03b23614..9817cc53c 100644 --- a/examples/controller/main/CMakeLists.txt +++ b/examples/controller/main/CMakeLists.txt @@ -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") diff --git a/examples/controller/paa_cert/Chip-Test-PAA-FFF1-Cert.der b/examples/controller/paa_cert/Chip-Test-PAA-FFF1-Cert.der new file mode 100644 index 0000000000000000000000000000000000000000..cb287bf8862bd4b41ea277a6415b94375bc55a3f GIT binary patch literal 449 zcmXqLV%%%c#F(;xnTe5!iNkNj3&W->GBO5SY#dr`9_MUXn3)U=3?&T2*qB3En0fep z6H7``ixfgqi%S#&932fs420OYwAmP07@HQ=FfsD5xVgC*8YqbK8W|dx8Ce*b7#W)w zM@jHo0)e5CF%X$rnp#GYVP>R(FdIAAO-zhX$1yXqGdnS`Y&)G?)KRag@pab;sg*aa z9y!abU3q<;ihini-OqD3jTZHtW!|+utN)aQmsEhM(==XJdjorUNhjG-x&D5sS+h$Q zrx~OGy}=wRE6m9FpM}GK4M;IDG8*uK#P~sCz+hlxGmr)G`B=nQM6&)WmCFapzu7P5 zI6Yn9&K<*rg>?qZE=&pms~VWT+%#IbfYst#aK>8x|0mw> zKDlrEt*{xU=VvVs+T;xWdcq8|bZi4*)Jf Bf!6>4 literal 0 HcmV?d00001 diff --git a/examples/controller/paa_cert/Chip-Test-PAA-NoVID-Cert.der b/examples/controller/paa_cert/Chip-Test-PAA-NoVID-Cert.der new file mode 100644 index 0000000000000000000000000000000000000000..44898404bc0a27915efe438729d207e5fbabd0c0 GIT binary patch literal 405 zcmXqLVw`Bu#Av>NnTe5!iJiND*NVGs?+m!uIJDY4&e^gsGZ{!3N*IW-F^94+^YHs7 zmXxFxDTJgJmnZ}{IvOa5^BNf%m>F3Zniv_I7)MF)TLOWhkueaNTAEr$;nf{!Ak4-N zwugxkY9TWtJF^o5i@vBb$LNh|k9&#v)P?^PF`@cE4Z#@yV+aPCLKK%xJo5APPC fo$Jl((z~`y==+P92tE75LU$x8eJ>Xm#>D~v7YTvh literal 0 HcmV?d00001 diff --git a/examples/controller/paa_cert/DCL-ESP-Cert.der b/examples/controller/paa_cert/DCL-ESP-Cert.der new file mode 100644 index 0000000000000000000000000000000000000000..f4299e6374d6c87072bf37fa3ca8d4269f089794 GIT binary patch literal 524 zcmXqLV&X7pVqCX?nTe5!Ng#vCDd4V0hr^l;&pdVsh1(c#v2kd%d7QIlVP-N2G?X=v zW@8RzVdfEWEiNcZEiTSXQ}9hJDM>9-2yk>XlroS2NptZCBBX;Wi%U{-iw#8#gxI*W z*%(SDm>8knV`gM$c4A=ZUdA2T%8`DqIQjF;ZO3;O9r_h?BlfF&N8hy4{w0n2+R|rt zyuIVq7Q(*a+7yw=Rv%^?iZ5$@FwwEwQ);f4oPW{cG=mhNKbb>ig&7(Dvv3%&0VyU% zMgw_}m@9>C(%}tw%#AymwXKvw2tH0|Qx*0zMWo7VOe|AZdP(nZSr( zY(tI~W)B7fS0+V