credresource.c 134 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
#include "secureresourcemanager.h"
59
#include "deviceonboardingstate.h"
60

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

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

75
#define TAG  "OIC_SRM_CREDL"
Sahil Bansal's avatar
Sahil Bansal committed
76

77 78
#ifdef HAVE_WINDOWS_H
#include <wincrypt.h>
79
#include <intsafe.h>
80 81
#endif

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

leechul's avatar
leechul committed
88
/** CRED size - Number of mandatory items. */
Randeep's avatar
Randeep committed
89
static const uint8_t CRED_ROOT_MAP_SIZE = 4;
leechul's avatar
leechul committed
90
static const uint8_t CRED_MAP_SIZE = 3;
91
static const uint8_t ROLEID_MAP_SIZE = 1;
leechul's avatar
leechul committed
92

Shilpa Sodani's avatar
Shilpa Sodani committed
93

Sachin Agrawal's avatar
Sachin Agrawal committed
94 95
static OicSecCred_t        *gCred = NULL;
static OCResourceHandle    gCredHandle = NULL;
96
static OicUuid_t           gRownerId = { .id = { 0 } };
Sachin Agrawal's avatar
Sachin Agrawal committed
97

98 99 100 101 102 103
typedef enum CredCompareResult{
    CRED_CMP_EQUAL = 0,
    CRED_CMP_NOT_EQUAL = 1,
    CRED_CMP_ERROR = 2
}CredCompareResult_t;

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
typedef struct CredIdList CredIdList_t;

struct CredIdList
{
    uint16_t credId;
    CredIdList_t *next;
};

static void DeleteCredIdList(CredIdList_t** list)
{
    if (list)
    {
        CredIdList_t *head = *list;

        while (head)
        {
            CredIdList_t *tmp = head->next;
            OICFree(head);
            head = tmp;
        }
    }
}

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
/**
 * 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__)
144 145
    const OicUuid_t emptyUuid = { .id = { 0 } };

146 147 148 149 150 151 152 153
    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));
        }
    }
154 155
#else
    OC_UNUSED(deviceID);
156 157 158 159 160 161 162 163 164
#endif

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

165 166 167
/**
 * Internal function to check credential
 */
168
static bool IsValidCredential(const OicSecCred_t* cred)
169 170 171 172
{
    OicUuid_t emptyUuid = {.id={0}};


173
    OIC_LOG(DEBUG, TAG, "IN IsValidCredential");
174

175
    VERIFY_NOT_NULL(TAG, cred, ERROR);
176 177 178 179 180 181 182 183 184 185 186 187
    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:
        {
188
            VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
189 190 191 192 193 194 195 196 197
            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:
        {
198
            VERIFY_NOT_NULL(TAG, cred->publicData.data, ERROR);
199
            VERIFY_SUCCESS(TAG, 0 != cred->publicData.len, ERROR);
200 201 202 203
            VERIFY_SUCCESS(TAG, \
                           (OIC_ENCODING_UNKNOW < cred->publicData.encoding && \
                            OIC_ENCODING_DER >= cred->publicData.encoding),
                           ERROR);
204 205 206 207 208 209 210 211 212 213
            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, \
214 215
                               (OIC_ENCODING_UNKNOW < cred->optionalData.encoding && \
                                OIC_ENCODING_DER >= cred->optionalData.encoding),
216 217 218 219 220 221
                               ERROR);
            }
            break;
        }
        case ASYMMETRIC_ENCRYPTION_KEY:
        {
222
            VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
223 224
            VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
            VERIFY_SUCCESS(TAG, \
225 226
                           (OIC_ENCODING_UNKNOW < cred->privateData.encoding && \
                            OIC_ENCODING_DER >= cred->privateData.encoding),
227 228 229 230 231 232 233 234 235 236 237 238 239
                           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);

240
    OIC_LOG(DEBUG, TAG, "OUT IsValidCredential");
241 242
    return true;
exit:
243
    OIC_LOG(WARNING, TAG, "OUT IsValidCredential : Invalid Credential detected.");
244 245 246
    return false;
}

247
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
248 249 250 251 252
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);
253
    VERIFY_SUCCESS(TAG, !IsNonEmptyRole(&cred->roleId), ERROR);
254 255 256 257 258 259 260 261 262 263
    VERIFY_SUCCESS(TAG, (0 == cred->credId), ERROR);
    VERIFY_SUCCESS(TAG, (0 == cred->credType), ERROR);
    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);
    return true;
exit:
    return false;
}
264
#endif // __WITH_DTLS__ or __WITH_TLS__
265

266 267 268
/**
 * This function frees OicSecCred_t object's fields and object itself.
 */
269
void FreeCred(OicSecCred_t *cred)
Sachin Agrawal's avatar
Sachin Agrawal committed
270
{
271
    if(NULL == cred)
Sachin Agrawal's avatar
Sachin Agrawal committed
272
    {
Sahil Bansal's avatar
Sahil Bansal committed
273
        OIC_LOG(ERROR, TAG, "Invalid Parameter");
274 275 276
        return;
    }
    //Note: Need further clarification on roleID data type
Sachin Agrawal's avatar
Sachin Agrawal committed
277
#if 0
278 279
    //Clean roleIds
    OICFree(cred->roleIds);
Sachin Agrawal's avatar
Sachin Agrawal committed
280 281
#endif

282
    //Clean PublicData/OptionalData/Credusage
283
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
284
     // TODO: Need to check credUsage.
285
    OICFree(cred->publicData.data);
286 287 288
    OICFree(cred->optionalData.data);
    OICFree(cred->credUsage);

289
#endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
Sachin Agrawal's avatar
Sachin Agrawal committed
290

291
    //Clean PrivateData
292
    OICClearMemory(cred->privateData.data, cred->privateData.len);
293
    OICFree(cred->privateData.data);
Sachin Agrawal's avatar
Sachin Agrawal committed
294

295 296
    //Clean Period
    OICFree(cred->period);
Sachin Agrawal's avatar
Sachin Agrawal committed
297

saurabh.s9's avatar
saurabh.s9 committed
298
#ifdef MULTIPLE_OWNER
299 300 301 302
    //Clean eowner
    OICFree(cred->eownerID);
#endif

303 304
    cred->next = NULL;

305 306 307
    //Clean Cred node itself
    OICFree(cred);
}
Sachin Agrawal's avatar
Sachin Agrawal committed
308

309 310 311 312 313 314 315 316 317
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
318 319 320 321
        }
    }
}

Andrii Shtompel's avatar
Andrii Shtompel committed
322 323 324 325 326 327 328 329 330 331 332 333
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;
            }
334
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
Andrii Shtompel's avatar
Andrii Shtompel committed
335 336 337 338 339 340 341 342 343 344 345
            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
        }
    }
346
    OIC_LOG_V(DEBUG, TAG, "Cred Key Data Size : %u", (unsigned int) size);
Andrii Shtompel's avatar
Andrii Shtompel committed
347 348 349
    return size;
}

Sahil Bansal's avatar
Sahil Bansal committed
350
static size_t OicSecCredCount(const OicSecCred_t *secCred)
Sachin Agrawal's avatar
Sachin Agrawal committed
351
{
Sahil Bansal's avatar
Sahil Bansal committed
352 353
    size_t size = 0;
    for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
Sachin Agrawal's avatar
Sachin Agrawal committed
354
    {
Sahil Bansal's avatar
Sahil Bansal committed
355 356 357 358
        size++;
    }
    return size;
}
359

360
static const char* EncodingValueToString(OicEncodingType_t encoding)
361 362 363
{
    switch (encoding)
    {
364 365 366 367 368
        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;
369 370 371 372 373 374
    }
}

static CborError SerializeEncodingToCborInternal(CborEncoder *map, const OicSecKey_t *value)
{
    CborError cborEncoderResult = CborNoError;
375
    const char *encoding = EncodingValueToString(value->encoding);
376 377 378 379
    if (encoding)
    {
        cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_ENCODING_NAME,
            strlen(OIC_JSON_ENCODING_NAME));
380
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Encoding Tag.");
381 382
        cborEncoderResult = cbor_encode_text_string(map, encoding,
            strlen(encoding));
383
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Encoding Value.");
384 385 386

        cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_DATA_NAME,
            strlen(OIC_JSON_DATA_NAME));
387
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Name Tag.");
388 389 390 391 392 393 394 395 396 397 398
        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);
        }
399
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Name Value.");
400 401 402
    }
    else
    {
403
        OIC_LOG_V(ERROR, TAG, "%s: Unknown encoding type: %u.", __func__, value->encoding);
404
        return CborErrorUnknownType;
405 406 407 408 409
    }
    exit:
    return cborEncoderResult;
}

410
CborError SerializeEncodingToCbor(CborEncoder *rootMap, const char* tag, const OicSecKey_t *value)
411 412 413 414 415 416
{
    CborError cborEncoderResult = CborNoError;
    CborEncoder map;
    const size_t mapSize = 2;

    cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
417
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
418 419

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

422
    cborEncoderResult = SerializeEncodingToCborInternal(&map, value);
423
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding OicSecKey_t structure");
424 425

    cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
426
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing Map.");
427 428 429 430 431

    exit:
    return cborEncoderResult;
}

432
CborError SerializeSecOptToCbor(CborEncoder *rootMap, const char* tag, const OicSecOpt_t *value)
433 434 435 436 437 438
{
    CborError cborEncoderResult = CborNoError;
    CborEncoder map;
    const size_t mapSize = 3;

    cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
439
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
440 441

    cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
442
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Map");
443 444 445 446 447 448

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

449
    cborEncoderResult = SerializeEncodingToCborInternal(&map, &in);
450
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding OicSecKey_t structure");
451 452 453

    cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_REVOCATION_STATUS_NAME,
        strlen(OIC_JSON_REVOCATION_STATUS_NAME));
454
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding optional revstat Tag.");
455
    cborEncoderResult = cbor_encode_boolean(&map, value->revstat);
456
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding optional revstat Value.");
457 458

    cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
459
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing Map.");
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

    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.");
        }
488
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding PrivateData.");
489 490 491 492 493 494 495
    }

    // encoding -- Mandatory
    if (strcmp(name, OIC_JSON_ENCODING_NAME) == 0)
    {
        char* strEncoding = NULL;
        cborFindResult = cbor_value_dup_text_string(map, &strEncoding, &len, NULL);
496
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding EncodingType");
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517

        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;
518
            OIC_LOG_V(WARNING, TAG, "%s: Unknown encoding type detected.", __func__);
519
        }
520 521
        //Because cbor using malloc directly, it is required to use free() instead of OICFree
        free(strEncoding);
522 523 524 525 526
    }
    exit:
    return cborFindResult;
}

527
CborError DeserializeEncodingFromCbor(CborValue *rootMap, OicSecKey_t *value)
528 529 530 531 532 533 534 535 536 537 538 539
{
    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);
540
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to get text");
541
            cborFindResult = cbor_value_advance(&map);
542
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to advance value");
543 544 545
        }
        if (name)
        {
546
            cborFindResult = DeserializeEncodingFromCborInternal(&map, name, value);
547
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to read OicSecKey_t value");
548 549 550 551
        }
        if (cbor_value_is_valid(&map))
        {
            cborFindResult = cbor_value_advance(&map);
552
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Advancing Map.");
553
        }
554 555
        //Because cbor using malloc directly, it is required to use free() instead of OICFree
        free(name);
556 557 558 559 560
    }
    exit:
    return cborFindResult;
}

561
CborError DeserializeSecOptFromCbor(CborValue *rootMap, OicSecOpt_t *value)
562 563 564 565 566 567 568 569 570 571 572 573 574
{
    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);
575
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to get text");
576
            cborFindResult = cbor_value_advance(&map);
577
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to advance value");
578 579 580 581 582 583 584
        }
        if (name)
        {
            // OptionalData::revstat -- Mandatory
            if (strcmp(name, OIC_JSON_REVOCATION_STATUS_NAME) == 0)
            {
                cborFindResult = cbor_value_get_boolean(&map, &value->revstat);
585
                VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding revstat Value.")
586 587
            }
            OicSecKey_t out;
588
            cborFindResult = DeserializeEncodingFromCborInternal(&map, name, &out);
589
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to read OicSecKey_t value");
590 591 592 593 594 595 596 597

            value->data = out.data;
            value->encoding = out.encoding;
            value->len = out.len;
        }
        if (cbor_value_is_valid(&map))
        {
            cborFindResult = cbor_value_advance(&map);
598
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Advancing Map.");
599
        }
600 601
        //Because cbor using malloc directly, it is required to use free() instead of OICFree
        free(name);
602 603 604 605 606
    }
    exit:
    return cborFindResult;
}

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
/* 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);
        }
632 633 634 635 636
        if (IsNonEmptyRole(&temp->roleId))
        {
            OIC_LOG_V(DEBUG, TAG, "Role ID: %s", temp->roleId.id);
            OIC_LOG_V(DEBUG, TAG, "Role authority: %s", temp->roleId.authority);
        }
637
        OIC_LOG_V(DEBUG, TAG, "Cred Type: %d", temp->credType);
638
        OIC_LOG_V(DEBUG, TAG, "privateData length: %" PRIuPTR ", encoding: %d", temp->privateData.len, temp->privateData.encoding);
639 640

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

647
        OIC_LOG_V(DEBUG, TAG, "optionalData length: %" PRIuPTR", encoding: %d" PRIuPTR, temp->optionalData.len, temp->optionalData.encoding);
648 649 650 651
#endif

    }

652
    OIC_LOG_V(DEBUG, TAG, "Found %" PRIuPTR " credentials.", count);
653 654 655 656 657

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

658
OCStackResult CredToCBORPayloadWithRowner(const OicSecCred_t *credS, const OicUuid_t *rownerId, uint8_t **cborPayload,
659
                                size_t *cborSize, int secureFlag)
Sahil Bansal's avatar
Sahil Bansal committed
660
{
661
    OIC_LOG_V(DEBUG, TAG, "IN %s:", __func__);
662
    if (NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
Sahil Bansal's avatar
Sahil Bansal committed
663 664 665
    {
        return OC_STACK_INVALID_PARAM;
    }
666

Sahil Bansal's avatar
Sahil Bansal committed
667
    OCStackResult ret = OC_STACK_ERROR;
Sachin Agrawal's avatar
Sachin Agrawal committed
668

leechul's avatar
leechul committed
669 670 671
    CborError cborEncoderResult = CborNoError;
    uint8_t *outPayload = NULL;
    size_t cborLen = *cborSize;
Sahil Bansal's avatar
Sahil Bansal committed
672 673
    *cborSize = 0;
    *cborPayload = NULL;
leechul's avatar
leechul committed
674
    const OicSecCred_t *cred = credS;
675 676 677
    CborEncoder encoder;
    CborEncoder credArray;
    CborEncoder credRootMap;
678
    CborEncoder roleIdMap;
Sachin Agrawal's avatar
Sachin Agrawal committed
679

leechul's avatar
leechul committed
680 681 682 683 684 685
    if (0 == cborLen)
    {
        cborLen = CBOR_SIZE;
    }

    outPayload = (uint8_t *)OICCalloc(1, cborLen);
686 687
    VERIFY_NOT_NULL_RETURN(TAG, outPayload, ERROR, OC_STACK_ERROR);

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

690
    size_t credRootMapSize = CRED_ROOT_MAP_SIZE;
691

leechul's avatar
leechul committed
692
    // Create CRED Root Map (creds, rownerid)
693
    cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, credRootMapSize);
694
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
leechul's avatar
leechul committed
695 696 697 698

    // creds
    cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
        strlen(OIC_JSON_CREDS_NAME));
699
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
leechul's avatar
leechul committed
700 701 702

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

Sahil Bansal's avatar
Sahil Bansal committed
705 706
    while (cred)
    {
707
        CborEncoder credMap;
Sahil Bansal's avatar
Sahil Bansal committed
708
        size_t mapSize = CRED_MAP_SIZE;
709
        size_t inLen = 0;
Sahil Bansal's avatar
Sahil Bansal committed
710 711 712 713
        if (cred->period)
        {
            mapSize++;
        }
714

715
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
saurabh.s9's avatar
saurabh.s9 committed
716
#ifdef MULTIPLE_OWNER
717 718 719 720
        if(cred->eownerID)
        {
            mapSize++;
        }
saurabh.s9's avatar
saurabh.s9 committed
721
#endif //MULTIPLE_OWNER
722

723
        if ((SIGNED_ASYMMETRIC_KEY == cred->credType || ASYMMETRIC_KEY == cred->credType)
Kevin Kane's avatar
Kevin Kane committed
724
            && cred->publicData.data)
Sahil Bansal's avatar
Sahil Bansal committed
725 726 727
        {
            mapSize++;
        }
728 729 730 731 732 733 734 735
        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
        {
            mapSize++;
        }
        if (cred->credUsage)
        {
            mapSize++;
        }
736 737 738 739
        if (IsNonEmptyRole(&cred->roleId))
        {
            mapSize++;
        }
740
#endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
741
        if (!secureFlag && cred->privateData.data)
Sahil Bansal's avatar
Sahil Bansal committed
742 743 744
        {
            mapSize++;
        }
leechul's avatar
leechul committed
745
        cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
746
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Map");
Sahil Bansal's avatar
Sahil Bansal committed
747 748

        //CredID -- Mandatory
leechul's avatar
leechul committed
749
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
750
            strlen(OIC_JSON_CREDID_NAME));
751
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
leechul's avatar
leechul committed
752
        cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
753
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
Sahil Bansal's avatar
Sahil Bansal committed
754 755

        //Subject -- Mandatory
leechul's avatar
leechul committed
756 757
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
            strlen(OIC_JSON_SUBJECTID_NAME));
758
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
759
        inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
760 761 762 763 764
            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));
765
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
766 767 768 769 770 771 772
        }
        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));
773
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
774 775
            OICFree(subject);
        }
Sahil Bansal's avatar
Sahil Bansal committed
776

777 778 779 780 781
        //Role ID -- optional
        if (IsNonEmptyRole(&cred->roleId))
        {
            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_ROLEID_NAME,
                strlen(OIC_JSON_ROLEID_NAME));
782
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding role ID map tag");
783 784 785

            bool includeAuthority = (0 != memcmp(&cred->roleId.authority, &EMPTY_ROLE.authority, sizeof(EMPTY_ROLE.authority)));

786
            cborEncoderResult = cbor_encoder_create_map(&credMap, &roleIdMap, ROLEID_MAP_SIZE + (includeAuthority ? 1 : 0));
787
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding role ID map");
788 789

            cborEncoderResult = cbor_encode_text_string(&roleIdMap, OIC_JSON_ROLE_NAME, strlen(OIC_JSON_ROLE_NAME));
790
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding role tag");
791

792
            cborEncoderResult = cbor_encode_text_string(&roleIdMap, cred->roleId.id, strlen(cred->roleId.id));
793
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding role value");
794 795 796 797

            if (includeAuthority)
            {
                cborEncoderResult = cbor_encode_text_string(&roleIdMap, OIC_JSON_AUTHORITY_NAME, strlen(OIC_JSON_AUTHORITY_NAME));
798
                VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding authority tag");
799 800

                cborEncoderResult = cbor_encode_text_string(&roleIdMap, cred->roleId.authority, strlen(cred->roleId.authority));
801
                VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding authority value");
802 803 804
            }

            cborEncoderResult = cbor_encoder_close_container(&credMap, &roleIdMap);
805
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed closing role ID map");
806 807
        }

Sahil Bansal's avatar
Sahil Bansal committed
808
        //CredType -- Mandatory
leechul's avatar
leechul committed
809
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
810
            strlen(OIC_JSON_CREDTYPE_NAME));
811
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
leechul's avatar
leechul committed
812
        cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
813
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
Sachin Agrawal's avatar
Sachin Agrawal committed
814

815
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
Sahil Bansal's avatar
Sahil Bansal committed
816
        //PublicData -- Not Mandatory
817
        if ((SIGNED_ASYMMETRIC_KEY == cred->credType || ASYMMETRIC_KEY == cred->credType)
Kevin Kane's avatar
Kevin Kane committed
818
            && cred->publicData.data)
Sahil Bansal's avatar
Sahil Bansal committed
819
        {
820 821
            cborEncoderResult = SerializeEncodingToCbor(&credMap,
                                         OIC_JSON_PUBLICDATA_NAME, &cred->publicData);
822
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
Sahil Bansal's avatar
Sahil Bansal committed
823
        }
824 825 826
        //OptionalData -- Not Mandatory
        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
        {
827 828
            cborEncoderResult = SerializeSecOptToCbor(&credMap,
                                         OIC_JSON_OPTDATA_NAME, &cred->optionalData);
829
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
830 831 832 833 834 835
        }
        //CredUsage -- Not Mandatory
        if(cred->credUsage)
        {
            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
                strlen(OIC_JSON_CREDUSAGE_NAME));
836
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
837 838
            cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
                strlen(cred->credUsage));
839
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
840
        }
841
#endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
Sahil Bansal's avatar
Sahil Bansal committed
842
        //PrivateData -- Not Mandatory
843
        if(!secureFlag && cred->privateData.data)
Sahil Bansal's avatar
Sahil Bansal committed
844
        {
845 846
            cborEncoderResult = SerializeEncodingToCbor(&credMap,
                                         OIC_JSON_PRIVATEDATA_NAME, &cred->privateData);
847
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
Sahil Bansal's avatar
Sahil Bansal committed
848
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
849

Sahil Bansal's avatar
Sahil Bansal committed
850 851 852
        //Period -- Not Mandatory
        if(cred->period)
        {
leechul's avatar
leechul committed
853
            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
854
                strlen(OIC_JSON_PERIOD_NAME));
855
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
leechul's avatar
leechul committed
856
            cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
Sahil Bansal's avatar
Sahil Bansal committed
857
                strlen(cred->period));
858
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
Sahil Bansal's avatar
Sahil Bansal committed
859
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
860

saurabh.s9's avatar
saurabh.s9 committed
861
#ifdef MULTIPLE_OWNER
862 863 864 865 866 867
        // Eownerid -- Not Mandatory
        if(cred->eownerID)
        {
            char *eowner = NULL;
            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_EOWNERID_NAME,
                strlen(OIC_JSON_EOWNERID_NAME));
868
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag.");
869 870 871
            ret = ConvertUuidToStr(cred->eownerID, &eowner);
            VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
            cborEncoderResult = cbor_encode_text_string(&credMap, eowner, strlen(eowner));
872
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
873 874
            OICFree(eowner);
        }
saurabh.s9's avatar
saurabh.s9 committed
875
#endif //MULTIPLE_OWNER
leechul's avatar
leechul committed
876 877

        cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
878
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing Cred Map.");
879

Sahil Bansal's avatar
Sahil Bansal committed
880
        cred = cred->next;
leechul's avatar
leechul committed
881 882
    }
    cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
883
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing Cred Array.");
leechul's avatar
leechul committed
884 885

    cred = credS;
886

leechul's avatar
leechul committed
887 888 889 890 891
    // Rownerid
    {
        char *rowner = NULL;
        cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
            strlen(OIC_JSON_ROWNERID_NAME));
892
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
893
        ret = ConvertUuidToStr(rownerId, &rowner);
leechul's avatar
leechul committed
894 895
        VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
        cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
896
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
leechul's avatar
leechul committed
897 898 899
        OICFree(rowner);
    }

Randeep's avatar
Randeep committed
900
    {
901 902 903 904
        //RT -- Mandatory
        CborEncoder rtArray;
        cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
                strlen(OIC_JSON_RT_NAME));
905
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
906
        cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
907
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding RT Value.");
908 909 910 911
        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));
912
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding RT Value.");
913 914
        }
        cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
915
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing RT.");
Randeep's avatar
Randeep committed
916

917 918 919 920
        //IF-- Mandatory
        CborEncoder ifArray;
        cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
                 strlen(OIC_JSON_IF_NAME));
921
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
922
        cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
923
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding IF Value.");
924 925 926 927
        for (size_t i = 0; i < 1; i++)
        {
            cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
                    strlen(OC_RSRVD_INTERFACE_DEFAULT));
928
            VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding IF Value.");
929 930
        }
        cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
931
        VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing IF.");
Randeep's avatar
Randeep committed
932 933
    }

leechul's avatar
leechul committed
934 935
    // Close CRED Root Map
    cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
936
    VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
leechul's avatar
leechul committed
937 938 939 940 941

    if (CborNoError == cborEncoderResult)
    {
        OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
        *cborPayload = outPayload;
942
        *cborSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
Sahil Bansal's avatar
Sahil Bansal committed
943 944 945
        ret = OC_STACK_OK;
    }
    OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
Sachin Agrawal's avatar
Sachin Agrawal committed
946
exit:
leechul's avatar
leechul committed
947
    if (CborErrorOutOfMemory == cborEncoderResult)
948
    {
leechul's avatar
leechul committed
949 950 951 952
        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.
953
        cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
leechul's avatar
leechul committed
954
        cborEncoderResult = CborNoError;
955
        ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
leechul's avatar
leechul committed
956
        *cborSize = cborLen;