mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[tcat] add TCAT Commissioner / Device certs for Thread certification testing (#10211)
This commit is contained in:
+39
-32
@@ -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"
|
||||
// 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-----\r\n" \
|
||||
"MHcCAQEEIDeJ6lVQKiOIBxKwTZp6TkU5QVHt9pvXOR9CGpPBI3DhoAoGCCqGSM49\r\n" \
|
||||
"AwEHoUQDQgAEAWlsBQzY9W6UCHTfiqdnB1sOeVP/n2vjpmZ6MtQeATk/vNto3cDw\r\n" \
|
||||
"bsl1gEKAXWHUCX3+EYJoXM8leD4QKzyLgA==\r\n" \
|
||||
"-----END EC PRIVATE KEY-----\r\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-----\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_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 {
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -240,6 +240,7 @@ public:
|
||||
enum TcatCertificateAttribute
|
||||
{
|
||||
kCertificateDomainName = 1,
|
||||
kCertificateThreadVersion = 2,
|
||||
kCertificateAuthorizationField = 3,
|
||||
kCertificateNetworkName = 4,
|
||||
kCertificateExtendedPanId = 5,
|
||||
|
||||
@@ -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)
|
||||
|
||||
+69
-35
@@ -35,40 +35,43 @@
|
||||
|
||||
#include <openthread/ble_secure.h>
|
||||
|
||||
#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_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-----\r\n" \
|
||||
"MHcCAQEEIDeJ6lVQKiOIBxKwTZp6TkU5QVHt9pvXOR9CGpPBI3DhoAoGCCqGSM49\r\n" \
|
||||
"AwEHoUQDQgAEAWlsBQzY9W6UCHTfiqdnB1sOeVP/n2vjpmZ6MtQeATk/vNto3cDw\r\n" \
|
||||
"bsl1gEKAXWHUCX3+EYJoXM8leD4QKzyLgA==\r\n" \
|
||||
"-----END EC PRIVATE KEY-----\r\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-----\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_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);
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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 <certs-path> {<device specifier> | --scan}
|
||||
```
|
||||
|
||||
where `<certs-path>` 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.
|
||||
|
||||
@@ -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-----
|
||||
@@ -0,0 +1,12 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB1TCCAXugAwIBAgIDDhqDMAoGCCqGSM49BAMCMHExJjAkBgNVBAMMHVRocmVh
|
||||
ZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQgR3JvdXAg
|
||||
SW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJV
|
||||
UzAeFw0yNDA1MDcwOTM5NDVaFw0yNDA1MjEwOTM5NDVaMDoxHzAdBgNVBAMMFlRD
|
||||
QVQgRXhhbXBsZSBDb21tQ2VydDExFzAVBgNVBAUTDjM1MjMtMTU0My0wMDAxMFkw
|
||||
EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHZq8vhZ816JEhgqe6zZKioMDFbrKEkJl
|
||||
nRfSJEdfXZYSS94wUFKHzEHcAY3PU4IPTGnF5pusUE41rJa2n8vC76M5MDcwHwYD
|
||||
VR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwFAYJKwYBBAGC3yoDBAcEBSEB
|
||||
AQEBMAoGCCqGSM49BAMCA0gAMEUCIHeEfOOEX3jya2+bJMoGEEcFE56eUOjaz9aV
|
||||
Tt1soEG8AiEA0taHGNpGgjE/b4kLW27dd8H+D/H5kNbq9Jlm9ct078Y=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIPUEbXoKX2i4zyuvq7IRTVIlMpzf3t3pmlLc4uQprrq6oAoGCCqGSM49
|
||||
AwEHoUQDQgAEHZq8vhZ816JEhgqe6zZKioMDFbrKEkJlnRfSJEdfXZYSS94wUFKH
|
||||
zEHcAY3PU4IPTGnF5pusUE41rJa2n8vC7w==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -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-----
|
||||
@@ -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-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEINQLE/8iWwfE4OCnANeNL2hUPFIOa5uHjfw+eXatusAuoAoGCCqGSM49
|
||||
AwEHoUQDQgAEBIvT4u0YQu5dka6tscIuV2DF/TpwDmWBu3bCMa9KF80zbEjkg9Z9
|
||||
mf31Ia6jXjGD5cUosuEpyW8TlQK5WMLfmg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -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-----
|
||||
@@ -0,0 +1,14 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICJDCCAcmgAwIBAgIDDhqFMAoGCCqGSM49BAMCMGYxHTAbBgNVBAMMFFRDQVQg
|
||||
RXhhbXBsZSBDQSAnY2EnMRQwEgYDVQQKDAtFeGFtcGxlIEluYzEVMBMGA1UEBwwM
|
||||
RXhhbXBsZSBDaXR5MQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwHhcNMjQwNTA3
|
||||
MDkzOTQ1WhcNMjQwNTIxMDkzOTQ1WjA6MR8wHQYDVQQDDBZUQ0FUIEV4YW1wbGUg
|
||||
Q29tbUNlcnQzMRcwFQYDVQQFEw4zNTIzLTE1NDMtMDAwMzBZMBMGByqGSM49AgEG
|
||||
CCqGSM49AwEHA0IABBMQUVTNWNZ4cFKOFHFdvrcWvDTRU98NyLfWgU28iZTE+sP8
|
||||
NUdJaom8LbOPmheVBJIH7tn6P8n5s6g6XpDCvTOjgZEwgY4wHwYDVR0jBBgwFoAU
|
||||
4EynoSw9eDKZEVPkums2IWLAJCowHAYJKwYBBAGC3yoBBA8WDURlZmF1bHREb21h
|
||||
aW4wFAYJKwYBBAGC3yoDBAcEBSEBAQEBMB4GCSsGAQQBgt8qBAQRDA9PcGVuVGhy
|
||||
ZWFkLWM2NGUwFwYJKwYBBAGC3yoFBAoECO8TmML9UEtnMAoGCCqGSM49BAMCA0kA
|
||||
MEYCIQCiVqJRirJq53f2EdbsaEXsquRa5uixF6BlHlwsT/zKdQIhAPytUgQLa0aO
|
||||
UjrzO+V2JIpJvboAZKYB45x56IfWrNZb
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIE0aPRr+B9R9MZ9SKadjEhIzV7LeoDB4E1Hkhd1mJuzPoAoGCCqGSM49
|
||||
AwEHoUQDQgAEExBRVM1Y1nhwUo4UcV2+txa8NNFT3w3It9aBTbyJlMT6w/w1R0lq
|
||||
ibwts4+aF5UEkgfu2fo/yfmzqDpekMK9Mw==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -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-----
|
||||
@@ -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-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIM1pKneJbjUDWNpRPfygf1Wfi/FkzQHv+gN8Co7f+6kioAoGCCqGSM49
|
||||
AwEHoUQDQgAEgIgp7nkc36xTPKv0lySnQYCyw/SDHjDI5iRDukFYEVBwRQ1CI20H
|
||||
DZ3iqf/MxXZb3UcLZ4aYylSHJeq8I5jX8w==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -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-----
|
||||
@@ -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-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIIqKM1QTlNaquV74W6Viz/ggXoLqlPOP6LagSyaFO3oUoAoGCCqGSM49
|
||||
AwEHoUQDQgAE11h/4vKZXVXv+1GDZo066spItloTdpCi0bux0jvpQSHLdQBIc+40
|
||||
zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -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-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIIqKM1QTlNaquV74W6Viz/ggXoLqlPOP6LagSyaFO3oUoAoGCCqGSM49
|
||||
AwEHoUQDQgAE11h/4vKZXVXv+1GDZo066spItloTdpCi0bux0jvpQSHLdQBIc+40
|
||||
zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -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-----
|
||||
@@ -0,0 +1,13 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB6TCCAZCgAwIBAgICNeowCgYIKoZIzj0EAwIwcTEmMCQGA1UEAwwdVGhyZWFk
|
||||
IENlcnRpZmljYXRpb24gRGV2aWNlQ0ExGTAXBgNVBAoMEFRocmVhZCBHcm91cCBJ
|
||||
bmMxEjAQBgNVBAcMCVNhbiBSYW1vbjELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVT
|
||||
MCAXDTI0MDUwNzA5Mzk0NVoYDzI5OTkxMjMxMDkzOTQ1WjA8MSEwHwYDVQQDDBhU
|
||||
Q0FUIEV4YW1wbGUgRGV2aWNlQ2VydDIxFzAVBgNVBAUTDjQ3MjMtOTgzMy0wMDAy
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE30GMkqSBj3049NtK6G/MRTqcDxpm
|
||||
i1LxTpSxFIB7P9HVoVM7Cd9X6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmi6NLMEkw
|
||||
HwYDVR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwEAYJKwYBBAGC3yoCBAMC
|
||||
AQUwFAYJKwYBBAGC3yoDBAcEBSABAQEBMAoGCCqGSM49BAMCA0cAMEQCIAbZzVbC
|
||||
toNYgSWSgxRGzLRo1YJANqRC7yRtJNKTdQ1ZAiAlgGxEW2lkxCAGPUK1m9Wbb4kl
|
||||
7AhBhYlK6vZz/omTsQ==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIP7Al8tJA3QgwD3yIuOSEmJkT3GlWmcHQ59JfhZOjSdUoAoGCCqGSM49
|
||||
AwEHoUQDQgAE30GMkqSBj3049NtK6G/MRTqcDxpmi1LxTpSxFIB7P9HVoVM7Cd9X
|
||||
6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmiw==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -0,0 +1,13 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB6TCCAZCgAwIBAgICNeowCgYIKoZIzj0EAwIwcTEmMCQGA1UEAwwdVGhyZWFk
|
||||
IENlcnRpZmljYXRpb24gRGV2aWNlQ0ExGTAXBgNVBAoMEFRocmVhZCBHcm91cCBJ
|
||||
bmMxEjAQBgNVBAcMCVNhbiBSYW1vbjELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVT
|
||||
MCAXDTI0MDUwNzA5Mzk0NVoYDzI5OTkxMjMxMDkzOTQ1WjA8MSEwHwYDVQQDDBhU
|
||||
Q0FUIEV4YW1wbGUgRGV2aWNlQ2VydDIxFzAVBgNVBAUTDjQ3MjMtOTgzMy0wMDAy
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE30GMkqSBj3049NtK6G/MRTqcDxpm
|
||||
i1LxTpSxFIB7P9HVoVM7Cd9X6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmi6NLMEkw
|
||||
HwYDVR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwEAYJKwYBBAGC3yoCBAMC
|
||||
AQUwFAYJKwYBBAGC3yoDBAcEBSABAQEBMAoGCCqGSM49BAMCA0cAMEQCIAbZzVbC
|
||||
toNYgSWSgxRGzLRo1YJANqRC7yRtJNKTdQ1ZAiAlgGxEW2lkxCAGPUK1m9Wbb4kl
|
||||
7AhBhYlK6vZz/omTsQ==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIP7Al8tJA3QgwD3yIuOSEmJkT3GlWmcHQ59JfhZOjSdUoAoGCCqGSM49
|
||||
AwEHoUQDQgAE30GMkqSBj3049NtK6G/MRTqcDxpmi1LxTpSxFIB7P9HVoVM7Cd9X
|
||||
6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmiw==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -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
|
||||
@@ -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-----
|
||||
+60
@@ -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 <NameOfCA>"
|
||||
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"
|
||||
@@ -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 <NameOfCommissioner> <NameOfCA>"
|
||||
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"
|
||||
@@ -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 <NameOfDevice> <NameOfCA>"
|
||||
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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIPUEbXoKX2i4zyuvq7IRTVIlMpzf3t3pmlLc4uQprrq6oAoGCCqGSM49
|
||||
AwEHoUQDQgAEHZq8vhZ816JEhgqe6zZKioMDFbrKEkJlnRfSJEdfXZYSS94wUFKH
|
||||
zEHcAY3PU4IPTGnF5pusUE41rJa2n8vC7w==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEINQLE/8iWwfE4OCnANeNL2hUPFIOa5uHjfw+eXatusAuoAoGCCqGSM49
|
||||
AwEHoUQDQgAEBIvT4u0YQu5dka6tscIuV2DF/TpwDmWBu3bCMa9KF80zbEjkg9Z9
|
||||
mf31Ia6jXjGD5cUosuEpyW8TlQK5WMLfmg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIE0aPRr+B9R9MZ9SKadjEhIzV7LeoDB4E1Hkhd1mJuzPoAoGCCqGSM49
|
||||
AwEHoUQDQgAEExBRVM1Y1nhwUo4UcV2+txa8NNFT3w3It9aBTbyJlMT6w/w1R0lq
|
||||
ibwts4+aF5UEkgfu2fo/yfmzqDpekMK9Mw==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIM1pKneJbjUDWNpRPfygf1Wfi/FkzQHv+gN8Co7f+6kioAoGCCqGSM49
|
||||
AwEHoUQDQgAEgIgp7nkc36xTPKv0lySnQYCyw/SDHjDI5iRDukFYEVBwRQ1CI20H
|
||||
DZ3iqf/MxXZb3UcLZ4aYylSHJeq8I5jX8w==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIIqKM1QTlNaquV74W6Viz/ggXoLqlPOP6LagSyaFO3oUoAoGCCqGSM49
|
||||
AwEHoUQDQgAE11h/4vKZXVXv+1GDZo066spItloTdpCi0bux0jvpQSHLdQBIc+40
|
||||
zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIP7Al8tJA3QgwD3yIuOSEmJkT3GlWmcHQ59JfhZOjSdUoAoGCCqGSM49
|
||||
AwEHoUQDQgAE30GMkqSBj3049NtK6G/MRTqcDxpmi1LxTpSxFIB7P9HVoVM7Cd9X
|
||||
6bBUp5FrSZI+KHtX2HKtXzmzsdJ3gxAmiw==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -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-----
|
||||
|
||||
@@ -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-----
|
||||
|
||||
@@ -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-----
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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 @@ class BleStreamSecure:
|
||||
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 @@ class BleStreamSecure:
|
||||
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 @@ class BleStreamSecure:
|
||||
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 @@ class BleStreamSecure:
|
||||
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?)')
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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 @@ class ScanCommand(Command):
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
@@ -31,6 +31,7 @@ from enum import Enum
|
||||
class TcatTLVType(Enum):
|
||||
RESPONSE_W_STATUS = 0x01
|
||||
RESPONSE_W_PAYLOAD = 0x02
|
||||
DISCONNECT = 0x09
|
||||
ACTIVE_DATASET = 0x20
|
||||
DECOMMISSION = 0x60
|
||||
APPLICATION = 0x82
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user