diff --git a/src/cli/cli_tcat.cpp b/src/cli/cli_tcat.cpp index 012665967..ab29bd0fd 100644 --- a/src/cli/cli_tcat.cpp +++ b/src/cli/cli_tcat.cpp @@ -42,40 +42,47 @@ #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE && OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE -#define OT_CLI_TCAT_X509_CERT \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIBmDCCAT+gAwIBAgIEAQIDBDAKBggqhkjOPQQDAjBvMQswCQYDVQQGEwJYWDEQ\r\n" \ - "MA4GA1UECBMHTXlTdGF0ZTEPMA0GA1UEBxMGTXlDaXR5MQ8wDQYDVQQLEwZNeVVu\r\n" \ - "aXQxETAPBgNVBAoTCE15VmVuZG9yMRkwFwYDVQQDExB3d3cubXl2ZW5kb3IuY29t\r\n" \ - "MB4XDTIzMTAxNjEwMzk1NFoXDTI0MTAxNjEwMzk1NFowIjEgMB4GA1UEAxMXbXl2\r\n" \ - "ZW5kb3IuY29tL3RjYXQvbXlkZXYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQB\r\n" \ - "aWwFDNj1bpQIdN+Kp2cHWw55U/+fa+OmZnoy1B4BOT+822jdwPBuyXWAQoBdYdQJ\r\n" \ - "ff4RgmhczyV4PhArPIuAoxYwFDASBgkrBgEEAYLfKgMEBQABAQEBMAoGCCqGSM49\r\n" \ - "BAMCA0cAMEQCIBEHxiEDij26y6V77Q311Gj4CZAuZuPGXZpnzL2BLk7bAiAlFk6G\r\n" \ - "mYGzkcrYyssFI9HlPgrisWoMmgummaTtCuvrEw==\r\n" \ - "-----END CERTIFICATE-----\r\n" - -#define OT_CLI_TCAT_PRIV_KEY \ - "-----BEGIN EC PRIVATE KEY-----\r\n" \ - "MHcCAQEEIDeJ6lVQKiOIBxKwTZp6TkU5QVHt9pvXOR9CGpPBI3DhoAoGCCqGSM49\r\n" \ - "AwEHoUQDQgAEAWlsBQzY9W6UCHTfiqdnB1sOeVP/n2vjpmZ6MtQeATk/vNto3cDw\r\n" \ - "bsl1gEKAXWHUCX3+EYJoXM8leD4QKzyLgA==\r\n" \ - "-----END EC PRIVATE KEY-----\r\n" - -#define OT_CLI_TCAT_TRUSTED_ROOT_CERTIFICATE \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIICCDCCAa2gAwIBAgIJAIKxygBXoH+5MAoGCCqGSM49BAMCMG8xCzAJBgNVBAYT\r\n" \ - "AlhYMRAwDgYDVQQIEwdNeVN0YXRlMQ8wDQYDVQQHEwZNeUNpdHkxDzANBgNVBAsT\r\n" \ - "Bk15VW5pdDERMA8GA1UEChMITXlWZW5kb3IxGTAXBgNVBAMTEHd3dy5teXZlbmRv\r\n" \ - "ci5jb20wHhcNMjMxMDE2MTAzMzE1WhcNMjYxMDE2MTAzMzE1WjBvMQswCQYDVQQG\r\n" \ - "EwJYWDEQMA4GA1UECBMHTXlTdGF0ZTEPMA0GA1UEBxMGTXlDaXR5MQ8wDQYDVQQL\r\n" \ - "EwZNeVVuaXQxETAPBgNVBAoTCE15VmVuZG9yMRkwFwYDVQQDExB3d3cubXl2ZW5k\r\n" \ - "b3IuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWdyzPAXGKeZY94OhHAWX\r\n" \ - "HzJfQIjGSyaOzlgL9OEFw2SoUDncLKPGwfPAUSfuMyEkzszNDM0HHkBsDLqu4n25\r\n" \ - "/6MyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU4EynoSw9eDKZEVPkums2\r\n" \ - "IWLAJCowCgYIKoZIzj0EAwIDSQAwRgIhAMYGGL9xShyE6P9wEU+MAYF6W3CzdrwV\r\n" \ - "kuerX1encIH2AiEA5rq490NUobM1Au43roxJq1T6Z43LscPVbGZfULD1Jq0=\r\n" \ - "-----END CERTIFICATE-----\r\n" +// DeviceCert1 default identity for TCAT certification testing. +// 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" \ + "-----END EC PRIVATE KEY-----\n" + +#define OT_CLI_TCAT_TRUSTED_ROOT_CERTIFICATE \ + "-----BEGIN CERTIFICATE-----\n" \ + "MIICOzCCAeGgAwIBAgIJAKOc2hehOGoBMAoGCCqGSM49BAMCMHExJjAkBgNVBAMM\n" \ + "HVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQg\n" \ + "R3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYD\n" \ + "VQQGEwJVUzAeFw0yNDA1MDMyMDAyMThaFw00NDA0MjgyMDAyMThaMHExJjAkBgNV\n" \ + "BAMMHVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJl\n" \ + "YWQgR3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQsw\n" \ + "CQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGy850VBIPTkN3oL\n" \ + "x++zIUsZk2k26w4fuieFz9oNvjdb5W14+Yf3mvGWsl4NHyLxqhmamVAR4h7zWRlZ\n" \ + "0XyMVpKjYjBgMB4GA1UdEQQXMBWBE3RvbUB0aHJlYWRncm91cC5vcmcwDgYDVR0P\n" \ + "AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFF+rGyloiKHUtDGo\n" \ + "hmHn52ZZ7fgZMAoGCCqGSM49BAMCA0gAMEUCIQCTq1qjPZs9fAJB6ppTXs588Pnu\n" \ + "eVFOwC8bd//D99KiHAIgU84kwFHIyDvFqu6y+u1hFqBGsiuTmKwZ2PHhVe/xK1k=\n" \ + "-----END CERTIFICATE-----\n" namespace ot { diff --git a/src/core/meshcop/secure_transport.cpp b/src/core/meshcop/secure_transport.cpp index 27ed62988..e527c1f1e 100644 --- a/src/core/meshcop/secure_transport.cpp +++ b/src/core/meshcop/secure_transport.cpp @@ -231,7 +231,7 @@ void SecureTransport::HandleReceive(Message &aMessage, const Ip6::MessageInfo &a } else { - // Once DTLS session is started, communicate only with a peer. + // Once DTLS session is started, communicate only with a single peer. VerifyOrExit((mMessageInfo.GetPeerAddr() == aMessageInfo.GetPeerAddr()) && (mMessageInfo.GetPeerPort() == aMessageInfo.GetPeerPort())); } @@ -725,28 +725,28 @@ Error SecureTransport::GetThreadAttributeFromCertificate(const mbedtls_x509_crt ret = mbedtls_asn1_get_bool(&p, endExtData, &isCritical); VerifyOrExit(ret == 0 || ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG, error = kErrorParse); - // Data should be octet string type + // Data must be octet string type, see https://datatracker.ietf.org/doc/html/rfc5280#section-4.1 VerifyOrExit(mbedtls_asn1_get_tag(&p, endExtData, &len, MBEDTLS_ASN1_OCTET_STRING) == 0, error = kErrorParse); VerifyOrExit(endExtData == p + len, error = kErrorParse); - if (isCritical || extnOid.len != sizeof(oid)) + // TODO: extensions with isCritical == 1 that are unknown should lead to rejection of the entire cert. + if (extnOid.len == sizeof(oid) && memcmp(extnOid.p, oid, sizeof(oid)) == 0) { - continue; - } - - if (memcmp(extnOid.p, oid, sizeof(oid)) == 0) - { - *aAttributeLength = len; + // per RFC 5280, octet string must contain ASN.1 Type Length Value octets + VerifyOrExit(len >= 2, error = kErrorParse); + VerifyOrExit(*(p + 1) == len - 2, error = kErrorParse); // check TLV Length, not Type. + *aAttributeLength = len - 2; // strip the ASN.1 Type Length bytes from embedded TLV if (aAttributeBuffer != nullptr) { - VerifyOrExit(len <= attributeBufferSize, error = kErrorNoBufs); - memcpy(aAttributeBuffer, p, len); + VerifyOrExit(*aAttributeLength <= attributeBufferSize, error = kErrorNoBufs); + memcpy(aAttributeBuffer, p + 2, *aAttributeLength); } error = kErrorNone; break; } + p += len; } exit: diff --git a/src/core/meshcop/tcat_agent.hpp b/src/core/meshcop/tcat_agent.hpp index d4224107f..468c40ffe 100644 --- a/src/core/meshcop/tcat_agent.hpp +++ b/src/core/meshcop/tcat_agent.hpp @@ -240,6 +240,7 @@ class TcatAgent : public InstanceLocator, private NonCopyable enum TcatCertificateAttribute { kCertificateDomainName = 1, + kCertificateThreadVersion = 2, kCertificateAuthorizationField = 3, kCertificateNetworkName = 4, kCertificateExtendedPanId = 5, diff --git a/src/core/radio/ble_secure.cpp b/src/core/radio/ble_secure.cpp index d5cffa812..dab82e125 100644 --- a/src/core/radio/ble_secure.cpp +++ b/src/core/radio/ble_secure.cpp @@ -337,7 +337,14 @@ void BleSecure::HandleTlsConnected(bool aConnected) if (mTcatAgent.IsEnabled()) { - IgnoreReturnValue(mTcatAgent.Connected(mTls)); + Error err = mTcatAgent.Connected(mTls); + + if (err != kErrorNone) + { + mTls.Close(); + LogWarn("Rejected TCAT Commissioner, error: %s", ErrorToString(err)); + ExitNow(); + } } } else @@ -352,6 +359,9 @@ void BleSecure::HandleTlsConnected(bool aConnected) } mConnectCallback.InvokeIfSet(&GetInstance(), aConnected, true); + +exit: + return; } void BleSecure::HandleTlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength) diff --git a/tests/unit/test_tcat.cpp b/tests/unit/test_tcat.cpp index 75afb9ab7..bb53e117c 100644 --- a/tests/unit/test_tcat.cpp +++ b/tests/unit/test_tcat.cpp @@ -35,40 +35,43 @@ #include -#define OT_TCAT_X509_CERT \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIBmDCCAT+gAwIBAgIEAQIDBDAKBggqhkjOPQQDAjBvMQswCQYDVQQGEwJYWDEQ\r\n" \ - "MA4GA1UECBMHTXlTdGF0ZTEPMA0GA1UEBxMGTXlDaXR5MQ8wDQYDVQQLEwZNeVVu\r\n" \ - "aXQxETAPBgNVBAoTCE15VmVuZG9yMRkwFwYDVQQDExB3d3cubXl2ZW5kb3IuY29t\r\n" \ - "MB4XDTIzMTAxNjEwMzk1NFoXDTI0MTAxNjEwMzk1NFowIjEgMB4GA1UEAxMXbXl2\r\n" \ - "ZW5kb3IuY29tL3RjYXQvbXlkZXYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQB\r\n" \ - "aWwFDNj1bpQIdN+Kp2cHWw55U/+fa+OmZnoy1B4BOT+822jdwPBuyXWAQoBdYdQJ\r\n" \ - "ff4RgmhczyV4PhArPIuAoxYwFDASBgkrBgEEAYLfKgMEBQABAQEBMAoGCCqGSM49\r\n" \ - "BAMCA0cAMEQCIBEHxiEDij26y6V77Q311Gj4CZAuZuPGXZpnzL2BLk7bAiAlFk6G\r\n" \ - "mYGzkcrYyssFI9HlPgrisWoMmgummaTtCuvrEw==\r\n" \ - "-----END CERTIFICATE-----\r\n" - -#define OT_TCAT_PRIV_KEY \ - "-----BEGIN EC PRIVATE KEY-----\r\n" \ - "MHcCAQEEIDeJ6lVQKiOIBxKwTZp6TkU5QVHt9pvXOR9CGpPBI3DhoAoGCCqGSM49\r\n" \ - "AwEHoUQDQgAEAWlsBQzY9W6UCHTfiqdnB1sOeVP/n2vjpmZ6MtQeATk/vNto3cDw\r\n" \ - "bsl1gEKAXWHUCX3+EYJoXM8leD4QKzyLgA==\r\n" \ - "-----END EC PRIVATE KEY-----\r\n" - -#define OT_TCAT_TRUSTED_ROOT_CERTIFICATE \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIICCDCCAa2gAwIBAgIJAIKxygBXoH+5MAoGCCqGSM49BAMCMG8xCzAJBgNVBAYT\r\n" \ - "AlhYMRAwDgYDVQQIEwdNeVN0YXRlMQ8wDQYDVQQHEwZNeUNpdHkxDzANBgNVBAsT\r\n" \ - "Bk15VW5pdDERMA8GA1UEChMITXlWZW5kb3IxGTAXBgNVBAMTEHd3dy5teXZlbmRv\r\n" \ - "ci5jb20wHhcNMjMxMDE2MTAzMzE1WhcNMjYxMDE2MTAzMzE1WjBvMQswCQYDVQQG\r\n" \ - "EwJYWDEQMA4GA1UECBMHTXlTdGF0ZTEPMA0GA1UEBxMGTXlDaXR5MQ8wDQYDVQQL\r\n" \ - "EwZNeVVuaXQxETAPBgNVBAoTCE15VmVuZG9yMRkwFwYDVQQDExB3d3cubXl2ZW5k\r\n" \ - "b3IuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWdyzPAXGKeZY94OhHAWX\r\n" \ - "HzJfQIjGSyaOzlgL9OEFw2SoUDncLKPGwfPAUSfuMyEkzszNDM0HHkBsDLqu4n25\r\n" \ - "/6MyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU4EynoSw9eDKZEVPkums2\r\n" \ - "IWLAJCowCgYIKoZIzj0EAwIDSQAwRgIhAMYGGL9xShyE6P9wEU+MAYF6W3CzdrwV\r\n" \ - "kuerX1encIH2AiEA5rq490NUobM1Au43roxJq1T6Z43LscPVbGZfULD1Jq0=\r\n" \ - "-----END CERTIFICATE-----\r\n" +#define OT_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_TCAT_PRIV_KEY \ + "-----BEGIN EC PRIVATE KEY-----\n" \ + "MHcCAQEEIIqKM1QTlNaquV74W6Viz/ggXoLqlPOP6LagSyaFO3oUoAoGCCqGSM49\n" \ + "AwEHoUQDQgAE11h/4vKZXVXv+1GDZo066spItloTdpCi0bux0jvpQSHLdQBIc+40\n" \ + "zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdg==\n" \ + "-----END EC PRIVATE KEY-----\n" + +#define OT_TCAT_TRUSTED_ROOT_CERTIFICATE \ + "-----BEGIN CERTIFICATE-----\n" \ + "MIICOzCCAeGgAwIBAgIJAKOc2hehOGoBMAoGCCqGSM49BAMCMHExJjAkBgNVBAMM\n" \ + "HVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQg\n" \ + "R3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYD\n" \ + "VQQGEwJVUzAeFw0yNDA1MDMyMDAyMThaFw00NDA0MjgyMDAyMThaMHExJjAkBgNV\n" \ + "BAMMHVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJl\n" \ + "YWQgR3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQsw\n" \ + "CQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGy850VBIPTkN3oL\n" \ + "x++zIUsZk2k26w4fuieFz9oNvjdb5W14+Yf3mvGWsl4NHyLxqhmamVAR4h7zWRlZ\n" \ + "0XyMVpKjYjBgMB4GA1UdEQQXMBWBE3RvbUB0aHJlYWRncm91cC5vcmcwDgYDVR0P\n" \ + "AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFF+rGyloiKHUtDGo\n" \ + "hmHn52ZZ7fgZMAoGCCqGSM49BAMCA0gAMEUCIQCTq1qjPZs9fAJB6ppTXs588Pnu\n" \ + "eVFOwC8bd//D99KiHAIgU84kwFHIyDvFqu6y+u1hFqBGsiuTmKwZ2PHhVe/xK1k=\n" \ + "-----END CERTIFICATE-----\n" namespace ot { @@ -104,9 +107,14 @@ static void HandleBleSecureConnect(otInstance *aInstance, bool aConnected, bool void TestTcat(void) { - const char kPskdVendor[] = "J01NM3"; - const char kUrl[] = "dummy_url"; - constexpr uint16_t kConnectionId = 0; + const char kPskdVendor[] = "J01NM3"; + const char kUrl[] = "dummy_url"; + constexpr uint16_t kConnectionId = 0; + const int kCertificateThreadVersion = 2; + const int kCertificateAuthorizationField = 3; + const uint8_t expectedTcatAuthField[5] = {0x20, 0x01, 0x01, 0x01, 0x01}; + uint8_t attributeBuffer[8]; + size_t attributeLen; TestBleSecure ble; Instance *instance = testInitInstance(); @@ -129,11 +137,21 @@ void TestTcat(void) SuccessOrQuit(otBleSecureTcatStart(instance, nullptr)); // Validate connection callbacks when platform informs that peer has connected/disconnected + VerifyOrQuit(!otBleSecureIsConnected(instance)); otPlatBleGapOnConnected(instance, kConnectionId); VerifyOrQuit(!ble.IsConnected() && ble.IsBleConnectionOpen()); otPlatBleGapOnDisconnected(instance, kConnectionId); VerifyOrQuit(!ble.IsConnected() && !ble.IsBleConnectionOpen()); + // Verify that Thread-attribute parsing isn't available yet when not connected as client or server. + attributeLen = sizeof(attributeBuffer); + VerifyOrQuit(otBleSecureGetThreadAttributeFromPeerCertificate(instance, kCertificateAuthorizationField, + &attributeBuffer[0], + &attributeLen) == kErrorInvalidState); + attributeLen = sizeof(attributeBuffer); + VerifyOrQuit(otBleSecureGetThreadAttributeFromOwnCertificate( + instance, kCertificateThreadVersion, &attributeBuffer[0], &attributeLen) == kErrorInvalidState); + // Validate connection callbacks when calling `otBleSecureDisconnect()` otPlatBleGapOnConnected(instance, kConnectionId); VerifyOrQuit(!ble.IsConnected() && ble.IsBleConnectionOpen()); @@ -143,6 +161,22 @@ void TestTcat(void) // Validate TLS connection can be started only when peer is connected otPlatBleGapOnConnected(instance, kConnectionId); SuccessOrQuit(otBleSecureConnect(instance)); + VerifyOrQuit(otBleSecureIsConnectionActive(instance)); + + // Once in TLS client connecting state, the below cert eval functions are available. + // Test that the Thread-specific attributes can be decoded properly. + attributeLen = 1; + SuccessOrQuit(otBleSecureGetThreadAttributeFromOwnCertificate(instance, kCertificateThreadVersion, + &attributeBuffer[0], &attributeLen)); + VerifyOrQuit(attributeLen == 1 && attributeBuffer[0] >= kThreadVersion1p4); + + static_assert(5 == sizeof(expectedTcatAuthField), "expectedTcatAuthField size incorrect for test"); + attributeLen = 5; + SuccessOrQuit(otBleSecureGetThreadAttributeFromOwnCertificate(instance, kCertificateAuthorizationField, + &attributeBuffer[0], &attributeLen)); + VerifyOrQuit(attributeLen == 5 && memcmp(&expectedTcatAuthField, &attributeBuffer, attributeLen) == 0); + + // Validate TLS connection can be started only when peer is connected otBleSecureDisconnect(instance); VerifyOrQuit(otBleSecureConnect(instance) == kErrorInvalidState); diff --git a/tools/tcat_ble_client/GENERATING_CERTIFICATES.md b/tools/tcat_ble_client/GENERATING_CERTIFICATES.md index 1eb1b7976..973d17e5b 100644 --- a/tools/tcat_ble_client/GENERATING_CERTIFICATES.md +++ b/tools/tcat_ble_client/GENERATING_CERTIFICATES.md @@ -1,4 +1,4 @@ -# BBTC X.509 certificates generation +# TCAT X.509 certificates generation --- @@ -8,9 +8,24 @@ TCAT uses X.509 Certificate Extensions to provide permissions with certificates. Extensions were introduced in version 3 of the X.509 standard for certificates. They allow certificates to be customised to applications by supporting the addition of arbitrary fields in the certificate. Each extension, identified by its OID (Object Identifier), is marked as "Critical" or "Non-Critical", and includes the extension-specific data. -## Certificates generation +## Certificates generation (by script) -Thread uses Elliptic Curve Cryptography (ECC), so we use the `ecparam` `openssl` argument to generate the keys. +The directory `auth-generate` contains example scripts and a Makefile to generate TCAT Commissioner certificates and TCAT Device certificates. The scripts can also handle multiple CAs, and provide the most detailed view on how to generate these certificates. + +To generate all certificates: + +``` +cd auth-generate +make +``` + +This will create an `output` directory with subdirectories for each of the created identities. Each subdirectory can be used as a value for the BBTC Commissioner `--cert_path` argument, if needed. + +NOTE: the directory `auth-generate/ca` contains an example CA certificate and private key (for signing). Other CAs can be added in here. This CA is not the same CA used for the TCAT Commissioner and Device identities in the `auth` and `auth-cert` directories! The CA for the latter is privately maintained by Thread Group. + +## Certificates generation (manually) + +Thread TCAT uses Elliptic Curve Cryptography (ECC), so we use the `ecparam` `openssl` argument to generate the keys. ### Root certificate @@ -20,19 +35,19 @@ Thread uses Elliptic Curve Cryptography (ECC), so we use the `ecparam` `openssl` openssl ecparam -genkey -name prime256v1 -out ca_key.pem ``` -1. We can then generate the **.csr** (certificate signing request) file, which will contain all the parameters of our final certificate: +2. We can then generate the **.csr** (certificate signing request) file, which will contain all the parameters of our final certificate: ``` openssl req -new -sha256 -key ca_key.pem -out ca.csr ``` -1. Finally, we can generate the certificate itself: +3. Finally, we can generate the certificate itself: ``` openssl req -x509 -sha256 -days 365 -key ca_key.pem -in ca.csr -out ca_cert.pem ``` -1. See the generated certificate using +4. See the generated certificate using ``` openssl x509 -in ca_cert.pem -text -noout @@ -46,25 +61,25 @@ openssl x509 -in ca_cert.pem -text -noout openssl ecparam -genkey -name prime256v1 -out commissioner_key.pem ``` -1. Specify additional extensions when generating the .csr (see [sample configuration](#Configurations)): +2. Specify additional extensions when generating the .csr (see [sample configuration](#Configurations)): ``` openssl req -new -sha256 -key commissioner_key.pem -out commissioner.csr -config commissioner.cnf ``` -1. Generate the certificate: +3. Generate the certificate: ``` openssl x509 -req -in commissioner.csr -CA ca_cert.pem -CAkey ca_key.pem -out commissioner_cert.pem -days 365 -sha256 -copy_extensions copy ``` -1. View the generated certificate using: +4. View the generated certificate using: ``` openssl x509 -in commissioner_cert.pem -text -noout ``` -1. View parsed certificate extensions using: +5. View parsed certificate extensions using: ``` openssl asn1parse -inform PEM -in commissioner_cert.pem @@ -72,7 +87,7 @@ openssl asn1parse -inform PEM -in commissioner_cert.pem ## Configurations -file: `commissioner.cnf` (line `1.3.6.1.4.1.44970.3 = DER:21:01:01:01:01` specifies permissions (all)) +file: `commissioner.cnf` (line `1.3.6.1.4.1.44970.3 = DER:21:01:01:01:01` specifies permissions (all)) See scripts in `auth-generate` directory for more details. ``` [ req ] @@ -85,7 +100,7 @@ req_extensions = v3_req CN = Commissioner [v3_req] -1.3.6.1.4.1.44970.3 = DER:21:01:01:01:01 +1.3.6.1.4.1.44970.3 = DER:04:05:21:01:01:01:01 authorityKeyIdentifier = none subjectKeyIdentifier = none ``` diff --git a/tools/tcat_ble_client/README.md b/tools/tcat_ble_client/README.md index 3af2fead0..9861f9cdf 100644 --- a/tools/tcat_ble_client/README.md +++ b/tools/tcat_ble_client/README.md @@ -2,7 +2,7 @@ ## Overview -This is a Python implementation of Bluetooth-Based Thread Commissioning client, based on Thread's TCAT (Thread Commissioning over Authenticated TLS) functionality. +This is a Python implementation of Bluetooth-Based Thread Commissioning (BBTC) client, based on Thread's TCAT (Thread Commissioning over Authenticated TLS) functionality. ## Installation @@ -12,8 +12,6 @@ If you don't have the poetry module installed (check with `poetry --version`), i python3 -m pip install poetry ``` -Thread uses Elliptic Curve Cryptography (ECC), so we use the `ecparam` `openssl` argument to generate the keys. - ``` poetry install ``` @@ -22,6 +20,12 @@ This will install all the required modules to a virtual environment, which can b ## Usage +To see the supported commandline arguments of BBTC client, use: + +``` +poetry run python3 bbtc.py --help +``` + In order to connect to a TCAT device, enter the project directory and run: ```bash @@ -43,7 +47,27 @@ poetry run python3 bbtc.py --name 'Thread BLE' The application will connect to the first matching device discovered and set up a secure TLS channel. The user is then presented with the CLI. -## Commands +## Usage with a specific TCAT Commissioner identity + +The TCAT Commissioner's certificate specifies what permissions it has obtained for specific features of managing a TCAT Device. By default, the identity in the `auth` directory is used. In order to use a different TCAT Commissioner certificate (identity), use the `--cert_path` argument, as follows: + +```bash +poetry run python3 bbtc.py --cert_path { | --scan} +``` + +where `` is the directory where the private key, certificate, and CA certificate of the TCAT Commissioner are stored. + +For example to use a pre-configured identity `CommCert2` (related to Thread certification tests): + +``` +poetry run python3 bbtc.py --cert_path ./auth-cert/CommCert2 --name 'Thread BLE' +``` + +The `auth-cert` directory contains some other identities too, for testing purposes. Refer to Thread TCAT test plan documents for details. + +See [GENERATING_CERTIFICATES.md](GENERATING_CERTIFICATES.md) for details on generating own certificates. + +## TCAT Commissioner CLI Commands The application supports the following interactive CLI commands: @@ -53,4 +77,4 @@ The application supports the following interactive CLI commands: - `thread stop` - Disable Thread interface. - `hello` - Send "hello world" application data and read the response. - `exit` - Close the connection and exit. -- `dataset` - View and manipulate current dataset. See `dataset help` for more information. +- `dataset` - View and manipulate current dataset. Use `dataset help` for more information. diff --git a/tools/tcat_ble_client/auth-cert/CommCert1/ca_cert.pem b/tools/tcat_ble_client/auth-cert/CommCert1/ca_cert.pem new file mode 100644 index 000000000..190687b2c --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert1/ca_cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICOzCCAeGgAwIBAgIJAKOc2hehOGoBMAoGCCqGSM49BAMCMHExJjAkBgNVBAMM +HVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQg +R3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYD +VQQGEwJVUzAeFw0yNDA1MDMyMDAyMThaFw00NDA0MjgyMDAyMThaMHExJjAkBgNV +BAMMHVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJl +YWQgR3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQsw +CQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGy850VBIPTkN3oL +x++zIUsZk2k26w4fuieFz9oNvjdb5W14+Yf3mvGWsl4NHyLxqhmamVAR4h7zWRlZ +0XyMVpKjYjBgMB4GA1UdEQQXMBWBE3RvbUB0aHJlYWRncm91cC5vcmcwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFF+rGyloiKHUtDGo +hmHn52ZZ7fgZMAoGCCqGSM49BAMCA0gAMEUCIQCTq1qjPZs9fAJB6ppTXs588Pnu +eVFOwC8bd//D99KiHAIgU84kwFHIyDvFqu6y+u1hFqBGsiuTmKwZ2PHhVe/xK1k= +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/CommCert1/commissioner_cert.pem b/tools/tcat_ble_client/auth-cert/CommCert1/commissioner_cert.pem new file mode 100644 index 000000000..27b4c3c3c --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert1/commissioner_cert.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB1TCCAXugAwIBAgIDDhqDMAoGCCqGSM49BAMCMHExJjAkBgNVBAMMHVRocmVh +ZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQgR3JvdXAg +SW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJV +UzAeFw0yNDA1MDcwOTM5NDVaFw0yNDA1MjEwOTM5NDVaMDoxHzAdBgNVBAMMFlRD +QVQgRXhhbXBsZSBDb21tQ2VydDExFzAVBgNVBAUTDjM1MjMtMTU0My0wMDAxMFkw +EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHZq8vhZ816JEhgqe6zZKioMDFbrKEkJl +nRfSJEdfXZYSS94wUFKHzEHcAY3PU4IPTGnF5pusUE41rJa2n8vC76M5MDcwHwYD +VR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwFAYJKwYBBAGC3yoDBAcEBSEB +AQEBMAoGCCqGSM49BAMCA0gAMEUCIHeEfOOEX3jya2+bJMoGEEcFE56eUOjaz9aV +Tt1soEG8AiEA0taHGNpGgjE/b4kLW27dd8H+D/H5kNbq9Jlm9ct078Y= +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/CommCert1/commissioner_key.pem b/tools/tcat_ble_client/auth-cert/CommCert1/commissioner_key.pem new file mode 100644 index 000000000..5e22b6e7c --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert1/commissioner_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIPUEbXoKX2i4zyuvq7IRTVIlMpzf3t3pmlLc4uQprrq6oAoGCCqGSM49 +AwEHoUQDQgAEHZq8vhZ816JEhgqe6zZKioMDFbrKEkJlnRfSJEdfXZYSS94wUFKH +zEHcAY3PU4IPTGnF5pusUE41rJa2n8vC7w== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-cert/CommCert2/ca_cert.pem b/tools/tcat_ble_client/auth-cert/CommCert2/ca_cert.pem new file mode 100644 index 000000000..190687b2c --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert2/ca_cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICOzCCAeGgAwIBAgIJAKOc2hehOGoBMAoGCCqGSM49BAMCMHExJjAkBgNVBAMM +HVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQg +R3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYD +VQQGEwJVUzAeFw0yNDA1MDMyMDAyMThaFw00NDA0MjgyMDAyMThaMHExJjAkBgNV +BAMMHVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJl +YWQgR3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQsw +CQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGy850VBIPTkN3oL +x++zIUsZk2k26w4fuieFz9oNvjdb5W14+Yf3mvGWsl4NHyLxqhmamVAR4h7zWRlZ +0XyMVpKjYjBgMB4GA1UdEQQXMBWBE3RvbUB0aHJlYWRncm91cC5vcmcwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFF+rGyloiKHUtDGo +hmHn52ZZ7fgZMAoGCCqGSM49BAMCA0gAMEUCIQCTq1qjPZs9fAJB6ppTXs588Pnu +eVFOwC8bd//D99KiHAIgU84kwFHIyDvFqu6y+u1hFqBGsiuTmKwZ2PHhVe/xK1k= +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/CommCert2/commissioner_cert.pem b/tools/tcat_ble_client/auth-cert/CommCert2/commissioner_cert.pem new file mode 100644 index 000000000..47f13849c --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert2/commissioner_cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICLTCCAdSgAwIBAgIDDhqEMAoGCCqGSM49BAMCMHExJjAkBgNVBAMMHVRocmVh +ZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQgR3JvdXAg +SW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJV +UzAeFw0yNDA1MDcwOTM5NDVaFw0yNDA1MjEwOTM5NDVaMDoxHzAdBgNVBAMMFlRD +QVQgRXhhbXBsZSBDb21tQ2VydDIxFzAVBgNVBAUTDjM1MjMtMTU0My0wMDAyMFkw +EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBIvT4u0YQu5dka6tscIuV2DF/TpwDmWB +u3bCMa9KF80zbEjkg9Z9mf31Ia6jXjGD5cUosuEpyW8TlQK5WMLfmqOBkTCBjjAf +BgNVHSMEGDAWgBRfqxspaIih1LQxqIZh5+dmWe34GTAcBgkrBgEEAYLfKgEEDxYN +RGVmYXVsdERvbWFpbjAUBgkrBgEEAYLfKgMEBwQFIR8/Pz8wHgYJKwYBBAGC3yoE +BBEMD09wZW5UaHJlYWQtYzY0ZTAXBgkrBgEEAYLfKgUECgQI7xOYwv1QS2cwCgYI +KoZIzj0EAwIDRwAwRAIgHT2+7Uy47WApbpRHzZxOBskSielc8v/iQ2Jh+ZCmhdMC +IDx4gIX537LWrR4AwRVxAbZgYc7dI0r60IYF1nNstifq +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/CommCert2/commissioner_key.pem b/tools/tcat_ble_client/auth-cert/CommCert2/commissioner_key.pem new file mode 100644 index 000000000..c68952bd5 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert2/commissioner_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEINQLE/8iWwfE4OCnANeNL2hUPFIOa5uHjfw+eXatusAuoAoGCCqGSM49 +AwEHoUQDQgAEBIvT4u0YQu5dka6tscIuV2DF/TpwDmWBu3bCMa9KF80zbEjkg9Z9 +mf31Ia6jXjGD5cUosuEpyW8TlQK5WMLfmg== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-cert/CommCert3/ca_cert.pem b/tools/tcat_ble_client/auth-cert/CommCert3/ca_cert.pem new file mode 100644 index 000000000..1f854531a --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert3/ca_cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHjCCAcSgAwIBAgIBATAKBggqhkjOPQQDAjBmMR0wGwYDVQQDDBRUQ0FUIEV4 +YW1wbGUgQ0EgJ2NhJzEUMBIGA1UECgwLRXhhbXBsZSBJbmMxFTATBgNVBAcMDEV4 +YW1wbGUgQ2l0eTELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVTMB4XDTI0MDUwNTE5 +MTAyMloXDTQ0MDQzMDE5MTAyMlowZjEdMBsGA1UEAwwUVENBVCBFeGFtcGxlIENB +ICdjYScxFDASBgNVBAoMC0V4YW1wbGUgSW5jMRUwEwYDVQQHDAxFeGFtcGxlIENp +dHkxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49 +AwEHA0IABFncszwFxinmWPeDoRwFlx8yX0CIxksmjs5YC/ThBcNkqFA53CyjxsHz +wFEn7jMhJM7MzQzNBx5AbAy6ruJ9uf+jYzBhMB8GA1UdEQQYMBaBFGNhLWFkbWlu +QGV4YW1wbGUub3JnMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G +A1UdDgQWBBTgTKehLD14MpkRU+S6azYhYsAkKjAKBggqhkjOPQQDAgNIADBFAiA2 +Wp9JGbwiqbW0l0fTS+AKdp6xFXkmuePftuUTsnMKcgIhAPdC1zdx8fHPoTnRLpiH +Pt2/QkcSashR9zOp9MrBnRPb +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/CommCert3/commissioner_cert.pem b/tools/tcat_ble_client/auth-cert/CommCert3/commissioner_cert.pem new file mode 100644 index 000000000..09ea0d4a5 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert3/commissioner_cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICJDCCAcmgAwIBAgIDDhqFMAoGCCqGSM49BAMCMGYxHTAbBgNVBAMMFFRDQVQg +RXhhbXBsZSBDQSAnY2EnMRQwEgYDVQQKDAtFeGFtcGxlIEluYzEVMBMGA1UEBwwM +RXhhbXBsZSBDaXR5MQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwHhcNMjQwNTA3 +MDkzOTQ1WhcNMjQwNTIxMDkzOTQ1WjA6MR8wHQYDVQQDDBZUQ0FUIEV4YW1wbGUg +Q29tbUNlcnQzMRcwFQYDVQQFEw4zNTIzLTE1NDMtMDAwMzBZMBMGByqGSM49AgEG +CCqGSM49AwEHA0IABBMQUVTNWNZ4cFKOFHFdvrcWvDTRU98NyLfWgU28iZTE+sP8 +NUdJaom8LbOPmheVBJIH7tn6P8n5s6g6XpDCvTOjgZEwgY4wHwYDVR0jBBgwFoAU +4EynoSw9eDKZEVPkums2IWLAJCowHAYJKwYBBAGC3yoBBA8WDURlZmF1bHREb21h +aW4wFAYJKwYBBAGC3yoDBAcEBSEBAQEBMB4GCSsGAQQBgt8qBAQRDA9PcGVuVGhy +ZWFkLWM2NGUwFwYJKwYBBAGC3yoFBAoECO8TmML9UEtnMAoGCCqGSM49BAMCA0kA +MEYCIQCiVqJRirJq53f2EdbsaEXsquRa5uixF6BlHlwsT/zKdQIhAPytUgQLa0aO +UjrzO+V2JIpJvboAZKYB45x56IfWrNZb +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/CommCert3/commissioner_key.pem b/tools/tcat_ble_client/auth-cert/CommCert3/commissioner_key.pem new file mode 100644 index 000000000..7d70c8f41 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert3/commissioner_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIE0aPRr+B9R9MZ9SKadjEhIzV7LeoDB4E1Hkhd1mJuzPoAoGCCqGSM49 +AwEHoUQDQgAEExBRVM1Y1nhwUo4UcV2+txa8NNFT3w3It9aBTbyJlMT6w/w1R0lq +ibwts4+aF5UEkgfu2fo/yfmzqDpekMK9Mw== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-cert/CommCert4/ca_cert.pem b/tools/tcat_ble_client/auth-cert/CommCert4/ca_cert.pem new file mode 100644 index 000000000..190687b2c --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert4/ca_cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICOzCCAeGgAwIBAgIJAKOc2hehOGoBMAoGCCqGSM49BAMCMHExJjAkBgNVBAMM +HVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQg +R3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYD +VQQGEwJVUzAeFw0yNDA1MDMyMDAyMThaFw00NDA0MjgyMDAyMThaMHExJjAkBgNV +BAMMHVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJl +YWQgR3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQsw +CQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGy850VBIPTkN3oL +x++zIUsZk2k26w4fuieFz9oNvjdb5W14+Yf3mvGWsl4NHyLxqhmamVAR4h7zWRlZ +0XyMVpKjYjBgMB4GA1UdEQQXMBWBE3RvbUB0aHJlYWRncm91cC5vcmcwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFF+rGyloiKHUtDGo +hmHn52ZZ7fgZMAoGCCqGSM49BAMCA0gAMEUCIQCTq1qjPZs9fAJB6ppTXs588Pnu +eVFOwC8bd//D99KiHAIgU84kwFHIyDvFqu6y+u1hFqBGsiuTmKwZ2PHhVe/xK1k= +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/CommCert4/commissioner_cert.pem b/tools/tcat_ble_client/auth-cert/CommCert4/commissioner_cert.pem new file mode 100644 index 000000000..e085a1273 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert4/commissioner_cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICLDCCAdOgAwIBAgIDDhqGMAoGCCqGSM49BAMCMHExJjAkBgNVBAMMHVRocmVh +ZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQgR3JvdXAg +SW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJV +UzAeFw0yNDA1MDcwOTM5NDVaFw0yNDA1MjEwOTM5NDVaMDoxHzAdBgNVBAMMFlRD +QVQgRXhhbXBsZSBDb21tQ2VydDQxFzAVBgNVBAUTDjM1MjMtMTU0My0wMDA0MFkw +EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgIgp7nkc36xTPKv0lySnQYCyw/SDHjDI +5iRDukFYEVBwRQ1CI20HDZ3iqf/MxXZb3UcLZ4aYylSHJeq8I5jX86OBkDCBjTAf +BgNVHSMEGDAWgBRfqxspaIih1LQxqIZh5+dmWe34GTAaBgkrBgEEAYLfKgEEDRYL +T3RoZXJEb21haW4wFAYJKwYBBAGC3yoDBAcEBSEhBQkRMB8GCSsGAQQBgt8qBAQS +DBBPdGhlclRocmVhZC1jNjRlMBcGCSsGAQQBgt8qBQQKBAjvE5jC/VBLaDAKBggq +hkjOPQQDAgNHADBEAiApGUDXoCYeY8jRTyEwgnm6GuMPuGOBHE2daLOaHd/TtQIg +JfNCGBbf8gQIUfH3bs5OheMj0BDzXmP66nsuF3mnyps= +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/CommCert4/commissioner_key.pem b/tools/tcat_ble_client/auth-cert/CommCert4/commissioner_key.pem new file mode 100644 index 000000000..6e9374312 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/CommCert4/commissioner_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIM1pKneJbjUDWNpRPfygf1Wfi/FkzQHv+gN8Co7f+6kioAoGCCqGSM49 +AwEHoUQDQgAEgIgp7nkc36xTPKv0lySnQYCyw/SDHjDI5iRDukFYEVBwRQ1CI20H +DZ3iqf/MxXZb3UcLZ4aYylSHJeq8I5jX8w== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-cert/DeviceCert1/ca_cert.pem b/tools/tcat_ble_client/auth-cert/DeviceCert1/ca_cert.pem new file mode 100644 index 000000000..190687b2c --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/DeviceCert1/ca_cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICOzCCAeGgAwIBAgIJAKOc2hehOGoBMAoGCCqGSM49BAMCMHExJjAkBgNVBAMM +HVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQg +R3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYD +VQQGEwJVUzAeFw0yNDA1MDMyMDAyMThaFw00NDA0MjgyMDAyMThaMHExJjAkBgNV +BAMMHVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJl +YWQgR3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQsw +CQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGy850VBIPTkN3oL +x++zIUsZk2k26w4fuieFz9oNvjdb5W14+Yf3mvGWsl4NHyLxqhmamVAR4h7zWRlZ +0XyMVpKjYjBgMB4GA1UdEQQXMBWBE3RvbUB0aHJlYWRncm91cC5vcmcwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFF+rGyloiKHUtDGo +hmHn52ZZ7fgZMAoGCCqGSM49BAMCA0gAMEUCIQCTq1qjPZs9fAJB6ppTXs588Pnu +eVFOwC8bd//D99KiHAIgU84kwFHIyDvFqu6y+u1hFqBGsiuTmKwZ2PHhVe/xK1k= +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/DeviceCert1/commissioner_cert.pem b/tools/tcat_ble_client/auth-cert/DeviceCert1/commissioner_cert.pem new file mode 100644 index 000000000..e7148ce13 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/DeviceCert1/commissioner_cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB6TCCAZCgAwIBAgICNekwCgYIKoZIzj0EAwIwcTEmMCQGA1UEAwwdVGhyZWFk +IENlcnRpZmljYXRpb24gRGV2aWNlQ0ExGTAXBgNVBAoMEFRocmVhZCBHcm91cCBJ +bmMxEjAQBgNVBAcMCVNhbiBSYW1vbjELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVT +MCAXDTI0MDUwNzA5Mzk0NVoYDzI5OTkxMjMxMDkzOTQ1WjA8MSEwHwYDVQQDDBhU +Q0FUIEV4YW1wbGUgRGV2aWNlQ2VydDExFzAVBgNVBAUTDjQ3MjMtOTgzMy0wMDAx +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE11h/4vKZXVXv+1GDZo066spItloT +dpCi0bux0jvpQSHLdQBIc+40zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdqNLMEkw +HwYDVR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwEAYJKwYBBAGC3yoCBAMC +AQUwFAYJKwYBBAGC3yoDBAcEBSABAQEBMAoGCCqGSM49BAMCA0cAMEQCIHWu+Rd1 +VRlzrD8KbuyJcJFTXh2sQ9UIrFIA7+4e/GVcAiAVBdGqTxbt3TGkBBllpafAUB2/ +s0GJj7E33oblqy5eHQ== +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/DeviceCert1/commissioner_key.pem b/tools/tcat_ble_client/auth-cert/DeviceCert1/commissioner_key.pem new file mode 100644 index 000000000..7864bfd30 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/DeviceCert1/commissioner_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIIqKM1QTlNaquV74W6Viz/ggXoLqlPOP6LagSyaFO3oUoAoGCCqGSM49 +AwEHoUQDQgAE11h/4vKZXVXv+1GDZo066spItloTdpCi0bux0jvpQSHLdQBIc+40 +zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdg== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-cert/DeviceCert1/device_cert.pem b/tools/tcat_ble_client/auth-cert/DeviceCert1/device_cert.pem new file mode 100644 index 000000000..e7148ce13 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/DeviceCert1/device_cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB6TCCAZCgAwIBAgICNekwCgYIKoZIzj0EAwIwcTEmMCQGA1UEAwwdVGhyZWFk +IENlcnRpZmljYXRpb24gRGV2aWNlQ0ExGTAXBgNVBAoMEFRocmVhZCBHcm91cCBJ +bmMxEjAQBgNVBAcMCVNhbiBSYW1vbjELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVT +MCAXDTI0MDUwNzA5Mzk0NVoYDzI5OTkxMjMxMDkzOTQ1WjA8MSEwHwYDVQQDDBhU +Q0FUIEV4YW1wbGUgRGV2aWNlQ2VydDExFzAVBgNVBAUTDjQ3MjMtOTgzMy0wMDAx +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE11h/4vKZXVXv+1GDZo066spItloT +dpCi0bux0jvpQSHLdQBIc+40zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdqNLMEkw +HwYDVR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwEAYJKwYBBAGC3yoCBAMC +AQUwFAYJKwYBBAGC3yoDBAcEBSABAQEBMAoGCCqGSM49BAMCA0cAMEQCIHWu+Rd1 +VRlzrD8KbuyJcJFTXh2sQ9UIrFIA7+4e/GVcAiAVBdGqTxbt3TGkBBllpafAUB2/ +s0GJj7E33oblqy5eHQ== +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/DeviceCert1/device_key.pem b/tools/tcat_ble_client/auth-cert/DeviceCert1/device_key.pem new file mode 100644 index 000000000..7864bfd30 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/DeviceCert1/device_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIIqKM1QTlNaquV74W6Viz/ggXoLqlPOP6LagSyaFO3oUoAoGCCqGSM49 +AwEHoUQDQgAE11h/4vKZXVXv+1GDZo066spItloTdpCi0bux0jvpQSHLdQBIc+40 +zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdg== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-cert/DeviceCert2/ca_cert.pem b/tools/tcat_ble_client/auth-cert/DeviceCert2/ca_cert.pem new file mode 100644 index 000000000..190687b2c --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/DeviceCert2/ca_cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICOzCCAeGgAwIBAgIJAKOc2hehOGoBMAoGCCqGSM49BAMCMHExJjAkBgNVBAMM +HVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQg +R3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYD +VQQGEwJVUzAeFw0yNDA1MDMyMDAyMThaFw00NDA0MjgyMDAyMThaMHExJjAkBgNV +BAMMHVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJl +YWQgR3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQsw +CQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGy850VBIPTkN3oL +x++zIUsZk2k26w4fuieFz9oNvjdb5W14+Yf3mvGWsl4NHyLxqhmamVAR4h7zWRlZ +0XyMVpKjYjBgMB4GA1UdEQQXMBWBE3RvbUB0aHJlYWRncm91cC5vcmcwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFF+rGyloiKHUtDGo +hmHn52ZZ7fgZMAoGCCqGSM49BAMCA0gAMEUCIQCTq1qjPZs9fAJB6ppTXs588Pnu +eVFOwC8bd//D99KiHAIgU84kwFHIyDvFqu6y+u1hFqBGsiuTmKwZ2PHhVe/xK1k= +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/DeviceCert2/commissioner_cert.pem b/tools/tcat_ble_client/auth-cert/DeviceCert2/commissioner_cert.pem new file mode 100644 index 000000000..41bdba7a9 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/DeviceCert2/commissioner_cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB6TCCAZCgAwIBAgICNeowCgYIKoZIzj0EAwIwcTEmMCQGA1UEAwwdVGhyZWFk +IENlcnRpZmljYXRpb24gRGV2aWNlQ0ExGTAXBgNVBAoMEFRocmVhZCBHcm91cCBJ +bmMxEjAQBgNVBAcMCVNhbiBSYW1vbjELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVT +MCAXDTI0MDUwNzA5Mzk0NVoYDzI5OTkxMjMxMDkzOTQ1WjA8MSEwHwYDVQQDDBhU +Q0FUIEV4YW1wbGUgRGV2aWNlQ2VydDIxFzAVBgNVBAUTDjQ3MjMtOTgzMy0wMDAy +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE30GMkqSBj3049NtK6G/MRTqcDxpm +i1LxTpSxFIB7P9HVoVM7Cd9X6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmi6NLMEkw +HwYDVR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwEAYJKwYBBAGC3yoCBAMC +AQUwFAYJKwYBBAGC3yoDBAcEBSABAQEBMAoGCCqGSM49BAMCA0cAMEQCIAbZzVbC +toNYgSWSgxRGzLRo1YJANqRC7yRtJNKTdQ1ZAiAlgGxEW2lkxCAGPUK1m9Wbb4kl +7AhBhYlK6vZz/omTsQ== +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/DeviceCert2/commissioner_key.pem b/tools/tcat_ble_client/auth-cert/DeviceCert2/commissioner_key.pem new file mode 100644 index 000000000..3f6b4ec49 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/DeviceCert2/commissioner_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIP7Al8tJA3QgwD3yIuOSEmJkT3GlWmcHQ59JfhZOjSdUoAoGCCqGSM49 +AwEHoUQDQgAE30GMkqSBj3049NtK6G/MRTqcDxpmi1LxTpSxFIB7P9HVoVM7Cd9X +6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmiw== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-cert/DeviceCert2/device_cert.pem b/tools/tcat_ble_client/auth-cert/DeviceCert2/device_cert.pem new file mode 100644 index 000000000..41bdba7a9 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/DeviceCert2/device_cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB6TCCAZCgAwIBAgICNeowCgYIKoZIzj0EAwIwcTEmMCQGA1UEAwwdVGhyZWFk +IENlcnRpZmljYXRpb24gRGV2aWNlQ0ExGTAXBgNVBAoMEFRocmVhZCBHcm91cCBJ +bmMxEjAQBgNVBAcMCVNhbiBSYW1vbjELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVT +MCAXDTI0MDUwNzA5Mzk0NVoYDzI5OTkxMjMxMDkzOTQ1WjA8MSEwHwYDVQQDDBhU +Q0FUIEV4YW1wbGUgRGV2aWNlQ2VydDIxFzAVBgNVBAUTDjQ3MjMtOTgzMy0wMDAy +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE30GMkqSBj3049NtK6G/MRTqcDxpm +i1LxTpSxFIB7P9HVoVM7Cd9X6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmi6NLMEkw +HwYDVR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwEAYJKwYBBAGC3yoCBAMC +AQUwFAYJKwYBBAGC3yoDBAcEBSABAQEBMAoGCCqGSM49BAMCA0cAMEQCIAbZzVbC +toNYgSWSgxRGzLRo1YJANqRC7yRtJNKTdQ1ZAiAlgGxEW2lkxCAGPUK1m9Wbb4kl +7AhBhYlK6vZz/omTsQ== +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth-cert/DeviceCert2/device_key.pem b/tools/tcat_ble_client/auth-cert/DeviceCert2/device_key.pem new file mode 100644 index 000000000..3f6b4ec49 --- /dev/null +++ b/tools/tcat_ble_client/auth-cert/DeviceCert2/device_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIP7Al8tJA3QgwD3yIuOSEmJkT3GlWmcHQ59JfhZOjSdUoAoGCCqGSM49 +AwEHoUQDQgAE30GMkqSBj3049NtK6G/MRTqcDxpmi1LxTpSxFIB7P9HVoVM7Cd9X +6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmiw== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-generate/Makefile b/tools/tcat_ble_client/auth-generate/Makefile new file mode 100644 index 000000000..6760a9845 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/Makefile @@ -0,0 +1,48 @@ +# +# Copyright (c) 2024, The OpenThread Authors. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# Makefile for creating TCAT example certificates (except CA). + +# Select here which named CAs from the 'ca' directory are used for signing. +#ca = TcatCertCa # for example +otherCa = ca +ca = ca + +all: DeviceCert1 DeviceCert2 CommCert1 CommCert2 CommCert3 CommCert4 + +DeviceCert1 DeviceCert2: ext/DeviceCert1.ext ext/DeviceCert2.ext + ./create-cert-tcat-device.sh $@ $(ca) + +CommCert1 CommCert2 CommCert4: ext/CommCert1.ext ext/CommCert2.ext ext/CommCert4.ext + ./create-cert-tcat-commissioner.sh $@ $(ca) + +CommCert3: ext/CommCert3.ext + ./create-cert-tcat-commissioner.sh $@ $(otherCa) + +clean: + rm -rf ./output diff --git a/tools/tcat_ble_client/auth-generate/ca/ca_cert.pem b/tools/tcat_ble_client/auth-generate/ca/ca_cert.pem new file mode 100644 index 000000000..1f854531a --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/ca/ca_cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHjCCAcSgAwIBAgIBATAKBggqhkjOPQQDAjBmMR0wGwYDVQQDDBRUQ0FUIEV4 +YW1wbGUgQ0EgJ2NhJzEUMBIGA1UECgwLRXhhbXBsZSBJbmMxFTATBgNVBAcMDEV4 +YW1wbGUgQ2l0eTELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVTMB4XDTI0MDUwNTE5 +MTAyMloXDTQ0MDQzMDE5MTAyMlowZjEdMBsGA1UEAwwUVENBVCBFeGFtcGxlIENB +ICdjYScxFDASBgNVBAoMC0V4YW1wbGUgSW5jMRUwEwYDVQQHDAxFeGFtcGxlIENp +dHkxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49 +AwEHA0IABFncszwFxinmWPeDoRwFlx8yX0CIxksmjs5YC/ThBcNkqFA53CyjxsHz +wFEn7jMhJM7MzQzNBx5AbAy6ruJ9uf+jYzBhMB8GA1UdEQQYMBaBFGNhLWFkbWlu +QGV4YW1wbGUub3JnMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G +A1UdDgQWBBTgTKehLD14MpkRU+S6azYhYsAkKjAKBggqhkjOPQQDAgNIADBFAiA2 +Wp9JGbwiqbW0l0fTS+AKdp6xFXkmuePftuUTsnMKcgIhAPdC1zdx8fHPoTnRLpiH +Pt2/QkcSashR9zOp9MrBnRPb +-----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth/ca_key.pem b/tools/tcat_ble_client/auth-generate/ca/ca_key.pem similarity index 100% rename from tools/tcat_ble_client/auth/ca_key.pem rename to tools/tcat_ble_client/auth-generate/ca/ca_key.pem diff --git a/tools/tcat_ble_client/auth-generate/create-cert-ca.sh b/tools/tcat_ble_client/auth-generate/create-cert-ca.sh new file mode 100755 index 000000000..e17ec5a51 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/create-cert-ca.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# +# Copyright (c) 2024, The OpenThread Authors. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# Create the certificate of an example CA for TCAT. This single CA creates both the +# TCAT Device certificates, as well as the TCAT Commissioner certificates that +# work for those TCAT Devices. + +if [ $# -ne 1 ]; then + echo "Usage: ./create-cert-ca.sh " + exit 1 +fi +set -eu + +# days certificate is valid +((VALIDITY = 20 * 365)) + +NAME=${1} + +# create csr +openssl req -new -key "ca/${NAME}_key.pem" -out "${NAME}.csr" \ + -subj "/CN=TCAT Example CA '${NAME}'/O=Example Inc/L=Example City/ST=CA/C=US" + +# self-sign csr +mkdir -p output +openssl x509 -set_serial 0x01 -extfile "ext/${NAME}.ext" \ + -extensions "${NAME}" -req -in "${NAME}.csr" \ + -signkey "ca/${NAME}_key.pem" -out "ca/${NAME}_cert.pem" \ + -days "${VALIDITY}" -sha256 + +# delete temp files +rm -f "${NAME}.csr" + +# show result +openssl x509 -text -in "ca/${NAME}_cert.pem" diff --git a/tools/tcat_ble_client/auth-generate/create-cert-tcat-commissioner.sh b/tools/tcat_ble_client/auth-generate/create-cert-tcat-commissioner.sh new file mode 100755 index 000000000..0afc1951d --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/create-cert-tcat-commissioner.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# +# Copyright (c) 2024, The OpenThread Authors. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# Script to generate a TCAT Commissioner X509v3 certificate. + +if [ $# -ne 2 ]; then + echo "Usage: ./create-cert-tcat-commissioner.sh " + exit 1 +fi +set -eu + +# number of days certificate is valid +((VALIDITY = "14")) +echo "create-cert-tcat-commissioner.sh - Using validity param -days ${VALIDITY}" + +NAME=${1} +CANAME=${2} +((ID = ${NAME:0-1})) +CACERTFILE="ca/${CANAME}_cert.pem" + +echo " TCAT commissioner name : ${NAME}" +echo " TCAT commissioner CA name: ${CANAME}" +echo " Numeric serial ID : ${ID}" + +# create csr for TCAT Commissioner +openssl req -new -key "keys/${NAME}_key.pem" -out "${NAME}.csr" -subj \ + "/CN=TCAT Example ${NAME}/serialNumber=3523-1543-000${ID}" + +# sign csr by CA +mkdir -p "output/${NAME}" +openssl x509 -set_serial "92429${ID}" -CAform PEM -CA "${CACERTFILE}" \ + -CAkey "ca/${CANAME}_key.pem" -extfile "ext/${NAME}.ext" -extensions \ + "${NAME}" -req -in "${NAME}.csr" -out "output/${NAME}/commissioner_cert.pem" \ + -days "${VALIDITY}" -sha256 + +# delete temp files +rm -f "${NAME}.csr" + +# copy supporting files, for immediate use by TCAT Commissioner as 'cert_path' +cp "${CACERTFILE}" "output/${NAME}/ca_cert.pem" +cp "keys/${NAME}_key.pem" "output/${NAME}/commissioner_key.pem" diff --git a/tools/tcat_ble_client/auth-generate/create-cert-tcat-device.sh b/tools/tcat_ble_client/auth-generate/create-cert-tcat-device.sh new file mode 100755 index 000000000..7e2805f30 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/create-cert-tcat-device.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# +# Copyright (c) 2024, The OpenThread Authors. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# Script to generate a TCAT Device X509v3 certificate. + +if [ $# -ne 2 ]; then + echo "Usage: ./create-cert-tcat-device.sh " + exit 1 +fi +set -eu + +# days certificate is valid +SECONDS1=$(date +%s) # time now +SECONDS2=$(date --date="2999-12-31 23:59:59Z" +%s) # target end time +((VALIDITY = "(${SECONDS2}-${SECONDS1})/(24*3600)")) +echo "create-cert-tcat-device.sh - Using validity param -days ${VALIDITY}" + +NAME="${1}" +CANAME="${2}" +CACERTFILE="ca/${CANAME}_cert.pem" +((ID = ${NAME:0-1})) +((SERIAL = 13800 + ID)) + +echo " TCAT device name : ${NAME}" +echo " TCAT device CA name: ${CANAME}" +echo " Numeric serial ID : ${ID}" + +# create csr for device. +# conform to 802.1AR guidelines, using only CN + serialNumber when +# manufacturer is already present as CA. CN is not even mandatory, but just good practice. +openssl req -new -key "keys/${NAME}_key.pem" -out "${NAME}.csr" -subj \ + "/CN=TCAT Example ${NAME}/serialNumber=4723-9833-000${ID}" + +# sign csr by CA +mkdir -p "output/${NAME}" +openssl x509 -set_serial "${SERIAL}" -CAform PEM -CA "${CACERTFILE}" \ + -CAkey "ca/${CANAME}_key.pem" -extfile "ext/${NAME}.ext" -extensions \ + "${NAME}" -req -in "${NAME}.csr" -out "output/${NAME}/device_cert.pem" \ + -days "${VALIDITY}" -sha256 + +# delete temp files +rm -f "${NAME}.csr" + +# copy supporting files, for immediate use by TCAT Commissioner as 'cert_path'. +# Normally a Commissioner must not use Device certs, but for testing purposes this +# option is provided here. +cp "output/${NAME}/device_cert.pem" "output/${NAME}/commissioner_cert.pem" +cp "${CACERTFILE}" "output/${NAME}/ca_cert.pem" +cp "keys/${NAME}_key.pem" "output/${NAME}/commissioner_key.pem" +cp "keys/${NAME}_key.pem" "output/${NAME}/device_key.pem" diff --git a/tools/tcat_ble_client/auth-generate/ext/CommCert1.ext b/tools/tcat_ble_client/auth-generate/ext/CommCert1.ext new file mode 100644 index 000000000..819fe45a6 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/ext/CommCert1.ext @@ -0,0 +1,12 @@ +# This file contains X509v3 extension definitions for OpenSSL +# certificate generation. + +[ CommCert1 ] +subjectKeyIdentifier = none +authorityKeyIdentifier = keyid + +# Include TCAT specified fields +# Because ASN1:OCTETSTRING doesn't work with hex input, we use raw DER here. Tag 0x04 is OCTETSTRING. +# See https://datatracker.ietf.org/doc/html/rfc5280#section-4.1 +# +1.3.6.1.4.1.44970.3 = DER:04:05:21:01:01:01:01 diff --git a/tools/tcat_ble_client/auth-generate/ext/CommCert2.ext b/tools/tcat_ble_client/auth-generate/ext/CommCert2.ext new file mode 100644 index 000000000..fb5323e3b --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/ext/CommCert2.ext @@ -0,0 +1,15 @@ +# This file contains X509v3 extension definitions for OpenSSL +# certificate generation. + +[ CommCert2 ] +subjectKeyIdentifier = none +authorityKeyIdentifier = keyid + +# Include TCAT specified fields +# Because ASN1:OCTETSTRING doesn't work with hex input, we use raw DER here. Tag 0x04 is OCTETSTRING. +# See https://datatracker.ietf.org/doc/html/rfc5280#section-4.1 +# +1.3.6.1.4.1.44970.1 = ASN1:IA5STRING:DefaultDomain +1.3.6.1.4.1.44970.3 = DER:04:05:21:1F:3F:3F:3F +1.3.6.1.4.1.44970.4 = ASN1:UTF8STRING:OpenThread-c64e +1.3.6.1.4.1.44970.5 = DER:04:08:ef:13:98:c2:fd:50:4b:67 diff --git a/tools/tcat_ble_client/auth-generate/ext/CommCert3.ext b/tools/tcat_ble_client/auth-generate/ext/CommCert3.ext new file mode 100644 index 000000000..67da08345 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/ext/CommCert3.ext @@ -0,0 +1,15 @@ +# This file contains X509v3 extension definitions for OpenSSL +# certificate generation. + +[ CommCert3 ] +subjectKeyIdentifier = none +authorityKeyIdentifier = keyid + +# Include TCAT specified fields +# Because ASN1:OCTETSTRING doesn't work with hex input, we use raw DER here. Tag 0x04 is OCTETSTRING. +# See https://datatracker.ietf.org/doc/html/rfc5280#section-4.1 +# +1.3.6.1.4.1.44970.1 = ASN1:IA5STRING:DefaultDomain +1.3.6.1.4.1.44970.3 = DER:04:05:21:01:01:01:01 +1.3.6.1.4.1.44970.4 = ASN1:UTF8STRING:OpenThread-c64e +1.3.6.1.4.1.44970.5 = DER:04:08:ef:13:98:c2:fd:50:4b:67 diff --git a/tools/tcat_ble_client/auth-generate/ext/CommCert4.ext b/tools/tcat_ble_client/auth-generate/ext/CommCert4.ext new file mode 100644 index 000000000..136679fbb --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/ext/CommCert4.ext @@ -0,0 +1,15 @@ +# This file contains X509v3 extension definitions for OpenSSL +# certificate generation. + +[ CommCert4 ] +subjectKeyIdentifier = none +authorityKeyIdentifier = keyid + +# Include TCAT specified fields +# Because ASN1:OCTETSTRING doesn't work with hex input, we use raw DER here. Tag 0x04 is OCTETSTRING. +# See https://datatracker.ietf.org/doc/html/rfc5280#section-4.1 +# +1.3.6.1.4.1.44970.1 = ASN1:IA5STRING:OtherDomain +1.3.6.1.4.1.44970.3 = DER:04:05:21:21:05:09:11 +1.3.6.1.4.1.44970.4 = ASN1:UTF8STRING:OtherThread-c64e +1.3.6.1.4.1.44970.5 = DER:04:08:ef:13:98:c2:fd:50:4b:68 diff --git a/tools/tcat_ble_client/auth-generate/ext/DeviceCert1.ext b/tools/tcat_ble_client/auth-generate/ext/DeviceCert1.ext new file mode 100644 index 000000000..88c5ce7a4 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/ext/DeviceCert1.ext @@ -0,0 +1,15 @@ +# This file contains X509v3 extension definitions for OpenSSL +# certificate generation. + +[ DeviceCert1 ] +subjectKeyIdentifier = none +authorityKeyIdentifier = keyid + +# Include Thread version field +1.3.6.1.4.1.44970.2 = ASN1:INTEGER:5 + +# Include TCAT specified fields +# Because ASN1:OCTETSTRING doesn't work with hex input, we use raw DER here. Tag 0x04 is OCTETSTRING. +# See https://datatracker.ietf.org/doc/html/rfc5280#section-4.1 +# +1.3.6.1.4.1.44970.3 = DER:04:05:20:01:01:01:01 diff --git a/tools/tcat_ble_client/auth-generate/ext/DeviceCert2.ext b/tools/tcat_ble_client/auth-generate/ext/DeviceCert2.ext new file mode 100644 index 000000000..02cdaf119 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/ext/DeviceCert2.ext @@ -0,0 +1,15 @@ +# This file contains X509v3 extension definitions for OpenSSL +# certificate generation. + +[ DeviceCert2 ] +subjectKeyIdentifier = none +authorityKeyIdentifier = keyid + +# Include Thread version field +1.3.6.1.4.1.44970.2 = ASN1:INTEGER:5 + +# Include TCAT specified fields +# Because ASN1:OCTETSTRING doesn't work with hex input, we use raw DER here. Tag 0x04 is OCTETSTRING. +# See https://datatracker.ietf.org/doc/html/rfc5280#section-4.1 +# +1.3.6.1.4.1.44970.3 = DER:04:05:20:01:01:01:01 diff --git a/tools/tcat_ble_client/auth-generate/ext/ca.ext b/tools/tcat_ble_client/auth-generate/ext/ca.ext new file mode 100644 index 000000000..4f0b939dd --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/ext/ca.ext @@ -0,0 +1,9 @@ +# This file contains X509v3 extension definitions for OpenSSL +# certificate generation. + +[ ca ] +subjectAltName = email:ca-admin@example.org +keyUsage = critical, digitalSignature, keyCertSign, cRLSign +basicConstraints = critical,CA:TRUE +subjectKeyIdentifier = hash +authorityKeyIdentifier = none diff --git a/tools/tcat_ble_client/auth-generate/keys/CommCert1_key.pem b/tools/tcat_ble_client/auth-generate/keys/CommCert1_key.pem new file mode 100644 index 000000000..5e22b6e7c --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/keys/CommCert1_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIPUEbXoKX2i4zyuvq7IRTVIlMpzf3t3pmlLc4uQprrq6oAoGCCqGSM49 +AwEHoUQDQgAEHZq8vhZ816JEhgqe6zZKioMDFbrKEkJlnRfSJEdfXZYSS94wUFKH +zEHcAY3PU4IPTGnF5pusUE41rJa2n8vC7w== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-generate/keys/CommCert2_key.pem b/tools/tcat_ble_client/auth-generate/keys/CommCert2_key.pem new file mode 100644 index 000000000..c68952bd5 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/keys/CommCert2_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEINQLE/8iWwfE4OCnANeNL2hUPFIOa5uHjfw+eXatusAuoAoGCCqGSM49 +AwEHoUQDQgAEBIvT4u0YQu5dka6tscIuV2DF/TpwDmWBu3bCMa9KF80zbEjkg9Z9 +mf31Ia6jXjGD5cUosuEpyW8TlQK5WMLfmg== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-generate/keys/CommCert3_key.pem b/tools/tcat_ble_client/auth-generate/keys/CommCert3_key.pem new file mode 100644 index 000000000..7d70c8f41 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/keys/CommCert3_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIE0aPRr+B9R9MZ9SKadjEhIzV7LeoDB4E1Hkhd1mJuzPoAoGCCqGSM49 +AwEHoUQDQgAEExBRVM1Y1nhwUo4UcV2+txa8NNFT3w3It9aBTbyJlMT6w/w1R0lq +ibwts4+aF5UEkgfu2fo/yfmzqDpekMK9Mw== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-generate/keys/CommCert4_key.pem b/tools/tcat_ble_client/auth-generate/keys/CommCert4_key.pem new file mode 100644 index 000000000..6e9374312 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/keys/CommCert4_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIM1pKneJbjUDWNpRPfygf1Wfi/FkzQHv+gN8Co7f+6kioAoGCCqGSM49 +AwEHoUQDQgAEgIgp7nkc36xTPKv0lySnQYCyw/SDHjDI5iRDukFYEVBwRQ1CI20H +DZ3iqf/MxXZb3UcLZ4aYylSHJeq8I5jX8w== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-generate/keys/DeviceCert1_key.pem b/tools/tcat_ble_client/auth-generate/keys/DeviceCert1_key.pem new file mode 100644 index 000000000..7864bfd30 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/keys/DeviceCert1_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIIqKM1QTlNaquV74W6Viz/ggXoLqlPOP6LagSyaFO3oUoAoGCCqGSM49 +AwEHoUQDQgAE11h/4vKZXVXv+1GDZo066spItloTdpCi0bux0jvpQSHLdQBIc+40 +zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdg== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth-generate/keys/DeviceCert2_key.pem b/tools/tcat_ble_client/auth-generate/keys/DeviceCert2_key.pem new file mode 100644 index 000000000..3f6b4ec49 --- /dev/null +++ b/tools/tcat_ble_client/auth-generate/keys/DeviceCert2_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIP7Al8tJA3QgwD3yIuOSEmJkT3GlWmcHQ59JfhZOjSdUoAoGCCqGSM49 +AwEHoUQDQgAE30GMkqSBj3049NtK6G/MRTqcDxpmi1LxTpSxFIB7P9HVoVM7Cd9X +6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmiw== +-----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/auth/ca_cert.pem b/tools/tcat_ble_client/auth/ca_cert.pem index e9994c122..190687b2c 100644 --- a/tools/tcat_ble_client/auth/ca_cert.pem +++ b/tools/tcat_ble_client/auth/ca_cert.pem @@ -1,13 +1,14 @@ -----BEGIN CERTIFICATE----- -MIICCDCCAa2gAwIBAgIJAIKxygBXoH+5MAoGCCqGSM49BAMCMG8xCzAJBgNVBAYT -AlhYMRAwDgYDVQQIEwdNeVN0YXRlMQ8wDQYDVQQHEwZNeUNpdHkxDzANBgNVBAsT -Bk15VW5pdDERMA8GA1UEChMITXlWZW5kb3IxGTAXBgNVBAMTEHd3dy5teXZlbmRv -ci5jb20wHhcNMjMxMDE2MTAzMzE1WhcNMjYxMDE2MTAzMzE1WjBvMQswCQYDVQQG -EwJYWDEQMA4GA1UECBMHTXlTdGF0ZTEPMA0GA1UEBxMGTXlDaXR5MQ8wDQYDVQQL -EwZNeVVuaXQxETAPBgNVBAoTCE15VmVuZG9yMRkwFwYDVQQDExB3d3cubXl2ZW5k -b3IuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWdyzPAXGKeZY94OhHAWX -HzJfQIjGSyaOzlgL9OEFw2SoUDncLKPGwfPAUSfuMyEkzszNDM0HHkBsDLqu4n25 -/6MyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU4EynoSw9eDKZEVPkums2 -IWLAJCowCgYIKoZIzj0EAwIDSQAwRgIhAMYGGL9xShyE6P9wEU+MAYF6W3CzdrwV -kuerX1encIH2AiEA5rq490NUobM1Au43roxJq1T6Z43LscPVbGZfULD1Jq0= +MIICOzCCAeGgAwIBAgIJAKOc2hehOGoBMAoGCCqGSM49BAMCMHExJjAkBgNVBAMM +HVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQg +R3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYD +VQQGEwJVUzAeFw0yNDA1MDMyMDAyMThaFw00NDA0MjgyMDAyMThaMHExJjAkBgNV +BAMMHVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJl +YWQgR3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQsw +CQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGy850VBIPTkN3oL +x++zIUsZk2k26w4fuieFz9oNvjdb5W14+Yf3mvGWsl4NHyLxqhmamVAR4h7zWRlZ +0XyMVpKjYjBgMB4GA1UdEQQXMBWBE3RvbUB0aHJlYWRncm91cC5vcmcwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFF+rGyloiKHUtDGo +hmHn52ZZ7fgZMAoGCCqGSM49BAMCA0gAMEUCIQCTq1qjPZs9fAJB6ppTXs588Pnu +eVFOwC8bd//D99KiHAIgU84kwFHIyDvFqu6y+u1hFqBGsiuTmKwZ2PHhVe/xK1k= -----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth/commissioner_cert.pem b/tools/tcat_ble_client/auth/commissioner_cert.pem index 3f40dc8d4..27b4c3c3c 100644 --- a/tools/tcat_ble_client/auth/commissioner_cert.pem +++ b/tools/tcat_ble_client/auth/commissioner_cert.pem @@ -1,11 +1,12 @@ -----BEGIN CERTIFICATE----- -MIIBnzCCAUSgAwIBAgIUQ5RUJMc95ssHQybR6pcx7LXSBzcwCgYIKoZIzj0EAwIw -bzELMAkGA1UEBhMCWFgxEDAOBgNVBAgTB015U3RhdGUxDzANBgNVBAcTBk15Q2l0 -eTEPMA0GA1UECxMGTXlVbml0MREwDwYDVQQKEwhNeVZlbmRvcjEZMBcGA1UEAxMQ -d3d3Lm15dmVuZG9yLmNvbTAeFw0yMzEwMTgxNTIyMTZaFw0zMzEwMTUxNTIyMTZa -MBcxFTATBgNVBAMMDENvbW1pc3Npb25lcjBZMBMGByqGSM49AgEGCCqGSM49AwEH -A0IABDU90Qpae5c+5Diou072S6MMHNv9+Ah9Kmo+mZTT6gQUyRScFey3+6wE08o7 -wl6/8EKRgS8TFSihK4mYGxYoN06jFjAUMBIGCSsGAQQBgt8qAwQFIQEBAQEwCgYI -KoZIzj0EAwIDSQAwRgIhAOgQH8wFSe3JtGSmEFLy4fbMhOg+5Mfhqoq95vu2ML/u -AiEAt4BjuFo7GTxQxXl1e8TvMGESPGBKnR7cIT/BCnn2fto= +MIIB1TCCAXugAwIBAgIDDhqDMAoGCCqGSM49BAMCMHExJjAkBgNVBAMMHVRocmVh +ZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQgR3JvdXAg +SW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJV +UzAeFw0yNDA1MDcwOTM5NDVaFw0yNDA1MjEwOTM5NDVaMDoxHzAdBgNVBAMMFlRD +QVQgRXhhbXBsZSBDb21tQ2VydDExFzAVBgNVBAUTDjM1MjMtMTU0My0wMDAxMFkw +EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHZq8vhZ816JEhgqe6zZKioMDFbrKEkJl +nRfSJEdfXZYSS94wUFKHzEHcAY3PU4IPTGnF5pusUE41rJa2n8vC76M5MDcwHwYD +VR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwFAYJKwYBBAGC3yoDBAcEBSEB +AQEBMAoGCCqGSM49BAMCA0gAMEUCIHeEfOOEX3jya2+bJMoGEEcFE56eUOjaz9aV +Tt1soEG8AiEA0taHGNpGgjE/b4kLW27dd8H+D/H5kNbq9Jlm9ct078Y= -----END CERTIFICATE----- diff --git a/tools/tcat_ble_client/auth/commissioner_key.pem b/tools/tcat_ble_client/auth/commissioner_key.pem index 57b683920..5e22b6e7c 100644 --- a/tools/tcat_ble_client/auth/commissioner_key.pem +++ b/tools/tcat_ble_client/auth/commissioner_key.pem @@ -1,8 +1,5 @@ ------BEGIN EC PARAMETERS----- -BggqhkjOPQMBBw== ------END EC PARAMETERS----- -----BEGIN EC PRIVATE KEY----- -MHcCAQEEIFOGszqvbs62fRwd3Rnd79wf6fpWxkXLO5YzhEuJ9EV1oAoGCCqGSM49 -AwEHoUQDQgAENT3RClp7lz7kOKi7TvZLowwc2/34CH0qaj6ZlNPqBBTJFJwV7Lf7 -rATTyjvCXr/wQpGBLxMVKKEriZgbFig3Tg== +MHcCAQEEIPUEbXoKX2i4zyuvq7IRTVIlMpzf3t3pmlLc4uQprrq6oAoGCCqGSM49 +AwEHoUQDQgAEHZq8vhZ816JEhgqe6zZKioMDFbrKEkJlnRfSJEdfXZYSS94wUFKH +zEHcAY3PU4IPTGnF5pusUE41rJa2n8vC7w== -----END EC PRIVATE KEY----- diff --git a/tools/tcat_ble_client/bbtc.py b/tools/tcat_ble_client/bbtc.py index 92539c12f..d2c7ea687 100755 --- a/tools/tcat_ble_client/bbtc.py +++ b/tools/tcat_ble_client/bbtc.py @@ -28,19 +28,21 @@ import asyncio import argparse -from os import path import logging +import os from ble.ble_connection_constants import BBTC_SERVICE_UUID, BBTC_TX_CHAR_UUID, \ - BBTC_RX_CHAR_UUID, SERVER_COMMON_NAME + BBTC_RX_CHAR_UUID from ble.ble_stream import BleStream -from ble.udp_stream import UdpStream from ble.ble_stream_secure import BleStreamSecure +from ble.udp_stream import UdpStream from ble import ble_scanner from cli.cli import CLI from dataset.dataset import ThreadDataset from cli.command import CommandResult -from utils import select_device_by_user_input +from utils import select_device_by_user_input, quit_with_reason + +logger = logging.getLogger(__name__) async def main(): @@ -48,6 +50,7 @@ async def main(): parser = argparse.ArgumentParser(description='Device parameters') parser.add_argument('--debug', help='Enable debug logs', action='store_true') + parser.add_argument('--info', help='Enable info logs', action='store_true') parser.add_argument('--cert_path', help='Path to certificate chain and key', action='store', default='auth') group = parser.add_mutually_exclusive_group() group.add_argument('--mac', type=str, help='Device MAC address', action='store') @@ -57,25 +60,40 @@ async def main(): args = parser.parse_args() if args.debug: - logging.getLogger('ble_stream').setLevel(logging.DEBUG) - logging.getLogger('ble_stream_secure').setLevel(logging.DEBUG) + logger.setLevel(logging.DEBUG) + logging.getLogger('ble.ble_stream').setLevel(logging.DEBUG) + logging.getLogger('ble.ble_stream_secure').setLevel(logging.DEBUG) + logging.getLogger('ble.udp_stream').setLevel(logging.DEBUG) + elif args.info: + logger.setLevel(logging.INFO) + logging.getLogger('ble.ble_stream').setLevel(logging.INFO) + logging.getLogger('ble.ble_stream_secure').setLevel(logging.INFO) + logging.getLogger('ble.udp_stream').setLevel(logging.INFO) device = await get_device_by_args(args) ble_sstream = None - if not (device is None): + if device is not None: print(f'Connecting to {device}') ble_sstream = BleStreamSecure(device) ble_sstream.load_cert( - certfile=path.join(args.cert_path, 'commissioner_cert.pem'), - keyfile=path.join(args.cert_path, 'commissioner_key.pem'), - cafile=path.join(args.cert_path, 'ca_cert.pem'), + certfile=os.path.join(args.cert_path, 'commissioner_cert.pem'), + keyfile=os.path.join(args.cert_path, 'commissioner_key.pem'), + cafile=os.path.join(args.cert_path, 'ca_cert.pem'), ) + logger.info(f"Certificates and key loaded from '{args.cert_path}'") - print('Setting up secure channel...') - await ble_sstream.do_handshake(hostname=SERVER_COMMON_NAME) - print('Done') + print('Setting up secure TLS channel..', end='') + try: + await ble_sstream.do_handshake() + print('\nDone') + ble_sstream.log_cert_identities() + except Exception as e: + print('\nFailed') + logger.error(e) + ble_sstream.log_cert_identities() + quit_with_reason('TLS handshake failure') ds = ThreadDataset() cli = CLI(ds, ble_sstream) @@ -85,13 +103,15 @@ async def main(): user_input = await loop.run_in_executor(None, lambda: input('> ')) if user_input.lower() == 'exit': print('Disconnecting...') + if ble_sstream is not None: + await ble_sstream.close() break try: result: CommandResult = await cli.evaluate_input(user_input) if result: result.pretty_print() except Exception as e: - print(e) + logger.error(e) async def get_device_by_args(args): diff --git a/tools/tcat_ble_client/ble/ble_connection_constants.py b/tools/tcat_ble_client/ble/ble_connection_constants.py index f1064c635..88013dcde 100644 --- a/tools/tcat_ble_client/ble/ble_connection_constants.py +++ b/tools/tcat_ble_client/ble/ble_connection_constants.py @@ -29,4 +29,3 @@ BBTC_SERVICE_UUID = 'FFFB' BBTC_RX_CHAR_UUID = '6BD10D8B-85A7-4E5A-BA2D-C83558A5F220' BBTC_TX_CHAR_UUID = '7FDDF61F-280A-4773-B448-BA1B8FE0DD69' -SERVER_COMMON_NAME = 'myvendor.com/tcat/mydev' diff --git a/tools/tcat_ble_client/ble/ble_stream_secure.py b/tools/tcat_ble_client/ble/ble_stream_secure.py index 4731c18e2..ab8858c29 100644 --- a/tools/tcat_ble_client/ble/ble_stream_secure.py +++ b/tools/tcat_ble_client/ble/ble_stream_secure.py @@ -26,10 +26,16 @@ POSSIBILITY OF SUCH DAMAGE. """ +import _ssl import asyncio import ssl +import sys import logging +from tlv.tlv import TLV +from tlv.tcat_tlv import TcatTLVType +import utils + logger = logging.getLogger(__name__) @@ -41,27 +47,35 @@ def __init__(self, stream): self.incoming = ssl.MemoryBIO() self.outgoing = ssl.MemoryBIO() self.ssl_object = None + self.cert = '' def load_cert(self, certfile='', keyfile='', cafile=''): if certfile and keyfile: self.ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile) + self.cert = utils.load_cert_pem(certfile) elif certfile: self.ssl_context.load_cert_chain(certfile=certfile) + self.cert = utils.load_cert_pem(certfile) if cafile: self.ssl_context.load_verify_locations(cafile=cafile) - async def do_handshake(self, hostname): + async def do_handshake(self): + is_debug = logger.getEffectiveLevel() <= logging.DEBUG self.ssl_object = self.ssl_context.wrap_bio( incoming=self.incoming, outgoing=self.outgoing, server_side=False, - server_hostname=hostname, + server_hostname=None, ) while True: try: + if not is_debug: + print('.', end='') + sys.stdout.flush() self.ssl_object.do_handshake() break + # SSLWantWrite means ssl wants to send data over the link, # but might need a receive first except ssl.SSLWantWriteError: @@ -71,7 +85,7 @@ async def do_handshake(self, hostname): data = self.outgoing.read() if data: await self.stream.send(data) - await asyncio.sleep(0.1) + await asyncio.sleep(0.02) # SSLWantRead means ssl wants to receive data from the link, # but might need to send first @@ -82,7 +96,7 @@ async def do_handshake(self, hostname): output = await self.stream.recv(4096) if output: self.incoming.write(output) - await asyncio.sleep(0.1) + await asyncio.sleep(0.02) async def send(self, bytes): self.ssl_object.write(bytes) @@ -117,3 +131,27 @@ async def send_with_resp(self, bytes): await self.send(bytes) res = await self.recv(buffersize=4096, timeout=5) return res + + async def close(self): + if self.ssl_object.session is not None: + data = TLV(TcatTLVType.DISCONNECT.value, bytes()).to_bytes() + await self.send(data) + + def log_cert_identities(self): + # using the internal object of the ssl library is necessary to see the cert data in + # case of handshake failure - see https://sethmlarson.dev/experimental-python-3.10-apis-and-trust-stores + # Should work for Python >= 3.10 + try: + cc = self.ssl_object._sslobj.get_unverified_chain() + if cc is None: + logger.info('No TCAT Device cert chain was received (yet).') + return + logger.info(f'TCAT Device cert chain: {len(cc)} certificates received.') + for cert in cc: + logger.info(f' cert info:\n{cert.get_info()}') + peer_cert_der_hex = utils.base64_string(cert.public_bytes(_ssl.ENCODING_DER)) + logger.info(f' base64: (paste in https://lapo.it/asn1js/ to decode)\n{peer_cert_der_hex}') + logger.info(f'TCAT Commissioner cert, PEM:\n{self.cert}') + + except Exception as e: + logger.warning('Could not display TCAT client cert info (check Python version is >= 3.10?)') diff --git a/tools/tcat_ble_client/ble/udp_stream.py b/tools/tcat_ble_client/ble/udp_stream.py index 542194046..c6ba599a0 100644 --- a/tools/tcat_ble_client/ble/udp_stream.py +++ b/tools/tcat_ble_client/ble/udp_stream.py @@ -26,11 +26,7 @@ POSSIBILITY OF SUCH DAMAGE. """ -from itertools import count, takewhile -from typing import Iterator import logging -import time -from asyncio import sleep import socket logger = logging.getLogger(__name__) diff --git a/tools/tcat_ble_client/cli/base_commands.py b/tools/tcat_ble_client/cli/base_commands.py index bd4c1dbea..a865b8711 100644 --- a/tools/tcat_ble_client/cli/base_commands.py +++ b/tools/tcat_ble_client/cli/base_commands.py @@ -27,7 +27,7 @@ """ from ble.ble_connection_constants import BBTC_SERVICE_UUID, BBTC_TX_CHAR_UUID, \ - BBTC_RX_CHAR_UUID, SERVER_COMMON_NAME + BBTC_RX_CHAR_UUID from ble.ble_stream import BleStream from ble.ble_stream_secure import BleStreamSecure from ble import ble_scanner @@ -160,6 +160,6 @@ async def execute_default(self, args, context): ) print('Setting up secure channel...') - await ble_sstream.do_handshake(hostname=SERVER_COMMON_NAME) + await ble_sstream.do_handshake() print('Done') context['ble_sstream'] = ble_sstream diff --git a/tools/tcat_ble_client/tlv/tcat_tlv.py b/tools/tcat_ble_client/tlv/tcat_tlv.py index cb5b49e0c..30ca543bf 100644 --- a/tools/tcat_ble_client/tlv/tcat_tlv.py +++ b/tools/tcat_ble_client/tlv/tcat_tlv.py @@ -31,6 +31,7 @@ class TcatTLVType(Enum): RESPONSE_W_STATUS = 0x01 RESPONSE_W_PAYLOAD = 0x02 + DISCONNECT = 0x09 ACTIVE_DATASET = 0x20 DECOMMISSION = 0x60 APPLICATION = 0x82 diff --git a/tools/tcat_ble_client/utils/__init__.py b/tools/tcat_ble_client/utils/__init__.py index d6d40bae9..47730e346 100644 --- a/tools/tcat_ble_client/utils/__init__.py +++ b/tools/tcat_ble_client/utils/__init__.py @@ -26,6 +26,8 @@ POSSIBILITY OF SUCH DAMAGE. """ +import base64 + def get_int_in_range(min_value, max_value): while True: @@ -61,3 +63,12 @@ def select_device_by_user_input(tcat_devices): print('Selected ', device) return device + + +def base64_string(bindata): + return base64.b64encode(bindata).decode('ascii') + + +def load_cert_pem(fn): + with open(fn, 'r') as file: + return file.read()