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

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

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

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

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

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

/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
 * The value of payload size is increased until reaching belox max cbor size. */
#ifndef __WITH_X509__
static const uint8_t CBOR_SIZE = 255;
leechul's avatar
leechul committed
61
#else
Sahil Bansal's avatar
Sahil Bansal committed
62
static const uint16_t CBOR_SIZE = 1024;
63
#endif
64

Sahil Bansal's avatar
Sahil Bansal committed
65 66
/** Max cbor size payload. */
static const uint16_t CBOR_MAX_SIZE = 4400;
Sachin Agrawal's avatar
Sachin Agrawal committed
67

Sahil Bansal's avatar
Sahil Bansal committed
68 69
/** CRED Map size - Number of mandatory items. */
static const uint8_t CRED_MAP_SIZE = 4;
Shilpa Sodani's avatar
Shilpa Sodani committed
70

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

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

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

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

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

101 102 103 104 105 106
    //Clean Owners
    OICFree(cred->owners);

    //Clean Cred node itself
    OICFree(cred);
}
Sachin Agrawal's avatar
Sachin Agrawal committed
107

108 109 110 111 112 113 114 115 116
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
117 118 119 120
        }
    }
}

Sahil Bansal's avatar
Sahil Bansal committed
121
static size_t OicSecCredCount(const OicSecCred_t *secCred)
Sachin Agrawal's avatar
Sachin Agrawal committed
122
{
Sahil Bansal's avatar
Sahil Bansal committed
123 124
    size_t size = 0;
    for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
Sachin Agrawal's avatar
Sachin Agrawal committed
125
    {
Sahil Bansal's avatar
Sahil Bansal committed
126 127 128 129
        size++;
    }
    return size;
}
130

Sahil Bansal's avatar
Sahil Bansal committed
131 132 133 134 135 136 137 138 139 140 141 142 143 144
OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
                                size_t *cborSize)
{
    if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
    {
        return OC_STACK_INVALID_PARAM;
    }
    OIC_LOG(DEBUG, TAG, "CredToCBORPayload IN");
    OCStackResult ret = OC_STACK_ERROR;
    size_t cborLen = *cborSize;
    if (0 == cborLen)
    {
        cborLen = CBOR_SIZE;
    }
Sachin Agrawal's avatar
Sachin Agrawal committed
145

Sahil Bansal's avatar
Sahil Bansal committed
146 147
    *cborSize = 0;
    *cborPayload = NULL;
Sachin Agrawal's avatar
Sachin Agrawal committed
148

Sahil Bansal's avatar
Sahil Bansal committed
149 150 151
    CborEncoder encoder = { {.ptr = NULL }, .end = 0 };
    CborEncoder credArray = { {.ptr = NULL }, .end = 0 };
    int64_t cborEncoderResult = CborNoError;
Sachin Agrawal's avatar
Sachin Agrawal committed
152

Sahil Bansal's avatar
Sahil Bansal committed
153 154 155 156
    const OicSecCred_t *cred = credS;
    uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
    VERIFY_NON_NULL(TAG, outPayload, ERROR);
    cbor_encoder_init(&encoder, outPayload, cborLen, 0);
Sachin Agrawal's avatar
Sachin Agrawal committed
157

Sahil Bansal's avatar
Sahil Bansal committed
158 159 160
    // Create CRED Array
    cborEncoderResult |= cbor_encoder_create_array(&encoder, &credArray, OicSecCredCount(cred));
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding0 Cred Array.");
leechul's avatar
leechul committed
161

Sahil Bansal's avatar
Sahil Bansal committed
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
    while (cred)
    {
        CborEncoder credMap = { {.ptr = NULL }, .end = 0, .added = 0, .flags = 0 };
        size_t mapSize = CRED_MAP_SIZE;
        if (cred->period)
        {
            mapSize++;
        }
#ifdef __WITH_X509__
        if (cred->publicData.data)
        {
            mapSize++;
        }
#endif /* __WITH_X509__ */
        if (cred->privateData.data)
        {
            mapSize++;
        }
        cborEncoderResult |= cbor_encoder_create_map(&credArray, &credMap, mapSize);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");

        //CredID -- Mandatory
        cborEncoderResult |= cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
            strlen(OIC_JSON_CREDID_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
        cborEncoderResult |= cbor_encode_int(&credMap, cred->credId);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");

        //Subject -- Mandatory
        cborEncoderResult |= cbor_encode_text_string(&credMap, OIC_JSON_SUBJECT_NAME,
            strlen(OIC_JSON_SUBJECT_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
        cborEncoderResult |= cbor_encode_byte_string(&credMap, cred->subject.id,
            sizeof(cred->subject.id));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Value.");

        //CredType -- Mandatory
        cborEncoderResult |= cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
            strlen(OIC_JSON_CREDTYPE_NAME));
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
        cborEncoderResult |= cbor_encode_int(&credMap, cred->credType);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
Sachin Agrawal's avatar
Sachin Agrawal committed
204

Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
205
#ifdef __WITH_X509__
Sahil Bansal's avatar
Sahil Bansal committed
206 207 208 209 210 211 212 213 214 215
        //PublicData -- Not Mandatory
        if (cred->publicData.data)
        {
            cborEncoderResult |= cbor_encode_text_string(&credMap,
                OIC_JSON_PUBLICDATA_NAME, strlen(OIC_JSON_PUBLICDATA_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Data Tag.");
            cborEncoderResult |= cbor_encode_byte_string(&credMap, cred->publicData.data,
                    cred->publicData.len);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Tag Value.");
        }
Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
216
#endif /*__WITH_X509__*/
Sahil Bansal's avatar
Sahil Bansal committed
217 218 219 220 221 222 223 224 225 226
        //PrivateData -- Not Mandatory
        if(cred->privateData.data)
        {
            cborEncoderResult |= cbor_encode_text_string(&credMap,
                OIC_JSON_PRIVATEDATA_NAME, strlen(OIC_JSON_PRIVATEDATA_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Data Tag");
            cborEncoderResult |= cbor_encode_byte_string(&credMap, cred->privateData.data,
                cred->privateData.len);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Data Value.");
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
227

Sahil Bansal's avatar
Sahil Bansal committed
228 229 230 231 232 233 234 235 236 237
        //Period -- Not Mandatory
        if(cred->period)
        {
            cborEncoderResult |= cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
                strlen(OIC_JSON_PERIOD_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
            cborEncoderResult |= cbor_encode_text_string(&credMap, cred->period,
                strlen(cred->period));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
238

Sahil Bansal's avatar
Sahil Bansal committed
239 240 241 242 243 244 245 246
        //Owners -- Mandatory
        {
            cborEncoderResult |= cbor_encode_text_string(&credMap, OIC_JSON_OWNERS_NAME,
                strlen(OIC_JSON_OWNERS_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owners Name Tag.");
            CborEncoder owners = { {.ptr = NULL }, .end = 0 };
            cborEncoderResult |= cbor_encoder_create_array(&credMap, &owners, cred->ownersLen);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owners Name Array.");
Sachin Agrawal's avatar
Sachin Agrawal committed
247 248
            for (size_t i = 0; i < cred->ownersLen; i++)
            {
Sahil Bansal's avatar
Sahil Bansal committed
249 250 251
                cborEncoderResult |= cbor_encode_byte_string(&owners, (uint8_t *)cred->owners[i].id,
                    sizeof(cred->owners[i].id));
                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owners Array Value.");
Sachin Agrawal's avatar
Sachin Agrawal committed
252
            }
Sahil Bansal's avatar
Sahil Bansal committed
253 254
            cborEncoderResult |= cbor_encoder_close_container(&credMap, &owners);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Owners Name Array.");
leechul's avatar
leechul committed
255
        }
Sahil Bansal's avatar
Sahil Bansal committed
256 257
        cborEncoderResult |= cbor_encoder_close_container(&credArray, &credMap);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
258

Sahil Bansal's avatar
Sahil Bansal committed
259 260 261 262
        cred = cred->next;
   }
   cborEncoderResult |= cbor_encoder_close_container(&encoder, &credArray);
   VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
Sachin Agrawal's avatar
Sachin Agrawal committed
263

Sahil Bansal's avatar
Sahil Bansal committed
264 265 266 267 268 269 270
   if (CborNoError == cborEncoderResult)
   {
       *cborPayload = outPayload;
       *cborSize = encoder.ptr - outPayload;
        ret = OC_STACK_OK;
    }
    OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
Sachin Agrawal's avatar
Sachin Agrawal committed
271
exit:
Sahil Bansal's avatar
Sahil Bansal committed
272
    if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
273
    {
Sahil Bansal's avatar
Sahil Bansal committed
274 275 276 277 278 279 280 281 282 283 284
       // reallocate and try again!
       OICFree(outPayload);
       outPayload = NULL;
       // Since the allocated initial memory failed, double the memory.
       cborLen += encoder.ptr - encoder.end;
       cborEncoderResult = CborNoError;
       ret = CredToCBORPayload(credS, cborPayload, &cborLen);
       if (OC_STACK_OK == ret)
       {
           *cborSize = cborLen;
        }
285
    }
Sahil Bansal's avatar
Sahil Bansal committed
286 287 288 289 290 291 292 293 294 295 296

    if (CborNoError != cborEncoderResult)
    {
       OICFree(outPayload);
       outPayload = NULL;
       *cborSize = 0;
       *cborPayload = NULL;
       ret = OC_STACK_ERROR;
    }

    return ret;
Sachin Agrawal's avatar
Sachin Agrawal committed
297 298
}

Sahil Bansal's avatar
Sahil Bansal committed
299 300
OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                OicSecCred_t **secCred)
Sachin Agrawal's avatar
Sachin Agrawal committed
301
{
Sahil Bansal's avatar
Sahil Bansal committed
302 303 304 305 306
    if (NULL == cborPayload || NULL == secCred || NULL != *secCred)
    {
        return OC_STACK_INVALID_PARAM;
    }
    OIC_LOG(DEBUG, TAG, "CBORPayloadToCred IN");
Sachin Agrawal's avatar
Sachin Agrawal committed
307

Sahil Bansal's avatar
Sahil Bansal committed
308
    *secCred = NULL;
Sachin Agrawal's avatar
Sachin Agrawal committed
309

Sahil Bansal's avatar
Sahil Bansal committed
310
    OCStackResult ret = OC_STACK_ERROR;
Sachin Agrawal's avatar
Sachin Agrawal committed
311

Sahil Bansal's avatar
Sahil Bansal committed
312 313 314 315
    CborValue credCbor;
    CborParser parser;
    CborError cborFindResult = CborNoError;
    OicSecCred_t *cred = NULL;
316

Sahil Bansal's avatar
Sahil Bansal committed
317 318 319 320 321 322
    int cborLen = size;
    if (0 == size)
    {
        cborLen = CBOR_SIZE;
    }
    cbor_parser_init(cborPayload, cborLen, 0, &parser, &credCbor);
leechul's avatar
leechul committed
323

Sahil Bansal's avatar
Sahil Bansal committed
324
    OicSecCred_t *headCred = NULL;
325

Sahil Bansal's avatar
Sahil Bansal committed
326 327 328 329
    size_t len = 0;
    CborValue credArray;
    cborFindResult = cbor_value_enter_container(&credCbor, &credArray);
    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
Sachin Agrawal's avatar
Sachin Agrawal committed
330

Sahil Bansal's avatar
Sahil Bansal committed
331 332 333 334
    while (cbor_value_is_valid(&credArray))
    {
        cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
        VERIFY_NON_NULL(TAG, cred, ERROR);
leechul's avatar
leechul committed
335

Sahil Bansal's avatar
Sahil Bansal committed
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
        //CredId -- Mandatory
        CborValue credMap;
        cborFindResult = cbor_value_map_find_value(&credArray, OIC_JSON_CREDID_NAME, &credMap);
        if (CborNoError == cborFindResult && cbor_value_is_integer(&credMap))
        {
            cborFindResult = cbor_value_get_int(&credMap, (int *) &cred->credId);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
        }
        //subject -- Mandatory
        cborFindResult = cbor_value_map_find_value(&credArray, OIC_JSON_SUBJECT_NAME, &credMap);
        if (CborNoError == cborFindResult && cbor_value_is_byte_string(&credMap))
        {
            uint8_t *id = NULL;
            cborFindResult = cbor_value_dup_byte_string(&credMap, &id, &len, NULL);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Subject Name.");
            memcpy(cred->subject.id, id, len);
            OICFree(id);
        }
        //CredType -- Mandatory
        cborFindResult = cbor_value_map_find_value(&credArray, OIC_JSON_CREDTYPE_NAME, &credMap);
        if (CborNoError == cborFindResult && cbor_value_is_integer(&credMap))
        {
            cborFindResult = cbor_value_get_int(&credMap, (int *) &cred->credType);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
        }
        //Owners -- Mandatory
        cborFindResult = cbor_value_map_find_value(&credArray, OIC_JSON_OWNERS_NAME, &credMap);
        if (CborNoError == cborFindResult && cbor_value_is_array(&credMap))
        {
            CborValue owners;
            cborFindResult = cbor_value_get_array_length(&credMap, &cred->ownersLen);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Array Len.");
            cborFindResult = cbor_value_enter_container(&credMap, &owners);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Container.");
            int i = 0;
            cred->owners = (OicUuid_t *)OICCalloc(cred->ownersLen, sizeof(*cred->owners));
            VERIFY_NON_NULL(TAG, cred->owners, ERROR);
            while (cbor_value_is_valid(&owners))
374
            {
Sahil Bansal's avatar
Sahil Bansal committed
375 376 377 378 379 380 381
                uint8_t *owner = NULL;
                cborFindResult = cbor_value_dup_byte_string(&owners, &owner, &len, NULL);
                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Owner Byte String.");
                memcpy(cred->owners[i++].id, owner, len);
                OICFree(owner);
                cborFindResult = cbor_value_advance(&owners);
                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Array.");
382
            }
Sahil Bansal's avatar
Sahil Bansal committed
383 384 385 386 387 388 389 390 391
        }
        //PrivateData is mandatory for some of the credential types listed below.
        cborFindResult = cbor_value_map_find_value(&credArray, OIC_JSON_PRIVATEDATA_NAME, &credMap);
        if (CborNoError == cborFindResult && cbor_value_is_byte_string(&credMap))
        {
            cborFindResult = cbor_value_dup_byte_string(&credMap,
                &cred->privateData.data, &cred->privateData.len, NULL);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Byte Array.");
        }
leechul's avatar
leechul committed
392
#ifdef __WITH_X509__
Sahil Bansal's avatar
Sahil Bansal committed
393 394 395 396
        //PublicData is mandatory only for SIGNED_ASYMMETRIC_KEY credentials type.
        cborFindResult = cbor_value_map_find_value(&credArray, OIC_JSON_PUBLICDATA_NAME, &credMap);
        if (CborNoError == cborFindResult && cbor_value_is_byte_string(&credMap))
        {
leechul's avatar
leechul committed
397
            if (cred->credType & SIGNED_ASYMMETRIC_KEY)
Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
398
            {
Sahil Bansal's avatar
Sahil Bansal committed
399 400 401
                cborFindResult = cbor_value_dup_byte_string(&credMap, &cred->publicData.data,
                &cred->publicData.len, NULL);
                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Public Data.");
402
            }
Sahil Bansal's avatar
Sahil Bansal committed
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
        }
#endif  //__WITH_X509__
        //Period -- Not Mandatory
        cborFindResult = cbor_value_map_find_value(&credArray, OIC_JSON_PERIOD_NAME, &credMap);
        if (CborNoError == cborFindResult && cbor_value_is_text_string(&credMap))
        {
            cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
        }
        cred->next = NULL;
        if (NULL == headCred)
        {
            headCred = cred;
        }
        else
        {
            OicSecCred_t *temp = headCred;
            while (temp->next)
Sachin Agrawal's avatar
Sachin Agrawal committed
421
            {
Sahil Bansal's avatar
Sahil Bansal committed
422
                temp = temp->next;
Sachin Agrawal's avatar
Sachin Agrawal committed
423
            }
Sahil Bansal's avatar
Sahil Bansal committed
424 425 426 427 428 429 430
            temp->next = cred;
        }
        if (cbor_value_is_valid(&credArray))
        {
            cborFindResult = cbor_value_advance(&credArray);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Cred Array.");
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
431
    }
Sahil Bansal's avatar
Sahil Bansal committed
432
    *secCred = headCred;
Sachin Agrawal's avatar
Sachin Agrawal committed
433
    ret = OC_STACK_OK;
leechul's avatar
leechul committed
434

Sahil Bansal's avatar
Sahil Bansal committed
435 436
    OIC_LOG(DEBUG, TAG, "CBORPayloadToCred OUT");

Sachin Agrawal's avatar
Sachin Agrawal committed
437
exit:
Sahil Bansal's avatar
Sahil Bansal committed
438
    if (CborNoError != cborFindResult)
Sachin Agrawal's avatar
Sachin Agrawal committed
439 440 441
    {
        DeleteCredList(headCred);
        headCred = NULL;
Sahil Bansal's avatar
Sahil Bansal committed
442
        ret = OC_STACK_ERROR;
443
    }
Sahil Bansal's avatar
Sahil Bansal committed
444 445

    return ret;
Sachin Agrawal's avatar
Sachin Agrawal committed
446 447 448
}

OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
Sahil Bansal's avatar
Sahil Bansal committed
449 450
                                  const OicSecCert_t * publicData, const OicSecKey_t* privateData,
                                  size_t ownersLen, const OicUuid_t * owners)
Sachin Agrawal's avatar
Sachin Agrawal committed
451
{
Jon A. Cruz's avatar
Jon A. Cruz committed
452
    (void)publicData;
Sachin Agrawal's avatar
Sachin Agrawal committed
453 454
    OCStackResult ret = OC_STACK_ERROR;

Sahil Bansal's avatar
Sahil Bansal committed
455
    OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
Sachin Agrawal's avatar
Sachin Agrawal committed
456 457
    VERIFY_NON_NULL(TAG, cred, ERROR);

458 459 460
    //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
461 462 463 464

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

465 466
    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
467 468
    cred->credType = credType;

Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
469
#ifdef __WITH_X509__
Sahil Bansal's avatar
Sahil Bansal committed
470
    if (publicData && publicData->data)
Sachin Agrawal's avatar
Sachin Agrawal committed
471
    {
Sahil Bansal's avatar
Sahil Bansal committed
472
        cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
Sachin Agrawal's avatar
Sachin Agrawal committed
473
        VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
474 475
        memcpy(cred->publicData.data, publicData->data, publicData->len);
        cred->publicData.len = publicData->len;
Sachin Agrawal's avatar
Sachin Agrawal committed
476
    }
Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
477
#endif // __WITH_X509__
Sachin Agrawal's avatar
Sachin Agrawal committed
478

Sahil Bansal's avatar
Sahil Bansal committed
479
    if (privateData && privateData->data)
Sachin Agrawal's avatar
Sachin Agrawal committed
480
    {
Sahil Bansal's avatar
Sahil Bansal committed
481
        cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
Sachin Agrawal's avatar
Sachin Agrawal committed
482
        VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
483 484
        memcpy(cred->privateData.data, privateData->data, privateData->len);
        cred->privateData.len = privateData->len;
Sachin Agrawal's avatar
Sachin Agrawal committed
485 486 487 488 489
    }

    VERIFY_SUCCESS(TAG, ownersLen > 0, ERROR);
    cred->ownersLen = ownersLen;

Sahil Bansal's avatar
Sahil Bansal committed
490
    cred->owners = (OicUuid_t *)OICCalloc(cred->ownersLen, sizeof(*cred->owners));
Sachin Agrawal's avatar
Sachin Agrawal committed
491
    VERIFY_NON_NULL(TAG, cred->owners, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
492
    for (size_t i = 0; i < cred->ownersLen; i++)
Sachin Agrawal's avatar
Sachin Agrawal committed
493 494 495 496 497 498 499 500 501 502 503 504 505 506
    {
        memcpy(cred->owners[i].id, owners[i].id, sizeof(cred->owners[i].id));
    }

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

507 508 509 510 511
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
512
    if (cred)
513
    {
Sahil Bansal's avatar
Sahil Bansal committed
514 515 516 517
        uint8_t *payload = NULL;
        size_t size = 0;
        OCStackResult res = CredToCBORPayload(cred, &payload, &size);
        if ((OC_STACK_OK == res) && payload)
518
        {
Sahil Bansal's avatar
Sahil Bansal committed
519 520 521 522 523
            if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
            {
                ret = true;
            }
            OICFree(payload);
524 525 526 527
        }
    }
    else //Empty cred list
    {
Sahil Bansal's avatar
Sahil Bansal committed
528
        if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
529 530 531 532 533 534 535 536
        {
            ret = true;
        }
    }
    return ret;
}

/**
Sahil Bansal's avatar
Sahil Bansal committed
537
 * Compare function used LL_SORT for sorting credentials.
538
 *
Sahil Bansal's avatar
Sahil Bansal committed
539 540
 * @param first pointer to OicSecCred_t struct.
 * @param second  pointer to OicSecCred_t struct.
541
 *
Sahil Bansal's avatar
Sahil Bansal committed
542 543 544
 *@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.
545 546 547
 */
static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
{
Sahil Bansal's avatar
Sahil Bansal committed
548
    if (first->credId < second->credId)
549 550 551
    {
        return -1;
    }
Sahil Bansal's avatar
Sahil Bansal committed
552
    else if (first->credId > second->credId)
553 554 555 556 557 558 559 560 561 562 563 564 565
    {
        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
566
 * @return next available credId if successful, else 0 for error.
567 568 569 570 571 572 573 574 575 576 577
 */
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
578
        if (currentCred->credId == nextCredId)
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
        {
            nextCredId += 1;
        }
        else
        {
            break;
        }
    }

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

exit:
    return 0;
}
594

595
/**
Sahil Bansal's avatar
Sahil Bansal committed
596 597 598
 * Get the default value.
 *
 * @return  NULL for now.
599 600 601
 */
static OicSecCred_t* GetCredDefault()
{
Sahil Bansal's avatar
Sahil Bansal committed
602
    // TODO:Update it when we finalize the default info.
603 604
    return NULL;
}
605

Sachin Agrawal's avatar
Sachin Agrawal committed
606 607 608
OCStackResult AddCredential(OicSecCred_t * newCred)
{
    OCStackResult ret = OC_STACK_ERROR;
609 610 611 612 613
    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
614 615 616

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

Sahil Bansal's avatar
Sahil Bansal committed
618
    if (UpdatePersistentStorage(gCred))
Sachin Agrawal's avatar
Sachin Agrawal committed
619
    {
620 621 622 623 624 625 626 627 628 629 630 631 632
        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
633

634 635
    LL_FOREACH_SAFE(gCred, cred, tempCred)
    {
Sahil Bansal's avatar
Sahil Bansal committed
636
        if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
Sachin Agrawal's avatar
Sachin Agrawal committed
637
        {
638 639 640
            LL_DELETE(gCred, cred);
            FreeCred(cred);
            deleteFlag = 1;
Sachin Agrawal's avatar
Sachin Agrawal committed
641 642 643
        }
    }

Sahil Bansal's avatar
Sahil Bansal committed
644
    if (deleteFlag)
645
    {
Sahil Bansal's avatar
Sahil Bansal committed
646
        if (UpdatePersistentStorage(gCred))
647 648 649 650
        {
            ret = OC_STACK_RESOURCE_DELETED;
        }
    }
Sachin Agrawal's avatar
Sachin Agrawal committed
651
    return ret;
652

Sachin Agrawal's avatar
Sachin Agrawal committed
653 654
}

655 656 657 658 659 660 661 662 663 664 665 666
/**
 * Remove all credential data on credential resource and persistent storage
 *
 * @retval
 *     OC_STACK_OK              - no errors
 *     OC_STACK_ERROR           - stack process error
 */
OCStackResult RemoveAllCredentials(void)
{
    DeleteCredList(gCred);
    gCred = GetCredDefault();

Sahil Bansal's avatar
Sahil Bansal committed
667
    if (!UpdatePersistentStorage(gCred))
668 669 670 671 672 673
    {
        return OC_STACK_ERROR;
    }
    return OC_STACK_OK;
}

674 675
#ifdef __WITH_DTLS__
/**
676
 * Internal function to fill private data of owner PSK.
677
 *
678
 * @param receviedCred recevied owner credential from OBT(PT)
679 680 681
 * @param ownerAdd address of OBT(PT)
 * @param doxm current device's doxm resource
 *
Sahil Bansal's avatar
Sahil Bansal committed
682
 * @return
683 684
 *     true successfully done and valid ower psk information
 *     false Invalid owner psk information or failed to owner psk generation
685
 */
686
static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
687 688 689 690 691 692 693 694 695 696 697 698 699 700
                           const OicSecDoxm_t* doxm)
{
    //Derive OwnerPSK locally
    const char* oxmLabel = GetOxmString(doxm->oxmSel);
    VERIFY_NON_NULL(TAG, oxmLabel, ERROR);

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

701 702 703 704
    OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
    OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);

    //Generate owner credential based on recevied credential information
Sahil Bansal's avatar
Sahil Bansal committed
705
    receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
706
    VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
707 708
    receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
    memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
709

710 711 712 713 714
    OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");

    //Verify OwnerPSK information
    return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
            receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
715
exit:
716
    //receviedCred->privateData.data will be deallocated when deleting credential.
717 718 719 720 721 722 723 724
    return false;
}

#endif //__WITH_DTLS__

static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehRequest)
{
    OCEntityHandlerResult ret = OC_EH_ERROR;
Sahil Bansal's avatar
Sahil Bansal committed
725 726 727 728 729 730 731 732
    OIC_LOG(DEBUG, TAG, "HandleCREDPutRequest IN");

    //Get binary representation of cbor
    OicSecCred_t *cred  = NULL;
    uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData1);
    size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
    OCStackResult res = CBORPayloadToCred(payload, size, &cred);
    if (res == OC_STACK_OK)
733 734 735 736 737 738 739 740 741 742 743 744
    {
#ifdef __WITH_DTLS__
        OicUuid_t emptyUuid = {.id={0}};
        const OicSecDoxm_t* doxm = GetDoxmResourceData();
        if(false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
        {
            //in case of owner PSK
            switch(cred->credType)
            {
                case SYMMETRIC_PAIR_WISE_KEY:
                {
                    OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
745
                    if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
746
                    {
747 748 749 750 751 752
                        if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
                        {
                            OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
                        }

                        OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
                        if(OC_STACK_OK == AddCredential(cred))
                        {
                            ret = OC_EH_RESOURCE_CREATED;
                        }
                        else
                        {
                            OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
                            ret = OC_EH_ERROR;
                        }
                    }
                    else
                    {
                        OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
                        ret = OC_EH_ERROR;
                    }

769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806
                    if(OC_EH_RESOURCE_CREATED == ret)
                    {
                        /**
                         * in case of random PIN based OxM,
                         * revert get_psk_info callback of tinyDTLS to use owner credential.
                         */
                        if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
                        {
                            OicUuid_t emptyUuid = { .id={0}};
                            SetUuidForRandomPinOxm(&emptyUuid);

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

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

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

807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
                    break;
                }
                case SYMMETRIC_GROUP_KEY:
                case ASYMMETRIC_KEY:
                case SIGNED_ASYMMETRIC_KEY:
                case PIN_PASSWORD:
                case ASYMMETRIC_ENCRYPTION_KEY:
                {
                    OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
                    ret = OC_EH_ERROR;
                    break;
                }
                default:
                {
                    OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
                    ret = OC_EH_ERROR;
                    break;
                }
            }
826 827 828 829 830 831 832 833 834 835

            if(OC_EH_RESOURCE_CREATED != ret)
            {
                /*
                  * If some error is occured while ownership transfer,
                  * ownership transfer related resource should be revert back to initial status.
                  */
                RestoreDoxmToInitState();
                RestorePstatToInitState();
            }
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
        }
        else
        {
            /*
             * If the post request credential has credId, it will be
             * discarded and the next available credId will be assigned
             * to it before getting appended to the existing credential
             * list and updating svr database.
             */
            ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
        }
#else //not __WITH_DTLS__
        /*
         * If the post request credential has credId, it will be
         * discarded and the next available credId will be assigned
         * to it before getting appended to the existing credential
         * list and updating svr database.
         */
        ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
#endif//__WITH_DTLS__
    }

Sahil Bansal's avatar
Sahil Bansal committed
858
    if (OC_EH_RESOURCE_CREATED != ret)
859 860 861 862 863 864 865
    {
        if(OC_STACK_OK != RemoveCredential(&cred->subject))
        {
            OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
        }
        FreeCred(cred);
    }
Sahil Bansal's avatar
Sahil Bansal committed
866
    OIC_LOG(DEBUG, TAG, "HandleCREDPutRequest OUT");
867 868 869
    return ret;
}

Sachin Agrawal's avatar
Sachin Agrawal committed
870 871 872 873
static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
{
    OCEntityHandlerResult ret = OC_EH_ERROR;

Sahil Bansal's avatar
Sahil Bansal committed
874 875 876 877 878 879
    //Get binary representation of CBOR
    OicSecCred_t *cred  = NULL;
    uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData1;
    size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize;
    OCStackResult res = CBORPayloadToCred(payload, size, &cred);
    if ((OC_STACK_OK == res) && cred)
Sachin Agrawal's avatar
Sachin Agrawal committed
880
    {
881 882 883 884
        //If the Post request credential has credId, it will be
        //discarded and the next available credId will be assigned
        //to it before getting appended to the existing credential
        //list and updating svr database.
885
        ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
Sachin Agrawal's avatar
Sachin Agrawal committed
886
    }
887

Sachin Agrawal's avatar
Sachin Agrawal committed
888 889 890
    return ret;
}

891 892
static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
{
893
    OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
894 895 896

    OCEntityHandlerResult ehRet = OC_EH_ERROR;

Sahil Bansal's avatar
Sahil Bansal committed
897 898 899 900 901
    unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
    B64Result b64Ret = B64_OK;
    uint32_t outLen = 0;

    if (NULL == ehRequest->query)
902 903 904 905
   {
       return ehRet;
   }

Sahil Bansal's avatar
Sahil Bansal committed
906
   OicParseQueryIter_t parseIter = { .attrPos=NULL };
907 908 909 910
   OicUuid_t subject = {.id={0}};

   //Parsing REST query to get the subject
   ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
Sahil Bansal's avatar
Sahil Bansal committed
911
   while (GetNextQuery(&parseIter))
912
   {
Sahil Bansal's avatar
Sahil Bansal committed
913
       if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECT_NAME,
914 915
               parseIter.attrLen) == 0)
       {
Sahil Bansal's avatar
Sahil Bansal committed
916 917 918 919 920
            b64Ret = b64Decode((char*)parseIter.valPos,  parseIter.valLen, base64Buff,
                    sizeof(base64Buff), &outLen);
            VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(subject.id)), ERROR);
            memcpy(subject.id, base64Buff, outLen);
        }
921 922
   }

Sahil Bansal's avatar
Sahil Bansal committed
923
   if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
924 925 926 927
   {
       ehRet = OC_EH_RESOURCE_DELETED;
   }

leechul's avatar
leechul committed
928
exit:
929 930 931
    return ehRet;
}

Sahil Bansal's avatar
Sahil Bansal committed
932
OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
933 934
                                        OCEntityHandlerRequest * ehRequest,
                                        void* callbackParameter)
Sachin Agrawal's avatar
Sachin Agrawal committed
935
{
Jon A. Cruz's avatar
Jon A. Cruz committed
936
    (void)callbackParameter;
Sachin Agrawal's avatar
Sachin Agrawal committed
937 938
    OCEntityHandlerResult ret = OC_EH_ERROR;

Sahil Bansal's avatar
Sahil Bansal committed
939
    if (!ehRequest)
Sachin Agrawal's avatar
Sachin Agrawal committed
940 941 942 943 944
    {
        return OC_EH_ERROR;
    }
    if (flag & OC_REQUEST_FLAG)
    {
945
        OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
Sachin Agrawal's avatar
Sachin Agrawal committed
946
        //TODO :  Handle PUT/DEL methods
Sahil Bansal's avatar
Sahil Bansal committed
947
        switch (ehRequest->method)
Sachin Agrawal's avatar
Sachin Agrawal committed
948 949 950 951
        {
            case OC_REST_GET:
                ret = OC_EH_FORBIDDEN;
                break;
952 953 954
            case OC_REST_PUT:
                ret = HandlePutRequest(ehRequest);
                break;
Sachin Agrawal's avatar
Sachin Agrawal committed
955 956 957
            case OC_REST_POST:
                ret = HandlePostRequest(ehRequest);
                break;
958 959 960
            case OC_REST_DELETE:
                ret = HandleDeleteRequest(ehRequest);
                break;
Sachin Agrawal's avatar
Sachin Agrawal committed
961 962 963 964 965 966 967
            default:
                ret = OC_EH_ERROR;
                break;
        }
    }

    //Send payload to request originator
Sahil Bansal's avatar
Sahil Bansal committed
968 969
    ret = (SendSRMCBORResponse(ehRequest, ret, NULL, 0) == OC_STACK_OK) ?
                       ret : OC_EH_ERROR;
Sachin Agrawal's avatar
Sachin Agrawal committed
970 971 972 973 974 975

    return ret;
}

OCStackResult CreateCredResource()
{
Sahil Bansal's avatar
Sahil Bansal committed
976 977 978 979 980 981 982
    OCStackResult ret = OCCreateResource(&gCredHandle,
                                         OIC_RSRC_TYPE_SEC_CRED,
                                         OIC_MI_DEF,
                                         OIC_RSRC_CRED_URI,
                                         CredEntityHandler,
                                         NULL,
                                         OC_RES_PROP_NONE);
Sachin Agrawal's avatar
Sachin Agrawal committed
983 984 985

    if (OC_STACK_OK != ret)
    {
986
        OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
Sachin Agrawal's avatar
Sachin Agrawal committed
987 988 989 990 991 992 993 994 995 996
        DeInitCredResource();
    }
    return ret;
}

OCStackResult InitCredResource()
{
    OCStackResult ret = OC_STACK_ERROR;

    //Read Cred resource from PS
Sahil Bansal's avatar
Sahil Bansal committed
997 998 999 1000 1001 1002 1003 1004 1005
    uint8_t *data = NULL;
    size_t size = 0;
    ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
    // If database read failed
    if (ret != OC_STACK_OK)
    {
        OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
    }
    if (data)
Sachin Agrawal's avatar
Sachin Agrawal committed
1006
    {
Sahil Bansal's avatar
Sahil Bansal committed
1007 1008
        // Read ACL resource from PS
        ret = CBORPayloadToCred(data, size, &gCred);
Sachin Agrawal's avatar
Sachin Agrawal committed
1009
    }
Sahil Bansal's avatar
Sahil Bansal committed
1010

Sachin Agrawal's avatar
Sachin Agrawal committed
1011 1012 1013 1014 1015
    /*
     * If SVR database in persistent storage got corrupted or
     * is not available for some reason, a default Cred is created
     * which allows user to initiate Cred provisioning again.
     */
Sahil Bansal's avatar
Sahil Bansal committed
1016
    if (ret != OC_STACK_OK || !data || !gCred)
Sachin Agrawal's avatar
Sachin Agrawal committed
1017 1018 1019 1020 1021
    {
        gCred = GetCredDefault();
    }
    //Instantiate 'oic.sec.cred'
    ret = CreateCredResource();
Sahil Bansal's avatar
Sahil Bansal committed
1022
    OICFree(data);
Sachin Agrawal's avatar
Sachin Agrawal committed
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037
    return ret;
}

OCStackResult DeInitCredResource()
{
    OCStackResult result = OCDeleteResource(gCredHandle);
    DeleteCredList(gCred);
    gCred = NULL;
    return result;
}

const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
{
    OicSecCred_t *cred = NULL;

1038
   if ( NULL == subject)
Sachin Agrawal's avatar
Sachin Agrawal committed
1039
    {
1040
       return NULL;
Sachin Agrawal's avatar
Sachin Agrawal committed
1041 1042 1043 1044 1045 1046
    }

    LL_FOREACH(gCred, cred)
    {
        if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
        {
1047
            return cred;
Sachin Agrawal's avatar
Sachin Agrawal committed
1048 1049 1050 1051 1052 1053 1054
        }
    }
    return NULL;
}


#if defined(__WITH_DTLS__)
Sahil Bansal's avatar
Sahil Bansal committed
1055 1056 1057
int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
              const uint8_t *desc, size_t desc_len,
              uint8_t *result, size_t result_length)
Sachin Agrawal's avatar
Sachin Agrawal committed
1058
{
1059
    int32_t ret = -1;
Sachin Agrawal's avatar
Sachin Agrawal committed
1060

1061 1062 1063 1064
    if (NULL == result)
    {
        return ret;
    }
Sachin Agrawal's avatar
Sachin Agrawal committed
1065

1066 1067 1068 1069
    switch (type)
    {
        case CA_DTLS_PSK_HINT:
        case CA_DTLS_PSK_IDENTITY:
Sachin Agrawal's avatar
Sachin Agrawal committed
1070
            {
1071 1072 1073
                OicUuid_t deviceID = {.id={}};
                // Retrieve Device ID from doxm resource
                if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
Sachin Agrawal's avatar
Sachin Agrawal committed
1074
                {
1075
                    OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
1076
                    return ret;
Sachin Agrawal's avatar
Sachin Agrawal committed
1077
                }
1078 1079 1080

                if (result_length < sizeof(deviceID.id))
                {
1081
                    OIC_LOG (ERROR, TAG, "Wrong value for result_length");
1082 1083 1084 1085
                    return ret;
                }
                memcpy(result, deviceID.id, sizeof(deviceID.id));
                return (sizeof(deviceID.id));
Sachin Agrawal's avatar
Sachin Agrawal committed
1086
            }
1087
            break;
Sachin Agrawal's avatar
Sachin Agrawal committed
1088

1089 1090 1091
        case CA_DTLS_PSK_KEY:
            {
                OicSecCred_t *cred = NULL;
Sachin Agrawal's avatar
Sachin Agrawal committed
1092 1093
                LL_FOREACH(gCred, cred)
                {
1094
                    if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
Sachin Agrawal's avatar
Sachin Agrawal committed
1095
                    {
1096 1097
                        continue;
                    }
Sachin Agrawal's avatar
Sachin Agrawal committed
1098

1099 1100 1101
                    if ((desc_len == sizeof(cred->subject.id)) &&
                        (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
                    {
1102 1103 1104 1105 1106 1107 1108 1109
                        /*
                         * If the credentials are valid for limited time,
                         * check their expiry.
                         */
                        if (cred->period)
                        {
                            if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
                            {
1110
                                OIC_LOG (INFO, TAG, "Credentials are expired.");
1111 1112 1113 1114 1115
                                ret = -1;
                                return ret;
                            }
                        }

Sahil Bansal's avatar
Sahil Bansal committed
1116 1117 1118 1119
                        // Copy PSK.
                        result_length = cred->privateData.len;
                        memcpy(result, cred->privateData.data, result_length);
                        return result_length;
Sachin Agrawal's avatar
Sachin Agrawal committed
1120 1121 1122
                    }
                }
            }
1123
            break;
Sachin Agrawal's avatar
Sachin Agrawal committed
1124

1125 1126
        default:
            {
1127
                OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
1128 1129 1130
                ret = -1;
            }
            break;
Sachin Agrawal's avatar
Sachin Agrawal committed
1131
    }
1132 1133

    return ret;
Sachin Agrawal's avatar
Sachin Agrawal committed
1134
}
1135

Joonghwan Lee's avatar
Joonghwan Lee committed
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146