Skip to content

Commit

Permalink
[tcat] Add tcat implementaions and bug fix.
Browse files Browse the repository at this point in the history
Commit adds check is commissioning is possible if tcat device is aready
commissioned.

Adds advertisement update on dissconnected and role change.

Fix key handling for key references.

Fixes the authorisation processing scheme.
  • Loading branch information
Przemyslaw Bida authored and canisLupus1313 committed Jan 27, 2025
1 parent 6694d5c commit 78f5460
Show file tree
Hide file tree
Showing 16 changed files with 475 additions and 314 deletions.
8 changes: 8 additions & 0 deletions examples/platforms/simulation/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,14 @@ otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementDat
return OT_ERROR_NONE;
}

otError otPlatBleGapAdvUpdateData(otInstance *aInstance, uint8_t *aAdvertisementData, uint16_t aAdvertisementLen)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aAdvertisementData);
OT_UNUSED_VARIABLE(aAdvertisementLen);
return OT_ERROR_NONE;
}

bool otPlatBleSupportsMultiRadio(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
Expand Down
16 changes: 16 additions & 0 deletions include/openthread/platform/ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,22 @@ otError otPlatBleGetAdvertisementBuffer(otInstance *aInstance, uint8_t **aAdvert
*/
otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementData, uint16_t aAdvertisementLen);

/**
* Updates BLE Advertising data.
*
* @note This function shall be used only for BLE Peripheral role.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aAdvertisementData The formatted TCAT advertisement frame.
* @param[in] aAdvertisementLen The TCAT advertisement frame length.
*
* @retval OT_ERROR_NONE Advertising procedure has been started.
* @retval OT_ERROR_FAILED Update of data failed.
* @retval OT_ERROR_INVALID_ARGS Invalid value has been supplied.
*
*/
otError otPlatBleGapAdvUpdateData(otInstance *aInstance, uint8_t *aAdvertisementData, uint16_t aAdvertisementLen);

/**
* Starts BLE Advertising procedure.
*
Expand Down
20 changes: 9 additions & 11 deletions include/openthread/tcat.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,10 @@ typedef enum otTcatStatusCode
OT_TCAT_STATUS_VALUE_ERROR = 3, ///< The value of the transmitted TLV has an error
OT_TCAT_STATUS_GENERAL_ERROR = 4, ///< An error not matching any other category occurred
OT_TCAT_STATUS_BUSY = 5, ///< Command cannot be executed because the resource is busy
OT_TCAT_STATUS_UNDEFINED = 6, ///< The requested value, data or service is not defined (currently) or not present
OT_TCAT_STATUS_HASH_ERROR = 7, ///< The hash value presented by the commissioner was incorrect
OT_TCAT_STATUS_UNDEFINED = 6, ///< The requested value, data or service is not defined (currently) or not present
OT_TCAT_STATUS_HASH_ERROR = 7, ///< The hash value presented by the commissioner was incorrect
OT_TCAT_STATUS_INVALID_STATE = 8, /** The Command cannot be executed because the TCAT
Device is not in a state correct state */
OT_TCAT_STATUS_UNAUTHORIZED = 16, ///< Sender does not have sufficient authorization for the given command

} otTcatStatusCode;
Expand Down Expand Up @@ -163,21 +165,17 @@ typedef struct otTcatVendorInfo
} otTcatVendorInfo;

/**
* Pointer to call when application data was received over a TCAT TLS connection.
* Pointer to call when vendor specific data was received over a TCAT TLS connection.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aMessage A pointer to the message.
* @param[in] aOffset The offset where the application data begins.
* @param[in] aTcatApplicationProtocol The protocol type of the message received.
* @param[in] aServiceName The name of the service the message is direced to.
* @param[in] aContext A pointer to arbitrary context information.
*/
typedef void (*otHandleTcatApplicationDataReceive)(otInstance *aInstance,
const otMessage *aMessage,
int32_t aOffset,
otTcatApplicationProtocol aTcatApplicationProtocol,
const char *aServiceName,
void *aContext);
typedef void (*otHandleTcatApplicationDataReceive)(otInstance *aInstance,
const otMessage *aMessage,
int32_t aOffset,
void *aContext);

/**
* Pointer to call to notify the completion of a join operation.
Expand Down
19 changes: 19 additions & 0 deletions src/cli/README_TCAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ tcat advid clear
Done
```

### certid

Displays ID of currently chosen device certificate.

```bash
tcat certid
0
Done
```

### certid \<id\>

Sets ID of device certificate.

```bash
tcat certid 1
Done
```

### devid

Displays currently set TCAT device id.
Expand Down
116 changes: 84 additions & 32 deletions src/cli/cli_tcat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@

#include "cli/cli_tcat.hpp"
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/error.hpp"
#include "common/string.hpp"

#include <openthread/ble_secure.h>

Expand All @@ -43,32 +45,57 @@

#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE && OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE

#define CERT_SET_COUNT 2
#define CERT_MAX_SIZE 1024
#define KEY_MAX_SIZE 512

// DeviceCert1 default identity for TCAT certification testing.
// DeviceCert2 extra example.
// WARNING: storage of private keys in code or program memory MUST NOT be used in production.
// The below code is for testing purposes only. For production, secure key storage must be
// used to store private keys.
#define OT_CLI_TCAT_X509_CERT \
"-----BEGIN CERTIFICATE-----\n" \
"MIIB6TCCAZCgAwIBAgICNekwCgYIKoZIzj0EAwIwcTEmMCQGA1UEAwwdVGhyZWFk\n" \
"IENlcnRpZmljYXRpb24gRGV2aWNlQ0ExGTAXBgNVBAoMEFRocmVhZCBHcm91cCBJ\n" \
"bmMxEjAQBgNVBAcMCVNhbiBSYW1vbjELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVT\n" \
"MCAXDTI0MDUwNzA5Mzk0NVoYDzI5OTkxMjMxMDkzOTQ1WjA8MSEwHwYDVQQDDBhU\n" \
"Q0FUIEV4YW1wbGUgRGV2aWNlQ2VydDExFzAVBgNVBAUTDjQ3MjMtOTgzMy0wMDAx\n" \
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE11h/4vKZXVXv+1GDZo066spItloT\n" \
"dpCi0bux0jvpQSHLdQBIc+40zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdqNLMEkw\n" \
"HwYDVR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwEAYJKwYBBAGC3yoCBAMC\n" \
"AQUwFAYJKwYBBAGC3yoDBAcEBSABAQEBMAoGCCqGSM49BAMCA0cAMEQCIHWu+Rd1\n" \
"VRlzrD8KbuyJcJFTXh2sQ9UIrFIA7+4e/GVcAiAVBdGqTxbt3TGkBBllpafAUB2/\n" \
"s0GJj7E33oblqy5eHQ==\n" \
"-----END CERTIFICATE-----\n"

#define OT_CLI_TCAT_PRIV_KEY \
"-----BEGIN EC PRIVATE KEY-----\n" \
"MHcCAQEEIIqKM1QTlNaquV74W6Viz/ggXoLqlPOP6LagSyaFO3oUoAoGCCqGSM49\n" \
"AwEHoUQDQgAE11h/4vKZXVXv+1GDZo066spItloTdpCi0bux0jvpQSHLdQBIc+40\n" \
"zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdg==\n" \
static const char OT_CLI_TCAT_X509_CERT[CERT_SET_COUNT][CERT_MAX_SIZE] = {
"-----BEGIN CERTIFICATE-----\n"
"MIIB6TCCAZCgAwIBAgICNekwCgYIKoZIzj0EAwIwcTEmMCQGA1UEAwwdVGhyZWFk\n"
"IENlcnRpZmljYXRpb24gRGV2aWNlQ0ExGTAXBgNVBAoMEFRocmVhZCBHcm91cCBJ\n"
"bmMxEjAQBgNVBAcMCVNhbiBSYW1vbjELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVT\n"
"MCAXDTI0MDUwNzA5Mzk0NVoYDzI5OTkxMjMxMDkzOTQ1WjA8MSEwHwYDVQQDDBhU\n"
"Q0FUIEV4YW1wbGUgRGV2aWNlQ2VydDExFzAVBgNVBAUTDjQ3MjMtOTgzMy0wMDAx\n"
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE11h/4vKZXVXv+1GDZo066spItloT\n"
"dpCi0bux0jvpQSHLdQBIc+40zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdqNLMEkw\n"
"HwYDVR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwEAYJKwYBBAGC3yoCBAMC\n"
"AQUwFAYJKwYBBAGC3yoDBAcEBSABAQEBMAoGCCqGSM49BAMCA0cAMEQCIHWu+Rd1\n"
"VRlzrD8KbuyJcJFTXh2sQ9UIrFIA7+4e/GVcAiAVBdGqTxbt3TGkBBllpafAUB2/\n"
"s0GJj7E33oblqy5eHQ==\n"
"-----END CERTIFICATE-----\n",
"-----BEGIN CERTIFICATE-----\n"
"MIIB6TCCAZCgAwIBAgICNeowCgYIKoZIzj0EAwIwcTEmMCQGA1UEAwwdVGhyZWFk\n"
"IENlcnRpZmljYXRpb24gRGV2aWNlQ0ExGTAXBgNVBAoMEFRocmVhZCBHcm91cCBJ\n"
"bmMxEjAQBgNVBAcMCVNhbiBSYW1vbjELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVT\n"
"MCAXDTI0MDUwNzA5Mzk0NVoYDzI5OTkxMjMxMDkzOTQ1WjA8MSEwHwYDVQQDDBhU\n"
"Q0FUIEV4YW1wbGUgRGV2aWNlQ2VydDIxFzAVBgNVBAUTDjQ3MjMtOTgzMy0wMDAy\n"
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE30GMkqSBj3049NtK6G/MRTqcDxpm\n"
"i1LxTpSxFIB7P9HVoVM7Cd9X6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmi6NLMEkw\n"
"HwYDVR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwEAYJKwYBBAGC3yoCBAMC\n"
"AQUwFAYJKwYBBAGC3yoDBAcEBSABAQEBMAoGCCqGSM49BAMCA0cAMEQCIAbZzVbC\n"
"toNYgSWSgxRGzLRo1YJANqRC7yRtJNKTdQ1ZAiAlgGxEW2lkxCAGPUK1m9Wbb4kl\n"
"7AhBhYlK6vZz/omTsQ==\n"
"-----END CERTIFICATE-----\n"};

static const char OT_CLI_TCAT_PRIV_KEY[CERT_SET_COUNT][KEY_MAX_SIZE] = {
"-----BEGIN EC PRIVATE KEY-----\n"
"MHcCAQEEIIqKM1QTlNaquV74W6Viz/ggXoLqlPOP6LagSyaFO3oUoAoGCCqGSM49\n"
"AwEHoUQDQgAE11h/4vKZXVXv+1GDZo066spItloTdpCi0bux0jvpQSHLdQBIc+40\n"
"zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdg==\n"
"-----END EC PRIVATE KEY-----\n",
"-----BEGIN EC PRIVATE KEY-----\n"
"MHcCAQEEIP7Al8tJA3QgwD3yIuOSEmJkT3GlWmcHQ59JfhZOjSdUoAoGCCqGSM49\n"
"AwEHoUQDQgAE30GMkqSBj3049NtK6G/MRTqcDxpmi1LxTpSxFIB7P9HVoVM7Cd9X\n"
"6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmiw==\n"
"-----END EC PRIVATE KEY-----\n"

};

#define OT_CLI_TCAT_TRUSTED_ROOT_CERTIFICATE \
"-----BEGIN CERTIFICATE-----\n" \
"MIICOzCCAeGgAwIBAgIJAKOc2hehOGoBMAoGCCqGSM49BAMCMHExJjAkBgNVBAMM\n" \
Expand All @@ -86,7 +113,6 @@
"-----END CERTIFICATE-----\n"

namespace ot {

namespace Cli {

otTcatAdvertisedDeviceId sAdvertisedDeviceIds[OT_TCAT_DEVICE_ID_MAX];
Expand All @@ -96,6 +122,8 @@ const char kPskdVendor[] = "JJJJJJ";
const char kInstallVendor[] = "InstallCode";
const char kUrl[] = "dummy_url";

uint8_t selectetCert = 0;

static bool IsDeviceIdSet(void)
{
bool ret = false;
Expand All @@ -110,16 +138,9 @@ static bool IsDeviceIdSet(void)
return ret;
}

static void HandleBleSecureReceive(otInstance *aInstance,
const otMessage *aMessage,
int32_t aOffset,
otTcatApplicationProtocol aTcatApplicationProtocol,
const char *aServiceName,
void *aContext)
static void HandleBleSecureReceive(otInstance *aInstance, const otMessage *aMessage, int32_t aOffset, void *aContext)
{
OT_UNUSED_VARIABLE(aContext);
OT_UNUSED_VARIABLE(aTcatApplicationProtocol);
OT_UNUSED_VARIABLE(aServiceName);

static constexpr int kTextMaxLen = 100;
static constexpr uint8_t kBufPrefixLen = 5;
Expand Down Expand Up @@ -230,6 +251,36 @@ template <> otError Tcat::Process<Cmd("advid")>(Arg aArgs[])
return error;
}

/**
* @cli tcat certid
* @code
* tcat devid certid 0
* Done
* @endcode
* @cparam tcat certid [@ca{value}]
* * The `value` int value of the ID.
* @par
* Selects predefined certificate.
*/
template <> otError Tcat::Process<Cmd("certid")>(Arg aArgs[])
{
Error error = kErrorNone;
uint8_t certCandidate = 0;

if (aArgs[0].IsEmpty())
{
OutputLine("%d", selectetCert);
ExitNow();
}

SuccessOrExit(error = aArgs[0].ParseAsUint8(certCandidate));

VerifyOrExit(certCandidate < CERT_SET_COUNT, error = kErrorInvalidArgs);

exit:
return error;
}

/**
* @cli tcat devid
* @code
Expand Down Expand Up @@ -306,9 +357,10 @@ template <> otError Tcat::Process<Cmd("start")>(Arg aArgs[])
mVendorInfo.mGeneralDeviceId = &sGeneralDeviceId;
}

otBleSecureSetCertificate(GetInstancePtr(), reinterpret_cast<const uint8_t *>(OT_CLI_TCAT_X509_CERT),
sizeof(OT_CLI_TCAT_X509_CERT), reinterpret_cast<const uint8_t *>(OT_CLI_TCAT_PRIV_KEY),
sizeof(OT_CLI_TCAT_PRIV_KEY));
otBleSecureSetCertificate(GetInstancePtr(), reinterpret_cast<const uint8_t *>(OT_CLI_TCAT_X509_CERT[selectetCert]),
StringLength(OT_CLI_TCAT_X509_CERT[selectetCert], CERT_MAX_SIZE) + 1,
reinterpret_cast<const uint8_t *>(OT_CLI_TCAT_PRIV_KEY[selectetCert]),
StringLength(OT_CLI_TCAT_PRIV_KEY[selectetCert], KEY_MAX_SIZE) + 1);

otBleSecureSetCaCertificateChain(GetInstancePtr(),
reinterpret_cast<const uint8_t *>(OT_CLI_TCAT_TRUSTED_ROOT_CERTIFICATE),
Expand Down
7 changes: 0 additions & 7 deletions src/core/api/ble_secure_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,6 @@ bool otBleSecureIsTcatEnabled(otInstance *aInstance)
{
return AsCoreType(aInstance).Get<Ble::BleSecure>().IsTcatEnabled();
}

bool otBleSecureIsCommandClassAuthorized(otInstance *aInstance, otTcatCommandClass aCommandClass)
{
return AsCoreType(aInstance).Get<Ble::BleSecure>().IsCommandClassAuthorized(
static_cast<Ble::BleSecure::CommandClass>(aCommandClass));
}

otError otBleSecureSendMessage(otInstance *aInstance, otMessage *aMessage)
{
return AsCoreType(aInstance).Get<Ble::BleSecure>().SendMessage(AsCoreType(aMessage));
Expand Down
Loading

0 comments on commit 78f5460

Please sign in to comment.