credresource.c 50.6 KB
Newer Older
Sachin Agrawal's avatar
Sachin Agrawal committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
//******************************************************************
//
// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

21
#define __STDC_LIMIT_MACROS
Sahil Bansal's avatar
Sahil Bansal committed
22 23 24 25 26 27 28 29 30 31 32

#include <stdlib.h>
#ifdef WITH_ARDUINO
#include <string.h>
#else
#include <strings.h>
#endif
#include <stdint.h>

#include "cainterface.h"
#include "payload_logging.h"
Sachin Agrawal's avatar
Sachin Agrawal committed
33
#include "ocstack.h"
Sahil Bansal's avatar
Sahil Bansal committed
34 35 36
#include "ocrandom.h"
#include "base64.h"
#include "ocserverrequest.h"
Sachin Agrawal's avatar
Sachin Agrawal committed
37
#include "oic_malloc.h"
Sahil Bansal's avatar
Sahil Bansal committed
38
#include "ocpayload.h"
Sachin Agrawal's avatar
Sachin Agrawal committed
39 40 41
#include "utlist.h"
#include "credresource.h"
#include "doxmresource.h"
Sahil Bansal's avatar
Sahil Bansal committed
42
#include "pstatresource.h"
leechul's avatar
leechul committed
43
#include "iotvticalendar.h"
Sahil Bansal's avatar
Sahil Bansal committed
44 45 46 47 48 49
#include "pbkdf2.h"
#include "resourcemanager.h"
#include "srmresourcestrings.h"
#include "srmutility.h"
#include "psinterface.h"
#include "pinoxmcommon.h"
50

51 52
#ifdef __WITH_DTLS__
#include "global.h"
Sahil Bansal's avatar
Sahil Bansal committed
53
#endif
leechul's avatar
leechul committed
54

Sahil Bansal's avatar
Sahil Bansal committed
55 56 57 58
#define TAG  "SRM-CREDL"

/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
 * The value of payload size is increased until reaching belox max cbor size. */
leechul's avatar
leechul committed
59
static const uint16_t CBOR_SIZE = 2048;
60

Sahil Bansal's avatar
Sahil Bansal committed
61 62
/** Max cbor size payload. */
static const uint16_t CBOR_MAX_SIZE = 4400;
Sachin Agrawal's avatar
Sachin Agrawal committed
63

leechul's avatar
leechul committed
64 65 66 67
/** CRED size - Number of mandatory items. */
static const uint8_t CRED_ROOT_MAP_SIZE = 2;
static const uint8_t CRED_MAP_SIZE = 3;

Shilpa Sodani's avatar
Shilpa Sodani committed
68

Sachin Agrawal's avatar
Sachin Agrawal committed
69 70 71
static OicSecCred_t        *gCred = NULL;
static OCResourceHandle    gCredHandle = NULL;

72 73 74 75
/**
 * This function frees OicSecCred_t object's fields and object itself.
 */
static void FreeCred(OicSecCred_t *cred)
Sachin Agrawal's avatar
Sachin Agrawal committed
76
{
77
    if(NULL == cred)
Sachin Agrawal's avatar
Sachin Agrawal committed
78
    {
Sahil Bansal's avatar
Sahil Bansal committed
79
        OIC_LOG(ERROR, TAG, "Invalid Parameter");
80 81 82
        return;
    }
    //Note: Need further clarification on roleID data type
Sachin Agrawal's avatar
Sachin Agrawal committed
83
#if 0
84 85
    //Clean roleIds
    OICFree(cred->roleIds);
Sachin Agrawal's avatar
Sachin Agrawal committed
86 87
#endif

88
    //Clean PublicData
Sahil Bansal's avatar
Sahil Bansal committed
89
#ifdef __WITH_X509__
90
    OICFree(cred->publicData.data);
Sahil Bansal's avatar
Sahil Bansal committed
91
#endif
Sachin Agrawal's avatar
Sachin Agrawal committed
92

93 94
    //Clean PrivateData
    OICFree(cred->privateData.data);
Sachin Agrawal's avatar
Sachin Agrawal committed
95

96 97
    //Clean Period
    OICFree(cred->period);
Sachin Agrawal's avatar
Sachin Agrawal committed
98

99 100 101
    //Clean Cred node itself
    OICFree(cred);
}
Sachin Agrawal's avatar
Sachin Agrawal committed
102

103 104 105 106 107 108 109 110 111
void DeleteCredList(OicSecCred_t* cred)
{
    if (cred)
    {
        OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
        LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
        {
            LL_DELETE(cred, credTmp1);
            FreeCred(credTmp1);
Sachin Agrawal's avatar
Sachin Agrawal committed
112 113 114 115
        }
    }
}

Sahil Bansal's avatar
Sahil Bansal committed
116
static size_t OicSecCredCount(const OicSecCred_t *secCred)
Sachin Agrawal's avatar
Sachin Agrawal committed
117
{
Sahil Bansal's avatar
Sahil Bansal committed
118 119
    size_t size = 0;
    for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
Sachin Agrawal's avatar
Sachin Agrawal committed
120
    {
Sahil Bansal's avatar
Sahil Bansal committed
121 122 123 124
        size++;
    }
    return size;
}
125

Sahil Bansal's avatar
Sahil Bansal committed
126 127 128 129 130 131 132
OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
                                size_t *cborSize)
{
    if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
    {
        return OC_STACK_INVALID_PARAM;
    }
133

Sahil Bansal's avatar
Sahil Bansal committed
134
    OCStackResult ret = OC_STACK_ERROR;
Sachin Agrawal's avatar
Sachin Agrawal committed
135

leechul's avatar
leechul committed
136 137 138
    CborError cborEncoderResult = CborNoError;
    uint8_t *outPayload = NULL;
    size_t cborLen = *cborSize;
Sahil Bansal's avatar
Sahil Bansal committed
139 140
    *cborSize = 0;
    *cborPayload = NULL;
leechul's avatar
leechul committed
141
    const OicSecCred_t *cred = credS;
142 143 144
    CborEncoder encoder;
    CborEncoder credArray;
    CborEncoder credRootMap;
Sachin Agrawal's avatar
Sachin Agrawal committed
145

leechul's avatar
leechul committed
146 147 148 149 150 151
    if (0 == cborLen)
    {
        cborLen = CBOR_SIZE;
    }

    outPayload = (uint8_t *)OICCalloc(1, cborLen);
Sahil Bansal's avatar
Sahil Bansal committed
152 153
    VERIFY_NON_NULL(TAG, outPayload, ERROR);
    cbor_encoder_init(&encoder, outPayload, cborLen, 0);
Sachin Agrawal's avatar
Sachin Agrawal committed
154

leechul's avatar
leechul committed
155 156 157 158 159 160 161 162 163 164 165 166
    // Create CRED Root Map (creds, rownerid)
    cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");

    // creds
    cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
        strlen(OIC_JSON_CREDS_NAME));
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");

    // creds array
    cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
leechul's avatar
leechul committed
167

Sahil Bansal's avatar
Sahil Bansal committed
168 169
    while (cred)
    {
170
        CborEncoder credMap;
Sahil Bansal's avatar
Sahil Bansal committed
171
        size_t mapSize = CRED_MAP_SIZE;
leechul's avatar
leechul committed
172
        char *subject = NULL;
Sahil Bansal's avatar
Sahil Bansal committed
173 174 175 176 177
        if (cred->period)
        {
            mapSize++;
        }
#ifdef __WITH_X509__
Dmitriy Zhuravlev's avatar
Dmitriy Zhuravlev committed
178
        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
Sahil Bansal's avatar
Sahil Bansal committed
179 180 181 182 183 184 185 186
        {
            mapSize++;
        }
#endif /* __WITH_X509__ */
        if (cred->privateData.data)
        {
            mapSize++;
        }
leechul's avatar
leechul committed
187
        cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
Sahil Bansal's avatar
Sahil Bansal committed
188 189 190
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");

        //CredID -- Mandatory
leechul's avatar
leechul committed
191
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
192 193
            strlen(OIC_JSON_CREDID_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
leechul's avatar
leechul committed
194
        cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
Sahil Bansal's avatar
Sahil Bansal committed
195 196 197
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");

        //Subject -- Mandatory
leechul's avatar
leechul committed
198 199
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
            strlen(OIC_JSON_SUBJECTID_NAME));
Sahil Bansal's avatar
Sahil Bansal committed
200
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
leechul's avatar
leechul committed
201 202 203 204 205
        ret = ConvertUuidToStr(&cred->subject, &subject);
        VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
        cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
        OICFree(subject);
Sahil Bansal's avatar
Sahil Bansal committed
206 207

        //CredType -- Mandatory
leechul's avatar
leechul committed
208
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
209 210
            strlen(OIC_JSON_CREDTYPE_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
leechul's avatar
leechul committed
211
        cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
Sahil Bansal's avatar
Sahil Bansal committed
212
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
Sachin Agrawal's avatar
Sachin Agrawal committed
213

Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
214
#ifdef __WITH_X509__
Sahil Bansal's avatar
Sahil Bansal committed
215
        //PublicData -- Not Mandatory
Dmitriy Zhuravlev's avatar
Dmitriy Zhuravlev committed
216
        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
Sahil Bansal's avatar
Sahil Bansal committed
217
        {
218
            CborEncoder publicMap;
leechul's avatar
leechul committed
219 220 221 222 223 224 225 226 227
            const size_t publicMapSize = 2;

            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
                strlen(OIC_JSON_PUBLICDATA_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");

            cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");

228 229
            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
                strlen(OIC_JSON_DATA_NAME));
leechul's avatar
leechul committed
230 231 232 233 234 235 236 237 238
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
            cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
                cred->publicData.len);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");

            // TODO: Need to data strucure modification for OicSecCert_t.
            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
                strlen(OIC_JSON_ENCODING_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
js126.lee's avatar
js126.lee committed
239 240
            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_RAW,
                strlen(OIC_SEC_ENCODING_RAW));
leechul's avatar
leechul committed
241 242 243 244
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");

            cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
Sahil Bansal's avatar
Sahil Bansal committed
245
        }
Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
246
#endif /*__WITH_X509__*/
Sahil Bansal's avatar
Sahil Bansal committed
247 248 249
        //PrivateData -- Not Mandatory
        if(cred->privateData.data)
        {
250
            CborEncoder privateMap;
leechul's avatar
leechul committed
251 252 253 254 255 256 257 258 259
            const size_t privateMapSize = 2;

            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
                strlen(OIC_JSON_PRIVATEDATA_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");

            cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");

260 261
            cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
                strlen(OIC_JSON_DATA_NAME));
leechul's avatar
leechul committed
262 263
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
            cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
Sahil Bansal's avatar
Sahil Bansal committed
264
                cred->privateData.len);
leechul's avatar
leechul committed
265 266 267 268 269 270
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");

            // TODO: Need to data strucure modification for OicSecKey_t.
            cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
                strlen(OIC_JSON_ENCODING_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
js126.lee's avatar
js126.lee committed
271 272
            cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
                strlen(OIC_SEC_ENCODING_RAW));
leechul's avatar
leechul committed
273 274 275 276
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");

            cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
Sahil Bansal's avatar
Sahil Bansal committed
277
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
278

Sahil Bansal's avatar
Sahil Bansal committed
279 280 281
        //Period -- Not Mandatory
        if(cred->period)
        {
leechul's avatar
leechul committed
282
            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
283 284
                strlen(OIC_JSON_PERIOD_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
leechul's avatar
leechul committed
285
            cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
Sahil Bansal's avatar
Sahil Bansal committed
286 287 288
                strlen(cred->period));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
289

leechul's avatar
leechul committed
290 291

        cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
Sahil Bansal's avatar
Sahil Bansal committed
292
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
293

Sahil Bansal's avatar
Sahil Bansal committed
294
        cred = cred->next;
leechul's avatar
leechul committed
295 296 297 298 299
    }
    cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");

    cred = credS;
300

leechul's avatar
leechul committed
301 302 303 304 305 306
    // Rownerid
    {
        char *rowner = NULL;
        cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
            strlen(OIC_JSON_ROWNERID_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
307
        ret = ConvertUuidToStr(&cred->rownerID, &rowner);
leechul's avatar
leechul committed
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
        VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
        cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
        OICFree(rowner);
    }

    // Close CRED Root Map
    cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");

    if (CborNoError == cborEncoderResult)
    {
        OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
        *cborPayload = outPayload;
        *cborSize = encoder.ptr - outPayload;
Sahil Bansal's avatar
Sahil Bansal committed
323 324 325
        ret = OC_STACK_OK;
    }
    OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
Sachin Agrawal's avatar
Sachin Agrawal committed
326
exit:
leechul's avatar
leechul committed
327
    if (CborErrorOutOfMemory == cborEncoderResult)
328
    {
leechul's avatar
leechul committed
329 330 331 332 333 334 335 336
        OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
        // reallocate and try again!
        OICFree(outPayload);
        // Since the allocated initial memory failed, double the memory.
        cborLen += encoder.ptr - encoder.end;
        cborEncoderResult = CborNoError;
        ret = CredToCBORPayload(credS, cborPayload, &cborLen);
        *cborSize = cborLen;
337
    }
Sahil Bansal's avatar
Sahil Bansal committed
338 339 340

    if (CborNoError != cborEncoderResult)
    {
leechul's avatar
leechul committed
341 342 343 344 345 346
        OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
        OICFree(outPayload);
        outPayload = NULL;
        *cborSize = 0;
        *cborPayload = NULL;
        ret = OC_STACK_ERROR;
Sahil Bansal's avatar
Sahil Bansal committed
347 348 349
    }

    return ret;
Sachin Agrawal's avatar
Sachin Agrawal committed
350 351
}

Sahil Bansal's avatar
Sahil Bansal committed
352 353
OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                OicSecCred_t **secCred)
Sachin Agrawal's avatar
Sachin Agrawal committed
354
{
Ashwini Kumar's avatar
Ashwini Kumar committed
355
    if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
Sahil Bansal's avatar
Sahil Bansal committed
356 357 358
    {
        return OC_STACK_INVALID_PARAM;
    }
Sachin Agrawal's avatar
Sachin Agrawal committed
359

Sahil Bansal's avatar
Sahil Bansal committed
360
    OCStackResult ret = OC_STACK_ERROR;
leechul's avatar
leechul committed
361 362
    CborValue credCbor = { .parser = NULL };
    CborParser parser = { .end = NULL };
Sahil Bansal's avatar
Sahil Bansal committed
363
    CborError cborFindResult = CborNoError;
leechul's avatar
leechul committed
364
    cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
leechul's avatar
leechul committed
365

leechul's avatar
leechul committed
366
    OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
367

leechul's avatar
leechul committed
368 369 370 371
    // Enter CRED Root Map
    CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
    cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
Sachin Agrawal's avatar
Sachin Agrawal committed
372

leechul's avatar
leechul committed
373
    while (cbor_value_is_valid(&CredRootMap))
Sahil Bansal's avatar
Sahil Bansal committed
374
    {
leechul's avatar
leechul committed
375 376 377 378
        char* tagName = NULL;
        size_t len = 0;
        CborType type = cbor_value_get_type(&CredRootMap);
        if (type == CborTextStringType)
Sahil Bansal's avatar
Sahil Bansal committed
379
        {
leechul's avatar
leechul committed
380 381 382 383
            cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
            cborFindResult = cbor_value_advance(&CredRootMap);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
Sahil Bansal's avatar
Sahil Bansal committed
384
        }
leechul's avatar
leechul committed
385
        if(tagName)
Sahil Bansal's avatar
Sahil Bansal committed
386
        {
leechul's avatar
leechul committed
387
            if (strcmp(tagName, OIC_JSON_CREDS_NAME)  == 0)
388
            {
leechul's avatar
leechul committed
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
                // Enter CREDS Array
                size_t len = 0;
                int credCount = 0;
                CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
                cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");

                while (cbor_value_is_valid(&credArray))
                {
                    credCount++;
                    //CredId -- Mandatory
                    CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
                    cborFindResult = cbor_value_enter_container(&credArray, &credMap);
                    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
                    OicSecCred_t *cred = NULL;

                    if(1 == credCount)
                    {
                        cred = headCred;
                    }
                    else
                    {
                        cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
                        OicSecCred_t *temp = headCred;
                        while (temp->next)
                        {
                            temp = temp->next;
                        }
                        temp->next = cred;
                    }

                    VERIFY_NON_NULL(TAG, cred, ERROR);

                    while(cbor_value_is_valid(&credMap))
                    {
                        char* name = NULL;
                        CborType type = cbor_value_get_type(&credMap);
                        if (type == CborTextStringType)
                        {
                            cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
                            cborFindResult = cbor_value_advance(&credMap);
                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
                        }
                        if(name)
                        {
                            //credid
                            if (strcmp(name, OIC_JSON_CREDID_NAME)  == 0)
                            {
                                cborFindResult = cbor_value_get_uint64(&credMap, (uint64_t *) &cred->credId);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
                            }
                            // subjectid
                            if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
                            {
                                char *subjectid = NULL;
                                cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
                                ret = ConvertStrToUuid(subjectid, &cred->subject);
                                VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
                                OICFree(subjectid);
                            }
451
                            // credtype
leechul's avatar
leechul committed
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
                            if (strcmp(name, OIC_JSON_CREDTYPE_NAME)  == 0)
                            {
                                cborFindResult = cbor_value_get_uint64(&credMap, (uint64_t *) &cred->credType);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
                            }
                            // privatedata
                            if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME)  == 0)
                            {
                                CborValue privateMap = { .parser = NULL };
                                cborFindResult = cbor_value_enter_container(&credMap, &privateMap);

                                while (cbor_value_is_valid(&privateMap))
                                {
                                    char* privname = NULL;
                                    CborType type = cbor_value_get_type(&privateMap);
                                    if (type == CborTextStringType)
                                    {
                                        cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
                                                &len, NULL);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
                                        cborFindResult = cbor_value_advance(&privateMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
                                    }
                                    if (privname)
                                    {
                                        // PrivateData::privdata -- Mandatory
478
                                        if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
leechul's avatar
leechul committed
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
                                        {
                                            cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
                                                &cred->privateData.len, NULL);
                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
                                        }
                                        // PrivateData::encoding -- Mandatory
                                        if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
                                        {
                                            // TODO: Need to update data structure, just ignore encoding value now.
                                        }
                                    }
                                    if (cbor_value_is_valid(&privateMap))
                                    {
                                        cborFindResult = cbor_value_advance(&privateMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
                                    }
                                    OICFree(privname);
                                }

                            }
leechul's avatar
leechul committed
499
#ifdef __WITH_X509__
leechul's avatar
leechul committed
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
                            if (strcmp(name, OIC_JSON_PUBLICDATA_NAME)  == 0)
                            {
                                CborValue pubMap = { .parser = NULL };
                                cborFindResult = cbor_value_enter_container(&credMap, &pubMap);

                                while (cbor_value_is_valid(&pubMap))
                                {
                                    char* pubname = NULL;
                                    CborType type = cbor_value_get_type(&pubMap);
                                    if (type == CborTextStringType)
                                    {
                                        cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
                                                &len, NULL);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
                                        cborFindResult = cbor_value_advance(&pubMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
                                    }
                                    if (pubname)
                                    {
                                        // PrivateData::privdata -- Mandatory
520
                                        if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0)
leechul's avatar
leechul committed
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
                                        {
                                            cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
                                                &cred->publicData.len, NULL);
                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
                                        }
                                        // PublicData::encoding -- Mandatory
                                        if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
                                        {
                                            // TODO: Need to update data structure, just ignore encoding value now.
                                        }
                                    }
                                    if (cbor_value_is_valid(&pubMap))
                                    {
                                        cborFindResult = cbor_value_advance(&pubMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
                                    }
                                    OICFree(pubname);
                                }
                            }
Sahil Bansal's avatar
Sahil Bansal committed
540
#endif  //__WITH_X509__
leechul's avatar
leechul committed
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564

                            if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
                            {
                                cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
                            }

                            if (cbor_value_is_valid(&credMap))
                            {
                                cborFindResult = cbor_value_advance(&credMap);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
                            }
                            OICFree(name);
                        }
                    }
                    cred->next = NULL;
                    if (cbor_value_is_valid(&credArray))
                    {
                        cborFindResult = cbor_value_advance(&credArray);
                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
                    }
                }
            }

565
            //ROwner -- Mandatory
leechul's avatar
leechul committed
566
            if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0)
Sachin Agrawal's avatar
Sachin Agrawal committed
567
            {
leechul's avatar
leechul committed
568 569 570
                char *stRowner = NULL;
                cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
571 572

                ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
leechul's avatar
leechul committed
573 574
                VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
                OICFree(stRowner);
Sachin Agrawal's avatar
Sachin Agrawal committed
575
            }
leechul's avatar
leechul committed
576
            OICFree(tagName);
Sahil Bansal's avatar
Sahil Bansal committed
577
        }
leechul's avatar
leechul committed
578
        if (cbor_value_is_valid(&CredRootMap))
Sahil Bansal's avatar
Sahil Bansal committed
579
        {
leechul's avatar
leechul committed
580 581
            cborFindResult = cbor_value_advance(&CredRootMap);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
Sahil Bansal's avatar
Sahil Bansal committed
582
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
583
    }
leechul's avatar
leechul committed
584

Sahil Bansal's avatar
Sahil Bansal committed
585
    *secCred = headCred;
Sachin Agrawal's avatar
Sachin Agrawal committed
586
    ret = OC_STACK_OK;
leechul's avatar
leechul committed
587

Sachin Agrawal's avatar
Sachin Agrawal committed
588
exit:
Sahil Bansal's avatar
Sahil Bansal committed
589
    if (CborNoError != cborFindResult)
Sachin Agrawal's avatar
Sachin Agrawal committed
590 591 592
    {
        DeleteCredList(headCred);
        headCred = NULL;
leechul's avatar
leechul committed
593
        *secCred = NULL;
Sahil Bansal's avatar
Sahil Bansal committed
594
        ret = OC_STACK_ERROR;
595
    }
Sahil Bansal's avatar
Sahil Bansal committed
596 597

    return ret;
Sachin Agrawal's avatar
Sachin Agrawal committed
598 599 600
}

OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
Sahil Bansal's avatar
Sahil Bansal committed
601
                                  const OicSecCert_t * publicData, const OicSecKey_t* privateData,
602
                                  const OicUuid_t * rownerID)
Sachin Agrawal's avatar
Sachin Agrawal committed
603
{
Jon A. Cruz's avatar
Jon A. Cruz committed
604
    (void)publicData;
Sachin Agrawal's avatar
Sachin Agrawal committed
605 606
    OCStackResult ret = OC_STACK_ERROR;

Sahil Bansal's avatar
Sahil Bansal committed
607
    OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
Sachin Agrawal's avatar
Sachin Agrawal committed
608 609
    VERIFY_NON_NULL(TAG, cred, ERROR);

610 611 612
    //CredId is assigned before appending new cred to the existing
    //credential list and updating svr database in AddCredential().
    cred->credId = 0;
Sachin Agrawal's avatar
Sachin Agrawal committed
613 614 615 616

    VERIFY_NON_NULL(TAG, subject, ERROR);
    memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));

617 618
    VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
            SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
Sachin Agrawal's avatar
Sachin Agrawal committed
619 620
    cred->credType = credType;

Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
621
#ifdef __WITH_X509__
Sahil Bansal's avatar
Sahil Bansal committed
622
    if (publicData && publicData->data)
Sachin Agrawal's avatar
Sachin Agrawal committed
623
    {
Sahil Bansal's avatar
Sahil Bansal committed
624
        cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
Sachin Agrawal's avatar
Sachin Agrawal committed
625
        VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
626 627
        memcpy(cred->publicData.data, publicData->data, publicData->len);
        cred->publicData.len = publicData->len;
Sachin Agrawal's avatar
Sachin Agrawal committed
628
    }
Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
629
#endif // __WITH_X509__
Sachin Agrawal's avatar
Sachin Agrawal committed
630

Sahil Bansal's avatar
Sahil Bansal committed
631
    if (privateData && privateData->data)
Sachin Agrawal's avatar
Sachin Agrawal committed
632
    {
Sahil Bansal's avatar
Sahil Bansal committed
633
        cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
Sachin Agrawal's avatar
Sachin Agrawal committed
634
        VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
635 636
        memcpy(cred->privateData.data, privateData->data, privateData->len);
        cred->privateData.len = privateData->len;
Sachin Agrawal's avatar
Sachin Agrawal committed
637 638
    }

639 640
    VERIFY_NON_NULL(TAG, rownerID, ERROR);
    memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
Sachin Agrawal's avatar
Sachin Agrawal committed
641 642 643 644 645 646 647 648 649 650 651

    ret = OC_STACK_OK;
exit:
    if (OC_STACK_OK != ret)
    {
        DeleteCredList(cred);
        cred = NULL;
    }
    return cred;
}

652 653 654 655 656
static bool UpdatePersistentStorage(const OicSecCred_t *cred)
{
    bool ret = false;

    // Convert Cred data into JSON for update to persistent storage
Sahil Bansal's avatar
Sahil Bansal committed
657
    if (cred)
658
    {
Sahil Bansal's avatar
Sahil Bansal committed
659 660 661 662
        uint8_t *payload = NULL;
        size_t size = 0;
        OCStackResult res = CredToCBORPayload(cred, &payload, &size);
        if ((OC_STACK_OK == res) && payload)
663
        {
Sahil Bansal's avatar
Sahil Bansal committed
664 665 666 667 668
            if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
            {
                ret = true;
            }
            OICFree(payload);
669 670 671 672
        }
    }
    else //Empty cred list
    {
Sahil Bansal's avatar
Sahil Bansal committed
673
        if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
674 675 676 677 678 679 680 681
        {
            ret = true;
        }
    }
    return ret;
}

/**
Sahil Bansal's avatar
Sahil Bansal committed
682
 * Compare function used LL_SORT for sorting credentials.
683
 *
Sahil Bansal's avatar
Sahil Bansal committed
684 685
 * @param first pointer to OicSecCred_t struct.
 * @param second  pointer to OicSecCred_t struct.
686
 *
Sahil Bansal's avatar
Sahil Bansal committed
687 688 689
 *@return -1, if credId of first is less than credId of second.
 * 0, if credId of first is equal to credId of second.
 * 1, if credId of first is greater than credId of second.
690 691 692
 */
static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
{
Sahil Bansal's avatar
Sahil Bansal committed
693
    if (first->credId < second->credId)
694 695 696
    {
        return -1;
    }
Sahil Bansal's avatar
Sahil Bansal committed
697
    else if (first->credId > second->credId)
698 699 700 701 702 703 704 705 706 707 708 709 710
    {
        return 1;
    }
    else
        return 0;
}

/**
 * GetCredId goes through the cred list and returns the next
 * available credId. The next credId could be the credId that is
 * available due deletion of OicSecCred_t object or one more than
 * credId of last credential in the list.
 *
Sahil Bansal's avatar
Sahil Bansal committed
711
 * @return next available credId if successful, else 0 for error.
712 713 714 715 716 717 718 719 720 721 722
 */
static uint16_t GetCredId()
{
    //Sorts credential list in incremental order of credId
    LL_SORT(gCred, CmpCredId);

    OicSecCred_t *currentCred = NULL, *credTmp = NULL;
    uint16_t nextCredId = 1;

    LL_FOREACH_SAFE(gCred, currentCred, credTmp)
    {
Sahil Bansal's avatar
Sahil Bansal committed
723
        if (currentCred->credId == nextCredId)
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738
        {
            nextCredId += 1;
        }
        else
        {
            break;
        }
    }

    VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
    return nextCredId;

exit:
    return 0;
}
739

740
/**
Sahil Bansal's avatar
Sahil Bansal committed
741 742 743
 * Get the default value.
 *
 * @return  NULL for now.
744 745 746
 */
static OicSecCred_t* GetCredDefault()
{
Sahil Bansal's avatar
Sahil Bansal committed
747
    // TODO:Update it when we finalize the default info.
748 749
    return NULL;
}
750

Sachin Agrawal's avatar
Sachin Agrawal committed
751 752 753
OCStackResult AddCredential(OicSecCred_t * newCred)
{
    OCStackResult ret = OC_STACK_ERROR;
754 755 756 757 758
    VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);

    //Assigning credId to the newCred
    newCred->credId = GetCredId();
    VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
Sachin Agrawal's avatar
Sachin Agrawal committed
759 760 761

    //Append the new Cred to existing list
    LL_APPEND(gCred, newCred);
762

Sahil Bansal's avatar
Sahil Bansal committed
763
    if (UpdatePersistentStorage(gCred))
Sachin Agrawal's avatar
Sachin Agrawal committed
764
    {
765 766 767 768 769 770 771 772 773 774 775 776 777
        ret = OC_STACK_OK;
    }

exit:
    return ret;
}

OCStackResult RemoveCredential(const OicUuid_t *subject)
{
    OCStackResult ret = OC_STACK_ERROR;
    OicSecCred_t *cred = NULL;
    OicSecCred_t *tempCred = NULL;
    bool deleteFlag = false;
Sachin Agrawal's avatar
Sachin Agrawal committed
778

779 780
    LL_FOREACH_SAFE(gCred, cred, tempCred)
    {
Sahil Bansal's avatar
Sahil Bansal committed
781
        if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
Sachin Agrawal's avatar
Sachin Agrawal committed
782
        {
783 784 785
            LL_DELETE(gCred, cred);
            FreeCred(cred);
            deleteFlag = 1;
Sachin Agrawal's avatar
Sachin Agrawal committed
786 787 788
        }
    }

Sahil Bansal's avatar
Sahil Bansal committed
789
    if (deleteFlag)
790
    {
Sahil Bansal's avatar
Sahil Bansal committed
791
        if (UpdatePersistentStorage(gCred))
792 793 794 795
        {
            ret = OC_STACK_RESOURCE_DELETED;
        }
    }
Sachin Agrawal's avatar
Sachin Agrawal committed
796
    return ret;
797

Sachin Agrawal's avatar
Sachin Agrawal committed
798 799
}

800 801 802 803 804 805 806 807 808 809 810 811
/**
 * Remove all credential data on credential resource and persistent storage
 *
 * @retval
 *     OC_STACK_OK              - no errors
 *     OC_STACK_ERROR           - stack process error
 */
OCStackResult RemoveAllCredentials(void)
{
    DeleteCredList(gCred);
    gCred = GetCredDefault();

Sahil Bansal's avatar
Sahil Bansal committed
812
    if (!UpdatePersistentStorage(gCred))
813 814 815 816 817 818
    {
        return OC_STACK_ERROR;
    }
    return OC_STACK_OK;
}

819 820
#ifdef __WITH_DTLS__
/**
821
 * Internal function to fill private data of owner PSK.
822
 *
823
 * @param receviedCred recevied owner credential from OBT(PT)
824 825 826
 * @param ownerAdd address of OBT(PT)
 * @param doxm current device's doxm resource
 *
Sahil Bansal's avatar
Sahil Bansal committed
827
 * @return
828 829
 *     true successfully done and valid ower psk information
 *     false Invalid owner psk information or failed to owner psk generation
830
 */
831
static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
832 833 834 835 836 837 838 839 840 841 842 843 844 845
                           const OicSecDoxm_t* doxm)
{
    //Derive OwnerPSK locally
    const char* oxmLabel = GetOxmString(doxm->oxmSel);
    VERIFY_NON_NULL(TAG, oxmLabel, ERROR);

    uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
    CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
        (uint8_t*)oxmLabel, strlen(oxmLabel),
        doxm->owner.id, sizeof(doxm->owner.id),
        doxm->deviceID.id, sizeof(doxm->deviceID.id),
        ownerPSK, OWNER_PSK_LENGTH_128);
    VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);

846 847 848 849
    OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
    OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);

    //Generate owner credential based on recevied credential information
Sahil Bansal's avatar
Sahil Bansal committed
850
    receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
851
    VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
852 853
    receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
    memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
854

855 856 857 858 859
    OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");

    //Verify OwnerPSK information
    return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
            receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
860
exit:
861
    //receviedCred->privateData.data will be deallocated when deleting credential.
862 863 864 865 866 867 868 869
    return false;
}

#endif //__WITH_DTLS__

static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehRequest)
{
    OCEntityHandlerResult ret = OC_EH_ERROR;
Sahil Bansal's avatar
Sahil Bansal committed
870 871 872 873
    OIC_LOG(DEBUG, TAG, "HandleCREDPutRequest IN");

    //Get binary representation of cbor
    OicSecCred_t *cred  = NULL;
Ashwini Kumar's avatar
Ashwini Kumar committed
874
    uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
Sahil Bansal's avatar
Sahil Bansal committed
875 876 877
    size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
    OCStackResult res = CBORPayloadToCred(payload, size, &cred);
    if (res == OC_STACK_OK)
878 879 880 881 882 883 884 885 886 887 888 889
    {
#ifdef __WITH_DTLS__
        OicUuid_t emptyUuid = {.id={0}};
        const OicSecDoxm_t* doxm = GetDoxmResourceData();
        if(false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
        {
            //in case of owner PSK
            switch(cred->credType)
            {
                case SYMMETRIC_PAIR_WISE_KEY:
                {
                    OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
890
                    if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
891
                    {
892 893 894 895 896 897
                        if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
                        {
                            OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
                        }

                        OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913
                        if(OC_STACK_OK == AddCredential(cred))
                        {
                            ret = OC_EH_RESOURCE_CREATED;
                        }
                        else
                        {
                            OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
                            ret = OC_EH_ERROR;
                        }
                    }
                    else
                    {
                        OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
                        ret = OC_EH_ERROR;
                    }

914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951
                    if(OC_EH_RESOURCE_CREATED == ret)
                    {
                        /**
                         * in case of random PIN based OxM,
                         * revert get_psk_info callback of tinyDTLS to use owner credential.
                         */
                        if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
                        {
                            OicUuid_t emptyUuid = { .id={0}};
                            SetUuidForRandomPinOxm(&emptyUuid);

                            if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
                            {
                                OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
                                ret = OC_EH_ERROR;
                                break;
                            }
                        }

                        //Select cipher suite to use owner PSK
                        if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
                        {
                            OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
                            ret = OC_EH_ERROR;
                        }
                        else
                        {
                            OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
                        }

                        if(CA_STATUS_OK !=
                           CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256))
                        {
                            OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
                            ret = OC_EH_ERROR;
                        }
                    }

952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970
                    break;
                }
                case SYMMETRIC_GROUP_KEY:
                case ASYMMETRIC_KEY:
                case SIGNED_ASYMMETRIC_KEY:
                case PIN_PASSWORD:
                case ASYMMETRIC_ENCRYPTION_KEY:
                {
                    OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
                    ret = OC_EH_ERROR;
                    break;
                }
                default:
                {
                    OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
                    ret = OC_EH_ERROR;
                    break;
                }
            }
971 972 973 974 975 976 977 978 979 980

            if(OC_EH_RESOURCE_CREATED != ret)
            {
                /*
                  * If some error is occured while ownership transfer,
                  * ownership transfer related resource should be revert back to initial status.
                  */
                RestoreDoxmToInitState();
                RestorePstatToInitState();
            }
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002
        }
        else
        {
            /*
             * If the post request credential has credId, it will be
             * discarded and the next available credId will be assigned
             * to it before getting appended to the existing credential
             * list and updating svr database.
             */
            ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
        }
#else //not __WITH_DTLS__
        /*
         * If the post request credential has credId, it will be
         * discarded and the next available credId will be assigned
         * to it before getting appended to the existing credential
         * list and updating svr database.
         */
        ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
#endif//__WITH_DTLS__
    }

Sahil Bansal's avatar
Sahil Bansal committed
1003
    if (OC_EH_RESOURCE_CREATED != ret)
1004 1005 1006 1007 1008 1009 1010
    {
        if(OC_STACK_OK != RemoveCredential(&cred->subject))
        {
            OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
        }
        FreeCred(cred);
    }
Sahil Bansal's avatar
Sahil Bansal committed
1011
    OIC_LOG(DEBUG, TAG, "HandleCREDPutRequest OUT");
1012 1013 1014
    return ret;
}

Sachin Agrawal's avatar
Sachin Agrawal committed
1015 1016 1017 1018
static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
{
    OCEntityHandlerResult ret = OC_EH_ERROR;

Sahil Bansal's avatar
Sahil Bansal committed
1019 1020
    //Get binary representation of CBOR
    OicSecCred_t *cred  = NULL;
Ashwini Kumar's avatar
Ashwini Kumar committed
1021
    uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData;
Sahil Bansal's avatar
Sahil Bansal committed
1022 1023 1024
    size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize;
    OCStackResult res = CBORPayloadToCred(payload, size, &cred);
    if ((OC_STACK_OK == res) && cred)
Sachin Agrawal's avatar
Sachin Agrawal committed
1025
    {
1026 1027 1028 1029
        //If the Post request credential has credId, it will be
        //discarded and the next available credId will be assigned
        //to it before getting appended to the existing credential
        //list and updating svr database.
1030
        ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
Sachin Agrawal's avatar
Sachin Agrawal committed
1031
    }
1032

Sachin Agrawal's avatar
Sachin Agrawal committed
1033 1034 1035
    return ret;
}

1036 1037
static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
{
1038
    OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1039 1040 1041

    OCEntityHandlerResult ehRet = OC_EH_ERROR;

Sahil Bansal's avatar
Sahil Bansal committed
1042
    if (NULL == ehRequest->query)
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
    {
        return ehRet;
    }

    OicParseQueryIter_t parseIter = { .attrPos=NULL };
    OicUuid_t subject = {.id={0}};

    //Parsing REST query to get the subject
    ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
    while (GetNextQuery(&parseIter))
    {
        if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
                parseIter.attrLen) == 0)
        {
            OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
            VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
1059
        }
1060
    }
1061

1062 1063 1064 1065
    if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
    {
        ehRet = OC_EH_RESOURCE_DELETED;
    }
1066

leechul's avatar
leechul committed
1067
exit:
1068 1069 1070
    return ehRet;
}

Sahil Bansal's avatar
Sahil Bansal committed
1071
OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1072 1073
                                        OCEntityHandlerRequest * ehRequest,
                                        void* callbackParameter)
Sachin Agrawal's avatar
Sachin Agrawal committed
1074
{
Jon A. Cruz's avatar
Jon A. Cruz committed
1075
    (void)callbackParameter;
Sachin Agrawal's avatar
Sachin Agrawal committed
1076 1077
    OCEntityHandlerResult ret = OC_EH_ERROR;

Sahil Bansal's avatar
Sahil Bansal committed
1078
    if (!ehRequest)
Sachin Agrawal's avatar
Sachin Agrawal committed
1079 1080 1081 1082 1083
    {
        return OC_EH_ERROR;
    }
    if (flag & OC_REQUEST_FLAG)
    {
1084
        OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
Sachin Agrawal's avatar
Sachin Agrawal committed
1085
        //TODO :  Handle PUT/DEL methods
Sahil Bansal's avatar
Sahil Bansal committed
1086
        switch (ehRequest->method)
Sachin Agrawal's avatar
Sachin Agrawal committed
1087 1088 1089 1090
        {
            case OC_REST_GET:
                ret = OC_EH_FORBIDDEN;
                break;
1091 1092 1093
            case OC_REST_PUT:
                ret = HandlePutRequest(ehRequest);
                break;
Sachin Agrawal's avatar
Sachin Agrawal committed
1094 1095 1096
            case OC_REST_POST:
                ret = HandlePostRequest(ehRequest);
                break;
1097 1098 1099
            case OC_REST_DELETE:
                ret = HandleDeleteRequest(ehRequest);
                break;
Sachin Agrawal's avatar
Sachin Agrawal committed
1100 1101 1102 1103 1104 1105 1106
            default:
                ret = OC_EH_ERROR;
                break;
        }
    }

    //Send payload to request originator
Ashwini Kumar's avatar
Ashwini Kumar committed
1107
    ret = (SendSRMResponse(ehRequest, ret, NULL, 0) == OC_STACK_OK) ?
Sahil Bansal's avatar
Sahil Bansal committed
1108
                       ret : OC_EH_ERROR;
Sachin Agrawal's avatar
Sachin Agrawal committed
1109 1110 1111 1112 1113 1114

    return ret;
}

OCStackResult CreateCredResource()
{
Sahil Bansal's avatar
Sahil Bansal committed
1115 1116 1117 1118 1119 1120 1121
    OCStackResult ret = OCCreateResource(&gCredHandle,
                                         OIC_RSRC_TYPE_SEC_CRED,
                                         OIC_MI_DEF,
                                         OIC_RSRC_CRED_URI,
                                         CredEntityHandler,
                                         NULL,
                                         OC_RES_PROP_NONE);
Sachin Agrawal's avatar
Sachin Agrawal committed
1122 1123 1124

    if (OC_STACK_OK != ret)
    {