diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml index d30277a07..2010469e3 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples.yml @@ -196,7 +196,8 @@ jobs: - name: Blues Wireless Notecard - name: ArduinoBLE - name: Arduino_KVStore - - name: Arduino_NetworkConfigurator + - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git + version: c7c6f9d4973222c1126ac3e73959e20870102c1f sketch-paths: | - examples/ArduinoIoTCloud-NetConfig - examples/ArduinoIoTCloud-DeferredOTA @@ -213,7 +214,8 @@ jobs: - name: Blues Wireless Notecard - name: ArduinoBLE - name: Arduino_KVStore - - name: Arduino_NetworkConfigurator + - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git + version: c7c6f9d4973222c1126ac3e73959e20870102c1f sketch-paths: | - examples/ArduinoIoTCloud-NetConfig - examples/ArduinoIoTCloud-DeferredOTA @@ -232,7 +234,8 @@ jobs: - name: Blues Wireless Notecard - name: ArduinoBLE - name: Arduino_KVStore - - name: Arduino_NetworkConfigurator + - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git + version: c7c6f9d4973222c1126ac3e73959e20870102c1f sketch-paths: | - examples/ArduinoIoTCloud-NetConfig - examples/ArduinoIoTCloud-DeferredOTA @@ -251,7 +254,8 @@ jobs: - name: Blues Wireless Notecard - name: ArduinoBLE - name: Arduino_KVStore - - name: Arduino_NetworkConfigurator + - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git + version: c7c6f9d4973222c1126ac3e73959e20870102c1f sketch-paths: | - examples/ArduinoIoTCloud-NetConfig - examples/ArduinoIoTCloud-DeferredOTA @@ -269,7 +273,8 @@ jobs: - name: Blues Wireless Notecard - name: ArduinoBLE - name: Arduino_KVStore - - name: Arduino_NetworkConfigurator + - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git + version: c7c6f9d4973222c1126ac3e73959e20870102c1f sketch-paths: | - examples/ArduinoIoTCloud-NetConfig - examples/ArduinoIoTCloud-Notecard @@ -285,7 +290,8 @@ jobs: - name: Blues Wireless Notecard - name: ArduinoBLE - name: Arduino_KVStore - - name: Arduino_NetworkConfigurator + - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git + version: c7c6f9d4973222c1126ac3e73959e20870102c1f sketch-paths: | - examples/ArduinoIoTCloud-NetConfig - examples/ArduinoIoTCloud-Notecard diff --git a/.github/workflows/compile-provisioning.yml b/.github/workflows/compile-provisioning.yml new file mode 100644 index 000000000..089647058 --- /dev/null +++ b/.github/workflows/compile-provisioning.yml @@ -0,0 +1,243 @@ +name: Compile Provisioning + +on: + pull_request: + paths: + - ".github/workflows/compile-provisioning.yml" + - "examples/**" + - "src/**" + push: + paths: + - ".github/workflows/compile-provisioning.yml" + - "examples/**" + - "src/**" + +jobs: + build: + runs-on: ubuntu-latest + + env: + # libraries to install for all boards + UNIVERSAL_LIBRARIES: | + # Install the ArduinoIoTCloud library from the repository + - source-path: ./ + - name: ArduinoBLE + version: 1.4.0 + - name: ArduinoHttpClient + version: 0.6.1 + - name: Arduino_DebugUtils + version: 1.4.0 + - name: ArduinoMqttClient + version: 0.1.8 + - name: Arduino_KVStore + version: 1.0.0 + - name: Arduino_ConnectionHandler + version: 1.1.2 + - name: Arduino_SecureElement + version: 0.4.0 + - name: Arduino_CloudUtils + version: 1.1.1 + - source-url: https://github.com/arduino-libraries/Arduino_UniqueHWId.git + version: 7e1bfeb586cac00f043c39997a1e9937ed8152b0 + - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git + version: 6278b97dd9b8549e9a5b2f2aff1a35d4ae06501a + # sketch paths to compile (recursive) for all boards + UNIVERSAL_SKETCH_PATHS: | + - examples/utility/Provisioning_2.0 + SKETCHES_REPORTS_PATH: sketches-reports + + strategy: + fail-fast: false + + matrix: + board: + - fqbn: arduino:samd:mkrwifi1010 + type: nina + artifact-name-suffix: arduino-samd-mkrwifi1010 + - fqbn: arduino:samd:nano_33_iot + type: nina + artifact-name-suffix: arduino-samd-nano_33_iot + - fqbn: arduino:mbed_portenta:envie_m7:split=100_0 + type: mbed_portenta + artifact-name-suffix: arduino-mbed_portenta-envie_m7 + - fqbn: arduino:mbed_nano:nanorp2040connect + type: nina + artifact-name-suffix: arduino-mbed_nano-nanorp2040connect + - fqbn: arduino:mbed_nicla:nicla_vision + type: mbed_nicla + artifact-name-suffix: arduino-mbed_nicla-nicla_vision + - fqbn: arduino:mbed_opta:opta + type: mbed_opta + artifact-name-suffix: arduino-mbed_opta-opta + - fqbn: arduino:mbed_giga:giga + type: mbed_giga + artifact-name-suffix: arduino-mbed_giga-giga + - fqbn: arduino:renesas_portenta:portenta_c33 + type: renesas_portenta + artifact-name-suffix: arduino-renesas_portenta-portenta_c33 + - fqbn: arduino:renesas_uno:unor4wifi + type: renesas_uno + artifact-name-suffix: arduino-renesas_uno-unor4wifi + + # make board type-specific customizations to the matrix jobs + include: + # MKR WiFi 1010, Nano 33 IoT, Nano RP2040 Connect + - board: + type: nina + platforms: | + # Install samd and mbed_nano platform via Boards Manager + - name: arduino:samd + version: 1.8.14 + - name: arduino:mbed_nano + version: 4.2.4 + libraries: | + - name: RTCZero + version: 1.6.0 + - source-url: https://github.com/fabik111/ArduinoECCX08.git + version: df1480b6d379c5feaa5ce7853b9a24193a5fa084 + - name: Adafruit SleepyDog Library + version: 1.6.5 + - name: ArduinoBearSSL + version: 1.7.6 + - source-url: https://github.com/arduino-libraries/WiFiNINA.git + version: 69e786c5c73fe94b7f408853550f6f151cfc58b0 + # Portenta + - board: + type: mbed_portenta + platforms: | + # Install mbed_portenta platform via Boards Manager + - name: arduino:mbed_portenta + version: 4.2.4 + libraries: | + - name: Arduino_Cellular + version: 1.2.1 + - source-url: https://github.com/fabik111/ArduinoECCX08.git + version: df1480b6d379c5feaa5ce7853b9a24193a5fa084 + - name: ArduinoBearSSL + version: 1.7.6 + # Nicla Vision + - board: + type: mbed_nicla + platforms: | + # Install mbed_nicla platform via Boards Manager + - name: arduino:mbed_nicla + version: 4.2.4 + # Opta + - board: + type: mbed_opta + platforms: | + # Install mbed_opta platform via Boards Manager + - name: arduino:mbed_opta + version: 4.2.4 + libraries: | + - source-url: https://github.com/fabik111/ArduinoECCX08.git + version: df1480b6d379c5feaa5ce7853b9a24193a5fa084 + - name: ArduinoBearSSL + version: 1.7.6 + # GIGA + - board: + type: mbed_giga + platforms: | + # Install mbed_giga platform via Boards Manager + - name: arduino:mbed_giga + version: 4.2.4 + libraries: | + - source-url: https://github.com/fabik111/ArduinoECCX08.git + version: df1480b6d379c5feaa5ce7853b9a24193a5fa084 + - name: ArduinoBearSSL + version: 1.7.6 + # Portenta C33 + - board: + type: renesas_portenta + platforms: | + # Install renesas_portenta platform via Boards Manager + - name: arduino:renesas_portenta + version: 1.4.1 + libraries: | + - name: Arduino_Cellular + version: 1.2.1 + # UNO R4 WiFi + - board: + type: renesas_uno + platforms: | + # Install renesas_uno platform via Boards Manager + - name: arduino:renesas_uno + version: 1.4.1 + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Clear cache + run: | + rm -rf ~/.cache + - name: Compile production provisioning sketch + uses: arduino/compile-sketches@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + platforms: ${{ matrix.platforms }} + fqbn: ${{ matrix.board.fqbn }} + libraries: | + ${{ env.UNIVERSAL_LIBRARIES }} + ${{ matrix.libraries }} + sketch-paths: | + ${{ env.UNIVERSAL_SKETCH_PATHS }} + ${{ matrix.sketch-paths }} + enable-deltas-report: "true" + sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} + cli-compile-flags: | + - --clean + - --verbose + - --output-dir + - ${{ runner.temp }}/provisioning-prod + + - name: Compile staging provisioning sketch + uses: arduino/compile-sketches@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + platforms: ${{ matrix.platforms }} + fqbn: ${{ matrix.board.fqbn }} + libraries: | + ${{ env.UNIVERSAL_LIBRARIES }} + ${{ matrix.libraries }} + sketch-paths: | + ${{ env.UNIVERSAL_SKETCH_PATHS }} + ${{ matrix.sketch-paths }} + enable-deltas-report: "true" + sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} + cli-compile-flags: | + - --clean + - --verbose + - --build-property + - "build.extra_flags=-DCOMPILE_TEST=1" + - --output-dir + - ${{ runner.temp }}/provisioning-staging + + - name: Write data to size trends report spreadsheet + # Update report on every push to the master branch + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + uses: arduino/report-size-trends@main + with: + sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} + google-key-file: ${{ secrets.GOOGLE_KEY_FILE }} + spreadsheet-id: 1I6NZkpZpf8KugBkE92adB1Z3_b7ZepOpCdYTOigJpN4 + + - name: Save memory usage change report as artifact + if: github.event_name == 'pull_request' + uses: actions/upload-artifact@v4 + with: + name: sketches-report-${{ matrix.board.artifact-name-suffix }} + path: ${{ env.SKETCHES_REPORTS_PATH }} + + - name: Save production artifact + if: github.event_name == 'pull_request' + uses: actions/upload-artifact@v4 + with: + name: provisioning-prod-${{ matrix.board.artifact-name-suffix }} + path: ${{ runner.temp }}/provisioning-prod/ + + - name: Save staging artifact + if: github.event_name == 'pull_request' + uses: actions/upload-artifact@v4 + with: + name: provisioning-staging-${{ matrix.board.artifact-name-suffix }} + path: ${{ runner.temp }}/provisioning-staging/ diff --git a/examples/utility/Provisioning_2.0/ClaimingHandler.cpp b/examples/utility/Provisioning_2.0/ClaimingHandler.cpp index 7456f410b..9e42c6469 100644 --- a/examples/utility/Provisioning_2.0/ClaimingHandler.cpp +++ b/examples/utility/Provisioning_2.0/ClaimingHandler.cpp @@ -92,30 +92,47 @@ void ClaimingHandlerClass::poll() { } void ClaimingHandlerClass::getIdReqHandler() { - if (_ts != 0) { - byte _uhwidBytes[32]; - hex::decode(_uhwid->c_str(), _uhwidBytes, _uhwid->length()); - //Send UHWID - ProvisioningOutputMessage idMsg = {MessageOutputType::UHWID}; - idMsg.m.uhwid = _uhwidBytes; - _agentManager.sendMsg(idMsg); - - String token = getAIoTCloudJWT(*_secureElement, *_uhwid, _ts, 1); - if (token == "") { - DEBUG_ERROR("CH::%s Error: token not created", __FUNCTION__); - sendStatus(StatusMessage::ERROR); - return; - } - - //Send JWT - ProvisioningOutputMessage jwtMsg = {MessageOutputType::JWT}; - jwtMsg.m.jwt = token.c_str(); - _agentManager.sendMsg(jwtMsg); - _ts = 0; - } else { + if (_ts == 0) { DEBUG_ERROR("CH::%s Error: timestamp not provided" , __FUNCTION__); sendStatus(StatusMessage::PARAMS_NOT_FOUND); + return; + } + + byte _uhwidBytes[32]; + hex::decode(_uhwid->c_str(), _uhwidBytes, _uhwid->length()); + + String token = generateToken(); + if (token == "") { + DEBUG_ERROR("CH::%s Error: token not created", __FUNCTION__); + sendStatus(StatusMessage::ERROR); + return; + } + + SElementJWS sejws; + String publicKey = sejws.publicKey(*_secureElement, 1, false); + if (publicKey == "") { + DEBUG_ERROR("CH::%s Error: public key not created", __FUNCTION__); + sendStatus(StatusMessage::ERROR); + return; } + + //Send public key + ProvisioningOutputMessage publicKeyMsg = {MessageOutputType::PROV_PUBLIC_KEY}; + publicKeyMsg.m.provPublicKey = publicKey.c_str(); + _agentManager.sendMsg(publicKeyMsg); + + + //Send UHWID + ProvisioningOutputMessage idMsg = {MessageOutputType::UHWID}; + idMsg.m.uhwid = _uhwidBytes; + _agentManager.sendMsg(idMsg); + + //Send JWT + ProvisioningOutputMessage jwtMsg = {MessageOutputType::JWT}; + jwtMsg.m.jwt = token.c_str(); + _agentManager.sendMsg(jwtMsg); + _ts = 0; + } void ClaimingHandlerClass::resetStoredCredReqHandler() { @@ -186,7 +203,24 @@ void ClaimingHandlerClass::getProvSketchVersionRequestCb() { _receivedEvent = ClaimingReqEvents::GET_PROV_SKETCH_VERSION; } -bool ClaimingHandlerClass::sendStatus(StatusMessage msg) { - ProvisioningOutputMessage statusMsg = { MessageOutputType::STATUS, { msg } }; - return _agentManager.sendMsg(statusMsg); +String ClaimingHandlerClass::generateToken() +{ + String token = getAIoTCloudJWT(*_secureElement, *_uhwid, _ts, 1); + if(token == "") { + byte publicKey[64]; + DEBUG_INFO("Generating private key"); + if(!_secureElement->generatePrivateKey(1, publicKey)){ + DEBUG_ERROR("CH::%s Error: private key generation failed", __FUNCTION__); + return ""; + } + token = getAIoTCloudJWT(*_secureElement, *_uhwid, _ts, 1); + } + + return token; +} + +bool ClaimingHandlerClass::sendStatus(StatusMessage msg) +{ + ProvisioningOutputMessage statusMsg = {MessageOutputType::STATUS, {msg}}; + return _agentManager.sendMsg(statusMsg); } diff --git a/examples/utility/Provisioning_2.0/ClaimingHandler.h b/examples/utility/Provisioning_2.0/ClaimingHandler.h index 77f2ebea6..7b8693b36 100644 --- a/examples/utility/Provisioning_2.0/ClaimingHandler.h +++ b/examples/utility/Provisioning_2.0/ClaimingHandler.h @@ -36,6 +36,7 @@ class ClaimingHandlerClass { LEDFeedbackClass &_ledFeedback; static inline uint64_t _ts; SecureElement *_secureElement; + String generateToken(); bool sendStatus(StatusMessage msg); /* Commands handlers */ diff --git a/examples/utility/Provisioning_2.0/Provisioning_2.0.ino b/examples/utility/Provisioning_2.0/Provisioning_2.0.ino index 3ab02a278..976d99805 100644 --- a/examples/utility/Provisioning_2.0/Provisioning_2.0.ino +++ b/examples/utility/Provisioning_2.0/Provisioning_2.0.ino @@ -15,7 +15,7 @@ #include #include "utility/LEDFeedback.h" -const char *SKETCH_VERSION = "0.1.0"; +const char *SKETCH_VERSION = "0.3.0"; enum class DeviceState { HARDWARE_CHECK, @@ -59,7 +59,7 @@ void setup() { initProperties(); AgentsManagerClass::getInstance().begin(); LEDFeedbackClass::getInstance().begin(); - DEBUG_INFO("Starting Provisioning"); + DEBUG_INFO("Starting Provisioning version %s", SKETCH_VERSION); } void sendStatus(StatusMessage msg) {