credresource.c 81.9 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>
Sahil Bansal's avatar
Sahil Bansal committed
33 34 35

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

Andrii Shtompel's avatar
Andrii Shtompel committed
54 55 56 57 58 59 60
#ifdef __unix__
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#endif

61 62
#ifdef __WITH_DTLS__
#include "global.h"
Sahil Bansal's avatar
Sahil Bansal committed
63
#endif
leechul's avatar
leechul committed
64

Sahil Bansal's avatar
Sahil Bansal committed
65 66
#define TAG  "SRM-CREDL"

Andrii Shtompel's avatar
Andrii Shtompel committed
67 68
/** Max credential types number used for TLS */
#define MAX_TYPE 2
Sahil Bansal's avatar
Sahil Bansal committed
69 70
/** 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
71
static const uint16_t CBOR_SIZE = 2048;
72

Sahil Bansal's avatar
Sahil Bansal committed
73 74
/** Max cbor size payload. */
static const uint16_t CBOR_MAX_SIZE = 4400;
Sachin Agrawal's avatar
Sachin Agrawal committed
75

leechul's avatar
leechul committed
76
/** CRED size - Number of mandatory items. */
Randeep's avatar
Randeep committed
77
static const uint8_t CRED_ROOT_MAP_SIZE = 4;
leechul's avatar
leechul committed
78 79
static const uint8_t CRED_MAP_SIZE = 3;

Shilpa Sodani's avatar
Shilpa Sodani committed
80

Sachin Agrawal's avatar
Sachin Agrawal committed
81 82 83
static OicSecCred_t        *gCred = NULL;
static OCResourceHandle    gCredHandle = NULL;

84 85 86 87
/**
 * This function frees OicSecCred_t object's fields and object itself.
 */
static void FreeCred(OicSecCred_t *cred)
Sachin Agrawal's avatar
Sachin Agrawal committed
88
{
89
    if(NULL == cred)
Sachin Agrawal's avatar
Sachin Agrawal committed
90
    {
Sahil Bansal's avatar
Sahil Bansal committed
91
        OIC_LOG(ERROR, TAG, "Invalid Parameter");
92 93 94
        return;
    }
    //Note: Need further clarification on roleID data type
Sachin Agrawal's avatar
Sachin Agrawal committed
95
#if 0
96 97
    //Clean roleIds
    OICFree(cred->roleIds);
Sachin Agrawal's avatar
Sachin Agrawal committed
98 99
#endif

100 101 102
    //Clean PublicData/OptionalData/Credusage
#if defined(__WITH_X509__) || defined(__WITH_TLS__)
     // TODO: Need to check credUsage.
103
    OICFree(cred->publicData.data);
104 105 106 107
    OICFree(cred->optionalData.data);
    OICFree(cred->credUsage);

#endif /* __WITH_X509__ ||  __WITH_TLS__*/
Sachin Agrawal's avatar
Sachin Agrawal committed
108

109 110
    //Clean PrivateData
    OICFree(cred->privateData.data);
Sachin Agrawal's avatar
Sachin Agrawal committed
111

112 113
    //Clean Period
    OICFree(cred->period);
Sachin Agrawal's avatar
Sachin Agrawal committed
114

115 116 117
    //Clean Cred node itself
    OICFree(cred);
}
Sachin Agrawal's avatar
Sachin Agrawal committed
118

119 120 121 122 123 124 125 126 127
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
128 129 130 131
        }
    }
}

Andrii Shtompel's avatar
Andrii Shtompel committed
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
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;
            }
#if defined(__WITH_X509__) || defined(__WITH_TLS__)
            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
        }
    }
    OIC_LOG_V(DEBUG, TAG, "Cred Key Data Size : %d\n", size);
    return size;
}

Sahil Bansal's avatar
Sahil Bansal committed
160
static size_t OicSecCredCount(const OicSecCred_t *secCred)
Sachin Agrawal's avatar
Sachin Agrawal committed
161
{
Sahil Bansal's avatar
Sahil Bansal committed
162 163
    size_t size = 0;
    for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
Sachin Agrawal's avatar
Sachin Agrawal committed
164
    {
Sahil Bansal's avatar
Sahil Bansal committed
165 166 167 168
        size++;
    }
    return size;
}
169

Sahil Bansal's avatar
Sahil Bansal committed
170
OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
171
                                size_t *cborSize, int secureFlag)
Sahil Bansal's avatar
Sahil Bansal committed
172 173 174 175 176
{
    if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
    {
        return OC_STACK_INVALID_PARAM;
    }
177

Sahil Bansal's avatar
Sahil Bansal committed
178
    OCStackResult ret = OC_STACK_ERROR;
Sachin Agrawal's avatar
Sachin Agrawal committed
179

leechul's avatar
leechul committed
180 181 182
    CborError cborEncoderResult = CborNoError;
    uint8_t *outPayload = NULL;
    size_t cborLen = *cborSize;
Sahil Bansal's avatar
Sahil Bansal committed
183 184
    *cborSize = 0;
    *cborPayload = NULL;
leechul's avatar
leechul committed
185
    const OicSecCred_t *cred = credS;
186 187 188
    CborEncoder encoder;
    CborEncoder credArray;
    CborEncoder credRootMap;
Sachin Agrawal's avatar
Sachin Agrawal committed
189

leechul's avatar
leechul committed
190 191 192 193 194 195
    if (0 == cborLen)
    {
        cborLen = CBOR_SIZE;
    }

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

leechul's avatar
leechul committed
199 200 201 202 203 204 205 206 207 208 209 210
    // 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
211

Sahil Bansal's avatar
Sahil Bansal committed
212 213
    while (cred)
    {
214
        CborEncoder credMap;
Sahil Bansal's avatar
Sahil Bansal committed
215
        size_t mapSize = CRED_MAP_SIZE;
216
        size_t inLen = 0;
Sahil Bansal's avatar
Sahil Bansal committed
217 218 219 220
        if (cred->period)
        {
            mapSize++;
        }
221
#if defined(__WITH_X509__) || defined(__WITH_TLS__)
Dmitriy Zhuravlev's avatar
Dmitriy Zhuravlev committed
222
        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
Sahil Bansal's avatar
Sahil Bansal committed
223 224 225
        {
            mapSize++;
        }
226 227 228 229 230 231 232 233 234
        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
        {
            mapSize++;
        }
        if (cred->credUsage)
        {
            mapSize++;
        }
#endif /* __WITH_X509__ ||  __WITH_TLS__*/
235
        if (!secureFlag && cred->privateData.data)
Sahil Bansal's avatar
Sahil Bansal committed
236 237 238
        {
            mapSize++;
        }
leechul's avatar
leechul committed
239
        cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
Sahil Bansal's avatar
Sahil Bansal committed
240 241 242
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");

        //CredID -- Mandatory
leechul's avatar
leechul committed
243
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
244 245
            strlen(OIC_JSON_CREDID_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
leechul's avatar
leechul committed
246
        cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
Sahil Bansal's avatar
Sahil Bansal committed
247 248 249
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");

        //Subject -- Mandatory
leechul's avatar
leechul committed
250 251
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
            strlen(OIC_JSON_SUBJECTID_NAME));
Sahil Bansal's avatar
Sahil Bansal committed
252
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
        inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN) == 0) ?
            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
270 271

        //CredType -- Mandatory
leechul's avatar
leechul committed
272
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
273 274
            strlen(OIC_JSON_CREDTYPE_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
leechul's avatar
leechul committed
275
        cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
Sahil Bansal's avatar
Sahil Bansal committed
276
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
Sachin Agrawal's avatar
Sachin Agrawal committed
277

278
#if defined(__WITH_X509__) || defined(__WITH_TLS__)
Sahil Bansal's avatar
Sahil Bansal committed
279
        //PublicData -- Not Mandatory
Dmitriy Zhuravlev's avatar
Dmitriy Zhuravlev committed
280
        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
Sahil Bansal's avatar
Sahil Bansal committed
281
        {
282
            CborEncoder publicMap;
leechul's avatar
leechul committed
283 284 285 286 287 288 289 290 291
            const size_t publicMapSize = 2;

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

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

292 293
            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
                strlen(OIC_JSON_DATA_NAME));
leechul's avatar
leechul committed
294 295 296 297 298 299 300 301 302
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
            cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
                cred->publicData.len);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");

            // TODO: Need to data strucure modification for OicSecCert_t.
            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
                strlen(OIC_JSON_ENCODING_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
Andrii Shtompel's avatar
Andrii Shtompel committed
303 304
            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_DER,
                strlen(OIC_SEC_ENCODING_DER));
leechul's avatar
leechul committed
305 306 307 308
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");

            cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
Sahil Bansal's avatar
Sahil Bansal committed
309
        }
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 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 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
        //OptionalData -- Not Mandatory
        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
        {
            CborEncoder optionalMap;
            const size_t optionalMapSize = 2;

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

            cborEncoderResult = cbor_encoder_create_map(&credMap, &optionalMap, optionalMapSize);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Map");

            // TODO: Need to data strucure modification for OicSecCert_t.
            if(OIC_ENCODING_RAW == cred->optionalData.encoding)
            {
                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
                    strlen(OIC_JSON_ENCODING_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_RAW,
                    strlen(OIC_SEC_ENCODING_RAW));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");

                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
                    strlen(OIC_JSON_DATA_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
                cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
                    cred->optionalData.len);
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
            }
            else if(OIC_ENCODING_BASE64 == cred->optionalData.encoding)
            {
                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
                    strlen(OIC_JSON_ENCODING_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_BASE64,
                    strlen(OIC_SEC_ENCODING_BASE64));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");

                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
                    strlen(OIC_JSON_DATA_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
                cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
                    cred->optionalData.len);
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
            }
            else if(OIC_ENCODING_PEM == cred->optionalData.encoding)
            {
                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
                    strlen(OIC_JSON_ENCODING_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_PEM,
                    strlen(OIC_SEC_ENCODING_PEM));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");

                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
                    strlen(OIC_JSON_DATA_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
                cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
                    cred->optionalData.len);
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
            }
            else if(OIC_ENCODING_DER == cred->optionalData.encoding)
            {
                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
                    strlen(OIC_JSON_ENCODING_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_DER,
                    strlen(OIC_SEC_ENCODING_DER));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");

                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
                    strlen(OIC_JSON_DATA_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
                cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
                    cred->optionalData.len);
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
            }
            else
            {
                OIC_LOG(ERROR, TAG, "Unknow encoding type for optional data.");
                VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding optional Encoding Value.");
            }

            cborEncoderResult = cbor_encoder_close_container(&credMap, &optionalMap);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing OptionalData Map.");
        }
        //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.");
        }
#endif /* __WITH_X509__ ||  __WITH_TLS__*/
Sahil Bansal's avatar
Sahil Bansal committed
408
        //PrivateData -- Not Mandatory
409
        if(!secureFlag && cred->privateData.data)
Sahil Bansal's avatar
Sahil Bansal committed
410
        {
411
            CborEncoder privateMap;
leechul's avatar
leechul committed
412 413 414 415 416 417 418 419 420 421
            const size_t privateMapSize = 2;

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

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

            // TODO: Need to data strucure modification for OicSecKey_t.
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
            // TODO: Added as workaround, will be replaced soon.
            if(OIC_ENCODING_RAW == cred->privateData.encoding)
            {
                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
                    strlen(OIC_JSON_ENCODING_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
                    strlen(OIC_SEC_ENCODING_RAW));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");

                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
                    strlen(OIC_JSON_DATA_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
                cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
                    cred->privateData.len);
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
            }
            else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
            {
                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
                    strlen(OIC_JSON_ENCODING_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64,
                    strlen(OIC_SEC_ENCODING_BASE64));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");

                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
                    strlen(OIC_JSON_DATA_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
                cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data),
                    cred->privateData.len);
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
            }
Andrii Shtompel's avatar
Andrii Shtompel committed
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
            else if(OIC_ENCODING_DER == cred->privateData.encoding)
            {
                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
                    strlen(OIC_JSON_ENCODING_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_DER,
                    strlen(OIC_SEC_ENCODING_DER));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");

                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
                    strlen(OIC_JSON_DATA_NAME));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
                cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
                    cred->privateData.len);
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
            }
471 472 473 474 475
            else
            {
                OIC_LOG(ERROR, TAG, "Unknow encoding type for private data.");
                VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value.");
            }
leechul's avatar
leechul committed
476 477 478

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

Sahil Bansal's avatar
Sahil Bansal committed
481 482 483
        //Period -- Not Mandatory
        if(cred->period)
        {
leechul's avatar
leechul committed
484
            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
485 486
                strlen(OIC_JSON_PERIOD_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
leechul's avatar
leechul committed
487
            cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
Sahil Bansal's avatar
Sahil Bansal committed
488 489 490
                strlen(cred->period));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
491

leechul's avatar
leechul committed
492 493

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

Sahil Bansal's avatar
Sahil Bansal committed
496
        cred = cred->next;
leechul's avatar
leechul committed
497 498 499 500 501
    }
    cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");

    cred = credS;
502

leechul's avatar
leechul committed
503 504 505 506 507 508
    // 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.");
509
        ret = ConvertUuidToStr(&cred->rownerID, &rowner);
leechul's avatar
leechul committed
510 511 512 513 514 515
        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
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
    //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
549 550 551 552 553 554 555 556 557
    // Close CRED Root Map
    cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");

    if (CborNoError == cborEncoderResult)
    {
        OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
        *cborPayload = outPayload;
        *cborSize = encoder.ptr - outPayload;
Sahil Bansal's avatar
Sahil Bansal committed
558 559 560
        ret = OC_STACK_OK;
    }
    OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
Sachin Agrawal's avatar
Sachin Agrawal committed
561
exit:
leechul's avatar
leechul committed
562
    if (CborErrorOutOfMemory == cborEncoderResult)
563
    {
leechul's avatar
leechul committed
564 565 566 567 568 569
        OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
        // reallocate and try again!
        OICFree(outPayload);
        // Since the allocated initial memory failed, double the memory.
        cborLen += encoder.ptr - encoder.end;
        cborEncoderResult = CborNoError;
570
        ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
leechul's avatar
leechul committed
571
        *cborSize = cborLen;
572
    }
Sahil Bansal's avatar
Sahil Bansal committed
573 574 575

    if (CborNoError != cborEncoderResult)
    {
leechul's avatar
leechul committed
576 577 578 579 580 581
        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
582 583 584
    }

    return ret;
Sachin Agrawal's avatar
Sachin Agrawal committed
585 586
}

Sahil Bansal's avatar
Sahil Bansal committed
587 588
OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                OicSecCred_t **secCred)
Sachin Agrawal's avatar
Sachin Agrawal committed
589
{
Ashwini Kumar's avatar
Ashwini Kumar committed
590
    if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
Sahil Bansal's avatar
Sahil Bansal committed
591 592 593
    {
        return OC_STACK_INVALID_PARAM;
    }
Sachin Agrawal's avatar
Sachin Agrawal committed
594

Sahil Bansal's avatar
Sahil Bansal committed
595
    OCStackResult ret = OC_STACK_ERROR;
leechul's avatar
leechul committed
596 597
    CborValue credCbor = { .parser = NULL };
    CborParser parser = { .end = NULL };
Sahil Bansal's avatar
Sahil Bansal committed
598
    CborError cborFindResult = CborNoError;
leechul's avatar
leechul committed
599
    cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
leechul's avatar
leechul committed
600

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

leechul's avatar
leechul committed
603 604 605 606
    // 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
607

leechul's avatar
leechul committed
608
    while (cbor_value_is_valid(&CredRootMap))
Sahil Bansal's avatar
Sahil Bansal committed
609
    {
leechul's avatar
leechul committed
610 611 612
        char* tagName = NULL;
        size_t len = 0;
        CborType type = cbor_value_get_type(&CredRootMap);
613
        if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
Sahil Bansal's avatar
Sahil Bansal committed
614
        {
leechul's avatar
leechul committed
615 616 617 618
            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
619
        }
leechul's avatar
leechul committed
620
        if(tagName)
Sahil Bansal's avatar
Sahil Bansal committed
621
        {
leechul's avatar
leechul committed
622
            if (strcmp(tagName, OIC_JSON_CREDS_NAME)  == 0)
623
            {
leechul's avatar
leechul committed
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
                // Enter CREDS Array
                size_t len = 0;
                int credCount = 0;
                CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
                cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");

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

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

                    VERIFY_NON_NULL(TAG, cred, ERROR);

657
                    while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
leechul's avatar
leechul committed
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
                    {
                        char* name = NULL;
                        CborType type = cbor_value_get_type(&credMap);
                        if (type == CborTextStringType)
                        {
                            cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
                            cborFindResult = cbor_value_advance(&credMap);
                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
                        }
                        if(name)
                        {
                            //credid
                            if (strcmp(name, OIC_JSON_CREDID_NAME)  == 0)
                            {
673 674
                                uint64_t credId = 0;
                                cborFindResult = cbor_value_get_uint64(&credMap, &credId);
leechul's avatar
leechul committed
675
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
676
                                cred->credId = (uint16_t)credId;
leechul's avatar
leechul committed
677 678 679 680 681 682 683
                            }
                            // subjectid
                            if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
                            {
                                char *subjectid = NULL;
                                cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
684 685 686 687 688 689 690 691 692
                                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);
                                }
leechul's avatar
leechul committed
693 694
                                OICFree(subjectid);
                            }
695
                            // credtype
leechul's avatar
leechul committed
696 697
                            if (strcmp(name, OIC_JSON_CREDTYPE_NAME)  == 0)
                            {
698 699
                                uint64_t credType = 0;
                                cborFindResult = cbor_value_get_uint64(&credMap, &credType);
leechul's avatar
leechul committed
700
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
701
                                cred->credType = (OicSecCredType_t)credType;
leechul's avatar
leechul committed
702 703 704 705 706 707 708 709 710 711 712
                            }
                            // privatedata
                            if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME)  == 0)
                            {
                                CborValue privateMap = { .parser = NULL };
                                cborFindResult = cbor_value_enter_container(&credMap, &privateMap);

                                while (cbor_value_is_valid(&privateMap))
                                {
                                    char* privname = NULL;
                                    CborType type = cbor_value_get_type(&privateMap);
713
                                    if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
leechul's avatar
leechul committed
714 715 716 717 718 719 720 721 722 723
                                    {
                                        cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
                                                &len, NULL);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
                                        cborFindResult = cbor_value_advance(&privateMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
                                    }
                                    if (privname)
                                    {
                                        // PrivateData::privdata -- Mandatory
724
                                        if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
leechul's avatar
leechul committed
725
                                        {
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740
                                            if(cbor_value_is_byte_string(&privateMap))
                                            {
                                                cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
                                                    &cred->privateData.len, NULL);
                                            }
                                            else if(cbor_value_is_text_string(&privateMap))
                                            {
                                                cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data),
                                                    &cred->privateData.len, NULL);
                                            }
                                            else
                                            {
                                                cborFindResult = CborErrorUnknownType;
                                                OIC_LOG(ERROR, TAG, "Unknow type for private data.");
                                            }
leechul's avatar
leechul committed
741 742
                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
                                        }
743

leechul's avatar
leechul committed
744 745 746
                                        // PrivateData::encoding -- Mandatory
                                        if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
                                        {
747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
                                            // TODO: Added as workaround. Will be replaced soon.
                                            char* strEncoding = NULL;
                                            cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL);
                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");

                                            if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
                                            {
                                                cred->privateData.encoding = OIC_ENCODING_RAW;
                                            }
                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
                                            {
                                                cred->privateData.encoding = OIC_ENCODING_BASE64;
                                            }
                                            else
                                            {
                                                //For unit test
                                                cred->privateData.encoding = OIC_ENCODING_RAW;
                                                OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for private data.");
                                            }

                                            OICFree(strEncoding);
leechul's avatar
leechul committed
768 769 770 771 772 773 774 775 776 777 778
                                        }
                                    }
                                    if (cbor_value_is_valid(&privateMap))
                                    {
                                        cborFindResult = cbor_value_advance(&privateMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
                                    }
                                    OICFree(privname);
                                }

                            }
779 780
#if defined(__WITH_X509__) || defined(__WITH_TLS__)
                            //PublicData -- Not Mandatory
leechul's avatar
leechul committed
781 782 783 784 785 786 787 788 789
                            if (strcmp(name, OIC_JSON_PUBLICDATA_NAME)  == 0)
                            {
                                CborValue pubMap = { .parser = NULL };
                                cborFindResult = cbor_value_enter_container(&credMap, &pubMap);

                                while (cbor_value_is_valid(&pubMap))
                                {
                                    char* pubname = NULL;
                                    CborType type = cbor_value_get_type(&pubMap);
790
                                    if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
leechul's avatar
leechul committed
791 792 793 794 795 796 797 798 799 800
                                    {
                                        cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
                                                &len, NULL);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
                                        cborFindResult = cbor_value_advance(&pubMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
                                    }
                                    if (pubname)
                                    {
                                        // PrivateData::privdata -- Mandatory
801
                                        if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
leechul's avatar
leechul committed
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820
                                        {
                                            cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
                                                &cred->publicData.len, NULL);
                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
                                        }
                                        // PublicData::encoding -- Mandatory
                                        if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
                                        {
                                            // TODO: Need to update data structure, just ignore encoding value now.
                                        }
                                    }
                                    if (cbor_value_is_valid(&pubMap))
                                    {
                                        cborFindResult = cbor_value_advance(&pubMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
                                    }
                                    OICFree(pubname);
                                }
                            }
821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 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 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
                            //OptionalData -- Not Mandatory
                            if (strcmp(name, OIC_JSON_OPTDATA_NAME)  == 0)
                            {
                                CborValue optMap = { .parser = NULL };
                                cborFindResult = cbor_value_enter_container(&credMap, &optMap);

                                while (cbor_value_is_valid(&optMap))
                                {
                                    char* optname = NULL;
                                    CborType type = cbor_value_get_type(&optMap);
                                    if (type == CborTextStringType && cbor_value_is_text_string(&optMap))
                                    {
                                        cborFindResult = cbor_value_dup_text_string(&optMap, &optname,
                                                &len, NULL);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
                                        cborFindResult = cbor_value_advance(&optMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
                                    }
                                    if (optname)
                                    {
                                        // OptionalData::optdata -- Mandatory
                                        if (strcmp(optname, OIC_JSON_DATA_NAME) == 0)
                                        {
                                            if(cbor_value_is_byte_string(&optMap))
                                            {
                                                cborFindResult = cbor_value_dup_byte_string(&optMap, &cred->optionalData.data,
                                                    &cred->optionalData.len, NULL);
                                            }
                                            else if(cbor_value_is_text_string(&optMap))
                                            {
                                                cborFindResult = cbor_value_dup_text_string(&optMap, (char**)(&cred->optionalData.data),
                                                    &cred->optionalData.len, NULL);
                                            }
                                            else
                                            {
                                                cborFindResult = CborErrorUnknownType;
                                                OIC_LOG(ERROR, TAG, "Unknow type for optional data.");
                                            }
                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OptionalData.");
                                        }
                                        // OptionalData::encoding -- Mandatory
                                        if (strcmp(optname, OIC_JSON_ENCODING_NAME) == 0)
                                        {
                                            // TODO: Added as workaround. Will be replaced soon.
                                            char* strEncoding = NULL;
                                            cborFindResult = cbor_value_dup_text_string(&optMap, &strEncoding, &len, NULL);
                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");

                                            if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
                                            {
                                                OIC_LOG(INFO,TAG,"cbor_value_is_byte_string");
                                                cred->optionalData.encoding = OIC_ENCODING_RAW;
                                            }
                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
                                            {
                                                cred->optionalData.encoding = OIC_ENCODING_BASE64;
                                            }
                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
                                            {
                                                cred->optionalData.encoding = OIC_ENCODING_PEM;
                                            }
                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
                                            {
                                                cred->optionalData.encoding = OIC_ENCODING_DER;
                                            }
                                            else
                                            {
                                                //For unit test
                                                cred->optionalData.encoding = OIC_ENCODING_RAW;
                                                OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for optional data.");
                                            }
                                            OICFree(strEncoding);
                                        }
                                    }
                                    if (cbor_value_is_valid(&optMap))
                                    {
                                        cborFindResult = cbor_value_advance(&optMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing optdata Map.");
                                    }
                                    OICFree(optname);
                                }
                            }
                            //Credusage -- Not Mandatory
                            if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
                            {
                                cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &len, NULL);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
                            }
#endif  //__WITH_X509__ ||  __WITH_TLS__
leechul's avatar
leechul committed
910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933

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

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

934
            //ROwner -- Mandatory
935
            if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0 && cbor_value_is_text_string(&CredRootMap))
Sachin Agrawal's avatar
Sachin Agrawal committed
936
            {
leechul's avatar
leechul committed
937 938 939
                char *stRowner = NULL;
                cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
940 941

                ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
leechul's avatar
leechul committed
942 943
                VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
                OICFree(stRowner);
Sachin Agrawal's avatar
Sachin Agrawal committed
944
            }
leechul's avatar
leechul committed
945
            OICFree(tagName);
Sahil Bansal's avatar
Sahil Bansal committed
946
        }
leechul's avatar
leechul committed
947
        if (cbor_value_is_valid(&CredRootMap))
Sahil Bansal's avatar
Sahil Bansal committed
948
        {
leechul's avatar
leechul committed
949 950
            cborFindResult = cbor_value_advance(&CredRootMap);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
Sahil Bansal's avatar
Sahil Bansal committed
951
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
952
    }
leechul's avatar
leechul committed
953

Sahil Bansal's avatar
Sahil Bansal committed
954
    *secCred = headCred;
Sachin Agrawal's avatar
Sachin Agrawal committed
955
    ret = OC_STACK_OK;
leechul's avatar
leechul committed
956

Sachin Agrawal's avatar
Sachin Agrawal committed
957
exit:
Sahil Bansal's avatar
Sahil Bansal committed
958
    if (CborNoError != cborFindResult)
Sachin Agrawal's avatar
Sachin Agrawal committed
959 960 961
    {
        DeleteCredList(headCred);
        headCred = NULL;
leechul's avatar
leechul committed
962
        *secCred = NULL;
Sahil Bansal's avatar
Sahil Bansal committed
963
        ret = OC_STACK_ERROR;
964
    }
Sahil Bansal's avatar
Sahil Bansal committed
965 966

    return ret;
Sachin Agrawal's avatar
Sachin Agrawal committed
967 968 969
}

OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
Sahil Bansal's avatar
Sahil Bansal committed
970
                                  const OicSecCert_t * publicData, const OicSecKey_t* privateData,
971
                                  const OicUuid_t * rownerID)
Sachin Agrawal's avatar
Sachin Agrawal committed
972
{
Jon A. Cruz's avatar
Jon A. Cruz committed
973
    (void)publicData;
Sachin Agrawal's avatar
Sachin Agrawal committed
974 975
    OCStackResult ret = OC_STACK_ERROR;

Sahil Bansal's avatar
Sahil Bansal committed
976
    OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
Sachin Agrawal's avatar
Sachin Agrawal committed
977 978
    VERIFY_NON_NULL(TAG, cred, ERROR);

979 980 981
    //CredId is assigned before appending new cred to the existing
    //credential list and updating svr database in AddCredential().
    cred->credId = 0;
Sachin Agrawal's avatar
Sachin Agrawal committed
982 983 984 985

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

986 987
    VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
            SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
Sachin Agrawal's avatar
Sachin Agrawal committed
988 989
    cred->credType = credType;

Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
990
#ifdef __WITH_X509__
Sahil Bansal's avatar
Sahil Bansal committed
991
    if (publicData && publicData->data)
Sachin Agrawal's avatar
Sachin Agrawal committed
992
    {
Sahil Bansal's avatar
Sahil Bansal committed
993
        cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
Sachin Agrawal's avatar
Sachin Agrawal committed
994
        VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
995 996
        memcpy(cred->publicData.data, publicData->data, publicData->len);
        cred->publicData.len = publicData->len;
Sachin Agrawal's avatar
Sachin Agrawal committed
997
    }
Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
998
#endif // __WITH_X509__
Sachin Agrawal's avatar
Sachin Agrawal committed
999

Sahil Bansal's avatar
Sahil Bansal committed
1000
    if (privateData && privateData->data)
Sachin Agrawal's avatar
Sachin Agrawal committed
1001
    {
Sahil Bansal's avatar
Sahil Bansal committed
1002
        cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
Sachin Agrawal's avatar
Sachin Agrawal committed
1003
        VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
1004 1005
        memcpy(cred->privateData.data, privateData->data, privateData->len);
        cred->privateData.len = privateData->len;
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027

        // TODO: Added as workaround. Will be replaced soon.
        cred->privateData.encoding = OIC_ENCODING_RAW;

#if 0
        // NOTE: Test codes to use base64 for credential.
        uint32_t outSize = 0;
        size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
        char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
        VERIFY_NON_NULL(TAG, b64Buf, ERROR);
        b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);

        OICFree( cred->privateData.data );
        cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
        VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);

        strcpy(cred->privateData.data, b64Buf);
        cred->privateData.encoding = OIC_ENCODING_BASE64;
        cred->privateData.len = outSize;
        OICFree(b64Buf);
#endif //End of Test codes

Sachin Agrawal's avatar
Sachin Agrawal committed
1028 1029
    }

1030 1031
    VERIFY_NON_NULL(TAG, rownerID, ERROR);
    memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
Sachin Agrawal's avatar
Sachin Agrawal committed
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042

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

1043 1044 1045 1046 1047
static bool UpdatePersistentStorage(const OicSecCred_t *cred)
{
    bool ret = false;

    // Convert Cred data into JSON for update to persistent storage
Sahil Bansal's avatar
Sahil Bansal committed
1048
    if (cred)
1049
    {
Sahil Bansal's avatar
Sahil Bansal committed
1050
        uint8_t *payload = NULL;
Andrii Shtompel's avatar
Andrii Shtompel committed
1051 1052 1053
        // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
        size_t size = GetCredKeyDataSize(cred);
        size += (256 * OicSecCredCount(cred));
1054 1055
        int secureFlag = 0;
        OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
Sahil Bansal's avatar
Sahil Bansal committed
1056
        if ((OC_STACK_OK == res) && payload)
1057
        {
Sahil Bansal's avatar
Sahil Bansal committed
1058 1059 1060 1061 1062
            if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
            {
                ret = true;
            }
            OICFree(payload);
1063 1064 1065 1066
        }
    }
    else //Empty cred list
    {
Sahil Bansal's avatar
Sahil Bansal committed
1067
        if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
1068 1069 1070 1071 1072 1073 1074 1075
        {
            ret = true;
        }
    }
    return ret;
}

/**
Sahil Bansal's avatar
Sahil Bansal committed
1076
 * Compare function used LL_SORT for sorting credentials.
1077
 *
Sahil Bansal's avatar
Sahil Bansal committed
1078 1079
 * @param first pointer to OicSecCred_t struct.
 * @param second  pointer to OicSecCred_t struct.
1080
 *
Sahil Bansal's avatar
Sahil Bansal committed
1081 1082 1083
 *@return -1, if credId of first is less than credId of second.
 * 0, if credId of first is equal to credId of second.
 * 1, if credId of first is greater than credId of second.
1084 1085 1086
 */
static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
{
Sahil Bansal's avatar
Sahil Bansal committed
1087
    if (first->credId < second->credId)
1088 1089 1090
    {
        return -1;
    }
Sahil Bansal's avatar
Sahil Bansal committed
1091
    else if (first->credId > second->credId)
1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
    {
        return 1;
    }
    else
        return 0;
}

/**
 * GetCredId goes through the cred list and returns the next
 * available credId. The next credId could be the credId that is
 * available due deletion of OicSecCred_t object or one more than
 * credId of last credential in the list.
 *
Sahil Bansal's avatar
Sahil Bansal committed
1105
 * @return next available credId if successful, else 0 for error.
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116
 */
static uint16_t GetCredId()
{
    //Sorts credential list in incremental order of credId
    LL_SORT(gCred, CmpCredId);

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

    LL_FOREACH_SAFE(gCred, currentCred, credTmp)
    {
Sahil Bansal's avatar
Sahil Bansal committed
1117
        if (currentCred->credId == nextCredId)
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132
        {
            nextCredId += 1;
        }
        else
        {
            break;
        }
    }

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

exit:
    return 0;
}
1133

1134
/**
Sahil Bansal's avatar
Sahil Bansal committed
1135 1136 1137
 * Get the default value.
 *
 * @return  NULL for now.
1138 1139 1140
 */
static OicSecCred_t* GetCredDefault()
{
Sahil Bansal's avatar
Sahil Bansal committed
1141
    // TODO:Update it when we finalize the default info.
1142 1143
    return NULL;
}
1144

Sachin Agrawal's avatar
Sachin Agrawal committed
1145 1146 1147
OCStackResult AddCredential(OicSecCred_t * newCred)
{
    OCStackResult ret = OC_STACK_ERROR;
1148 1149 1150 1151 1152
    VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);

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

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

Sahil Bansal's avatar
Sahil Bansal committed
1157
    if (UpdatePersistentStorage(gCred))
Sachin Agrawal's avatar
Sachin Agrawal committed
1158
    {
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171
        ret = OC_STACK_OK;
    }

exit:
    return ret;
}

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

1173 1174
    LL_FOREACH_SAFE(gCred, cred, tempCred)
    {
Sahil Bansal's avatar
Sahil Bansal committed
1175
        if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
Sachin Agrawal's avatar
Sachin Agrawal committed
1176
        {
1177 1178 1179
            LL_DELETE(gCred, cred);
            FreeCred(cred);
            deleteFlag = 1;
Sachin Agrawal's avatar
Sachin Agrawal committed
1180 1181 1182
        }
    }

Sahil Bansal's avatar
Sahil Bansal committed
1183
    if (deleteFlag)
1184
    {
Sahil Bansal's avatar
Sahil Bansal committed
1185
        if (UpdatePersistentStorage(gCred))
1186 1187 1188 1189
        {
            ret = OC_STACK_RESOURCE_DELETED;
        }
    }
Sachin Agrawal's avatar
Sachin Agrawal committed
1190
    return ret;