/src/openweave-core/src/test-apps/PASEEngineTest.cpp
Line | Count | Source |
1 | | /* |
2 | | * |
3 | | * Copyright (c) 2013-2017 Nest Labs, Inc. |
4 | | * All rights reserved. |
5 | | * |
6 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
7 | | * you may not use this file except in compliance with the License. |
8 | | * You may obtain a copy of the License at |
9 | | * |
10 | | * http://www.apache.org/licenses/LICENSE-2.0 |
11 | | * |
12 | | * Unless required by applicable law or agreed to in writing, software |
13 | | * distributed under the License is distributed on an "AS IS" BASIS, |
14 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 | | * See the License for the specific language governing permissions and |
16 | | * limitations under the License. |
17 | | */ |
18 | | |
19 | | /** |
20 | | * @file |
21 | | * A library for manipulating PASE state for testing and fuzzing |
22 | | * |
23 | | */ |
24 | | |
25 | | |
26 | | #include <stdio.h> |
27 | | #include <vector> |
28 | | |
29 | | #include "ToolCommon.h" |
30 | | #include "PASEEngineTest.h" |
31 | | #include <Weave/Support/ErrorStr.h> |
32 | | #include <Weave/Profiles/security/WeaveSecurity.h> |
33 | | #include <Weave/Profiles/security/WeavePASE.h> |
34 | | #include <Weave/Support/RandUtils.h> |
35 | | |
36 | | #if WEAVE_SYSTEM_CONFIG_USE_LWIP |
37 | | #include "lwip/tcpip.h" |
38 | | #endif // WEAVE_SYSTEM_CONFIG_USE_LWIP |
39 | | |
40 | | using namespace nl::Weave::Profiles::Security; |
41 | | using namespace nl::Weave::Profiles::Security::PASE; |
42 | | using System::PacketBuffer; |
43 | | |
44 | | #define TOOL_NAME "TestPASE" |
45 | | const char * INITIATOR_STEP_1 = "InitiatorStep1"; |
46 | | const char * RESPONDER_RECONFIGURE = "ResponderReconfigure"; |
47 | | const char * RESPONDER_STEP_1 = "ResponderStep1"; |
48 | | const char * RESPONDER_STEP_2 = "ResponderStep2"; |
49 | | const char * INITIATOR_STEP_2 = "InitiatorStep2"; |
50 | | const char * RESPONDER_KEY_CONFIRM = "ResponderKeyConfirm"; |
51 | | |
52 | 14.7k | #define VerifyOrQuit(TST, MSG) \ |
53 | 14.7k | do { \ |
54 | 14.7k | if (!(TST)) \ |
55 | 14.7k | { \ |
56 | 0 | fprintf(stderr, "%s FAILED: ", __FUNCTION__); \ |
57 | 0 | fputs(MSG, stderr); \ |
58 | 0 | exit(-1); \ |
59 | 0 | } \ |
60 | 14.7k | } while (0) |
61 | | |
62 | 55.8k | #define SuccessOrQuit(ERR, MSG) \ |
63 | 55.8k | do { \ |
64 | 55.8k | if ((ERR) != WEAVE_NO_ERROR) \ |
65 | 55.8k | { \ |
66 | 0 | fprintf(stderr, "%s FAILED: ", __FUNCTION__); \ |
67 | 0 | fputs(MSG, stderr); \ |
68 | 0 | fputs(ErrorStr(ERR), stderr); \ |
69 | 0 | fputs("\n", stderr); \ |
70 | 0 | exit(-1); \ |
71 | 0 | } \ |
72 | 55.8k | } while (0) |
73 | | |
74 | 0 | void MessageMutator::MutateMessage(const char *msgName, PacketBuffer *msgBuf) { } |
75 | | |
76 | | static MessageMutator gNullMutator; |
77 | | |
78 | | MessageExternalFuzzer::MessageExternalFuzzer(const char *msgType) |
79 | 8.62k | { |
80 | 8.62k | mMsgType = msgType; |
81 | 8.62k | mSaveCorpus = false; |
82 | 8.62k | } |
83 | | void MessageExternalFuzzer::MutateMessage(const char *msgType, PacketBuffer *msgBuf) |
84 | 24.5k | { |
85 | 24.5k | if (strcmp(msgType, mMsgType) == 0) |
86 | 8.62k | { |
87 | 8.62k | uint8_t *msgStart = msgBuf->Start(); |
88 | 8.62k | if (mSaveCorpus) |
89 | 0 | { |
90 | 0 | MessageExternalFuzzer::SaveCorpus(msgStart, msgBuf->DataLength(), mMsgType); |
91 | 0 | } |
92 | 8.62k | msgBuf->SetDataLength(mFuzzInputSize); |
93 | 8.62k | memcpy(msgStart, mFuzzInput, msgBuf->DataLength()); |
94 | 8.62k | } |
95 | 24.5k | } |
96 | | |
97 | | void MessageExternalFuzzer::SaveCorpus(const uint8_t *inBuf, size_t size, const char *fileName) |
98 | 0 | { |
99 | 0 | FILE* file = fopen(fileName, "wb+" ); |
100 | 0 | VerifyOrQuit(file != NULL, "Could not open file"); |
101 | 0 | VerifyOrQuit((fwrite(inBuf, 1, size, file) == size), "Could not write corpus file."); |
102 | 0 | fclose(file); |
103 | 0 | } |
104 | | |
105 | 0 | MessageExternalFuzzer& MessageExternalFuzzer::SaveCorpusFile(bool val) { mSaveCorpus = val; return *this; } |
106 | | |
107 | 8.62k | MessageExternalFuzzer& MessageExternalFuzzer::FuzzInput(const uint8_t *val, size_t size) { mFuzzInput = val; mFuzzInputSize = size; return *this; } |
108 | | |
109 | | //Start PASEEngineTest Initialization |
110 | | PASEEngineTest::PASEEngineTest(const char *testName) |
111 | 8.62k | { |
112 | 8.62k | mTestName = testName; |
113 | 8.62k | mProposedConfig = mExpectedConfig = kPASEConfig_Unspecified; |
114 | 8.62k | mInitPW = mRespPW = "TestPassword"; |
115 | 8.62k | mInitiatorAllowedConfigs = mResponderAllowedConfigs = kPASEConfig_Config1|kPASEConfig_Config4; |
116 | 8.62k | mExpectReconfig = false; |
117 | 8.62k | mForceRepeatedReconfig = false; |
118 | 8.62k | memset(mExpectedErrors, 0, sizeof(mExpectedErrors)); |
119 | 8.62k | mMutator = &gNullMutator; |
120 | 8.62k | mLogMessageData = false; |
121 | 8.62k | } |
122 | | |
123 | 0 | const char *PASEEngineTest::TestName() const { return mTestName; } |
124 | | |
125 | 8.62k | uint32_t PASEEngineTest::ProposedConfig() const { return mProposedConfig; } |
126 | 8.62k | PASEEngineTest& PASEEngineTest::ProposedConfig(uint32_t val) { mProposedConfig = val; return *this; } |
127 | | |
128 | 0 | uint32_t PASEEngineTest::InitiatorAllowedConfigs() const { return mInitiatorAllowedConfigs; } |
129 | 0 | PASEEngineTest& PASEEngineTest::InitiatorAllowedConfigs(uint32_t val) { mInitiatorAllowedConfigs = val; return *this; } |
130 | | |
131 | 0 | uint32_t PASEEngineTest::ResponderAllowedConfigs() const { return mResponderAllowedConfigs; } |
132 | 8.62k | PASEEngineTest& PASEEngineTest::ResponderAllowedConfigs(uint32_t val) { mResponderAllowedConfigs = val; return *this; } |
133 | | |
134 | 0 | const char* PASEEngineTest::InitiatorPassword() const { return mInitPW; } |
135 | 8.62k | PASEEngineTest& PASEEngineTest::InitiatorPassword(const char* val) { mInitPW = val; return *this; } |
136 | | |
137 | 0 | const char* PASEEngineTest::ResponderPassword() const { return mRespPW; } |
138 | 8.62k | PASEEngineTest& PASEEngineTest::ResponderPassword(const char* val) { mRespPW = val; return *this; } |
139 | | |
140 | 6.14k | uint32_t PASEEngineTest::ExpectReconfig() const { return mExpectReconfig; } |
141 | | PASEEngineTest& PASEEngineTest::ExpectReconfig(uint32_t expectedConfig) |
142 | 0 | { |
143 | 0 | mExpectReconfig = true; |
144 | 0 | mExpectedConfig = expectedConfig; |
145 | 0 | return *this; |
146 | 0 | } |
147 | 0 | uint32_t PASEEngineTest::ExpectedConfig() const { return mExpectedConfig != kPASEConfig_Unspecified ? mExpectedConfig : mProposedConfig; } |
148 | | |
149 | 0 | bool PASEEngineTest::PerformReconfig() const { return mForceRepeatedReconfig; } |
150 | 0 | PASEEngineTest& PASEEngineTest::PerformReconfig(bool val) { mForceRepeatedReconfig = val; return *this; } |
151 | | |
152 | 0 | bool PASEEngineTest::ConfirmKey() const { return mConfirmKey; } |
153 | 8.62k | PASEEngineTest& PASEEngineTest::ConfirmKey(bool val) { mConfirmKey = val; return *this; } |
154 | | |
155 | | PASEEngineTest& PASEEngineTest::ExpectError(WEAVE_ERROR err) |
156 | 0 | { |
157 | 0 | return ExpectError(NULL, err); |
158 | 0 | } |
159 | | |
160 | | PASEEngineTest& PASEEngineTest::ExpectError(const char *opName, WEAVE_ERROR err) |
161 | 51.6k | { |
162 | 187k | for (size_t i = 0; i < kMaxExpectedErrors; i++) |
163 | 187k | { |
164 | 187k | if (mExpectedErrors[i].Error == WEAVE_NO_ERROR) |
165 | 51.6k | { |
166 | 51.6k | mExpectedErrors[i].Error = err; |
167 | 51.6k | mExpectedErrors[i].OpName = opName; |
168 | 51.6k | break; |
169 | 51.6k | } |
170 | 187k | } |
171 | | |
172 | 51.6k | return *this; |
173 | 51.6k | } |
174 | | |
175 | | bool PASEEngineTest::IsExpectedError(const char *opName, WEAVE_ERROR err) const |
176 | 31.3k | { |
177 | 170k | for (size_t i = 0; i < kMaxExpectedErrors && mExpectedErrors[i].Error != WEAVE_NO_ERROR; i++) |
178 | 147k | { |
179 | 147k | if (mExpectedErrors[i].Error == err && |
180 | 8.62k | (mExpectedErrors[i].OpName == NULL || strcmp(mExpectedErrors[i].OpName, opName) == 0)) |
181 | 8.62k | { |
182 | 8.62k | return true; |
183 | 8.62k | } |
184 | 147k | } |
185 | 22.6k | return false; |
186 | 31.3k | } |
187 | | |
188 | 0 | bool PASEEngineTest::IsSuccessExpected() const { return mExpectedErrors[0].Error == WEAVE_NO_ERROR; } |
189 | | |
190 | 8.62k | PASEEngineTest& PASEEngineTest::Mutator(MessageMutator *mutator) { mMutator = mutator; return *this; } |
191 | | |
192 | 41.8k | bool PASEEngineTest::LogMessageData() const { return mLogMessageData; } |
193 | 8.62k | PASEEngineTest& PASEEngineTest::LogMessageData(bool val) { mLogMessageData = val; return *this; } |
194 | | |
195 | | //private |
196 | | void PASEEngineTest::setAllowedResponderConfigs(WeavePASEEngine &responderEng) |
197 | 8.62k | { |
198 | | #if WEAVE_CONFIG_SUPPORT_PASE_CONFIG0_TEST_ONLY |
199 | | if (mResponderAllowedConfigs == kPASEConfig_Config0_TEST_ONLY) |
200 | | responderEng.AllowedPASEConfigs = kPASEConfig_SupportConfig0Bit_TEST_ONLY; |
201 | | else |
202 | | #endif |
203 | 8.62k | #if WEAVE_CONFIG_SUPPORT_PASE_CONFIG1 |
204 | 8.62k | if (mResponderAllowedConfigs == kPASEConfig_Config1) |
205 | 8.62k | responderEng.AllowedPASEConfigs = kPASEConfig_SupportConfig1Bit; |
206 | 0 | else |
207 | 0 | #endif |
208 | | #if WEAVE_CONFIG_SUPPORT_PASE_CONFIG2 |
209 | | if (mResponderAllowedConfigs == kPASEConfig_Config2) |
210 | | respEng.AllowedPASEConfigs = kPASEConfig_SupportConfig2Bit; |
211 | | else |
212 | | #endif |
213 | | #if WEAVE_CONFIG_SUPPORT_PASE_CONFIG3 |
214 | | if (mResponderAllowedConfigs == kPASEConfig_Config3) |
215 | | responderEng.AllowedPASEConfigs = kPASEConfig_SupportConfig3Bit; |
216 | | else |
217 | | #endif |
218 | 0 | #if WEAVE_CONFIG_SUPPORT_PASE_CONFIG4 |
219 | 0 | if (mResponderAllowedConfigs == kPASEConfig_Config4) |
220 | 0 | responderEng.AllowedPASEConfigs = kPASEConfig_SupportConfig4Bit; |
221 | 0 | else |
222 | 0 | #endif |
223 | | #if WEAVE_CONFIG_SUPPORT_PASE_CONFIG5 |
224 | | if (mResponderAllowedConfigs == kPASEConfig_Config5) |
225 | | responderEng.AllowedPASEConfigs = kPASEConfig_SupportConfig5Bit; |
226 | | else |
227 | | #endif |
228 | 0 | responderEng.AllowedPASEConfigs = 0x0; |
229 | 8.62k | } |
230 | | |
231 | | enum |
232 | | { |
233 | | kMaxExpectedErrors = 32 |
234 | | }; |
235 | | |
236 | | //end PASEEngineTest Initialization |
237 | | void PASEEngineTest::Run() |
238 | 8.62k | { |
239 | 8.62k | WEAVE_ERROR err; |
240 | 8.62k | WeavePASEEngine initiatorEng; |
241 | 8.62k | WeavePASEEngine responderEng; |
242 | 8.62k | PacketBuffer *msgBuf = NULL; |
243 | 8.62k | PacketBuffer *msgBuf2 = NULL; |
244 | 8.62k | WeaveFabricState initFabricState; |
245 | 8.62k | WeaveFabricState respFabricState; |
246 | 8.62k | const WeaveEncryptionKey *initiatorKey; |
247 | 8.62k | const WeaveEncryptionKey *responderKey; |
248 | | |
249 | 8.62k | uint64_t initNodeId = 1; |
250 | 8.62k | uint64_t respNodeId = 2; |
251 | 8.62k | uint16_t sessionKeyId = sTestDefaultSessionKeyId; |
252 | 8.62k | uint16_t encType = kWeaveEncryptionType_AES128CTRSHA1; |
253 | 8.62k | uint16_t pwSrc = kPasswordSource_PairingCode; |
254 | 8.62k | bool expectSuccess = strcmp(mInitPW, mRespPW) == 0; |
255 | | |
256 | 8.62k | if (LogMessageData()) |
257 | 0 | { |
258 | 0 | printf("========== Starting Test: %s\n", TestName()); |
259 | 0 | printf("Pr: %d\nex: %d\n", ProposedConfig(), ExpectedConfig()); |
260 | 0 | } |
261 | 8.62k | initiatorEng.Init(); |
262 | 8.62k | err = initFabricState.Init(); |
263 | 8.62k | SuccessOrQuit(err, "initFabricState.Init failed\n"); |
264 | 8.62k | initiatorEng.Pw = (const uint8_t *)mInitPW; |
265 | 8.62k | initiatorEng.PwLen = (uint16_t)strlen(mInitPW); |
266 | | |
267 | 8.62k | onReconfig: |
268 | 8.62k | responderEng.Init(); |
269 | 8.62k | err = respFabricState.Init(); |
270 | 8.62k | setAllowedResponderConfigs(responderEng); |
271 | | |
272 | 8.62k | SuccessOrQuit(err, "respFabricState.Init failed\n"); |
273 | 8.62k | respFabricState.PairingCode = mRespPW; |
274 | | |
275 | | // =========== Start PASE InitiatorStep1 ============================== |
276 | 8.62k | msgBuf = PacketBuffer::New(); |
277 | 8.62k | VerifyOrQuit(msgBuf != NULL, "PacketBuffer::New() failed"); |
278 | | |
279 | | // Initiator generates and sends PASE Initiator Step 1 message. |
280 | 8.62k | err = initiatorEng.GenerateInitiatorStep1(msgBuf, ProposedConfig(), initNodeId, respNodeId, sessionKeyId, encType, pwSrc, &initFabricState, mConfirmKey); |
281 | | |
282 | 8.62k | if (IsExpectedError("Initiator:GenerateInitiatorStep1", err)) |
283 | 0 | goto onExpectedError; |
284 | 8.62k | SuccessOrQuit(err, "WeavePASEEngine::GenerateInitiatorStep1 failed\n"); |
285 | | |
286 | | // =========== Initiator Sends InitiatorStep1 to Responder ============ |
287 | | |
288 | 8.62k | mMutator->MutateMessage(INITIATOR_STEP_1, msgBuf); |
289 | 8.62k | if (LogMessageData()) |
290 | 0 | { |
291 | 0 | printf("Initiator->Responder: InitiatorStep1 Message (%d bytes)\n", msgBuf->DataLength()); |
292 | 0 | DumpMemory(msgBuf->Start(), msgBuf->DataLength(), " ", 16); |
293 | 0 | } |
294 | | |
295 | | // =========== Responder Processes PASE InitiatorStep1 ================ |
296 | 8.62k | err = responderEng.ProcessInitiatorStep1(msgBuf, respNodeId, initNodeId, &respFabricState); |
297 | 8.62k | if (IsExpectedError(INITIATOR_STEP_1, err)) |
298 | 2.48k | goto onExpectedError; |
299 | | |
300 | 6.14k | if (ExpectReconfig()) |
301 | 0 | { |
302 | 0 | VerifyOrQuit(err == WEAVE_ERROR_PASE_RECONFIGURE_REQUIRED, "WEAVE_ERROR_PASE_RECONFIG_REQUIRED error expected"); |
303 | 0 | PacketBuffer::Free(msgBuf); |
304 | 0 | msgBuf = NULL; |
305 | | |
306 | | // =========== Responder generates PASE ResponderReconfigMessage == |
307 | 0 | { |
308 | 0 | msgBuf = PacketBuffer::New(); |
309 | 0 | err = responderEng.GenerateResponderReconfigure(msgBuf); |
310 | 0 | SuccessOrQuit(err, "WeavePASEEngine::GenerateResponderReconfigure failed\n"); |
311 | | // Reset PASE Engines |
312 | 0 | responderEng.Reset(); |
313 | 0 | } |
314 | | // ========== Responder sends ResponderReconfig Message ============ |
315 | 0 | mMutator->MutateMessage(RESPONDER_RECONFIGURE, msgBuf); |
316 | |
|
317 | 0 | if (LogMessageData()) |
318 | 0 | { |
319 | 0 | printf("Responder->Initiator: ResponderReconfig Message (%d bytes)\n", msgBuf->DataLength()); |
320 | 0 | DumpMemory(msgBuf->Start(), msgBuf->DataLength(), " ", 16); |
321 | 0 | } |
322 | | |
323 | | // =========== Initiator processes PASE ResponderReconfig ========= |
324 | 0 | { |
325 | 0 | uint32_t tempProposedConfig = mProposedConfig; |
326 | 0 | err = initiatorEng.ProcessResponderReconfigure(msgBuf, mProposedConfig); |
327 | 0 | if (IsExpectedError("Initiator:ProcessResponderReconfigure", err)) |
328 | 0 | { |
329 | 0 | mProposedConfig = tempProposedConfig; |
330 | 0 | goto onExpectedError; |
331 | 0 | } |
332 | 0 | SuccessOrQuit(err, "WeavePASEEngine::ProcessResponderReconfigure failed\n"); |
333 | 0 | PacketBuffer::Free(msgBuf); |
334 | 0 | msgBuf = NULL; |
335 | 0 | } |
336 | | |
337 | 0 | respFabricState.Shutdown(); |
338 | 0 | mExpectReconfig = false; |
339 | |
|
340 | 0 | goto onReconfig; |
341 | |
|
342 | 6.14k | } else { |
343 | 6.14k | VerifyOrQuit(err != WEAVE_ERROR_PASE_RECONFIGURE_REQUIRED, "Unexpected reconfig!"); |
344 | 6.14k | } |
345 | | |
346 | 6.14k | SuccessOrQuit(err, "WeavePASEEngine::ProcessInitiatorStep1 failed\n"); |
347 | 6.14k | PacketBuffer::Free(msgBuf); |
348 | 6.14k | msgBuf = NULL; |
349 | | |
350 | | // =========== Responder Generates ResponderStep1 and ResponderStep2 == |
351 | 6.14k | { |
352 | 6.14k | msgBuf = PacketBuffer::New(); |
353 | 6.14k | err = responderEng.GenerateResponderStep1(msgBuf); |
354 | 6.14k | SuccessOrQuit(err, "WeavePASEEngine::GenerateResponderStep1 failed\n"); |
355 | | |
356 | | // Responder generates and sends PASE Responder Step 2 message. |
357 | 6.14k | msgBuf2 = PacketBuffer::New(); |
358 | 6.14k | err = responderEng.GenerateResponderStep2(msgBuf2); |
359 | 6.14k | SuccessOrQuit(err, "WeavePASEEngine::GenerateResponderStep2 failed\n"); |
360 | 6.14k | } |
361 | | // =========== Responder sends ResponderStep1 ========================== |
362 | 6.14k | mMutator->MutateMessage(RESPONDER_STEP_1, msgBuf); |
363 | | |
364 | 6.14k | if (LogMessageData()) |
365 | 0 | { |
366 | 0 | printf("Responder->Initiator: ResponderStep1 Message (%d bytes)\n", msgBuf->DataLength()); |
367 | 0 | DumpMemory(msgBuf->Start(), msgBuf->DataLength(), " ", 16); |
368 | 0 | } |
369 | | |
370 | | // =========== Responder sends ResponderStep2 ========================== |
371 | 6.14k | mMutator->MutateMessage(RESPONDER_STEP_2, msgBuf2); |
372 | | |
373 | 6.14k | if (LogMessageData()) |
374 | 0 | { |
375 | 0 | printf("Responder->Initiator: ResponderStep2 Message (%d bytes)\n", msgBuf2->DataLength()); |
376 | 0 | DumpMemory(msgBuf2->Start(), msgBuf2->DataLength(), " ", 16); |
377 | 0 | } |
378 | | |
379 | | // =========== Initator Parses ResponderStep1 and ResponderStep2 ====== |
380 | 6.14k | { |
381 | | // Initiator receives and processes PASE Responder Step 1 message. |
382 | 6.14k | err = initiatorEng.ProcessResponderStep1(msgBuf); |
383 | 6.14k | if (IsExpectedError(RESPONDER_STEP_1, err)) |
384 | 1.89k | goto onExpectedError; |
385 | 4.25k | SuccessOrQuit(err, "WeavePASEEngine::ProcessResponderStep1 failed\n"); |
386 | 4.25k | PacketBuffer::Free(msgBuf); |
387 | 4.25k | msgBuf = NULL; |
388 | | |
389 | | // Initiator receives and processes PASE Responder Step 2 message. |
390 | 4.25k | err = initiatorEng.ProcessResponderStep2(msgBuf2); |
391 | 4.25k | if (IsExpectedError(RESPONDER_STEP_2, err)) |
392 | 1.64k | goto onExpectedError; |
393 | 2.61k | SuccessOrQuit(err, "WeavePASEEngine::ProcessResponderStep2 failed\n"); |
394 | 2.61k | PacketBuffer::Free(msgBuf2); |
395 | 2.61k | msgBuf2 = NULL; |
396 | 2.61k | } |
397 | | |
398 | | // =========== Initator Generates InitatorStep2 =========================== |
399 | 0 | { |
400 | 2.61k | msgBuf = PacketBuffer::New(); |
401 | 2.61k | err = initiatorEng.GenerateInitiatorStep2(msgBuf); |
402 | 2.61k | SuccessOrQuit(err, "WeavePASEEngine::GenerateInitiatorStep2 failed\n"); |
403 | 2.61k | } |
404 | | //=========== Initator Sends InitatorStep2 ============================ |
405 | | |
406 | 2.61k | mMutator->MutateMessage(INITIATOR_STEP_2, msgBuf); |
407 | | |
408 | 2.61k | if (LogMessageData()) |
409 | 0 | { |
410 | 0 | printf("Initiator->Responder: InitatorStep2 Message (%d bytes)\n", msgBuf->DataLength()); |
411 | 0 | DumpMemory(msgBuf->Start(), msgBuf->DataLength(), " ", 16); |
412 | 0 | } |
413 | | |
414 | | // =========== Responder Parses InitatorStep2 ========================= |
415 | 2.61k | { |
416 | 2.61k | err = responderEng.ProcessInitiatorStep2(msgBuf); |
417 | 2.61k | PacketBuffer::Free(msgBuf); |
418 | 2.61k | msgBuf = NULL; |
419 | | |
420 | 2.61k | if (IsExpectedError(INITIATOR_STEP_2, err)) |
421 | 1.56k | goto onExpectedError; |
422 | | |
423 | 1.04k | if (expectSuccess) |
424 | 1.04k | SuccessOrQuit(err, "WeavePASEEngine::ProcessInitiatorStep2 failed\n"); |
425 | 0 | else if (mConfirmKey) |
426 | 0 | { |
427 | 0 | VerifyOrQuit(err == WEAVE_ERROR_KEY_CONFIRMATION_FAILED, "Expected error from WeavePASEEngine::ProcessInitiatorStep2\n"); |
428 | 0 | return; |
429 | 0 | } |
430 | 1.04k | } |
431 | | |
432 | 1.04k | if (mConfirmKey) |
433 | 1.04k | { |
434 | | // ========== Responder Forms ResponderKeyConfirm ================= |
435 | 1.04k | { |
436 | 1.04k | msgBuf = PacketBuffer::New(); |
437 | 1.04k | err = responderEng.GenerateResponderKeyConfirm(msgBuf); |
438 | 1.04k | SuccessOrQuit(err, "WeavePASEEngine::GenerateResponderKeyConfirm failed\n"); |
439 | 1.04k | } |
440 | | |
441 | | // ========== Responder Sends ResponderKeyConfirm to Responder ==== |
442 | | |
443 | 1.04k | mMutator->MutateMessage(RESPONDER_KEY_CONFIRM, msgBuf); |
444 | | |
445 | 1.04k | if (LogMessageData()) |
446 | 0 | { |
447 | 0 | printf("Responder->Initiator: ResponderKeyConfirm Message (%d bytes)\n", msgBuf->DataLength()); |
448 | 0 | DumpMemory(msgBuf->Start(), msgBuf->DataLength(), " ", 16); |
449 | 0 | } |
450 | | |
451 | | // ========== Initiator Processes ResponderKeyConfirm ============= |
452 | 1.04k | { |
453 | 1.04k | err = initiatorEng.ProcessResponderKeyConfirm(msgBuf); |
454 | | |
455 | 1.04k | if (IsExpectedError(RESPONDER_KEY_CONFIRM, err)) |
456 | 1.04k | goto onExpectedError; |
457 | | |
458 | 0 | SuccessOrQuit(err, "WeavePASEEngine::ProcessResponderKeyConfirm failed\n"); |
459 | 0 | PacketBuffer::Free(msgBuf); |
460 | 0 | msgBuf = NULL; |
461 | 0 | } |
462 | 0 | } |
463 | | |
464 | 0 | VerifyOrQuit(initiatorEng.State == WeavePASEEngine::kState_InitiatorDone, "Initiator state != Done\n"); |
465 | 0 | VerifyOrQuit(responderEng.State == WeavePASEEngine::kState_ResponderDone, "Responder state != Done\n"); |
466 | | |
467 | 0 | VerifyOrQuit(initiatorEng.SessionKeyId == responderEng.SessionKeyId, "Initiator SessionKeyId != Responder SessionKeyId\n"); |
468 | 0 | VerifyOrQuit(initiatorEng.EncryptionType == responderEng.EncryptionType, "Initiator EncryptionType != Responder EncryptionType\n"); |
469 | 0 | VerifyOrQuit(initiatorEng.PerformKeyConfirmation == responderEng.PerformKeyConfirmation, "Initiator SessionKeyId != Responder SessionKeyId\n"); |
470 | | |
471 | 0 | err = initiatorEng.GetSessionKey(initiatorKey); |
472 | 0 | SuccessOrQuit(err, "WeavePASEEngine::GetSessionKey() failed\n"); |
473 | | |
474 | 0 | err = responderEng.GetSessionKey(responderKey); |
475 | 0 | SuccessOrQuit(err, "WeavePASEEngine::GetSessionKey() failed\n"); |
476 | | |
477 | 0 | VerifyOrQuit(memcmp(initiatorKey->AES128CTRSHA1.DataKey, responderKey->AES128CTRSHA1.DataKey, WeaveEncryptionKey_AES128CTRSHA1::DataKeySize) == 0, |
478 | 0 | "Data key mismatch\n"); |
479 | 0 | VerifyOrQuit(memcmp(initiatorKey->AES128CTRSHA1.IntegrityKey, responderKey->AES128CTRSHA1.IntegrityKey, WeaveEncryptionKey_AES128CTRSHA1::IntegrityKeySize) == 0, |
480 | 0 | "Integrity key mismatch\n"); |
481 | | |
482 | | // Shutdown the Initiator/Responder FabricState objects |
483 | 0 | err = initFabricState.Shutdown(); |
484 | 0 | SuccessOrQuit(err, "initFabricState.Shutdown failed\n"); |
485 | 0 | err = respFabricState.Shutdown(); |
486 | 0 | SuccessOrQuit(err, "respFabricState.Shutdown failed\n"); |
487 | | |
488 | 8.62k | onExpectedError: |
489 | 8.62k | PacketBuffer::Free(msgBuf); |
490 | 8.62k | msgBuf = NULL; |
491 | | |
492 | 8.62k | PacketBuffer::Free(msgBuf2); |
493 | 8.62k | msgBuf2 = NULL; |
494 | | |
495 | 8.62k | initiatorEng.Shutdown(); |
496 | 8.62k | responderEng.Shutdown(); |
497 | 8.62k | initFabricState.Shutdown(); |
498 | 8.62k | respFabricState.Shutdown(); |
499 | 8.62k | if (LogMessageData()) |
500 | 0 | printf("Test Complete: %s\n", TestName()); |
501 | 8.62k | } |