/src/openweave-core/src/test-apps/TAKEOptions.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | * Implementation of TAKEConfig object, which provides an implementation of the WeaveTAKEAuthDelegate |
22 | | * interface for use in test applications. |
23 | | * |
24 | | */ |
25 | | |
26 | | |
27 | | #include "ToolCommon.h" |
28 | | #include <Weave/Support/ASN1.h> |
29 | | #include "TAKEOptions.h" |
30 | | |
31 | | TAKEOptions gTAKEOptions; |
32 | | MockTAKEChallengerDelegate gMockTAKEChallengerDelegate; |
33 | | MockTAKETokenDelegate gMockTAKETokenDelegate; |
34 | | |
35 | | TAKEOptions::TAKEOptions() |
36 | 10 | { |
37 | 10 | static OptionDef optionDefs[] = |
38 | 10 | { |
39 | | #if WEAVE_CONFIG_ENABLE_TAKE_INITIATOR || WEAVE_CONFIG_ENABLE_TAKE_RESPONDER |
40 | | { "take-reauth", kNoArgument, kToolCommonOpt_TAKEReauth }, |
41 | | #endif |
42 | 10 | { } |
43 | 10 | }; |
44 | 10 | OptionDefs = optionDefs; |
45 | | |
46 | 10 | HelpGroupName = "TAKE OPTIONS"; |
47 | | |
48 | 10 | OptionHelp = |
49 | | #if WEAVE_CONFIG_ENABLE_TAKE_INITIATOR || WEAVE_CONFIG_ENABLE_TAKE_RESPONDER |
50 | | " --take-reauth\n" |
51 | | " Pre-populate the challenger token data store with the AK and\n" |
52 | | " encrypted-AK for the token such that the initial TAKE interaction\n" |
53 | | " is a re-authentication.\n" |
54 | | "\n" |
55 | | #endif |
56 | 10 | ""; |
57 | | |
58 | | // Defaults |
59 | 10 | static const uint8_t ik[] = { 0x05, 0x26, 0xAD, 0xB7, 0xBB, 0xD7, 0x82, 0x52, 0x78, 0x2D, 0x60, 0xD6, 0x40, 0xFD, 0xE6, 0xF9 }; |
60 | 10 | static const uint8_t challengerId[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; |
61 | 10 | static uint8_t tPub[] = { 0x04, 0x55, 0x7B, 0x11, 0x55, 0xE5, 0xE2, 0x59, 0xB1, 0x98, 0xB2, 0x56, 0x13, 0xE3, 0x5B, 0xA7, 0x91, 0x5C, 0xB1, 0x4A, 0x8D, 0xC4, 0x08, 0x99, 0x03, 0x8F, 0x51, 0xB4, 0xAE, 0xC4, 0xA8, 0x95, 0x1F, 0xF6, 0x65, 0xFF, 0x21, 0x12, 0x3E, 0x8E, 0x1C, 0x36, 0x60, 0xB3, 0x3D, 0xB3, 0x02, 0x5B, 0xA5, 0xB7, 0xD9, 0xFE, 0xA2, 0xB1, 0x01, 0x42, 0x13 }; |
62 | 10 | static const uint8_t tPriv[] = { 0x54, 0x7A, 0x86, 0xF5, 0x6E, 0xFF, 0xDC, 0x52, 0x22, 0x13, 0xBA, 0x8C, 0x00, 0x88, 0x0A, 0x9C, 0x62, 0x1D, 0xCB, 0xA5, 0xD1, 0xD7, 0x70, 0xDF, 0x23, 0x40, 0x7D, 0x18 }; |
63 | 10 | static const uint8_t irk[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; |
64 | 10 | static const uint8_t masterKey[] = { 0x11, 0xFF, 0xF1, 0x1F, 0xD1, 0x3F, 0xB1, 0x5F, 0x91, 0x7F, 0x71, 0x9F, 0x51, 0xBF, 0x31, 0xDF, 0x11, 0xFF, 0xF1, 0x1F, 0xD1, 0x3F, 0xB1, 0x5F, 0x91, 0x7F, 0x71, 0x9F, 0x51, 0xBF, 0x31, 0xDF }; |
65 | 10 | static const uint8_t ak[] = { 0x9F, 0x0F, 0x92, 0xE3, 0xB9, 0x04, 0x96, 0xA1, 0xCB, 0x7C, 0x94, 0x99, 0xAB, 0x34, 0xDD, 0x04 }; |
66 | 10 | static const uint8_t encAK[] = { 0xE6, 0xC4, 0x03, 0xE8, 0xEE, 0xA3, 0x80, 0x56, 0xE0, 0xB1, 0x9C, 0xE9, 0xE3, 0xA6, 0xD8, 0x3A }; |
67 | 10 | IK = ik; |
68 | 10 | ChallengerId = challengerId; |
69 | 10 | ChallengerIdLen = sizeof(challengerId); |
70 | 10 | TPub = tPub; |
71 | 10 | TPubLen = sizeof(tPub); |
72 | 10 | TPriv = tPriv; |
73 | 10 | TPrivLen = sizeof(tPriv); |
74 | 10 | IRK = irk; |
75 | 10 | MasterKey = masterKey; |
76 | 10 | AK = ak; |
77 | 10 | EncAK = encAK; |
78 | 10 | ForceReauth = false; |
79 | 10 | } |
80 | | |
81 | | bool TAKEOptions::HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg) |
82 | 0 | { |
83 | 0 | switch (id) |
84 | 0 | { |
85 | 0 | case kToolCommonOpt_TAKEReauth: |
86 | 0 | ForceReauth = true; |
87 | 0 | break; |
88 | 0 | default: |
89 | 0 | PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name); |
90 | 0 | return false; |
91 | 0 | } |
92 | | |
93 | 0 | return true; |
94 | 0 | } |
95 | | |
96 | | WEAVE_ERROR TAKEOptions::PrepopulateTokenData() |
97 | 0 | { |
98 | 0 | WEAVE_ERROR err; |
99 | 0 | uint16_t authKeyLen = TAKE::kAuthenticationKeySize; |
100 | 0 | uint16_t encryptedAuthKeyLen = kTokenEncryptedStateSize; |
101 | |
|
102 | 0 | err = gMockTAKEChallengerDelegate.StoreTokenAuthData(1, kTAKEConfig_Config1, AK, authKeyLen, EncAK, encryptedAuthKeyLen); |
103 | 0 | SuccessOrExit(err); |
104 | | |
105 | 0 | exit: |
106 | 0 | return err; |
107 | 0 | } |
108 | | |
109 | | static uint8_t AuthenticationKeyBuffer[TAKE::kAuthenticationKeySize]; |
110 | | static uint8_t EncryptedAuthenticationKeyBuffer[TAKE::kTokenEncryptedStateSize]; |
111 | | |
112 | | |
113 | | MockTAKEChallengerDelegate::MockTAKEChallengerDelegate() : |
114 | 10 | AuthenticationKeySet(false), |
115 | 10 | Rewinded(false) |
116 | 10 | { |
117 | 10 | return; |
118 | 10 | } |
119 | | |
120 | | // Rewind Identification Key Iterator. |
121 | | // Called to prepare for a new Identification Key search. |
122 | | WEAVE_ERROR MockTAKEChallengerDelegate::RewindIdentificationKeyIterator() |
123 | 0 | { |
124 | 0 | Rewinded = true; |
125 | 0 | return WEAVE_NO_ERROR; |
126 | 0 | } |
127 | | |
128 | | // Get next {tokenId, IK} pair. |
129 | | // returns tokenId = kNodeIdNotSpecified if no more IKs are available. |
130 | | WEAVE_ERROR MockTAKEChallengerDelegate::GetNextIdentificationKey(uint64_t & tokenId, uint8_t *identificationKey, uint16_t & identificationKeyLen) |
131 | 0 | { |
132 | 0 | if (Rewinded) |
133 | 0 | { |
134 | 0 | if (identificationKeyLen < kIdentificationKeySize) |
135 | 0 | return WEAVE_ERROR_BUFFER_TOO_SMALL; |
136 | 0 | tokenId = 1; |
137 | 0 | identificationKeyLen = kIdentificationKeySize; |
138 | 0 | memcpy(identificationKey, gTAKEOptions.IK, identificationKeyLen); |
139 | 0 | Rewinded = false; |
140 | 0 | } |
141 | 0 | else |
142 | 0 | { |
143 | 0 | tokenId = nl::Weave::kNodeIdNotSpecified; |
144 | 0 | } |
145 | 0 | return WEAVE_NO_ERROR; |
146 | 0 | } |
147 | | |
148 | | // Get Token Authentication Data. |
149 | | // Function returns {takeConfig = kTAKEConfig_Invalid, authKey = NULL, encAuthBlob = NULL} if Authentication Data associated with a specified Token |
150 | | // is not stored on the device. |
151 | | // On the function call authKeyLen and encAuthBlobLen inputs specify sizes of the authKey and encAuthBlob buffers, respectively. |
152 | | // Function should update these parameters to reflect actual sizes. |
153 | | WEAVE_ERROR MockTAKEChallengerDelegate::GetTokenAuthData(uint64_t tokenId, uint8_t &takeConfig, uint8_t *authKey, uint16_t &authKeyLen, uint8_t *encAuthBlob, uint16_t &encAuthBlobLen) |
154 | 0 | { |
155 | 0 | if (tokenId == 1) |
156 | 0 | { |
157 | 0 | if (!AuthenticationKeySet) |
158 | 0 | { |
159 | 0 | takeConfig = kTAKEConfig_Invalid; |
160 | 0 | authKey = NULL; |
161 | 0 | encAuthBlob = NULL; |
162 | 0 | return WEAVE_NO_ERROR; |
163 | 0 | } |
164 | 0 | if (authKeyLen < TAKE::kAuthenticationKeySize) |
165 | 0 | return WEAVE_ERROR_BUFFER_TOO_SMALL; |
166 | 0 | if (encAuthBlobLen < kTokenEncryptedStateSize) |
167 | 0 | return WEAVE_ERROR_BUFFER_TOO_SMALL; |
168 | | |
169 | 0 | takeConfig = kTAKEConfig_Config1; |
170 | 0 | authKeyLen = TAKE::kAuthenticationKeySize; |
171 | 0 | encAuthBlobLen = kTokenEncryptedStateSize; |
172 | 0 | memcpy(authKey, AuthenticationKeyBuffer, authKeyLen); |
173 | 0 | memcpy(encAuthBlob, EncryptedAuthenticationKeyBuffer, encAuthBlobLen); |
174 | 0 | } |
175 | 0 | else |
176 | 0 | { |
177 | 0 | return WEAVE_ERROR_INVALID_ARGUMENT; |
178 | 0 | } |
179 | 0 | return WEAVE_NO_ERROR; |
180 | 0 | } |
181 | | |
182 | | // Store Token Authentication Data. |
183 | | // This function should clear Authentication Data that was previously stored on the device for the specified Token (if any). |
184 | | WEAVE_ERROR MockTAKEChallengerDelegate::StoreTokenAuthData(uint64_t tokenId, uint8_t takeConfig, const uint8_t *authKey, uint16_t authKeyLen, const uint8_t *encAuthBlob, uint16_t encAuthBlobLen) |
185 | 0 | { |
186 | 0 | if (tokenId == 1 && takeConfig == kTAKEConfig_Config1) |
187 | 0 | { |
188 | 0 | if (authKeyLen < TAKE::kAuthenticationKeySize) |
189 | 0 | return WEAVE_ERROR_BUFFER_TOO_SMALL; |
190 | 0 | if (encAuthBlobLen < kTokenEncryptedStateSize) |
191 | 0 | return WEAVE_ERROR_BUFFER_TOO_SMALL; |
192 | | |
193 | 0 | memcpy(AuthenticationKeyBuffer, authKey, authKeyLen); |
194 | 0 | memcpy(EncryptedAuthenticationKeyBuffer, encAuthBlob, encAuthBlobLen); |
195 | |
|
196 | 0 | AuthenticationKeySet = true; |
197 | 0 | } |
198 | 0 | else |
199 | 0 | { |
200 | 0 | return WEAVE_ERROR_INVALID_ARGUMENT; |
201 | 0 | } |
202 | 0 | return WEAVE_NO_ERROR; |
203 | |
|
204 | 0 | } |
205 | | |
206 | | // Clear Token Authentication Data. |
207 | | // This function should be called if ReAuthentication phase with the Token Authentication Data stored on the device failed. |
208 | | WEAVE_ERROR MockTAKEChallengerDelegate::ClearTokenAuthData(uint64_t tokenId) |
209 | 0 | { |
210 | 0 | if (tokenId == 1 && AuthenticationKeySet) |
211 | 0 | { |
212 | 0 | AuthenticationKeySet = false; |
213 | 0 | return WEAVE_NO_ERROR; |
214 | 0 | } |
215 | 0 | return WEAVE_ERROR_INVALID_ARGUMENT; |
216 | 0 | } |
217 | | |
218 | | // Get Token public key. |
219 | | // On the function call tokenPubKeyLen input specifies size of the tokenPubKey buffer. Function should update this parameter to reflect actual sizes. |
220 | | WEAVE_ERROR MockTAKEChallengerDelegate::GetTokenPublicKey(uint64_t tokenId, OID& curveOID, EncodedECPublicKey& tokenPubKey) |
221 | 0 | { |
222 | 0 | if (tokenId == 1) |
223 | 0 | { |
224 | 0 | if (tokenPubKey.ECPointLen < kConfig1_ECPointX962FormatSize) |
225 | 0 | return WEAVE_ERROR_BUFFER_TOO_SMALL; |
226 | | |
227 | 0 | tokenPubKey.ECPointLen = kConfig1_ECPointX962FormatSize; |
228 | 0 | memcpy(tokenPubKey.ECPoint, gTAKEOptions.TPub, tokenPubKey.ECPointLen); |
229 | 0 | curveOID = nl::Weave::ASN1::kOID_EllipticCurve_secp224r1; |
230 | 0 | return WEAVE_NO_ERROR; |
231 | 0 | } |
232 | 0 | return WEAVE_ERROR_INVALID_ARGUMENT; |
233 | 0 | } |
234 | | |
235 | | |
236 | | // Get the challenger ID. |
237 | | WEAVE_ERROR MockTAKEChallengerDelegate::GetChallengerID(uint8_t *challengerID, uint8_t &challengerIDLen) const |
238 | 0 | { |
239 | 0 | if (challengerIDLen < gTAKEOptions.ChallengerIdLen) |
240 | 0 | return WEAVE_ERROR_BUFFER_TOO_SMALL; |
241 | 0 | challengerIDLen = gTAKEOptions.ChallengerIdLen; |
242 | |
|
243 | 0 | memcpy(challengerID, gTAKEOptions.ChallengerId, challengerIDLen); |
244 | |
|
245 | 0 | return WEAVE_NO_ERROR; |
246 | 0 | } |
247 | | |
248 | | // Get the token Master key. size: kTokenMasterKeySize |
249 | | WEAVE_ERROR MockTAKETokenDelegate::GetTokenMasterKey(uint8_t *tokenMasterKey) const |
250 | 0 | { |
251 | 0 | memcpy(tokenMasterKey, gTAKEOptions.MasterKey, kTokenMasterKeySize); |
252 | 0 | return WEAVE_NO_ERROR; |
253 | 0 | } |
254 | | |
255 | | // Get the Identification Root Key. size: kIdentificationRootKeySize |
256 | | WEAVE_ERROR MockTAKETokenDelegate::GetIdentificationRootKey(uint8_t *identificationRootKey) const |
257 | 0 | { |
258 | 0 | memcpy(identificationRootKey, gTAKEOptions.IRK, kIdentificationRootKeySize); |
259 | 0 | return WEAVE_NO_ERROR; |
260 | 0 | } |
261 | | |
262 | | // Get the token Private Key. |
263 | | // On the function call tokenPrivKeyLen input specifies size of the tokenPrivKey buffer. |
264 | | // Function should update this parameter to reflect actual sizes of the private key. |
265 | | WEAVE_ERROR MockTAKETokenDelegate::GetTokenPrivateKey(OID& curveOID, EncodedECPrivateKey& tokenPrivKey) const |
266 | 0 | { |
267 | 0 | if (tokenPrivKey.PrivKeyLen < gTAKEOptions.TPrivLen) |
268 | 0 | return WEAVE_ERROR_BUFFER_TOO_SMALL; |
269 | 0 | tokenPrivKey.PrivKeyLen = gTAKEOptions.TPrivLen; |
270 | 0 | memcpy(tokenPrivKey.PrivKey, gTAKEOptions.TPriv, gTAKEOptions.TPrivLen); |
271 | |
|
272 | 0 | curveOID = nl::Weave::ASN1::kOID_EllipticCurve_secp224r1; |
273 | |
|
274 | 0 | return WEAVE_NO_ERROR; |
275 | 0 | } |
276 | | |
277 | | // Get TAKE Time. |
278 | | // Function returns takeTime, which is Unix time rounded with 24 hour granularity |
279 | | // i.e. number of days elapsed after 1 January 1970. |
280 | | WEAVE_ERROR MockTAKETokenDelegate::GetTAKETime(uint32_t &takeTime) const |
281 | 0 | { |
282 | 0 | takeTime = 17167; // number of days til 01/01/2017 |
283 | |
|
284 | 0 | return WEAVE_NO_ERROR; |
285 | 0 | } |