credresource.c 114 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
#include "iotivity_config.h"
Sahil Bansal's avatar
Sahil Bansal committed
24
#include <stdlib.h>
25
#ifdef HAVE_STRING_H
Sahil Bansal's avatar
Sahil Bansal committed
26
#include <string.h>
27 28
#endif
#ifdef HAVE_STRINGS_H
Sahil Bansal's avatar
Sahil Bansal committed
29 30 31
#include <strings.h>
#endif
#include <stdint.h>
Andrii Shtompel's avatar
Andrii Shtompel committed
32
#include <stdbool.h>
George Nash's avatar
George Nash committed
33
#include <inttypes.h>
Sahil Bansal's avatar
Sahil Bansal committed
34 35 36

#include "cainterface.h"
#include "payload_logging.h"
Sachin Agrawal's avatar
Sachin Agrawal committed
37
#include "ocstack.h"
Sahil Bansal's avatar
Sahil Bansal committed
38 39 40
#include "ocrandom.h"
#include "base64.h"
#include "ocserverrequest.h"
Sachin Agrawal's avatar
Sachin Agrawal committed
41
#include "oic_malloc.h"
42
#include "oic_string.h"
Sahil Bansal's avatar
Sahil Bansal committed
43
#include "ocpayload.h"
44
#include "ocpayloadcbor.h"
Sachin Agrawal's avatar
Sachin Agrawal committed
45 46 47
#include "utlist.h"
#include "credresource.h"
#include "doxmresource.h"
Sahil Bansal's avatar
Sahil Bansal committed
48
#include "pstatresource.h"
leechul's avatar
leechul committed
49
#include "iotvticalendar.h"
Sahil Bansal's avatar
Sahil Bansal committed
50 51 52 53 54 55
#include "pbkdf2.h"
#include "resourcemanager.h"
#include "srmresourcestrings.h"
#include "srmutility.h"
#include "psinterface.h"
#include "pinoxmcommon.h"
Kevin Kane's avatar
Kevin Kane committed
56 57
#include "certhelpers.h"
#include "cacommon.h"
58

Andrii Shtompel's avatar
Andrii Shtompel committed
59 60 61 62 63 64 65
#ifdef __unix__
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#endif

66 67
#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
#include <mbedtls/ssl_ciphersuites.h>
68 69 70
#include <mbedtls/pk.h>
#include <mbedtls/base64.h>
#include <mbedtls/pem.h>
Sahil Bansal's avatar
Sahil Bansal committed
71
#endif
leechul's avatar
leechul committed
72

73
#define TAG  "OIC_SRM_CREDL"
Sahil Bansal's avatar
Sahil Bansal committed
74

75 76
#ifdef HAVE_WINDOWS_H
#include <wincrypt.h>
77
#include <intsafe.h>
78 79
#endif

Andrii Shtompel's avatar
Andrii Shtompel committed
80 81
/** Max credential types number used for TLS */
#define MAX_TYPE 2
Sahil Bansal's avatar
Sahil Bansal committed
82 83
/** 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
84
static const uint16_t CBOR_SIZE = 2048;
85

leechul's avatar
leechul committed
86
/** CRED size - Number of mandatory items. */
Randeep's avatar
Randeep committed
87
static const uint8_t CRED_ROOT_MAP_SIZE = 4;
leechul's avatar
leechul committed
88 89
static const uint8_t CRED_MAP_SIZE = 3;

Shilpa Sodani's avatar
Shilpa Sodani committed
90

Sachin Agrawal's avatar
Sachin Agrawal committed
91 92 93
static OicSecCred_t        *gCred = NULL;
static OCResourceHandle    gCredHandle = NULL;

94 95 96 97 98 99
typedef enum CredCompareResult{
    CRED_CMP_EQUAL = 0,
    CRED_CMP_NOT_EQUAL = 1,
    CRED_CMP_ERROR = 2
}CredCompareResult_t;

100 101 102 103 104 105 106 107 108 109 110
static bool ValueWithinBounds(uint64_t value, uint64_t maxValue)
{
    if (value > maxValue)
    {
        OIC_LOG_V(ERROR, TAG, "The value (%ull) is greater than allowed maximum of %ull.", value, maxValue);
        return false;
    }

    return true;
}

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
/**
 * Internal function to check a subject of SIGNED_ASYMMETRIC_KEY(Certificate).
 * If that subject is NULL or wildcard, set it to own deviceID.
 * @param cred credential on SVR DB file
 * @param deviceID own deviceuuid of doxm resource
 *
 * @return
 *     true successfully done
 *     false Invalid cred
 */

static bool CheckSubjectOfCertificate(OicSecCred_t* cred, OicUuid_t deviceID)
{
    OIC_LOG(DEBUG, TAG, "IN CheckSubjectOfCertificate");
    VERIFY_NOT_NULL(TAG, cred, ERROR);

#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
128 129
    const OicUuid_t emptyUuid = { .id = { 0 } };

130 131 132 133 134 135 136 137
    if ( SIGNED_ASYMMETRIC_KEY == cred->credType)
    {
        if((0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(cred->subject.id))) ||
            (0 == memcmp(cred->subject.id, &WILDCARD_SUBJECT_ID, sizeof(cred->subject.id))))
        {
            memcpy(cred->subject.id, deviceID.id, sizeof(deviceID.id));
        }
    }
138 139
#else
    OC_UNUSED(deviceID);
140 141 142 143 144 145 146 147 148
#endif

    OIC_LOG(DEBUG, TAG, "OUT CheckSubjectOfCertificate");
    return true;
exit:
    OIC_LOG(ERROR, TAG, "OUT CheckSubjectOfCertificate");
    return false;
}

149 150 151
/**
 * Internal function to check credential
 */
152
static bool IsValidCredential(const OicSecCred_t* cred)
153 154 155 156
{
    OicUuid_t emptyUuid = {.id={0}};


157
    OIC_LOG(DEBUG, TAG, "IN IsValidCredential");
158

159
    VERIFY_NOT_NULL(TAG, cred, ERROR);
160 161 162 163 164 165 166 167 168 169 170 171
    VERIFY_SUCCESS(TAG, 0 != cred->credId, ERROR);
    OIC_LOG_V(DEBUG, TAG, "Cred ID = %d", cred->credId);

#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
    OIC_LOG_V(DEBUG, TAG, "Cred Type = %d", cred->credType);

    switch(cred->credType)
    {
        case SYMMETRIC_PAIR_WISE_KEY:
        case SYMMETRIC_GROUP_KEY:
        case PIN_PASSWORD:
        {
172
            VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
173 174 175 176 177 178 179 180 181
            VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
            VERIFY_SUCCESS(TAG, \
                           (OIC_ENCODING_RAW == cred->privateData.encoding || \
                           OIC_ENCODING_BASE64 == cred->privateData.encoding), \
                           ERROR);
            break;
        }
        case ASYMMETRIC_KEY:
        {
182
            VERIFY_NOT_NULL(TAG, cred->publicData.data, ERROR);
183
            VERIFY_SUCCESS(TAG, 0 != cred->publicData.len, ERROR);
184 185 186 187
            VERIFY_SUCCESS(TAG, \
                           (OIC_ENCODING_UNKNOW < cred->publicData.encoding && \
                            OIC_ENCODING_DER >= cred->publicData.encoding),
                           ERROR);
188 189 190 191 192 193 194 195 196 197
            break;
        }
        case SIGNED_ASYMMETRIC_KEY:
        {
            VERIFY_SUCCESS(TAG, (NULL != cred->publicData.data ||NULL != cred->optionalData.data) , ERROR);
            VERIFY_SUCCESS(TAG, (0 != cred->publicData.len || 0 != cred->optionalData.len), ERROR);

            if(NULL != cred->optionalData.data)
            {
                VERIFY_SUCCESS(TAG, \
198 199
                               (OIC_ENCODING_UNKNOW < cred->optionalData.encoding && \
                                OIC_ENCODING_DER >= cred->optionalData.encoding),
200 201 202 203 204 205
                               ERROR);
            }
            break;
        }
        case ASYMMETRIC_ENCRYPTION_KEY:
        {
206
            VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
207 208
            VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
            VERIFY_SUCCESS(TAG, \
209 210
                           (OIC_ENCODING_UNKNOW < cred->privateData.encoding && \
                            OIC_ENCODING_DER >= cred->privateData.encoding),
211 212 213 214 215 216 217 218 219 220 221 222 223
                           ERROR);
            break;
        }
        default:
        {
            OIC_LOG(WARNING, TAG, "Unknown credential type");
            return false;
        }
    }
#endif

    VERIFY_SUCCESS(TAG, 0 != memcmp(emptyUuid.id, cred->subject.id, sizeof(cred->subject.id)), ERROR);

224
    OIC_LOG(DEBUG, TAG, "OUT IsValidCredential");
225 226
    return true;
exit:
227
    OIC_LOG(WARNING, TAG, "OUT IsValidCredential : Invalid Credential detected.");
228 229 230
    return false;
}

231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
static bool IsEmptyCred(const OicSecCred_t* cred)
{
    OicUuid_t emptyUuid = {.id={0}};

    VERIFY_SUCCESS(TAG, (0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(emptyUuid))), ERROR);
    VERIFY_SUCCESS(TAG, (0 == cred->credId), ERROR);
    VERIFY_SUCCESS(TAG, (0 == cred->credType), ERROR);
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
    VERIFY_SUCCESS(TAG, (NULL == cred->privateData.data), ERROR);
    VERIFY_SUCCESS(TAG, (NULL == cred->publicData.data), ERROR);
    VERIFY_SUCCESS(TAG, (NULL == cred->optionalData.data), ERROR);
    VERIFY_SUCCESS(TAG, (NULL == cred->credUsage), ERROR);
#endif
    return true;
exit:
    return false;
}

249 250 251 252
/**
 * This function frees OicSecCred_t object's fields and object itself.
 */
static void FreeCred(OicSecCred_t *cred)
Sachin Agrawal's avatar
Sachin Agrawal committed
253
{
254
    if(NULL == cred)
Sachin Agrawal's avatar
Sachin Agrawal committed
255
    {
Sahil Bansal's avatar
Sahil Bansal committed
256
        OIC_LOG(ERROR, TAG, "Invalid Parameter");
257 258 259
        return;
    }
    //Note: Need further clarification on roleID data type
Sachin Agrawal's avatar
Sachin Agrawal committed
260
#if 0
261 262
    //Clean roleIds
    OICFree(cred->roleIds);
Sachin Agrawal's avatar
Sachin Agrawal committed
263 264
#endif

265
    //Clean PublicData/OptionalData/Credusage
266
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
267
     // TODO: Need to check credUsage.
268
    OICFree(cred->publicData.data);
269 270 271
    OICFree(cred->optionalData.data);
    OICFree(cred->credUsage);

272
#endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
Sachin Agrawal's avatar
Sachin Agrawal committed
273

274
    //Clean PrivateData
275
    OICClearMemory(cred->privateData.data, cred->privateData.len);
276
    OICFree(cred->privateData.data);
Sachin Agrawal's avatar
Sachin Agrawal committed
277

278 279
    //Clean Period
    OICFree(cred->period);
Sachin Agrawal's avatar
Sachin Agrawal committed
280

saurabh.s9's avatar
saurabh.s9 committed
281
#ifdef MULTIPLE_OWNER
282 283 284 285
    //Clean eowner
    OICFree(cred->eownerID);
#endif

286 287 288
    //Clean Cred node itself
    OICFree(cred);
}
Sachin Agrawal's avatar
Sachin Agrawal committed
289

290 291 292 293 294 295 296 297 298
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
299 300 301 302
        }
    }
}

Andrii Shtompel's avatar
Andrii Shtompel committed
303 304 305 306 307 308 309 310 311 312 313 314
size_t GetCredKeyDataSize(const OicSecCred_t* cred)
{
    size_t size = 0;
    if (cred)
    {
        OicSecCred_t *credPtr = NULL, *credTmp = NULL;
        LL_FOREACH_SAFE((OicSecCred_t*)cred, credPtr, credTmp)
        {
            if (credPtr->privateData.data && 0 < credPtr->privateData.len)
            {
                size += credPtr->privateData.len;
            }
315
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
Andrii Shtompel's avatar
Andrii Shtompel committed
316 317 318 319 320 321 322 323 324 325 326
            if (credPtr->publicData.data && 0 < credPtr->publicData.len)
            {
                size += credPtr->publicData.len;
            }
            if (credPtr->optionalData.data && 0 < credPtr->optionalData.len)
            {
                size += credPtr->optionalData.len;
            }
#endif
        }
    }
327
    OIC_LOG_V(DEBUG, TAG, "Cred Key Data Size : %zd\n", size);
Andrii Shtompel's avatar
Andrii Shtompel committed
328 329 330
    return size;
}

Sahil Bansal's avatar
Sahil Bansal committed
331
static size_t OicSecCredCount(const OicSecCred_t *secCred)
Sachin Agrawal's avatar
Sachin Agrawal committed
332
{
Sahil Bansal's avatar
Sahil Bansal committed
333 334
    size_t size = 0;
    for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
Sachin Agrawal's avatar
Sachin Agrawal committed
335
    {
Sahil Bansal's avatar
Sahil Bansal committed
336 337 338 339
        size++;
    }
    return size;
}
340

341
static const char* EncodingValueToString(OicEncodingType_t encoding)
342 343 344
{
    switch (encoding)
    {
345 346 347 348 349
        case OIC_ENCODING_RAW:    return OIC_SEC_ENCODING_RAW;
        case OIC_ENCODING_BASE64: return OIC_SEC_ENCODING_BASE64;
        case OIC_ENCODING_DER:    return OIC_SEC_ENCODING_DER;
        case OIC_ENCODING_PEM:    return OIC_SEC_ENCODING_PEM;
        default:                  return NULL;
350 351 352 353 354 355
    }
}

static CborError SerializeEncodingToCborInternal(CborEncoder *map, const OicSecKey_t *value)
{
    CborError cborEncoderResult = CborNoError;
356
    const char *encoding = EncodingValueToString(value->encoding);
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
    if (encoding)
    {
        cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_ENCODING_NAME,
            strlen(OIC_JSON_ENCODING_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Tag.");
        cborEncoderResult = cbor_encode_text_string(map, encoding,
            strlen(encoding));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Value.");

        cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_DATA_NAME,
            strlen(OIC_JSON_DATA_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Tag.");
        if (OIC_ENCODING_DER == value->encoding ||
            OIC_ENCODING_RAW == value->encoding)
        {
            cborEncoderResult = cbor_encode_byte_string(map,
                    value->data, value->len);
        }
        else
        {
            cborEncoderResult = cbor_encode_text_string(map,
                    (char*)value->data, value->len);
        }
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Value.");
    }
    else
    {
384
        OIC_LOG_V(ERROR, TAG, "%s: Unknown encoding type: %u.", __func__, value->encoding);
385
        return CborErrorUnknownType;
386 387 388 389 390
    }
    exit:
    return cborEncoderResult;
}

391
CborError SerializeEncodingToCbor(CborEncoder *rootMap, const char* tag, const OicSecKey_t *value)
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
{
    CborError cborEncoderResult = CborNoError;
    CborEncoder map;
    const size_t mapSize = 2;

    cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");

    cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");

    VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, value),
                        "Failed adding OicSecKey_t structure");

    cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");

    exit:
    return cborEncoderResult;
}

413
CborError SerializeSecOptToCbor(CborEncoder *rootMap, const char* tag, const OicSecOpt_t *value)
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 451 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 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
{
    CborError cborEncoderResult = CborNoError;
    CborEncoder map;
    const size_t mapSize = 3;

    cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");

    cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");

    OicSecKey_t in;
    in.data = value->data;
    in.encoding = value->encoding;
    in.len = value->len;

    VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, &in),
                        "Failed adding OicSecKey_t structure");

    cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_REVOCATION_STATUS_NAME,
        strlen(OIC_JSON_REVOCATION_STATUS_NAME));
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Tag.");
    cborEncoderResult = cbor_encode_boolean(&map, value->revstat);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Value.");

    cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");

    exit:
    return cborEncoderResult;
}

static CborError DeserializeEncodingFromCborInternal(CborValue *map, char *name, OicSecKey_t *value)
{
    size_t len = 0;
    CborError cborFindResult = CborNoError;

    // data -- Mandatory
    if (strcmp(name, OIC_JSON_DATA_NAME) == 0)
    {
        if(cbor_value_is_byte_string(map))
        {
            cborFindResult = cbor_value_dup_byte_string(map, &value->data,
                &value->len, NULL);
        }
        else if(cbor_value_is_text_string(map))
        {
            cborFindResult = cbor_value_dup_text_string(map, (char**)(&value->data),
                &value->len, NULL);
        }
        else
        {
            cborFindResult = CborErrorUnknownType;
            OIC_LOG(ERROR, TAG, "Unknown type for private data.");
        }
        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
    }

    // encoding -- Mandatory
    if (strcmp(name, OIC_JSON_ENCODING_NAME) == 0)
    {
        char* strEncoding = NULL;
        cborFindResult = cbor_value_dup_text_string(map, &strEncoding, &len, NULL);
        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");

        if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
        {
            value->encoding = OIC_ENCODING_RAW;
        }
        else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
        {
            value->encoding = OIC_ENCODING_BASE64;
        }
        else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
        {
            value->encoding = OIC_ENCODING_DER;
        }
        else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
        {
            value->encoding = OIC_ENCODING_PEM;
        }
        else
        {
            //For unit test
            value->encoding = OIC_ENCODING_RAW;
499
            OIC_LOG_V(WARNING, TAG, "%s: Unknown encoding type detected.", __func__);
500
        }
501 502
        //Because cbor using malloc directly, it is required to use free() instead of OICFree
        free(strEncoding);
503 504 505 506 507
    }
    exit:
    return cborFindResult;
}

508
CborError DeserializeEncodingFromCbor(CborValue *rootMap, OicSecKey_t *value)
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
{
    CborValue map = { .parser = NULL };
    CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
    size_t len = 0;

    while (cbor_value_is_valid(&map))
    {
        char* name = NULL;
        CborType type = cbor_value_get_type(&map);
        if (type == CborTextStringType && cbor_value_is_text_string(&map))
        {
            cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
            cborFindResult = cbor_value_advance(&map);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
        }
        if (name)
        {
            VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, value),
                                "Failed to read OicSecKey_t value");
        }
        if (cbor_value_is_valid(&map))
        {
            cborFindResult = cbor_value_advance(&map);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
        }
535 536
        //Because cbor using malloc directly, it is required to use free() instead of OICFree
        free(name);
537 538 539 540 541
    }
    exit:
    return cborFindResult;
}

542
CborError DeserializeSecOptFromCbor(CborValue *rootMap, OicSecOpt_t *value)
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
{
    CborValue map = { .parser = NULL };
    CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
    size_t len = 0;
    value->revstat = false;

    while (cbor_value_is_valid(&map))
    {
        char* name = NULL;
        CborType type = cbor_value_get_type(&map);
        if (type == CborTextStringType && cbor_value_is_text_string(&map))
        {
            cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
            cborFindResult = cbor_value_advance(&map);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
        }
        if (name)
        {
            // OptionalData::revstat -- Mandatory
            if (strcmp(name, OIC_JSON_REVOCATION_STATUS_NAME) == 0)
            {
                cborFindResult = cbor_value_get_boolean(&map, &value->revstat);
                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding revstat Value.")
            }
            OicSecKey_t out;
            VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, &out),
                                "Failed to read OicSecKey_t value");

            value->data = out.data;
            value->encoding = out.encoding;
            value->len = out.len;
        }
        if (cbor_value_is_valid(&map))
        {
            cborFindResult = cbor_value_advance(&map);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
        }
581 582
        //Because cbor using malloc directly, it is required to use free() instead of OICFree
        free(name);
583 584 585 586 587
    }
    exit:
    return cborFindResult;
}

588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
/* Produce debugging output for all credentials, output metadata. */
static void logCredMetadata()
{
#if defined(TB_LOG)
    OicSecCred_t * temp = NULL;
    size_t count = 0;
    char uuidString[UUID_STRING_SIZE];
    OicUuid_t ownUuid;

    OIC_LOG_V(DEBUG, TAG, "IN %s:", __func__);

    if (GetDoxmDeviceID(&ownUuid) == OC_STACK_OK && OCConvertUuidToString(ownUuid.id, uuidString))
    {
        OIC_LOG_V(DEBUG, TAG, "Own UUID: %s", uuidString);
    }

    LL_FOREACH(gCred, temp)
    {
        count++;
        OIC_LOG(DEBUG, TAG, " ");
        OIC_LOG_V(DEBUG, TAG, "Cred ID: %d", temp->credId);
        if (OCConvertUuidToString(temp->subject.id, uuidString))
        {
            OIC_LOG_V(DEBUG, TAG, "Subject UUID: %s", uuidString);
        }
        OIC_LOG_V(DEBUG, TAG, "Cred Type: %d", temp->credType);
        OIC_LOG_V(DEBUG, TAG, "privateData length: %d, encoding: %d", temp->privateData.len, temp->privateData.encoding);

#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
        OIC_LOG_V(DEBUG, TAG, "publicData length: %d, encoding: %d", temp->publicData.len, temp->publicData.encoding);           
        if (temp->credUsage)
        {
            OIC_LOG_V(DEBUG, TAG, "credUsage: %s", temp->credUsage);
        }

        OIC_LOG_V(DEBUG, TAG, "optionalData length: %d, encoding: %d", temp->optionalData.len, temp->optionalData.encoding);
#endif

    }

    OIC_LOG_V(DEBUG, TAG, "Found %d credentials.", count);

    OIC_LOG_V(DEBUG, TAG, "OUT %s:", __func__);
#endif
}


Sahil Bansal's avatar
Sahil Bansal committed
635
OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
636
                                size_t *cborSize, int secureFlag)
Sahil Bansal's avatar
Sahil Bansal committed
637
{
638
    OIC_LOG_V(DEBUG, TAG, "IN %s:", __func__);
Sahil Bansal's avatar
Sahil Bansal committed
639 640 641 642
    if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
    {
        return OC_STACK_INVALID_PARAM;
    }
643

Sahil Bansal's avatar
Sahil Bansal committed
644
    OCStackResult ret = OC_STACK_ERROR;
Sachin Agrawal's avatar
Sachin Agrawal committed
645

leechul's avatar
leechul committed
646 647 648
    CborError cborEncoderResult = CborNoError;
    uint8_t *outPayload = NULL;
    size_t cborLen = *cborSize;
Sahil Bansal's avatar
Sahil Bansal committed
649 650
    *cborSize = 0;
    *cborPayload = NULL;
leechul's avatar
leechul committed
651
    const OicSecCred_t *cred = credS;
652 653 654
    CborEncoder encoder;
    CborEncoder credArray;
    CborEncoder credRootMap;
Sachin Agrawal's avatar
Sachin Agrawal committed
655

leechul's avatar
leechul committed
656 657 658 659 660 661
    if (0 == cborLen)
    {
        cborLen = CBOR_SIZE;
    }

    outPayload = (uint8_t *)OICCalloc(1, cborLen);
662 663
    VERIFY_NOT_NULL_RETURN(TAG, outPayload, ERROR, OC_STACK_ERROR);

Sahil Bansal's avatar
Sahil Bansal committed
664
    cbor_encoder_init(&encoder, outPayload, cborLen, 0);
Sachin Agrawal's avatar
Sachin Agrawal committed
665

leechul's avatar
leechul committed
666 667 668 669 670 671 672 673 674 675 676 677
    // 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
678

Sahil Bansal's avatar
Sahil Bansal committed
679 680
    while (cred)
    {
681
        CborEncoder credMap;
Sahil Bansal's avatar
Sahil Bansal committed
682
        size_t mapSize = CRED_MAP_SIZE;
683
        size_t inLen = 0;
Sahil Bansal's avatar
Sahil Bansal committed
684 685 686 687
        if (cred->period)
        {
            mapSize++;
        }
688

689
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
saurabh.s9's avatar
saurabh.s9 committed
690
#ifdef MULTIPLE_OWNER
691 692 693 694
        if(cred->eownerID)
        {
            mapSize++;
        }
saurabh.s9's avatar
saurabh.s9 committed
695
#endif //MULTIPLE_OWNER
696

Kevin Kane's avatar
Kevin Kane committed
697 698
        if ((SIGNED_ASYMMETRIC_KEY == cred->credType || ASYMMETRIC_KEY == cred->credType) 
            && cred->publicData.data)
Sahil Bansal's avatar
Sahil Bansal committed
699 700 701
        {
            mapSize++;
        }
702 703 704 705 706 707 708 709
        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
        {
            mapSize++;
        }
        if (cred->credUsage)
        {
            mapSize++;
        }
710
#endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
711
        if (!secureFlag && cred->privateData.data)
Sahil Bansal's avatar
Sahil Bansal committed
712 713 714
        {
            mapSize++;
        }
leechul's avatar
leechul committed
715
        cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
Sahil Bansal's avatar
Sahil Bansal committed
716 717 718
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");

        //CredID -- Mandatory
leechul's avatar
leechul committed
719
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
720 721
            strlen(OIC_JSON_CREDID_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
leechul's avatar
leechul committed
722
        cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
Sahil Bansal's avatar
Sahil Bansal committed
723 724 725
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");

        //Subject -- Mandatory
leechul's avatar
leechul committed
726 727
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
            strlen(OIC_JSON_SUBJECTID_NAME));
Sahil Bansal's avatar
Sahil Bansal committed
728
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
729
        inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
            WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
        if(inLen == WILDCARD_SUBJECT_ID_LEN)
        {
            cborEncoderResult = cbor_encode_text_string(&credMap, WILDCARD_RESOURCE_URI,
                strlen(WILDCARD_RESOURCE_URI));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
        }
        else
        {
            char *subject = NULL;
            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
746 747

        //CredType -- Mandatory
leechul's avatar
leechul committed
748
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
749 750
            strlen(OIC_JSON_CREDTYPE_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
leechul's avatar
leechul committed
751
        cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
Sahil Bansal's avatar
Sahil Bansal committed
752
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
Sachin Agrawal's avatar
Sachin Agrawal committed
753

754
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
Sahil Bansal's avatar
Sahil Bansal committed
755
        //PublicData -- Not Mandatory
Kevin Kane's avatar
Kevin Kane committed
756 757
        if ((SIGNED_ASYMMETRIC_KEY == cred->credType || ASYMMETRIC_KEY == cred->credType) 
            && cred->publicData.data)
Sahil Bansal's avatar
Sahil Bansal committed
758
        {
759 760
            cborEncoderResult = SerializeEncodingToCbor(&credMap,
                                         OIC_JSON_PUBLICDATA_NAME, &cred->publicData);
leechul's avatar
leechul committed
761
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
Sahil Bansal's avatar
Sahil Bansal committed
762
        }
763 764 765
        //OptionalData -- Not Mandatory
        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
        {
766 767
            cborEncoderResult = SerializeSecOptToCbor(&credMap,
                                         OIC_JSON_OPTDATA_NAME, &cred->optionalData);
768 769 770 771 772 773 774 775 776 777 778 779
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
        }
        //CredUsage -- Not Mandatory
        if(cred->credUsage)
        {
            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
                strlen(OIC_JSON_CREDUSAGE_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
            cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
                strlen(cred->credUsage));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
        }
780
#endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
Sahil Bansal's avatar
Sahil Bansal committed
781
        //PrivateData -- Not Mandatory
782
        if(!secureFlag && cred->privateData.data)
Sahil Bansal's avatar
Sahil Bansal committed
783
        {
784 785
            cborEncoderResult = SerializeEncodingToCbor(&credMap,
                                         OIC_JSON_PRIVATEDATA_NAME, &cred->privateData);
leechul's avatar
leechul committed
786
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
Sahil Bansal's avatar
Sahil Bansal committed
787
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
788

Sahil Bansal's avatar
Sahil Bansal committed
789 790 791
        //Period -- Not Mandatory
        if(cred->period)
        {
leechul's avatar
leechul committed
792
            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
793 794
                strlen(OIC_JSON_PERIOD_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
leechul's avatar
leechul committed
795
            cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
Sahil Bansal's avatar
Sahil Bansal committed
796 797 798
                strlen(cred->period));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
799

saurabh.s9's avatar
saurabh.s9 committed
800
#ifdef MULTIPLE_OWNER
801 802 803 804 805 806 807 808 809 810 811 812 813
        // Eownerid -- Not Mandatory
        if(cred->eownerID)
        {
            char *eowner = NULL;
            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_EOWNERID_NAME,
                strlen(OIC_JSON_EOWNERID_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag.");
            ret = ConvertUuidToStr(cred->eownerID, &eowner);
            VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
            cborEncoderResult = cbor_encode_text_string(&credMap, eowner, strlen(eowner));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
            OICFree(eowner);
        }
saurabh.s9's avatar
saurabh.s9 committed
814
#endif //MULTIPLE_OWNER
leechul's avatar
leechul committed
815 816

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

Sahil Bansal's avatar
Sahil Bansal committed
819
        cred = cred->next;
leechul's avatar
leechul committed
820 821 822 823 824
    }
    cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");

    cred = credS;
825

leechul's avatar
leechul committed
826 827 828 829 830 831
    // 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.");
832
        ret = ConvertUuidToStr(&cred->rownerID, &rowner);
leechul's avatar
leechul committed
833 834 835 836 837 838
        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);
    }

Randeep's avatar
Randeep committed
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871
    //RT -- Mandatory
    CborEncoder rtArray;
    cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
            strlen(OIC_JSON_RT_NAME));
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
    cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
    for (size_t i = 0; i < 1; i++)
    {
        cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
                strlen(OIC_RSRC_TYPE_SEC_CRED));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
    }
    cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");

    //IF-- Mandatory
    CborEncoder ifArray;
    cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
             strlen(OIC_JSON_IF_NAME));
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
    cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
    for (size_t i = 0; i < 1; i++)
    {
        cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
                strlen(OC_RSRVD_INTERFACE_DEFAULT));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
    }
    cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");


leechul's avatar
leechul committed
872 873 874 875 876 877 878 879
    // 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;
880
        *cborSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
Sahil Bansal's avatar
Sahil Bansal committed
881 882 883
        ret = OC_STACK_OK;
    }
    OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
Sachin Agrawal's avatar
Sachin Agrawal committed
884
exit:
leechul's avatar
leechul committed
885
    if (CborErrorOutOfMemory == cborEncoderResult)
886
    {
leechul's avatar
leechul committed
887 888 889 890
        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.
891
        cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
leechul's avatar
leechul committed
892
        cborEncoderResult = CborNoError;
893
        ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
leechul's avatar
leechul committed
894
        *cborSize = cborLen;
895
    }
Sahil Bansal's avatar
Sahil Bansal committed
896 897 898

    if (CborNoError != cborEncoderResult)
    {
leechul's avatar
leechul committed
899 900 901 902 903 904
        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
905 906
    }

907 908
    OIC_LOG_V(DEBUG, TAG, "OUT %s:", __func__);

Sahil Bansal's avatar
Sahil Bansal committed
909
    return ret;
Sachin Agrawal's avatar
Sachin Agrawal committed
910 911
}

Sahil Bansal's avatar
Sahil Bansal committed
912 913
OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                OicSecCred_t **secCred)
Sachin Agrawal's avatar
Sachin Agrawal committed
914
{
Ashwini Kumar's avatar
Ashwini Kumar committed
915
    if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
Sahil Bansal's avatar
Sahil Bansal committed
916 917 918
    {
        return OC_STACK_INVALID_PARAM;
    }
Sachin Agrawal's avatar
Sachin Agrawal committed
919

Sahil Bansal's avatar
Sahil Bansal committed
920
    OCStackResult ret = OC_STACK_ERROR;
leechul's avatar
leechul committed
921 922
    CborValue credCbor = { .parser = NULL };
    CborParser parser = { .end = NULL };
Sahil Bansal's avatar
Sahil Bansal committed
923
    CborError cborFindResult = CborNoError;
leechul's avatar
leechul committed
924
    cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
leechul's avatar
leechul committed
925

926 927 928 929 930
    if (!cbor_value_is_container(&credCbor))
    {
        return OC_STACK_ERROR;
    }

931
    OicSecCred_t *headCred = NULL;
932

leechul's avatar
leechul committed
933 934 935 936
    // 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
937

938 939 940
    headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
    VERIFY_NOT_NULL(TAG, headCred, ERROR);

leechul's avatar
leechul committed
941
    while (cbor_value_is_valid(&CredRootMap))
Sahil Bansal's avatar
Sahil Bansal committed
942
    {
leechul's avatar
leechul committed
943 944 945
        char* tagName = NULL;
        size_t len = 0;
        CborType type = cbor_value_get_type(&CredRootMap);
946
        if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
Sahil Bansal's avatar
Sahil Bansal committed
947
        {
leechul's avatar
leechul committed
948 949 950 951
            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
952
        }
leechul's avatar
leechul committed
953
        if(tagName)
Sahil Bansal's avatar
Sahil Bansal committed
954
        {
leechul's avatar
leechul committed
955
            if (strcmp(tagName, OIC_JSON_CREDS_NAME)  == 0)
956
            {
leechul's avatar
leechul committed
957
                // Enter CREDS Array
958
                size_t tempLen = 0;
leechul's avatar
leechul committed
959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979
                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));
980
                        VERIFY_NOT_NULL(TAG, cred, ERROR);
leechul's avatar
leechul committed
981 982 983 984 985 986 987 988
                        OicSecCred_t *temp = headCred;
                        while (temp->next)
                        {
                            temp = temp->next;
                        }
                        temp->next = cred;
                    }

989
                    while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
leechul's avatar
leechul committed
990 991
                    {
                        char* name = NULL;
992 993
                        CborType cmType = cbor_value_get_type(&credMap);
                        if (cmType == CborTextStringType)
leechul's avatar
leechul committed
994
                        {
995
                            cborFindResult = cbor_value_dup_text_string(&credMap, &name, &tempLen, NULL);
leechul's avatar
leechul committed
996 997 998 999 1000 1001 1002 1003 1004
                            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)
                            {
1005 1006
                                uint64_t credId = 0;
                                cborFindResult = cbor_value_get_uint64(&credMap, &credId);
leechul's avatar
leechul committed
1007
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
1008
                                cred->credId = (uint16_t)credId;
leechul's avatar
leechul committed
1009 1010 1011 1012 1013
                            }
                            // subjectid
                            if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
                            {
                                char *subjectid = NULL;
1014
                                cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &tempLen, NULL);
leechul's avatar
leechul committed
1015
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
1016 1017 1018 1019 1020 1021 1022 1023 1024
                                if(strcmp(subjectid, WILDCARD_RESOURCE_URI) == 0)
                                {
                                    cred->subject.id[0] = '*';
                                }
                                else
                                {
                                    ret = ConvertStrToUuid(subjectid, &cred->subject);
                                    VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
                                }
1025 1026 1027
                                //Because cbor using malloc directly
                                //It is required to use free() instead of OICFree
                                free(subjectid);
leechul's avatar
leechul committed
1028
                            }
1029
                            // credtype
leechul's avatar
leechul committed
1030 1031
                            if (strcmp(name, OIC_JSON_CREDTYPE_NAME)  == 0)
                            {
1032 1033
                                uint64_t credType = 0;
                                cborFindResult = cbor_value_get_uint64(&credMap, &credType);
leechul's avatar
leechul committed
1034
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
1035
                                cred->credType = (OicSecCredType_t)credType;
leechul's avatar
leechul committed
1036 1037 1038 1039
                            }
                            // privatedata
                            if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME)  == 0)
                            {
1040 1041
                                cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->privateData);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read privateData structure");
leechul's avatar
leechul committed
1042
                            }
1043
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1044
                            //PublicData -- Not Mandatory
leechul's avatar
leechul committed
1045 1046
                            if (strcmp(name, OIC_JSON_PUBLICDATA_NAME)  == 0)
                            {
1047 1048
                                cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->publicData);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read publicData structure");
leechul's avatar
leechul committed
1049
                            }
1050 1051 1052
                            //OptionalData -- Not Mandatory
                            if (strcmp(name, OIC_JSON_OPTDATA_NAME)  == 0)
                            {
1053 1054
                                cborFindResult = DeserializeSecOptFromCbor(&credMap, &cred->optionalData);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read optionalData structure");
1055 1056 1057 1058
                            }
                            //Credusage -- Not Mandatory
                            if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
                            {
1059
                                cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &tempLen, NULL);
1060 1061
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
                            }
1062
#endif  //__WITH_DTLS__ ||  __WITH_TLS__
leechul's avatar
leechul committed
1063 1064 1065

                            if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
                            {
1066
                                cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &tempLen, NULL);
leechul's avatar
leechul committed
1067 1068 1069
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
                            }

saurabh.s9's avatar
saurabh.s9 committed
1070
#ifdef MULTIPLE_OWNER
1071 1072 1073 1074
                            // Eowner uuid -- Not Mandatory
                            if (strcmp(OIC_JSON_EOWNERID_NAME, name)  == 0 && cbor_value_is_text_string(&credMap))
                            {
                                char *eowner = NULL;
1075
                                cborFindResult = cbor_value_dup_text_string(&credMap, &eowner, &tempLen, NULL);
1076 1077 1078 1079
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding eownerId Value.");
                                if(NULL == cred->eownerID)
                                {
                                    cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1080
                                    VERIFY_NOT_NULL(TAG, cred->eownerID, ERROR);
1081 1082
                                }
                                ret = ConvertStrToUuid(eowner, cred->eownerID);
1083 1084 1085
                                //Because cbor using malloc directly
                                //It is required to use free() instead of OICFree
                                free(eowner);
1086 1087
                                VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
                            }
saurabh.s9's avatar
saurabh.s9 committed
1088
#endif //MULTIPLE_OWNER
1089

leechul's avatar
leechul committed
1090 1091 1092 1093 1094
                            if (cbor_value_is_valid(&credMap))
                            {
                                cborFindResult = cbor_value_advance(&credMap);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
                            }
1095 1096 1097
                            //Because cbor using malloc directly
                            //It is required to use free() instead of OICFree
                            free(name);
leechul's avatar
leechul committed
1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108
                        }
                    }
                    cred->next = NULL;
                    if (cbor_value_is_valid(&credArray))
                    {
                        cborFindResult = cbor_value_advance(&credArray);
                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
                    }
                }
            }

1109
            //ROwner -- Mandatory
1110
            if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0 && cbor_value_is_text_string(&CredRootMap))
Sachin Agrawal's avatar
Sachin Agrawal committed
1111
            {
leechul's avatar
leechul committed
1112 1113 1114
                char *stRowner = NULL;
                cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
1115 1116

                ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
leechul's avatar
leechul committed
1117
                VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
1118 1119 1120
                //Because cbor using malloc directly
                //It is required to use free() instead of OICFree
                free(stRowner);
Sachin Agrawal's avatar
Sachin Agrawal committed
1121
            }
1122 1123 1124 1125
            else if (NULL != gCred)
            {
                memcpy(&(headCred->rownerID), &(gCred->rownerID), sizeof(OicUuid_t));
            }
1126 1127 1128
            //Because cbor using malloc directly
            //It is required to use free() instead of OICFree
            free(tagName);
Sahil Bansal's avatar
Sahil Bansal committed
1129
        }
leechul's avatar
leechul committed
1130
        if (cbor_value_is_valid(&CredRootMap))
Sahil Bansal's avatar
Sahil Bansal committed
1131
        {
leechul's avatar
leechul committed
1132 1133
            cborFindResult = cbor_value_advance(&CredRootMap);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
Sahil Bansal's avatar