Skip to content
Merged
121 changes: 97 additions & 24 deletions src/ArduinoIoTCloudTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ ArduinoIoTCloudTCP::ArduinoIoTCloudTCP()
#ifdef BOARD_HAS_SECRET_KEY
, _password("")
#endif
#if defined(BOARD_HAS_SECURE_ELEMENT)
, _writeCertOnConnect(false)
#endif
, _mqttClient{nullptr}
, _messageTopicOut("")
, _messageTopicIn("")
Expand All @@ -80,11 +83,6 @@ int ArduinoIoTCloudTCP::begin(ConnectionHandler & connection, bool const enable_
{
_connection = &connection;
_brokerAddress = brokerAddress;
#ifdef BOARD_HAS_SECRET_KEY
_brokerPort = _password.length() ? DEFAULT_BROKER_PORT_USER_PASS_AUTH : brokerPort;
#else
_brokerPort = brokerPort;
#endif

/* Setup broker TLS client */
_brokerClient.begin(connection);
Expand All @@ -94,20 +92,7 @@ int ArduinoIoTCloudTCP::begin(ConnectionHandler & connection, bool const enable_
_otaClient.begin(connection);
#endif

/* Setup TimeService */
_time_service.begin(_connection);

/* Setup retry timers */
_connection_attempt.begin(AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms);
return begin(enable_watchdog, _brokerAddress, _brokerPort);
}

int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, uint16_t brokerPort)
{
_brokerAddress = brokerAddress;
_brokerPort = brokerPort;

#if defined(BOARD_HAS_SECRET_KEY)
#if defined (BOARD_HAS_SECRET_KEY)
/* If board is not configured for username and password login */
if(!_password.length())
{
Expand All @@ -129,23 +114,44 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
DEBUG_ERROR("ArduinoIoTCloudTCP::%s could not read device id.", __FUNCTION__);
return 0;
}
#if !defined(BOARD_HAS_OFFLOADED_ECCX08)
if (!SElementArduinoCloudCertificate::read(_selement, _cert, SElementArduinoCloudSlot::CompressedCertificate))
{
DEBUG_ERROR("ArduinoIoTCloudTCP::%s could not read device certificate.", __FUNCTION__);
return 0;
if (!_writeCertOnConnect) {
/* No update pending read certificate stored in secure element */
if (!SElementArduinoCloudCertificate::read(_selement, _cert, SElementArduinoCloudSlot::CompressedCertificate))
{
DEBUG_ERROR("ArduinoIoTCloudTCP::%s could not read device certificate.", __FUNCTION__);
return 0;
}
}
#if !defined(BOARD_HAS_OFFLOADED_ECCX08)
_brokerClient.setEccSlot(static_cast<int>(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length());
#if OTA_ENABLED
_otaClient.setEccSlot(static_cast<int>(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length());
#endif
#endif
_brokerPort = (brokerPort == DEFAULT_BROKER_PORT_AUTO) ? mqttPort() : brokerPort;
#endif

#if defined(BOARD_HAS_SECRET_KEY)
}
else
{
_brokerPort = (brokerPort == DEFAULT_BROKER_PORT_AUTO) ? DEFAULT_BROKER_PORT_USER_PASS_AUTH : brokerPort;
}
#endif

/* Setup TimeService */
_time_service.begin(_connection);

/* Setup retry timers */
_connection_attempt.begin(AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms);
return begin(enable_watchdog, _brokerAddress, _brokerPort);
}

int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, uint16_t brokerPort)
{
_brokerAddress = brokerAddress;
_brokerPort = brokerPort;

_mqttClient.setClient(_brokerClient);

#ifdef BOARD_HAS_SECRET_KEY
Expand Down Expand Up @@ -281,6 +287,17 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectMqttBroker()
/* Subscribe to message topic to receive commands */
_mqttClient.subscribe(_messageTopicIn);

#if defined(BOARD_HAS_SECURE_ELEMENT)
/* A device certificate update was pending */
if (_writeCertOnConnect)
{
if (SElementArduinoCloudCertificate::write(_selement, _cert, SElementArduinoCloudSlot::CompressedCertificate))
{
DEBUG_INFO("ArduinoIoTCloudTCP::%s device certificate update done.", __FUNCTION__);
_writeCertOnConnect = false;
}
}
#endif
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s connected to %s:%d", __FUNCTION__, _brokerAddress.c_str(), _brokerPort);
return State::Connected;
}
Expand Down Expand Up @@ -558,6 +575,62 @@ int ArduinoIoTCloudTCP::write(String const topic, byte const data[], int const l
return 0;
}

#if defined(BOARD_HAS_SECURE_ELEMENT)
int ArduinoIoTCloudTCP::mqttPort()
{
if (memcmp(DEPRECATED_BROKER_AUTHORITY_KEY_IDENTIFIER, _cert.authorityKeyIdentifierBytes() , ECP256_CERT_AUTHORITY_KEY_ID_LENGTH) == 0) {
return DEPRECATED_BROKER_PORT_SECURE_AUTH;
} else {
return DEFAULT_BROKER_PORT_SECURE_AUTH;
}
}

int ArduinoIoTCloudTCP::updateCertificate(String authorityKeyIdentifier, String serialNumber, String notBefore, String notAfter, String signature)
{
if (!_selement.begin())
{
DEBUG_ERROR("ArduinoIoTCloudTCP::%s could not initialize secure element.", __FUNCTION__);
#if defined(ARDUINO_UNOWIFIR4)
if (String(WiFi.firmwareVersion()) < String("0.4.1")) {
DEBUG_ERROR("ArduinoIoTCloudTCP::%s In order to read device certificate, WiFi firmware needs to be >= 0.4.1, current %s", __FUNCTION__, WiFi.firmwareVersion());
}
#endif
return 0;
}
if (!SElementArduinoCloudDeviceId::read(_selement, getDeviceId(), SElementArduinoCloudSlot::DeviceId))
{
DEBUG_ERROR("ArduinoIoTCloudTCP::%s could not read device id.", __FUNCTION__);
return 0;
}
/* read certificate stored in secure element to compare AUTHORITY_KEY_ID */
if (!SElementArduinoCloudCertificate::read(_selement, _cert, SElementArduinoCloudSlot::CompressedCertificate))
{
DEBUG_ERROR("ArduinoIoTCloudTCP::%s could not read device certificate.", __FUNCTION__);
return 0;
}
/* check if we need to update 0 = equal <0 = error skip rebuild */
if(SElementArduinoCloudCertificate::signatureCompare(_cert.signatureBytes(), signature) <= 0) {
DEBUG_INFO("ArduinoIoTCloudTCP::%s request skipped.", __FUNCTION__);
return 0;
}
/* rebuild device certificate */
if (SElementArduinoCloudCertificate::rebuild(_selement, _cert, getDeviceId(), notBefore, notAfter, serialNumber, authorityKeyIdentifier, signature))
{
DEBUG_INFO("ArduinoIoTCloudTCP::%s request started.", __FUNCTION__);
#if defined(BOARD_HAS_OFFLOADED_ECCX08)
if (SElementArduinoCloudCertificate::write(_selement, _cert, SElementArduinoCloudSlot::CompressedCertificate))
{
DEBUG_INFO("ArduinoIoTCloudTCP::%s update done.", __FUNCTION__);
}
#else
_writeCertOnConnect = true;
#endif
return 1;
}
return 0;
}
#endif

/******************************************************************************
* EXTERN DEFINITION
******************************************************************************/
Expand Down
37 changes: 24 additions & 13 deletions src/ArduinoIoTCloudTCP.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,14 @@
#if defined(BOARD_HAS_SECURE_ELEMENT)
#include <Arduino_SecureElement.h>
#include <utility/SElementArduinoCloudDeviceId.h>
#if !defined(BOARD_HAS_OFFLOADED_ECCX08)
#include <utility/SElementArduinoCloudCertificate.h>
#endif
#include <utility/SElementArduinoCloudCertificate.h>
#endif

#include <tls/utility/TLSClientMqtt.h>
#include <tls/utility/TLSClientOta.h>

#if OTA_ENABLED
#include <ota/OTA.h>
#include <ota/OTA.h>
#endif

#include "cbor/MessageDecoder.h"
Expand All @@ -49,9 +47,14 @@
/******************************************************************************
CONSTANTS
******************************************************************************/
static char const DEFAULT_BROKER_ADDRESS_SECURE_AUTH[] = "iot.arduino.cc";
static uint16_t const DEFAULT_BROKER_PORT_SECURE_AUTH = 8883;
static uint16_t const DEFAULT_BROKER_PORT_USER_PASS_AUTH = 8884;
static constexpr char DEFAULT_BROKER_ADDRESS[] = "iot.arduino.cc";
static constexpr uint16_t DEFAULT_BROKER_PORT_SECURE_AUTH = 8885;
static constexpr uint16_t DEPRECATED_BROKER_PORT_SECURE_AUTH = 8883;
static constexpr uint8_t DEPRECATED_BROKER_AUTHORITY_KEY_IDENTIFIER[] = {
0x5b, 0x3e, 0x2a, 0x6b, 0x8e, 0xc9, 0xb0, 0x1a, 0xa8, 0x54,
0xe6, 0x36, 0x9b, 0x8c, 0x09, 0xf9, 0xfc, 0xe1, 0xb9, 0x80 };
static constexpr uint16_t DEFAULT_BROKER_PORT_USER_PASS_AUTH = 8884;
static constexpr uint16_t DEFAULT_BROKER_PORT_AUTO = 0;

/******************************************************************************
* TYPEDEF
Expand All @@ -74,13 +77,17 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
virtual int connected () override;
virtual void printDebugInfo() override;

int begin(ConnectionHandler & connection, bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH);
int begin(bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH);
int begin(ConnectionHandler & connection, bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS, uint16_t brokerPort = DEFAULT_BROKER_PORT_AUTO);
int begin(bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS, uint16_t brokerPort = DEFAULT_BROKER_PORT_AUTO);

#ifdef BOARD_HAS_SECRET_KEY
#if defined(BOARD_HAS_SECURE_ELEMENT)
int updateCertificate(String authorityKeyIdentifier, String serialNumber, String notBefore, String notAfter, String signature);
#endif

#ifdef BOARD_HAS_SECRET_KEY
inline void setBoardId (String const device_id) { setDeviceId(device_id); }
inline void setSecretDeviceKey(String const password) { _password = password; }
#endif
#endif

inline String getBrokerAddress() const { return _brokerAddress; }
inline uint16_t getBrokerPort () const { return _brokerPort; }
Expand Down Expand Up @@ -142,9 +149,9 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass

#if defined(BOARD_HAS_SECURE_ELEMENT)
SecureElement _selement;
#if !defined(BOARD_HAS_OFFLOADED_ECCX08)
ECP256Certificate _cert;
#endif
/* Flag used to store updated device certificate after broker connection has succeeded */
bool _writeCertOnConnect;
#endif

TLSClientMqtt _brokerClient;
Expand Down Expand Up @@ -183,6 +190,10 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
void detachThing();
int write(String const topic, byte const data[], int const length);

#if defined(BOARD_HAS_SECURE_ELEMENT)
int mqttPort();
#endif

};

/******************************************************************************
Expand Down
27 changes: 27 additions & 0 deletions src/tls/AIoTCSSCert.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* CONSTANTS
******************************************************************************/
static const char AIoTSSCert[] =
/* https://iot.arduino.cc:8883 */
"-----BEGIN CERTIFICATE-----\n"
"MIIBzzCCAXSgAwIBAgIUHxAd66fhJecnwaOR4+wNF03tSlkwCgYIKoZIzj0EAwIw\n"
"RTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkFyZHVpbm8gTExDIFVTMQswCQYDVQQL\n"
Expand All @@ -41,6 +42,32 @@ static const char AIoTSSCert[] =
"VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWz4qa47JsBqoVOY2m4wJ+fzhuYAwCgYI\n"
"KoZIzj0EAwIDSQAwRgIhAL/T3CNmaLUK3D8NDsNz4grH92CqEA3TIL/hApabawXY\n"
"AiEA6tnZ2lrNElKXCajtZg/hjWRE/+giFzBP8riar8qOz2w=\n"
"-----END CERTIFICATE-----\n"
/* https://iot.arduino.cc:8885 */
"-----BEGIN CERTIFICATE-----\n"
"MIIB0DCCAXagAwIBAgIUb62eK/Vv1baaPAaY5DADBUbxB1owCgYIKoZIzj0EAwIw\n"
"RTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkFyZHVpbm8gTExDIFVTMQswCQYDVQQL\n"
"EwJJVDEQMA4GA1UEAxMHQXJkdWlubzAgFw0yNTAxMTAxMDUzMjJaGA8yMDU1MDEw\n"
"MzEwNTMyMlowRTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkFyZHVpbm8gTExDIFVT\n"
"MQswCQYDVQQLEwJJVDEQMA4GA1UEAxMHQXJkdWlubzBZMBMGByqGSM49AgEGCCqG\n"
"SM49AwEHA0IABKHhU2w1UhozDegrrFsSwY9QN7M+ZJug7icCNceNWhBF0Mr1UuyX\n"
"8pr/gcbieZc/0znG16HMa2GFcPY7rmIdccijQjBAMA8GA1UdEwEB/wQFMAMBAf8w\n"
"DgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRCZSmE0ASI0cYD9AmzeOM7EijgPjAK\n"
"BggqhkjOPQQDAgNIADBFAiEAz6TLYP9eiVOr/cVU/11zwGofe/FoNe4p1BlzMl7G\n"
"VVACIG8tL3Ta2WbIOaUVpBL2gfLuI9WSW1sR++zXP+zFhmen\n"
"-----END CERTIFICATE-----\n"
/* https://iot.oniudra.cc:8885 */
"-----BEGIN CERTIFICATE-----\n"
"MIIBzzCCAXagAwIBAgIUI5fEitwlnwujc/mU0d8LnDiDXBIwCgYIKoZIzj0EAwIw\n"
"RTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkFyZHVpbm8gTExDIFVTMQswCQYDVQQL\n"
"EwJJVDEQMA4GA1UEAxMHQXJkdWlubzAgFw0yNTAxMDgxMTA4MzdaGA8yMDU1MDEw\n"
"MTExMDgzN1owRTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkFyZHVpbm8gTExDIFVT\n"
"MQswCQYDVQQLEwJJVDEQMA4GA1UEAxMHQXJkdWlubzBZMBMGByqGSM49AgEGCCqG\n"
"SM49AwEHA0IABBFwNODDPgC9C1kDmKBbawtQ31FmTudAXVpGSOUwcDX582z820cD\n"
"eIaCwOxghmI+p/CpOH63f5F6h23ErqZMBkijQjBAMA8GA1UdEwEB/wQFMAMBAf8w\n"
"DgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQdnBmQGLB7ls/r1Tetdp+MVMqxfTAK\n"
"BggqhkjOPQQDAgNHADBEAiBPSZ9HpF7MuFoK4Jsz//PHILQuHM4WmRopQR9ysSs0\n"
"HAIgNadMPgxv01dy59kCgzehgKzmKdTF0rG1SniYqnkLqPA=\n"
"-----END CERTIFICATE-----\n";

#endif /* #if defined(BOARD_HAS_SE050) || defined(BOARD_HAS_SOFTSE) */
Expand Down
Loading
Loading