1 /*
2 * Copyright (c) 2024, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "openthread-core-config.h"
30
31 #include "test_platform.h"
32 #include "test_util.h"
33
34 #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
35
36 #include <openthread/ble_secure.h>
37
38 #define OT_TCAT_X509_CERT \
39 "-----BEGIN CERTIFICATE-----\r\n" \
40 "MIIBmDCCAT+gAwIBAgIEAQIDBDAKBggqhkjOPQQDAjBvMQswCQYDVQQGEwJYWDEQ\r\n" \
41 "MA4GA1UECBMHTXlTdGF0ZTEPMA0GA1UEBxMGTXlDaXR5MQ8wDQYDVQQLEwZNeVVu\r\n" \
42 "aXQxETAPBgNVBAoTCE15VmVuZG9yMRkwFwYDVQQDExB3d3cubXl2ZW5kb3IuY29t\r\n" \
43 "MB4XDTIzMTAxNjEwMzk1NFoXDTI0MTAxNjEwMzk1NFowIjEgMB4GA1UEAxMXbXl2\r\n" \
44 "ZW5kb3IuY29tL3RjYXQvbXlkZXYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQB\r\n" \
45 "aWwFDNj1bpQIdN+Kp2cHWw55U/+fa+OmZnoy1B4BOT+822jdwPBuyXWAQoBdYdQJ\r\n" \
46 "ff4RgmhczyV4PhArPIuAoxYwFDASBgkrBgEEAYLfKgMEBQABAQEBMAoGCCqGSM49\r\n" \
47 "BAMCA0cAMEQCIBEHxiEDij26y6V77Q311Gj4CZAuZuPGXZpnzL2BLk7bAiAlFk6G\r\n" \
48 "mYGzkcrYyssFI9HlPgrisWoMmgummaTtCuvrEw==\r\n" \
49 "-----END CERTIFICATE-----\r\n"
50
51 #define OT_TCAT_PRIV_KEY \
52 "-----BEGIN EC PRIVATE KEY-----\r\n" \
53 "MHcCAQEEIDeJ6lVQKiOIBxKwTZp6TkU5QVHt9pvXOR9CGpPBI3DhoAoGCCqGSM49\r\n" \
54 "AwEHoUQDQgAEAWlsBQzY9W6UCHTfiqdnB1sOeVP/n2vjpmZ6MtQeATk/vNto3cDw\r\n" \
55 "bsl1gEKAXWHUCX3+EYJoXM8leD4QKzyLgA==\r\n" \
56 "-----END EC PRIVATE KEY-----\r\n"
57
58 #define OT_TCAT_TRUSTED_ROOT_CERTIFICATE \
59 "-----BEGIN CERTIFICATE-----\r\n" \
60 "MIICCDCCAa2gAwIBAgIJAIKxygBXoH+5MAoGCCqGSM49BAMCMG8xCzAJBgNVBAYT\r\n" \
61 "AlhYMRAwDgYDVQQIEwdNeVN0YXRlMQ8wDQYDVQQHEwZNeUNpdHkxDzANBgNVBAsT\r\n" \
62 "Bk15VW5pdDERMA8GA1UEChMITXlWZW5kb3IxGTAXBgNVBAMTEHd3dy5teXZlbmRv\r\n" \
63 "ci5jb20wHhcNMjMxMDE2MTAzMzE1WhcNMjYxMDE2MTAzMzE1WjBvMQswCQYDVQQG\r\n" \
64 "EwJYWDEQMA4GA1UECBMHTXlTdGF0ZTEPMA0GA1UEBxMGTXlDaXR5MQ8wDQYDVQQL\r\n" \
65 "EwZNeVVuaXQxETAPBgNVBAoTCE15VmVuZG9yMRkwFwYDVQQDExB3d3cubXl2ZW5k\r\n" \
66 "b3IuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWdyzPAXGKeZY94OhHAWX\r\n" \
67 "HzJfQIjGSyaOzlgL9OEFw2SoUDncLKPGwfPAUSfuMyEkzszNDM0HHkBsDLqu4n25\r\n" \
68 "/6MyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU4EynoSw9eDKZEVPkums2\r\n" \
69 "IWLAJCowCgYIKoZIzj0EAwIDSQAwRgIhAMYGGL9xShyE6P9wEU+MAYF6W3CzdrwV\r\n" \
70 "kuerX1encIH2AiEA5rq490NUobM1Au43roxJq1T6Z43LscPVbGZfULD1Jq0=\r\n" \
71 "-----END CERTIFICATE-----\r\n"
72
73 namespace ot {
74
75 class TestBleSecure
76 {
77 public:
TestBleSecure(void)78 TestBleSecure(void)
79 : mIsConnected(false)
80 , mIsBleConnectionOpen(false)
81 {
82 }
83
HandleBleSecureConnect(bool aConnected,bool aBleConnectionOpen)84 void HandleBleSecureConnect(bool aConnected, bool aBleConnectionOpen)
85 {
86 mIsConnected = aConnected;
87 mIsBleConnectionOpen = aBleConnectionOpen;
88 }
89
IsConnected(void) const90 bool IsConnected(void) const { return mIsConnected; }
IsBleConnectionOpen(void) const91 bool IsBleConnectionOpen(void) const { return mIsBleConnectionOpen; }
92
93 private:
94 bool mIsConnected;
95 bool mIsBleConnectionOpen;
96 };
97
HandleBleSecureConnect(otInstance * aInstance,bool aConnected,bool aBleConnectionOpen,void * aContext)98 static void HandleBleSecureConnect(otInstance *aInstance, bool aConnected, bool aBleConnectionOpen, void *aContext)
99 {
100 OT_UNUSED_VARIABLE(aInstance);
101
102 static_cast<TestBleSecure *>(aContext)->HandleBleSecureConnect(aConnected, aBleConnectionOpen);
103 }
104
TestTcat(void)105 void TestTcat(void)
106 {
107 const char kPskdVendor[] = "J01NM3";
108 const char kUrl[] = "dummy_url";
109 constexpr uint16_t kConnectionId = 0;
110
111 TestBleSecure ble;
112 Instance *instance = testInitInstance();
113
114 otTcatVendorInfo vendorInfo = {.mProvisioningUrl = kUrl, .mPskdString = kPskdVendor};
115
116 otBleSecureSetCertificate(instance, reinterpret_cast<const uint8_t *>(OT_TCAT_X509_CERT), sizeof(OT_TCAT_X509_CERT),
117 reinterpret_cast<const uint8_t *>(OT_TCAT_PRIV_KEY), sizeof(OT_TCAT_PRIV_KEY));
118
119 otBleSecureSetCaCertificateChain(instance, reinterpret_cast<const uint8_t *>(OT_TCAT_TRUSTED_ROOT_CERTIFICATE),
120 sizeof(OT_TCAT_TRUSTED_ROOT_CERTIFICATE));
121
122 otBleSecureSetSslAuthMode(instance, true);
123
124 // Validate BLE secure and Tcat start APIs
125 VerifyOrQuit(otBleSecureTcatStart(instance, &vendorInfo, nullptr) == kErrorInvalidState);
126 SuccessOrQuit(otBleSecureStart(instance, HandleBleSecureConnect, nullptr, true, &ble));
127 VerifyOrQuit(otBleSecureStart(instance, HandleBleSecureConnect, nullptr, true, nullptr) == kErrorAlready);
128 SuccessOrQuit(otBleSecureTcatStart(instance, &vendorInfo, nullptr));
129
130 // Validate connection callbacks when platform informs that peer has connected/disconnected
131 otPlatBleGapOnConnected(instance, kConnectionId);
132 VerifyOrQuit(!ble.IsConnected() && ble.IsBleConnectionOpen());
133 otPlatBleGapOnDisconnected(instance, kConnectionId);
134 VerifyOrQuit(!ble.IsConnected() && !ble.IsBleConnectionOpen());
135
136 // Validate connection callbacks when calling `otBleSecureDisconnect()`
137 otPlatBleGapOnConnected(instance, kConnectionId);
138 VerifyOrQuit(!ble.IsConnected() && ble.IsBleConnectionOpen());
139 otBleSecureDisconnect(instance);
140 VerifyOrQuit(!ble.IsConnected() && !ble.IsBleConnectionOpen());
141
142 // Validate TLS connection can be started only when peer is connected
143 otPlatBleGapOnConnected(instance, kConnectionId);
144 SuccessOrQuit(otBleSecureConnect(instance));
145 otBleSecureDisconnect(instance);
146 VerifyOrQuit(otBleSecureConnect(instance) == kErrorInvalidState);
147
148 // Validate Tcat state changes after stopping BLE secure
149 VerifyOrQuit(otBleSecureIsTcatEnabled(instance));
150 otBleSecureStop(instance);
151 VerifyOrQuit(!otBleSecureIsTcatEnabled(instance));
152
153 testFreeInstance(instance);
154 }
155
156 } // namespace ot
157
158 #endif // OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
159
main(void)160 int main(void)
161 {
162 #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
163 ot::TestTcat();
164 printf("All tests passed\n");
165 #else
166 printf("Tcat is not enabled\n");
167 return -1;
168 #endif
169 return 0;
170 }
171