Coverage Report

Created: 2025-05-04 06:22

/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
}