Skip to content

Refactor cryptologic initialisation code #108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
Closed
5 changes: 3 additions & 2 deletions examples/utility/Provisioning/Provisioning.ino
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include <ArduinoIoTCloud.h>
#include <utility/ECCX08Cert.h>
#include <utility/ECCX08TLSConfig.h>
#include "ECCX08TLSConfig.h"

#include <ArduinoBearSSL.h>
#include <ArduinoECCX08.h>
Expand All @@ -11,6 +10,8 @@ const int compressedCertSlot = 10;
const int serialNumberAndAuthorityKeyIdentifierSlot = 11;
const int deviceIdSlot = 12;

ECCX08CertClass ECCX08Cert;

void setup() {
Serial.begin(9600);
while (!Serial);
Expand Down
63 changes: 7 additions & 56 deletions src/ArduinoIoTCloudTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,12 @@
#include <ArduinoIoTCloudTCP.h>
#include "utility/time/TimeService.h"
#ifdef BOARD_HAS_ECCX08
#include "utility/ECCX08Cert.h"
#include "utility/BearSSLTrustAnchor.h"
#include <ArduinoECCX08.h>
#include "utility/crypto/BearSSLTrustAnchor.h"
#endif

TimeService time_service;

#ifdef BOARD_HAS_ECCX08
const static int keySlot = 0;
const static int compressedCertSlot = 10;
const static int serialNumberAndAuthorityKeyIdentifierSlot = 11;
const static int deviceIdSlot = 12;
#endif

const static int CONNECT_SUCCESS = 1;
const static int CONNECT_FAILURE = 0;
const static int CONNECT_FAILURE_SUBSCRIBE = -1;
Expand Down Expand Up @@ -62,17 +54,9 @@ ArduinoIoTCloudTCP::ArduinoIoTCloudTCP():
_otaTopic("")
{}


ArduinoIoTCloudTCP::~ArduinoIoTCloudTCP() {
if (_mqttClient) {
delete _mqttClient;
_mqttClient = NULL;
}

if (_sslClient) {
delete _sslClient;
_sslClient = NULL;
}
delete _mqttClient; _mqttClient = NULL;
delete _sslClient; _sslClient = NULL;
}

int ArduinoIoTCloudTCP::begin(ConnectionHandler & connection, String brokerAddress, uint16_t brokerPort) {
Expand All @@ -89,45 +73,12 @@ int ArduinoIoTCloudTCP::begin(String brokerAddress, uint16_t brokerPort) {
_brokerPort = brokerPort;

#ifdef BOARD_HAS_ECCX08
byte deviceIdBytes[72];
if (!ECCX08.begin()) {
Debug.print(DBG_ERROR, "Cryptography processor failure. Make sure you have a compatible board.");
return 0;
}

if (!ECCX08.readSlot(deviceIdSlot, deviceIdBytes, sizeof(deviceIdBytes))) {
Debug.print(DBG_ERROR, "Cryptography processor read failure.");
return 0;
}
_device_id = (char*)deviceIdBytes;

if (!ECCX08Cert.beginReconstruction(keySlot, compressedCertSlot, serialNumberAndAuthorityKeyIdentifierSlot)) {
Debug.print(DBG_ERROR, "Cryptography certificate reconstruction failure.");
return 0;
}

ECCX08Cert.setSubjectCommonName(_device_id);
ECCX08Cert.setIssuerCountryName("US");
ECCX08Cert.setIssuerOrganizationName("Arduino LLC US");
ECCX08Cert.setIssuerOrganizationalUnitName("IT");
ECCX08Cert.setIssuerCommonName("Arduino");

if (!ECCX08Cert.endReconstruction()) {
Debug.print(DBG_ERROR, "Cryptography certificate reconstruction failure.");
return 0;
}

if (!ECCX08.begin()) { Debug.print(DBG_ERROR, "Cryptography processor failure. Make sure you have a compatible board."); return 0; }
if (!CryptoUtil::readDeviceId(ECCX08, _device_id, ECCX08Slot::DeviceId)) { Debug.print(DBG_ERROR, "Cryptography processor read failure."); return 0; }
if (!CryptoUtil::reconstructCertificate(_eccx08_cert, _device_id, ECCX08Slot::Key, ECCX08Slot::CompressedCertificate, ECCX08Slot::SerialNumberAndAuthorityKeyIdentifier)) { Debug.print(DBG_ERROR, "Cryptography certificate reconstruction failure."); return 0; }
ArduinoBearSSL.onGetTime(getTime);
#endif /* BOARD_HAS_ECCX08 */

if (_sslClient) {
delete _sslClient;
_sslClient = NULL;
}

#ifdef BOARD_HAS_ECCX08
_sslClient = new BearSSLClient(_connection->getClient(), ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM);
_sslClient->setEccSlot(keySlot, ECCX08Cert.bytes(), ECCX08Cert.length());
_sslClient->setEccSlot(static_cast<int>(ECCX08Slot::Key), _eccx08_cert.bytes(), _eccx08_cert.length());
#elif defined(BOARD_ESP)
_sslClient = new WiFiClientSecure();
_sslClient->setInsecure();
Expand Down
4 changes: 3 additions & 1 deletion src/ArduinoIoTCloudTCP.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>

#ifdef BOARD_HAS_ECCX08 /
#ifdef BOARD_HAS_ECCX08
#include <ArduinoBearSSL.h>
#include "utility/crypto/CryptoUtil.h"
#elif defined(BOARD_ESP)
#include <WiFiClientSecure.h>
#endif
Expand Down Expand Up @@ -99,6 +100,7 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass {
bool _mqtt_data_request_retransmit;

#ifdef BOARD_HAS_ECCX08
ECCX08CertClass _eccx08_cert;
BearSSLClient* _sslClient;
#elif defined(BOARD_ESP)
WiFiClientSecure* _sslClient;
Expand Down
61 changes: 61 additions & 0 deletions src/utility/crypto/CryptoUtil.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
This file is part of ArduinoIoTCloud.

Copyright 2019 ARDUINO SA (http://www.arduino.cc/)

This software is released under the GNU General Public License version 3,
which covers the main part of arduino-cli.
The terms of this license can be found at:
https://www.gnu.org/licenses/gpl-3.0.en.html

You can be released from the requirements of the above licenses by purchasing
a commercial license. Buying such a license is mandatory if you want to modify or
otherwise use the software for commercial activities involving the Arduino
software without disclosing the source code of your own applications. To purchase
a commercial license, send an email to [email protected].
*/

/******************************************************************************
INCLUDE
******************************************************************************/

#include "CryptoUtil.h"

#ifdef BOARD_HAS_ECCX08

/******************************************************************************
PUBLIC MEMBER FUNCTIONS
******************************************************************************/

bool CryptoUtil::readDeviceId(ECCX08Class & eccx08, String & device_id, ECCX08Slot const device_id_slot)
{
byte device_id_bytes[72] = {0};

if (eccx08.readSlot(static_cast<int>(device_id_slot), device_id_bytes, sizeof(device_id_bytes))) {
device_id = String(reinterpret_cast<char *>(device_id_bytes));
return true;
}
else
{
return false;
}
}

bool CryptoUtil::reconstructCertificate(ECCX08CertClass & cert, String const & device_id, ECCX08Slot const key, ECCX08Slot const compressed_certificate, ECCX08Slot const serial_number_and_authority_key)
{
if (cert.beginReconstruction(static_cast<int>(key), static_cast<int>(compressed_certificate), static_cast<int>(serial_number_and_authority_key)))
{
cert.setSubjectCommonName(device_id);
cert.setIssuerCountryName("US");
cert.setIssuerOrganizationName("Arduino LLC US");
cert.setIssuerOrganizationalUnitName("IT");
cert.setIssuerCommonName("Arduino");
return cert.endReconstruction();
}
else
{
return false;
}
}

#endif /* BOARD_HAS_ECCX08 */
66 changes: 66 additions & 0 deletions src/utility/crypto/CryptoUtil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
This file is part of ArduinoIoTCloud.

Copyright 2019 ARDUINO SA (http://www.arduino.cc/)

This software is released under the GNU General Public License version 3,
which covers the main part of arduino-cli.
The terms of this license can be found at:
https://www.gnu.org/licenses/gpl-3.0.en.html

You can be released from the requirements of the above licenses by purchasing
a commercial license. Buying such a license is mandatory if you want to modify or
otherwise use the software for commercial activities involving the Arduino
software without disclosing the source code of your own applications. To purchase
a commercial license, send an email to [email protected].
*/

#ifndef ARDUINO_IOT_CLOUD_UTILITY_CRYPTO_CRYPTO_UTIL_H_
#define ARDUINO_IOT_CLOUD_UTILITY_CRYPTO_CRYPTO_UTIL_H_

/******************************************************************************
INCLUDE
******************************************************************************/

#include <ArduinoIoTCloud_Defines.h>

#ifdef BOARD_HAS_ECCX08

#include <Arduino.h>
#include <ArduinoECCX08.h>
#include "ECCX08Cert.h"

/******************************************************************************
TYPEDEF
******************************************************************************/

enum class ECCX08Slot : int
{
Key = 0,
CompressedCertificate = 10,
SerialNumberAndAuthorityKeyIdentifier = 11,
DeviceId = 12
};

/******************************************************************************
CLASS DECLARATION
******************************************************************************/

class CryptoUtil
{
public:

static bool readDeviceId(ECCX08Class & eccx08, String & device_id, ECCX08Slot const device_id_slot);
static bool reconstructCertificate(ECCX08CertClass & cert, String const & device_id, ECCX08Slot const key, ECCX08Slot const compressed_certificate, ECCX08Slot const serial_number_and_authority_key);


private:

CryptoUtil() { }
CryptoUtil(CryptoUtil const & other) { }

};

#endif /* BOARD_HAS_ECCX08 */

#endif /* ARDUINO_IOT_CLOUD_UTILITY_CRYPTO_CRYPTO_UTIL_H_ */
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,4 @@ int ECCX08CertClass::appendEcdsaWithSHA256(byte out[]) {
return 12;
}

ECCX08CertClass ECCX08Cert;

#endif /* BOARD_HAS_ECCX08 */
2 changes: 0 additions & 2 deletions src/utility/ECCX08Cert.h → src/utility/crypto/ECCX08Cert.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,6 @@ class ECCX08CertClass {
int _length;
};

extern ECCX08CertClass ECCX08Cert;

#endif /* BOARD_HAS_ECCX08 */

#endif /* _ECCX08_CERT_H_ */