credresource.c 77.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 <stdlib.h>
24
#ifdef HAVE_STRING_H
Sahil Bansal's avatar
Sahil Bansal committed
25
#include <string.h>
26 27
#endif
#ifdef HAVE_STRINGS_H
Sahil Bansal's avatar
Sahil Bansal committed
28 29 30 31 32 33
#include <strings.h>
#endif
#include <stdint.h>

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

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

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

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

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

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

Shilpa Sodani's avatar
Shilpa Sodani committed
69

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

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

89
    //Clean PublicData
Andrii Shtompel's avatar
Andrii Shtompel committed
90
#if defined(__WITH_X509__) || defined(WITH_TLS) 
91
    OICFree(cred->publicData.data);
Sahil Bansal's avatar
Sahil Bansal committed
92
#endif
Sachin Agrawal's avatar
Sachin Agrawal committed
93

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

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

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

104 105 106 107 108 109 110 111 112
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
113 114 115 116
        }
    }
}

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

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

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

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

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

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

leechul's avatar
leechul committed
156 157 158 159 160 161 162 163 164 165 166 167
    // 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
168

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

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

        //Subject -- Mandatory
leechul's avatar
leechul committed
199 200
        cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
            strlen(OIC_JSON_SUBJECTID_NAME));
Sahil Bansal's avatar
Sahil Bansal committed
201
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
leechul's avatar
leechul committed
202 203 204 205 206
        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
207 208

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

Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
215
#ifdef __WITH_X509__
Sahil Bansal's avatar
Sahil Bansal committed
216
        //PublicData -- Not Mandatory
Dmitriy Zhuravlev's avatar
Dmitriy Zhuravlev committed
217
        if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
Sahil Bansal's avatar
Sahil Bansal committed
218
        {
219
            CborEncoder publicMap;
leechul's avatar
leechul committed
220 221 222 223 224 225 226 227 228
            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");

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

            // TODO: Need to data strucure modification for OicSecCert_t.
            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
                strlen(OIC_JSON_ENCODING_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
js126.lee's avatar
js126.lee committed
240 241
            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_RAW,
                strlen(OIC_SEC_ENCODING_RAW));
leechul's avatar
leechul committed
242 243 244 245
            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
246
        }
Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
247
#endif /*__WITH_X509__*/
Sahil Bansal's avatar
Sahil Bansal committed
248
        //PrivateData -- Not Mandatory
249
        if(!secureFlag && cred->privateData.data)
Sahil Bansal's avatar
Sahil Bansal committed
250
        {
251
            CborEncoder privateMap;
leechul's avatar
leechul committed
252 253 254 255 256 257 258 259 260 261
            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.
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
            // 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.");
            }
            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
300 301 302

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

Sahil Bansal's avatar
Sahil Bansal committed
305 306 307
        //Period -- Not Mandatory
        if(cred->period)
        {
leechul's avatar
leechul committed
308
            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
Sahil Bansal's avatar
Sahil Bansal committed
309 310
                strlen(OIC_JSON_PERIOD_NAME));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
leechul's avatar
leechul committed
311
            cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
Sahil Bansal's avatar
Sahil Bansal committed
312 313 314
                strlen(cred->period));
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
315

leechul's avatar
leechul committed
316 317

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

Sahil Bansal's avatar
Sahil Bansal committed
320
        cred = cred->next;
leechul's avatar
leechul committed
321 322 323 324 325
    }
    cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");

    cred = credS;
326

leechul's avatar
leechul committed
327 328 329 330 331 332
    // 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.");
333
        ret = ConvertUuidToStr(&cred->rownerID, &rowner);
leechul's avatar
leechul committed
334 335 336 337 338 339
        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
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
    //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
373 374 375 376 377 378 379 380 381
    // 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
382 383 384
        ret = OC_STACK_OK;
    }
    OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
Sachin Agrawal's avatar
Sachin Agrawal committed
385
exit:
leechul's avatar
leechul committed
386
    if (CborErrorOutOfMemory == cborEncoderResult)
387
    {
leechul's avatar
leechul committed
388 389 390 391 392 393
        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;
394
        ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
leechul's avatar
leechul committed
395
        *cborSize = cborLen;
396
    }
Sahil Bansal's avatar
Sahil Bansal committed
397 398 399

    if (CborNoError != cborEncoderResult)
    {
leechul's avatar
leechul committed
400 401 402 403 404 405
        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
406 407 408
    }

    return ret;
Sachin Agrawal's avatar
Sachin Agrawal committed
409 410
}

Sahil Bansal's avatar
Sahil Bansal committed
411 412
OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                OicSecCred_t **secCred)
Sachin Agrawal's avatar
Sachin Agrawal committed
413
{
Ashwini Kumar's avatar
Ashwini Kumar committed
414
    if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
Sahil Bansal's avatar
Sahil Bansal committed
415 416 417
    {
        return OC_STACK_INVALID_PARAM;
    }
Sachin Agrawal's avatar
Sachin Agrawal committed
418

Sahil Bansal's avatar
Sahil Bansal committed
419
    OCStackResult ret = OC_STACK_ERROR;
leechul's avatar
leechul committed
420 421
    CborValue credCbor = { .parser = NULL };
    CborParser parser = { .end = NULL };
Sahil Bansal's avatar
Sahil Bansal committed
422
    CborError cborFindResult = CborNoError;
leechul's avatar
leechul committed
423
    cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
leechul's avatar
leechul committed
424

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

leechul's avatar
leechul committed
427 428 429 430
    // 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
431

leechul's avatar
leechul committed
432
    while (cbor_value_is_valid(&CredRootMap))
Sahil Bansal's avatar
Sahil Bansal committed
433
    {
leechul's avatar
leechul committed
434 435 436
        char* tagName = NULL;
        size_t len = 0;
        CborType type = cbor_value_get_type(&CredRootMap);
437
        if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
Sahil Bansal's avatar
Sahil Bansal committed
438
        {
leechul's avatar
leechul committed
439 440 441 442
            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
443
        }
leechul's avatar
leechul committed
444
        if(tagName)
Sahil Bansal's avatar
Sahil Bansal committed
445
        {
leechul's avatar
leechul committed
446
            if (strcmp(tagName, OIC_JSON_CREDS_NAME)  == 0)
447
            {
leechul's avatar
leechul committed
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
                // 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);

481
                    while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
leechul's avatar
leechul committed
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
                    {
                        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)
                            {
497 498
                                uint64_t credId = 0;
                                cborFindResult = cbor_value_get_uint64(&credMap, &credId);
leechul's avatar
leechul committed
499
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
500
                                cred->credId = (uint16_t)credId;
leechul's avatar
leechul committed
501 502 503 504 505 506 507 508 509 510 511
                            }
                            // subjectid
                            if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
                            {
                                char *subjectid = NULL;
                                cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
                                ret = ConvertStrToUuid(subjectid, &cred->subject);
                                VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
                                OICFree(subjectid);
                            }
512
                            // credtype
leechul's avatar
leechul committed
513 514
                            if (strcmp(name, OIC_JSON_CREDTYPE_NAME)  == 0)
                            {
515 516
                                uint64_t credType = 0;
                                cborFindResult = cbor_value_get_uint64(&credMap, &credType);
leechul's avatar
leechul committed
517
                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
518
                                cred->credType = (OicSecCredType_t)credType;
leechul's avatar
leechul committed
519 520 521 522 523 524 525 526 527 528 529
                            }
                            // 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);
530
                                    if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
leechul's avatar
leechul committed
531 532 533 534 535 536 537 538 539 540
                                    {
                                        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
541
                                        if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
leechul's avatar
leechul committed
542
                                        {
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
                                            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
558 559
                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
                                        }
560

leechul's avatar
leechul committed
561 562 563
                                        // PrivateData::encoding -- Mandatory
                                        if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
                                        {
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584
                                            // 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
585 586 587 588 589 590 591 592 593 594 595
                                        }
                                    }
                                    if (cbor_value_is_valid(&privateMap))
                                    {
                                        cborFindResult = cbor_value_advance(&privateMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
                                    }
                                    OICFree(privname);
                                }

                            }
leechul's avatar
leechul committed
596
#ifdef __WITH_X509__
leechul's avatar
leechul committed
597 598 599 600 601 602 603 604 605
                            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);
606
                                    if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
leechul's avatar
leechul committed
607 608 609 610 611 612 613 614 615 616
                                    {
                                        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
617
                                        if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
leechul's avatar
leechul committed
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
                                        {
                                            cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
                                                &cred->publicData.len, NULL);
                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
                                        }
                                        // PublicData::encoding -- Mandatory
                                        if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
                                        {
                                            // TODO: Need to update data structure, just ignore encoding value now.
                                        }
                                    }
                                    if (cbor_value_is_valid(&pubMap))
                                    {
                                        cborFindResult = cbor_value_advance(&pubMap);
                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
                                    }
                                    OICFree(pubname);
                                }
                            }
Sahil Bansal's avatar
Sahil Bansal committed
637
#endif  //__WITH_X509__
leechul's avatar
leechul committed
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661

                            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.");
                    }
                }
            }

662
            //ROwner -- Mandatory
663
            if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0 && cbor_value_is_text_string(&CredRootMap))
Sachin Agrawal's avatar
Sachin Agrawal committed
664
            {
leechul's avatar
leechul committed
665 666 667
                char *stRowner = NULL;
                cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
668 669

                ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
leechul's avatar
leechul committed
670 671
                VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
                OICFree(stRowner);
Sachin Agrawal's avatar
Sachin Agrawal committed
672
            }
leechul's avatar
leechul committed
673
            OICFree(tagName);
Sahil Bansal's avatar
Sahil Bansal committed
674
        }
leechul's avatar
leechul committed
675
        if (cbor_value_is_valid(&CredRootMap))
Sahil Bansal's avatar
Sahil Bansal committed
676
        {
leechul's avatar
leechul committed
677 678
            cborFindResult = cbor_value_advance(&CredRootMap);
            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
Sahil Bansal's avatar
Sahil Bansal committed
679
        }
Sachin Agrawal's avatar
Sachin Agrawal committed
680
    }
leechul's avatar
leechul committed
681

Sahil Bansal's avatar
Sahil Bansal committed
682
    *secCred = headCred;
Sachin Agrawal's avatar
Sachin Agrawal committed
683
    ret = OC_STACK_OK;
leechul's avatar
leechul committed
684

Sachin Agrawal's avatar
Sachin Agrawal committed
685
exit:
Sahil Bansal's avatar
Sahil Bansal committed
686
    if (CborNoError != cborFindResult)
Sachin Agrawal's avatar
Sachin Agrawal committed
687 688 689
    {
        DeleteCredList(headCred);
        headCred = NULL;
leechul's avatar
leechul committed
690
        *secCred = NULL;
Sahil Bansal's avatar
Sahil Bansal committed
691
        ret = OC_STACK_ERROR;
692
    }
Sahil Bansal's avatar
Sahil Bansal committed
693 694

    return ret;
Sachin Agrawal's avatar
Sachin Agrawal committed
695 696 697
}

OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
Sahil Bansal's avatar
Sahil Bansal committed
698
                                  const OicSecCert_t * publicData, const OicSecKey_t* privateData,
699
                                  const OicUuid_t * rownerID)
Sachin Agrawal's avatar
Sachin Agrawal committed
700
{
Jon A. Cruz's avatar
Jon A. Cruz committed
701
    (void)publicData;
Sachin Agrawal's avatar
Sachin Agrawal committed
702 703
    OCStackResult ret = OC_STACK_ERROR;

Sahil Bansal's avatar
Sahil Bansal committed
704
    OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
Sachin Agrawal's avatar
Sachin Agrawal committed
705 706
    VERIFY_NON_NULL(TAG, cred, ERROR);

707 708 709
    //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
710 711 712 713

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

714 715
    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
716 717
    cred->credType = credType;

Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
718
#ifdef __WITH_X509__
Sahil Bansal's avatar
Sahil Bansal committed
719
    if (publicData && publicData->data)
Sachin Agrawal's avatar
Sachin Agrawal committed
720
    {
Sahil Bansal's avatar
Sahil Bansal committed
721
        cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
Sachin Agrawal's avatar
Sachin Agrawal committed
722
        VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
723 724
        memcpy(cred->publicData.data, publicData->data, publicData->len);
        cred->publicData.len = publicData->len;
Sachin Agrawal's avatar
Sachin Agrawal committed
725
    }
Dmitrii Zhuravlev's avatar
Dmitrii Zhuravlev committed
726
#endif // __WITH_X509__
Sachin Agrawal's avatar
Sachin Agrawal committed
727

Sahil Bansal's avatar
Sahil Bansal committed
728
    if (privateData && privateData->data)
Sachin Agrawal's avatar
Sachin Agrawal committed
729
    {
Sahil Bansal's avatar
Sahil Bansal committed
730
        cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
Sachin Agrawal's avatar
Sachin Agrawal committed
731
        VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
Sahil Bansal's avatar
Sahil Bansal committed
732 733
        memcpy(cred->privateData.data, privateData->data, privateData->len);
        cred->privateData.len = privateData->len;
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755

        // 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
756 757
    }

758 759
    VERIFY_NON_NULL(TAG, rownerID, ERROR);
    memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
Sachin Agrawal's avatar
Sachin Agrawal committed
760 761 762 763 764 765 766 767 768 769 770

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

771 772 773 774 775
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
776
    if (cred)
777
    {
Sahil Bansal's avatar
Sahil Bansal committed
778 779
        uint8_t *payload = NULL;
        size_t size = 0;
780 781
        int secureFlag = 0;
        OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
Sahil Bansal's avatar
Sahil Bansal committed
782
        if ((OC_STACK_OK == res) && payload)
783
        {
Sahil Bansal's avatar
Sahil Bansal committed
784 785 786 787 788
            if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
            {
                ret = true;
            }
            OICFree(payload);
789 790 791 792
        }
    }
    else //Empty cred list
    {
Sahil Bansal's avatar
Sahil Bansal committed
793
        if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
794 795 796 797 798 799 800 801
        {
            ret = true;
        }
    }
    return ret;
}

/**
Sahil Bansal's avatar
Sahil Bansal committed
802
 * Compare function used LL_SORT for sorting credentials.
803
 *
Sahil Bansal's avatar
Sahil Bansal committed
804 805
 * @param first pointer to OicSecCred_t struct.
 * @param second  pointer to OicSecCred_t struct.
806
 *
Sahil Bansal's avatar
Sahil Bansal committed
807 808 809
 *@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.
810 811 812
 */
static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
{
Sahil Bansal's avatar
Sahil Bansal committed
813
    if (first->credId < second->credId)
814 815 816
    {
        return -1;
    }
Sahil Bansal's avatar
Sahil Bansal committed
817
    else if (first->credId > second->credId)
818 819 820 821 822 823 824 825 826 827 828 829 830
    {
        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
831
 * @return next available credId if successful, else 0 for error.
832 833 834 835 836 837 838 839 840 841 842
 */
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
843
        if (currentCred->credId == nextCredId)
844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
        {
            nextCredId += 1;
        }
        else
        {
            break;
        }
    }

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

exit:
    return 0;
}
859

860
/**
Sahil Bansal's avatar
Sahil Bansal committed
861 862 863
 * Get the default value.
 *
 * @return  NULL for now.
864 865 866
 */
static OicSecCred_t* GetCredDefault()
{
Sahil Bansal's avatar
Sahil Bansal committed
867
    // TODO:Update it when we finalize the default info.
868 869
    return NULL;
}
870

Sachin Agrawal's avatar
Sachin Agrawal committed
871 872 873
OCStackResult AddCredential(OicSecCred_t * newCred)
{
    OCStackResult ret = OC_STACK_ERROR;
874 875 876 877 878
    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
879 880 881

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

Sahil Bansal's avatar
Sahil Bansal committed
883
    if (UpdatePersistentStorage(gCred))
Sachin Agrawal's avatar
Sachin Agrawal committed
884
    {
885 886 887 888 889 890 891 892 893 894 895 896 897
        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
898

899 900
    LL_FOREACH_SAFE(gCred, cred, tempCred)
    {
Sahil Bansal's avatar
Sahil Bansal committed
901
        if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
Sachin Agrawal's avatar
Sachin Agrawal committed
902
        {
903 904 905
            LL_DELETE(gCred, cred);
            FreeCred(cred);
            deleteFlag = 1;
Sachin Agrawal's avatar
Sachin Agrawal committed
906 907 908
        }
    }

Sahil Bansal's avatar
Sahil Bansal committed
909
    if (deleteFlag)
910
    {
Sahil Bansal's avatar
Sahil Bansal committed
911
        if (UpdatePersistentStorage(gCred))
912 913 914 915
        {
            ret = OC_STACK_RESOURCE_DELETED;
        }
    }
Sachin Agrawal's avatar
Sachin Agrawal committed
916
    return ret;
917

Sachin Agrawal's avatar
Sachin Agrawal committed
918 919
}

920 921 922 923 924 925 926 927 928 929 930 931
/**
 * 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
932
    if (!UpdatePersistentStorage(gCred))
933 934 935 936 937 938
    {
        return OC_STACK_ERROR;
    }
    return OC_STACK_OK;
}

Andrii Shtompel's avatar
Andrii Shtompel committed
939
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
940
/**
941
 * Internal function to fill private data of owner PSK.
942
 *
943
 * @param receviedCred recevied owner credential from OBT(PT)
944 945 946
 * @param ownerAdd address of OBT(PT)
 * @param doxm current device's doxm resource
 *
Sahil Bansal's avatar
Sahil Bansal committed
947
 * @return
948 949
 *     true successfully done and valid ower psk information
 *     false Invalid owner psk information or failed to owner psk generation
950
 */
951
static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
952 953 954 955 956 957 958 959 960 961 962 963 964 965
                           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);

966 967 968 969
    OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
    OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);

    //Generate owner credential based on recevied credential information
970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990

    // TODO: Added as workaround, will be replaced soon.
    if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
    {
        receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
        VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
        receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
        memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
    }
    else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
    {
        uint32_t b64OutSize = 0;
        size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
        char* b64Buf = OICCalloc(1, b64BufSize);
        VERIFY_NON_NULL(TAG, b64Buf, ERROR);

        b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);

        receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
        VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
        receviedCred->privateData.len = b64OutSize;
Vinay Bhatia's avatar
Vinay Bhatia committed
991 992
        strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
        receviedCred->privateData.data[b64OutSize] = '\0';
993 994 995 996 997 998
    }
    else
    {
        // TODO: error
        VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
    }
999

1000 1001 1002 1003 1004
    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);
1005
exit:
1006
    //receviedCred->privateData.data will be deallocated when deleting credential.
1007 1008 1009 1010 1011
    return false;
}

#endif //__WITH_DTLS__

1012
static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
1013 1014
{
    OCEntityHandlerResult ret = OC_EH_ERROR;
1015
    OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
Sahil Bansal's avatar
Sahil Bansal committed
1016

1017
    static uint16_t previousMsgId = 0;
Sahil Bansal's avatar
Sahil Bansal committed
1018 1019
    //Get binary representation of cbor
    OicSecCred_t *cred  = NULL;
Ashwini Kumar's avatar
Ashwini Kumar committed
1020
    uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
Sahil Bansal's avatar
Sahil Bansal committed
1021
    size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1022

Sahil Bansal's avatar
Sahil Bansal committed
1023 1024
    OCStackResult res = CBORPayloadToCred(payload, size, &cred);
    if (res == OC_STACK_OK)
1025
    {
Andrii Shtompel's avatar
Andrii Shtompel committed
1026
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1027 1028
        OicUuid_t emptyUuid = {.id={0}};
        const OicSecDoxm_t* doxm = GetDoxmResourceData();
1029
        if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1030 1031 1032 1033 1034 1035 1036
        {
            //in case of owner PSK
            switch(cred->credType)
            {
                case SYMMETRIC_PAIR_WISE_KEY:
                {
                    OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1037
                    if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1038
                    {
1039 1040 1041 1042 1043 1044
                        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.");
1045 1046
                        if(OC_STACK_OK == AddCredential(cred))
                        {
Randeep's avatar
Randeep committed
1047
                            ret = OC_EH_CHANGED;
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
                        }
                        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;
                    }

Randeep's avatar
Randeep committed
1061
                    if(OC_EH_CHANGED == ret)
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
                    {
                        /**
                         * 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);

Andrii Shtompel's avatar
Andrii Shtompel committed
1072 1073 1074 1075 1076 1077 1078 1079
#ifdef __WITH_TLS__
                            if(CA_STATUS_OK != CAregisterTlsCredentialsHandler(GetDtlsPskCredentials))
                            {
                                OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
                                ret = OC_EH_ERROR;
                                break;
                            }
#endif
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096