[IOT-2830] add PSK callback logging
[iotivity.git] / resource / csdk / security / src / credresource.c
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #define __STDC_LIMIT_MACROS
22
23 #include "iotivity_config.h"
24 #include <stdlib.h>
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28 #ifdef HAVE_STRINGS_H
29 #include <strings.h>
30 #endif
31 #include <stdint.h>
32 #include <stdbool.h>
33 #include <inttypes.h>
34
35 #include "cainterface.h"
36 #include "payload_logging.h"
37 #include "ocstack.h"
38 #include "ocrandom.h"
39 #include "base64.h"
40 #include "ocserverrequest.h"
41 #include "oic_malloc.h"
42 #include "oic_string.h"
43 #include "ocpayload.h"
44 #include "ocpayloadcbor.h"
45 #include "utlist.h"
46 #include "credresource.h"
47 #include "doxmresource.h"
48 #include "pstatresource.h"
49 #include "iotvticalendar.h"
50 #include "pbkdf2.h"
51 #include "resourcemanager.h"
52 #include "srmresourcestrings.h"
53 #include "srmutility.h"
54 #include "psinterface.h"
55 #include "pinoxmcommon.h"
56 #include "certhelpers.h"
57 #include "cacommon.h"
58 #include "secureresourcemanager.h"
59 #include "deviceonboardingstate.h"
60
61 #ifdef __unix__
62 #include <sys/types.h>
63 #include <sys/stat.h>
64 #include <fcntl.h>
65 #include <unistd.h>
66 #endif
67
68 #if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
69 #include <mbedtls/ssl_ciphersuites.h>
70 #include <mbedtls/pk.h>
71 #include <mbedtls/base64.h>
72 #include <mbedtls/pem.h>
73 #endif
74
75 #define TAG  "OIC_SRM_CREDL"
76
77 #ifdef HAVE_WINDOWS_H
78 #include <wincrypt.h>
79 #include <intsafe.h>
80 #endif
81
82 /** Max credential types number used for TLS */
83 #define MAX_TYPE 2
84 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
85  * The value of payload size is increased until reaching belox max cbor size. */
86 static const uint16_t CBOR_SIZE = 2048;
87
88 /** CRED size - Number of mandatory items. */
89 static const uint8_t CRED_ROOT_MAP_SIZE = 4;
90 static const uint8_t CRED_MAP_SIZE = 3;
91 static const uint8_t ROLEID_MAP_SIZE = 1;
92
93
94 static OicSecCred_t        *gCred = NULL;
95 static OCResourceHandle    gCredHandle = NULL;
96 static OicUuid_t           gRownerId = { .id = { 0 } };
97
98 typedef enum CredCompareResult{
99     CRED_CMP_EQUAL = 0,
100     CRED_CMP_NOT_EQUAL = 1,
101     CRED_CMP_ERROR = 2
102 }CredCompareResult_t;
103
104 typedef struct CredIdList CredIdList_t;
105
106 struct CredIdList
107 {
108     uint16_t credId;
109     CredIdList_t *next;
110 };
111
112 static void DeleteCredIdList(CredIdList_t** list)
113 {
114     if (list)
115     {
116         CredIdList_t *head = *list;
117
118         while (head)
119         {
120             CredIdList_t *tmp = head->next;
121             OICFree(head);
122             head = tmp;
123         }
124     }
125 }
126
127 /**
128  * Internal function to check a subject of SIGNED_ASYMMETRIC_KEY(Certificate).
129  * If that subject is NULL or wildcard, set it to own deviceID.
130  * @param cred credential on SVR DB file
131  * @param deviceID own deviceuuid of doxm resource
132  *
133  * @return
134  *     true successfully done
135  *     false Invalid cred
136  */
137
138 static bool CheckSubjectOfCertificate(OicSecCred_t* cred, OicUuid_t deviceID)
139 {
140     OIC_LOG(DEBUG, TAG, "IN CheckSubjectOfCertificate");
141     VERIFY_NOT_NULL(TAG, cred, ERROR);
142
143 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
144     const OicUuid_t emptyUuid = { .id = { 0 } };
145
146     if ( SIGNED_ASYMMETRIC_KEY == cred->credType)
147     {
148         if((0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(cred->subject.id))) ||
149             (0 == memcmp(cred->subject.id, &WILDCARD_SUBJECT_ID, sizeof(cred->subject.id))))
150         {
151             memcpy(cred->subject.id, deviceID.id, sizeof(deviceID.id));
152         }
153     }
154 #else
155     OC_UNUSED(deviceID);
156 #endif
157
158     OIC_LOG(DEBUG, TAG, "OUT CheckSubjectOfCertificate");
159     return true;
160 exit:
161     OIC_LOG(ERROR, TAG, "OUT CheckSubjectOfCertificate");
162     return false;
163 }
164
165 /**
166  * Internal function to check credential
167  */
168 static bool IsValidCredential(const OicSecCred_t* cred)
169 {
170     OicUuid_t emptyUuid = {.id={0}};
171
172
173     OIC_LOG(DEBUG, TAG, "IN IsValidCredential");
174
175     VERIFY_NOT_NULL(TAG, cred, ERROR);
176     VERIFY_SUCCESS(TAG, 0 != cred->credId, ERROR);
177     OIC_LOG_V(DEBUG, TAG, "Cred ID = %d", cred->credId);
178
179 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
180     OIC_LOG_V(DEBUG, TAG, "Cred Type = %d", cred->credType);
181
182     switch(cred->credType)
183     {
184         case SYMMETRIC_PAIR_WISE_KEY:
185         case SYMMETRIC_GROUP_KEY:
186         case PIN_PASSWORD:
187         {
188             VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
189             VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
190             VERIFY_SUCCESS(TAG, \
191                            (OIC_ENCODING_RAW == cred->privateData.encoding || \
192                            OIC_ENCODING_BASE64 == cred->privateData.encoding), \
193                            ERROR);
194             break;
195         }
196         case ASYMMETRIC_KEY:
197         {
198             VERIFY_NOT_NULL(TAG, cred->publicData.data, ERROR);
199             VERIFY_SUCCESS(TAG, 0 != cred->publicData.len, ERROR);
200             VERIFY_SUCCESS(TAG, \
201                            (OIC_ENCODING_UNKNOW < cred->publicData.encoding && \
202                             OIC_ENCODING_DER >= cred->publicData.encoding),
203                            ERROR);
204             break;
205         }
206         case SIGNED_ASYMMETRIC_KEY:
207         {
208             VERIFY_SUCCESS(TAG, (NULL != cred->publicData.data ||NULL != cred->optionalData.data) , ERROR);
209             VERIFY_SUCCESS(TAG, (0 != cred->publicData.len || 0 != cred->optionalData.len), ERROR);
210
211             if(NULL != cred->optionalData.data)
212             {
213                 VERIFY_SUCCESS(TAG, \
214                                (OIC_ENCODING_UNKNOW < cred->optionalData.encoding && \
215                                 OIC_ENCODING_DER >= cred->optionalData.encoding),
216                                ERROR);
217             }
218             break;
219         }
220         case ASYMMETRIC_ENCRYPTION_KEY:
221         {
222             VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
223             VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
224             VERIFY_SUCCESS(TAG, \
225                            (OIC_ENCODING_UNKNOW < cred->privateData.encoding && \
226                             OIC_ENCODING_DER >= cred->privateData.encoding),
227                            ERROR);
228             break;
229         }
230         default:
231         {
232             OIC_LOG(WARNING, TAG, "Unknown credential type");
233             return false;
234         }
235     }
236 #endif
237
238     VERIFY_SUCCESS(TAG, 0 != memcmp(emptyUuid.id, cred->subject.id, sizeof(cred->subject.id)), ERROR);
239
240     OIC_LOG(DEBUG, TAG, "OUT IsValidCredential");
241     return true;
242 exit:
243     OIC_LOG(WARNING, TAG, "OUT IsValidCredential : Invalid Credential detected.");
244     return false;
245 }
246
247 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
248 static bool IsEmptyCred(const OicSecCred_t* cred)
249 {
250     OicUuid_t emptyUuid = {.id={0}};
251
252     VERIFY_SUCCESS(TAG, (0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(emptyUuid))), ERROR);
253     VERIFY_SUCCESS(TAG, !IsNonEmptyRole(&cred->roleId), ERROR);
254     VERIFY_SUCCESS(TAG, (0 == cred->credId), ERROR);
255     VERIFY_SUCCESS(TAG, (0 == cred->credType), ERROR);
256     VERIFY_SUCCESS(TAG, (NULL == cred->privateData.data), ERROR);
257     VERIFY_SUCCESS(TAG, (NULL == cred->publicData.data), ERROR);
258     VERIFY_SUCCESS(TAG, (NULL == cred->optionalData.data), ERROR);
259     VERIFY_SUCCESS(TAG, (NULL == cred->credUsage), ERROR);
260     return true;
261 exit:
262     return false;
263 }
264 #endif // __WITH_DTLS__ or __WITH_TLS__
265
266 /**
267  * This function frees OicSecCred_t object's fields and object itself.
268  */
269 void FreeCred(OicSecCred_t *cred)
270 {
271     if(NULL == cred)
272     {
273         OIC_LOG(ERROR, TAG, "Invalid Parameter");
274         return;
275     }
276     //Note: Need further clarification on roleID data type
277 #if 0
278     //Clean roleIds
279     OICFree(cred->roleIds);
280 #endif
281
282     //Clean PublicData/OptionalData/Credusage
283 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
284      // TODO: Need to check credUsage.
285     OICFree(cred->publicData.data);
286     OICFree(cred->optionalData.data);
287     OICFree(cred->credUsage);
288
289 #endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
290
291     //Clean PrivateData
292     OICClearMemory(cred->privateData.data, cred->privateData.len);
293     OICFree(cred->privateData.data);
294
295     //Clean Period
296     OICFree(cred->period);
297
298 #ifdef MULTIPLE_OWNER
299     //Clean eowner
300     OICFree(cred->eownerID);
301 #endif
302
303     cred->next = NULL;
304
305     //Clean Cred node itself
306     OICFree(cred);
307 }
308
309 void DeleteCredList(OicSecCred_t* cred)
310 {
311     if (cred)
312     {
313         OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
314         LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
315         {
316             LL_DELETE(cred, credTmp1);
317             FreeCred(credTmp1);
318         }
319     }
320 }
321
322 size_t GetCredKeyDataSize(const OicSecCred_t* cred)
323 {
324     size_t size = 0;
325     if (cred)
326     {
327         OicSecCred_t *credPtr = NULL, *credTmp = NULL;
328         LL_FOREACH_SAFE((OicSecCred_t*)cred, credPtr, credTmp)
329         {
330             if (credPtr->privateData.data && 0 < credPtr->privateData.len)
331             {
332                 size += credPtr->privateData.len;
333             }
334 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
335             if (credPtr->publicData.data && 0 < credPtr->publicData.len)
336             {
337                 size += credPtr->publicData.len;
338             }
339             if (credPtr->optionalData.data && 0 < credPtr->optionalData.len)
340             {
341                 size += credPtr->optionalData.len;
342             }
343 #endif
344         }
345     }
346     OIC_LOG_V(DEBUG, TAG, "Cred Key Data Size : %u", (unsigned int) size);
347     return size;
348 }
349
350 static size_t OicSecCredCount(const OicSecCred_t *secCred)
351 {
352     size_t size = 0;
353     for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
354     {
355         size++;
356     }
357     return size;
358 }
359
360 static const char* EncodingValueToString(OicEncodingType_t encoding)
361 {
362     switch (encoding)
363     {
364         case OIC_ENCODING_RAW:    return OIC_SEC_ENCODING_RAW;
365         case OIC_ENCODING_BASE64: return OIC_SEC_ENCODING_BASE64;
366         case OIC_ENCODING_DER:    return OIC_SEC_ENCODING_DER;
367         case OIC_ENCODING_PEM:    return OIC_SEC_ENCODING_PEM;
368         default:                  return NULL;
369     }
370 }
371
372 static CborError SerializeEncodingToCborInternal(CborEncoder *map, const OicSecKey_t *value)
373 {
374     CborError cborEncoderResult = CborNoError;
375     const char *encoding = EncodingValueToString(value->encoding);
376     if (encoding)
377     {
378         cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_ENCODING_NAME,
379             strlen(OIC_JSON_ENCODING_NAME));
380         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Encoding Tag.");
381         cborEncoderResult = cbor_encode_text_string(map, encoding,
382             strlen(encoding));
383         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Encoding Value.");
384
385         cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_DATA_NAME,
386             strlen(OIC_JSON_DATA_NAME));
387         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Name Tag.");
388         if (OIC_ENCODING_DER == value->encoding ||
389             OIC_ENCODING_RAW == value->encoding)
390         {
391             cborEncoderResult = cbor_encode_byte_string(map,
392                     value->data, value->len);
393         }
394         else
395         {
396             cborEncoderResult = cbor_encode_text_string(map,
397                     (char*)value->data, value->len);
398         }
399         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Name Value.");
400     }
401     else
402     {
403         OIC_LOG_V(ERROR, TAG, "%s: Unknown encoding type: %u.", __func__, value->encoding);
404         return CborErrorUnknownType;
405     }
406     exit:
407     return cborEncoderResult;
408 }
409
410 CborError SerializeEncodingToCbor(CborEncoder *rootMap, const char* tag, const OicSecKey_t *value)
411 {
412     CborError cborEncoderResult = CborNoError;
413     CborEncoder map;
414     const size_t mapSize = 2;
415
416     cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
417     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
418
419     cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
420     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Map");
421
422     cborEncoderResult = SerializeEncodingToCborInternal(&map, value);
423     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding OicSecKey_t structure");
424
425     cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
426     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing Map.");
427
428     exit:
429     return cborEncoderResult;
430 }
431
432 CborError SerializeSecOptToCbor(CborEncoder *rootMap, const char* tag, const OicSecOpt_t *value)
433 {
434     CborError cborEncoderResult = CborNoError;
435     CborEncoder map;
436     const size_t mapSize = 3;
437
438     cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
439     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
440
441     cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
442     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Map");
443
444     OicSecKey_t in;
445     in.data = value->data;
446     in.encoding = value->encoding;
447     in.len = value->len;
448
449     cborEncoderResult = SerializeEncodingToCborInternal(&map, &in);
450     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding OicSecKey_t structure");
451
452     cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_REVOCATION_STATUS_NAME,
453         strlen(OIC_JSON_REVOCATION_STATUS_NAME));
454     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding optional revstat Tag.");
455     cborEncoderResult = cbor_encode_boolean(&map, value->revstat);
456     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding optional revstat Value.");
457
458     cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
459     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing Map.");
460
461     exit:
462     return cborEncoderResult;
463 }
464
465 static CborError DeserializeEncodingFromCborInternal(CborValue *map, char *name, OicSecKey_t *value)
466 {
467     size_t len = 0;
468     CborError cborFindResult = CborNoError;
469
470     // data -- Mandatory
471     if (strcmp(name, OIC_JSON_DATA_NAME) == 0)
472     {
473         if(cbor_value_is_byte_string(map))
474         {
475             cborFindResult = cbor_value_dup_byte_string(map, &value->data,
476                 &value->len, NULL);
477         }
478         else if(cbor_value_is_text_string(map))
479         {
480             cborFindResult = cbor_value_dup_text_string(map, (char**)(&value->data),
481                 &value->len, NULL);
482         }
483         else
484         {
485             cborFindResult = CborErrorUnknownType;
486             OIC_LOG(ERROR, TAG, "Unknown type for private data.");
487         }
488         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding PrivateData.");
489     }
490
491     // encoding -- Mandatory
492     if (strcmp(name, OIC_JSON_ENCODING_NAME) == 0)
493     {
494         char* strEncoding = NULL;
495         cborFindResult = cbor_value_dup_text_string(map, &strEncoding, &len, NULL);
496         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding EncodingType");
497
498         if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
499         {
500             value->encoding = OIC_ENCODING_RAW;
501         }
502         else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
503         {
504             value->encoding = OIC_ENCODING_BASE64;
505         }
506         else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
507         {
508             value->encoding = OIC_ENCODING_DER;
509         }
510         else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
511         {
512             value->encoding = OIC_ENCODING_PEM;
513         }
514         else
515         {
516             //For unit test
517             value->encoding = OIC_ENCODING_RAW;
518             OIC_LOG_V(WARNING, TAG, "%s: Unknown encoding type detected.", __func__);
519         }
520         //Because cbor using malloc directly, it is required to use free() instead of OICFree
521         free(strEncoding);
522     }
523     exit:
524     return cborFindResult;
525 }
526
527 CborError DeserializeEncodingFromCbor(CborValue *rootMap, OicSecKey_t *value)
528 {
529     CborValue map = { .parser = NULL };
530     CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
531     size_t len = 0;
532
533     while (cbor_value_is_valid(&map))
534     {
535         char* name = NULL;
536         CborType type = cbor_value_get_type(&map);
537         if (type == CborTextStringType && cbor_value_is_text_string(&map))
538         {
539             cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
540             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to get text");
541             cborFindResult = cbor_value_advance(&map);
542             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to advance value");
543         }
544         if (name)
545         {
546             cborFindResult = DeserializeEncodingFromCborInternal(&map, name, value);
547             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to read OicSecKey_t value");
548         }
549         if (cbor_value_is_valid(&map))
550         {
551             cborFindResult = cbor_value_advance(&map);
552             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Advancing Map.");
553         }
554         //Because cbor using malloc directly, it is required to use free() instead of OICFree
555         free(name);
556     }
557     exit:
558     return cborFindResult;
559 }
560
561 CborError DeserializeSecOptFromCbor(CborValue *rootMap, OicSecOpt_t *value)
562 {
563     CborValue map = { .parser = NULL };
564     CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
565     size_t len = 0;
566     value->revstat = false;
567
568     while (cbor_value_is_valid(&map))
569     {
570         char* name = NULL;
571         CborType type = cbor_value_get_type(&map);
572         if (type == CborTextStringType && cbor_value_is_text_string(&map))
573         {
574             cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
575             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to get text");
576             cborFindResult = cbor_value_advance(&map);
577             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to advance value");
578         }
579         if (name)
580         {
581             // OptionalData::revstat -- Mandatory
582             if (strcmp(name, OIC_JSON_REVOCATION_STATUS_NAME) == 0)
583             {
584                 cborFindResult = cbor_value_get_boolean(&map, &value->revstat);
585                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding revstat Value.")
586             }
587             OicSecKey_t out;
588             cborFindResult = DeserializeEncodingFromCborInternal(&map, name, &out);
589             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to read OicSecKey_t value");
590
591             value->data = out.data;
592             value->encoding = out.encoding;
593             value->len = out.len;
594         }
595         if (cbor_value_is_valid(&map))
596         {
597             cborFindResult = cbor_value_advance(&map);
598             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Advancing Map.");
599         }
600         //Because cbor using malloc directly, it is required to use free() instead of OICFree
601         free(name);
602     }
603     exit:
604     return cborFindResult;
605 }
606
607 /* Produce debugging output for all credentials, output metadata. */
608 static void logCredMetadata()
609 {
610 #if defined(TB_LOG)
611     OicSecCred_t * temp = NULL;
612     size_t count = 0;
613     char uuidString[UUID_STRING_SIZE];
614     OicUuid_t ownUuid;
615
616     OIC_LOG_V(DEBUG, TAG, "IN %s:", __func__);
617
618     if (GetDoxmDeviceID(&ownUuid) == OC_STACK_OK && OCConvertUuidToString(ownUuid.id, uuidString))
619     {
620         OIC_LOG_V(DEBUG, TAG, "Own UUID: %s", uuidString);
621     }
622
623     LL_FOREACH(gCred, temp)
624     {
625         count++;
626         OIC_LOG(DEBUG, TAG, " ");
627         OIC_LOG_V(DEBUG, TAG, "Cred ID: %d", temp->credId);
628         if (OCConvertUuidToString(temp->subject.id, uuidString))
629         {
630             OIC_LOG_V(DEBUG, TAG, "Subject UUID: %s", uuidString);
631         }
632         if (IsNonEmptyRole(&temp->roleId))
633         {
634             OIC_LOG_V(DEBUG, TAG, "Role ID: %s", temp->roleId.id);
635             OIC_LOG_V(DEBUG, TAG, "Role authority: %s", temp->roleId.authority);
636         }
637         OIC_LOG_V(DEBUG, TAG, "Cred Type: %d", temp->credType);
638         OIC_LOG_V(DEBUG, TAG, "privateData length: %" PRIuPTR ", encoding: %d", temp->privateData.len, temp->privateData.encoding);
639
640 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
641         OIC_LOG_V(DEBUG, TAG, "publicData length: %" PRIuPTR ", encoding: %d", temp->publicData.len, temp->publicData.encoding);
642         if (temp->credUsage)
643         {
644             OIC_LOG_V(DEBUG, TAG, "credUsage: %s", temp->credUsage);
645         }
646
647         OIC_LOG_V(DEBUG, TAG, "optionalData length: %" PRIuPTR", encoding: %d" PRIuPTR, temp->optionalData.len, temp->optionalData.encoding);
648 #endif
649
650     }
651
652     OIC_LOG_V(DEBUG, TAG, "Found %" PRIuPTR " credentials.", count);
653
654     OIC_LOG_V(DEBUG, TAG, "OUT %s:", __func__);
655 #endif
656 }
657
658 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
659                                 size_t *cborSize, int secureFlag)
660 {
661     OIC_LOG_V(DEBUG, TAG, "IN %s:", __func__);
662     if (NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
663     {
664         return OC_STACK_INVALID_PARAM;
665     }
666
667     OCStackResult ret = OC_STACK_ERROR;
668
669     CborError cborEncoderResult = CborNoError;
670     uint8_t *outPayload = NULL;
671     size_t cborLen = *cborSize;
672     *cborSize = 0;
673     *cborPayload = NULL;
674     const OicSecCred_t *cred = credS;
675     CborEncoder encoder;
676     CborEncoder credArray;
677     CborEncoder credRootMap;
678     CborEncoder roleIdMap;
679
680     if (0 == cborLen)
681     {
682         cborLen = CBOR_SIZE;
683     }
684
685     outPayload = (uint8_t *)OICCalloc(1, cborLen);
686     VERIFY_NOT_NULL_RETURN(TAG, outPayload, ERROR, OC_STACK_ERROR);
687
688     cbor_encoder_init(&encoder, outPayload, cborLen, 0);
689
690     size_t credRootMapSize = CRED_ROOT_MAP_SIZE;
691
692     // Create CRED Root Map (creds, rownerid)
693     cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, credRootMapSize);
694     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
695
696     // creds
697     cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
698         strlen(OIC_JSON_CREDS_NAME));
699     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
700
701     // creds array
702     cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
703     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Array.");
704
705     while (cred)
706     {
707         CborEncoder credMap;
708         size_t mapSize = CRED_MAP_SIZE;
709         size_t inLen = 0;
710         if (cred->period)
711         {
712             mapSize++;
713         }
714
715 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
716 #ifdef MULTIPLE_OWNER
717         if(cred->eownerID)
718         {
719             mapSize++;
720         }
721 #endif //MULTIPLE_OWNER
722
723         if ((SIGNED_ASYMMETRIC_KEY == cred->credType || ASYMMETRIC_KEY == cred->credType)
724             && cred->publicData.data)
725         {
726             mapSize++;
727         }
728         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
729         {
730             mapSize++;
731         }
732         if (cred->credUsage)
733         {
734             mapSize++;
735         }
736         if (IsNonEmptyRole(&cred->roleId))
737         {
738             mapSize++;
739         }
740 #endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
741         if (!secureFlag && cred->privateData.data)
742         {
743             mapSize++;
744         }
745         cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
746         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Map");
747
748         //CredID -- Mandatory
749         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
750             strlen(OIC_JSON_CREDID_NAME));
751         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
752         cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
753         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
754
755         //Subject -- Mandatory
756         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
757             strlen(OIC_JSON_SUBJECTID_NAME));
758         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
759         inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
760             WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
761         if(inLen == WILDCARD_SUBJECT_ID_LEN)
762         {
763             cborEncoderResult = cbor_encode_text_string(&credMap, WILDCARD_RESOURCE_URI,
764                 strlen(WILDCARD_RESOURCE_URI));
765             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
766         }
767         else
768         {
769             char *subject = NULL;
770             ret = ConvertUuidToStr(&cred->subject, &subject);
771             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
772             cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
773             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
774             OICFree(subject);
775         }
776
777         //Role ID -- optional
778         if (IsNonEmptyRole(&cred->roleId))
779         {
780             cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_ROLEID_NAME,
781                 strlen(OIC_JSON_ROLEID_NAME));
782             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding role ID map tag");
783
784             bool includeAuthority = (0 != memcmp(&cred->roleId.authority, &EMPTY_ROLE.authority, sizeof(EMPTY_ROLE.authority)));
785
786             cborEncoderResult = cbor_encoder_create_map(&credMap, &roleIdMap, ROLEID_MAP_SIZE + (includeAuthority ? 1 : 0));
787             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding role ID map");
788
789             cborEncoderResult = cbor_encode_text_string(&roleIdMap, OIC_JSON_ROLE_NAME, strlen(OIC_JSON_ROLE_NAME));
790             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding role tag");
791
792             cborEncoderResult = cbor_encode_text_string(&roleIdMap, cred->roleId.id, strlen(cred->roleId.id));
793             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding role value");
794
795             if (includeAuthority)
796             {
797                 cborEncoderResult = cbor_encode_text_string(&roleIdMap, OIC_JSON_AUTHORITY_NAME, strlen(OIC_JSON_AUTHORITY_NAME));
798                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding authority tag");
799
800                 cborEncoderResult = cbor_encode_text_string(&roleIdMap, cred->roleId.authority, strlen(cred->roleId.authority));
801                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed adding authority value");
802             }
803
804             cborEncoderResult = cbor_encoder_close_container(&credMap, &roleIdMap);
805             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed closing role ID map");
806         }
807
808         //CredType -- Mandatory
809         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
810             strlen(OIC_JSON_CREDTYPE_NAME));
811         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
812         cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
813         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
814
815 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
816         //PublicData -- Not Mandatory
817         if ((SIGNED_ASYMMETRIC_KEY == cred->credType || ASYMMETRIC_KEY == cred->credType)
818             && cred->publicData.data)
819         {
820             cborEncoderResult = SerializeEncodingToCbor(&credMap,
821                                          OIC_JSON_PUBLICDATA_NAME, &cred->publicData);
822             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
823         }
824         //OptionalData -- Not Mandatory
825         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
826         {
827             cborEncoderResult = SerializeSecOptToCbor(&credMap,
828                                          OIC_JSON_OPTDATA_NAME, &cred->optionalData);
829             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
830         }
831         //CredUsage -- Not Mandatory
832         if(cred->credUsage)
833         {
834             cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
835                 strlen(OIC_JSON_CREDUSAGE_NAME));
836             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
837             cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
838                 strlen(cred->credUsage));
839             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
840         }
841 #endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
842         //PrivateData -- Not Mandatory
843         if(!secureFlag && cred->privateData.data)
844         {
845             cborEncoderResult = SerializeEncodingToCbor(&credMap,
846                                          OIC_JSON_PRIVATEDATA_NAME, &cred->privateData);
847             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
848         }
849
850         //Period -- Not Mandatory
851         if(cred->period)
852         {
853             cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
854                 strlen(OIC_JSON_PERIOD_NAME));
855             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
856             cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
857                 strlen(cred->period));
858             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
859         }
860
861 #ifdef MULTIPLE_OWNER
862         // Eownerid -- Not Mandatory
863         if(cred->eownerID)
864         {
865             char *eowner = NULL;
866             cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_EOWNERID_NAME,
867                 strlen(OIC_JSON_EOWNERID_NAME));
868             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag.");
869             ret = ConvertUuidToStr(cred->eownerID, &eowner);
870             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
871             cborEncoderResult = cbor_encode_text_string(&credMap, eowner, strlen(eowner));
872             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
873             OICFree(eowner);
874         }
875 #endif //MULTIPLE_OWNER
876
877         cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
878         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing Cred Map.");
879
880         cred = cred->next;
881     }
882     cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
883     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing Cred Array.");
884
885     cred = credS;
886
887     // Rownerid
888     {
889         char *rowner = NULL;
890         cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
891             strlen(OIC_JSON_ROWNERID_NAME));
892         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
893         ret = ConvertUuidToStr(&gRownerId, &rowner);
894         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
895         cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
896         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
897         OICFree(rowner);
898     }
899
900     {
901         //RT -- Mandatory
902         CborEncoder rtArray;
903         cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
904                 strlen(OIC_JSON_RT_NAME));
905         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
906         cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
907         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding RT Value.");
908         for (size_t i = 0; i < 1; i++)
909         {
910             cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
911                     strlen(OIC_RSRC_TYPE_SEC_CRED));
912             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding RT Value.");
913         }
914         cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
915         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing RT.");
916
917         //IF-- Mandatory
918         CborEncoder ifArray;
919         cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
920                  strlen(OIC_JSON_IF_NAME));
921         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
922         cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
923         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Addding IF Value.");
924         for (size_t i = 0; i < 1; i++)
925         {
926             cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
927                     strlen(OC_RSRVD_INTERFACE_DEFAULT));
928             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding IF Value.");
929         }
930         cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
931         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing IF.");
932     }
933
934     // Close CRED Root Map
935     cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
936     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
937
938     if (CborNoError == cborEncoderResult)
939     {
940         OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
941         *cborPayload = outPayload;
942         *cborSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
943         ret = OC_STACK_OK;
944     }
945     OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
946 exit:
947     if (CborErrorOutOfMemory == cborEncoderResult)
948     {
949         OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
950         // reallocate and try again!
951         OICFree(outPayload);
952         // Since the allocated initial memory failed, double the memory.
953         cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
954         cborEncoderResult = CborNoError;
955         ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
956         *cborSize = cborLen;
957     }
958
959     if (CborNoError != cborEncoderResult)
960     {
961         OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
962         OICFree(outPayload);
963         outPayload = NULL;
964         *cborSize = 0;
965         *cborPayload = NULL;
966         ret = OC_STACK_ERROR;
967     }
968
969     OIC_LOG_V(DEBUG, TAG, "OUT %s:", __func__);
970
971     return ret;
972 }
973
974 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
975                                 OicSecCred_t **secCred, OicUuid_t **rownerid)
976 {
977     if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
978     {
979         return OC_STACK_INVALID_PARAM;
980     }
981
982     char* tagName = NULL;
983     char* roleIdTagName = NULL;
984     char* name = NULL;
985     OCStackResult ret = OC_STACK_ERROR;
986     CborValue credCbor = { .parser = NULL };
987     CborParser parser = { .end = NULL };
988     CborError cborFindResult = CborNoError;
989     cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
990
991     if (!cbor_value_is_container(&credCbor))
992     {
993         return OC_STACK_ERROR;
994     }
995
996     OicSecCred_t *headCred = NULL;
997
998     // Enter CRED Root Map
999     CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
1000     cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
1001     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Entering CRED Root Map.");
1002
1003     headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
1004     VERIFY_NOT_NULL(TAG, headCred, ERROR);
1005
1006     while (cbor_value_is_valid(&CredRootMap))
1007     {
1008         size_t len = 0;
1009         CborType type = cbor_value_get_type(&CredRootMap);
1010         if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
1011         {
1012             cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
1013             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
1014             cborFindResult = cbor_value_advance(&CredRootMap);
1015             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
1016         }
1017         if(tagName)
1018         {
1019             if (strcmp(tagName, OIC_JSON_CREDS_NAME)  == 0)
1020             {
1021                 // Enter CREDS Array
1022                 size_t tempLen = 0;
1023                 int credCount = 0;
1024                 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
1025                 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
1026                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding Cred Array.");
1027
1028                 while (cbor_value_is_valid(&credArray))
1029                 {
1030                     credCount++;
1031                     //CredId -- Mandatory
1032                     CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
1033                     cborFindResult = cbor_value_enter_container(&credArray, &credMap);
1034                     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding Cred Map.");
1035                     OicSecCred_t *cred = NULL;
1036
1037                     if(1 == credCount)
1038                     {
1039                         cred = headCred;
1040                     }
1041                     else
1042                     {
1043                         cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
1044                         VERIFY_NOT_NULL(TAG, cred, ERROR);
1045                         OicSecCred_t *temp = headCred;
1046                         while (temp->next)
1047                         {
1048                             temp = temp->next;
1049                         }
1050                         temp->next = cred;
1051                     }
1052
1053                     while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
1054                     {
1055                         CborType cmType = cbor_value_get_type(&credMap);
1056                         if (cmType == CborTextStringType)
1057                         {
1058                             cborFindResult = cbor_value_dup_text_string(&credMap, &name, &tempLen, NULL);
1059                             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
1060                             cborFindResult = cbor_value_advance(&credMap);
1061                             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
1062                         }
1063                         if(name)
1064                         {
1065                             //credid
1066                             if (strcmp(name, OIC_JSON_CREDID_NAME)  == 0)
1067                             {
1068                                 uint64_t credId = 0;
1069                                 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
1070                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding CredId.");
1071                                 cred->credId = (uint16_t)credId;
1072                             }
1073                             // subjectid
1074                             if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
1075                             {
1076                                 char *subjectid = NULL;
1077                                 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &tempLen, NULL);
1078                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding subjectid Value.");
1079                                 if(strcmp(subjectid, WILDCARD_RESOURCE_URI) == 0)
1080                                 {
1081                                     cred->subject.id[0] = '*';
1082                                 }
1083                                 else
1084                                 {
1085                                     ret = ConvertStrToUuid(subjectid, &cred->subject);
1086                                     VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
1087                                 }
1088                                 //Because cbor using malloc directly
1089                                 //It is required to use free() instead of OICFree
1090                                 free(subjectid);
1091                             }
1092                             // roleid
1093                             if (strcmp(name, OIC_JSON_ROLEID_NAME) == 0)
1094                             {
1095                                 /* Role subject */
1096                                 size_t unusedLen = 0;
1097                                 CborValue roleIdMap;
1098                                 memset(&roleIdMap, 0, sizeof(roleIdMap));
1099
1100                                 cborFindResult = cbor_value_enter_container(&credMap, &roleIdMap);
1101                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed entering role ID map");
1102
1103                                 while (cbor_value_is_valid(&roleIdMap) && cbor_value_is_text_string(&roleIdMap))
1104                                 {
1105                                     cborFindResult = cbor_value_dup_text_string(&roleIdMap, &roleIdTagName, &unusedLen, NULL);
1106                                     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed getting role ID map tag name");
1107                                     cborFindResult = cbor_value_advance(&roleIdMap);
1108                                     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed advancing role ID map");
1109
1110                                     if (NULL != roleIdTagName)
1111                                     {
1112                                         if (strcmp(roleIdTagName, OIC_JSON_ROLE_NAME) == 0)
1113                                         {
1114                                             char *roleId = NULL;
1115                                             cborFindResult = cbor_value_dup_text_string(&roleIdMap, &roleId, &unusedLen, NULL);
1116                                             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed getting role id value");
1117                                             if (strlen(roleId) >= sizeof(cred->roleId.id))
1118                                             {
1119                                                 cborFindResult = CborUnknownError;
1120                                                 free(roleId);
1121                                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Role ID is too long");
1122                                             }
1123                                             OICStrcpy(cred->roleId.id, sizeof(cred->roleId.id), roleId);
1124                                             free(roleId);
1125                                         }
1126                                         else if (strcmp(roleIdTagName, OIC_JSON_AUTHORITY_NAME) == 0)
1127                                         {
1128                                             char *authorityName = NULL;
1129                                             cborFindResult = cbor_value_dup_text_string(&roleIdMap, &authorityName, &unusedLen, NULL);
1130                                             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed getting role authority value");
1131                                             if (strlen(authorityName) >= sizeof(cred->roleId.authority))
1132                                             {
1133                                                 cborFindResult = CborUnknownError;
1134                                                 free(authorityName);
1135                                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Authority name is too long");
1136                                             }
1137                                             OICStrcpy(cred->roleId.authority, sizeof(cred->roleId.authority), authorityName);
1138                                             free(authorityName);
1139                                         }
1140                                         else
1141                                         {
1142                                             OIC_LOG_V(WARNING, TAG, "Unknown tag name in role ID map: %s", roleIdTagName);
1143                                         }
1144
1145                                         free(roleIdTagName);
1146                                         roleIdTagName = NULL;
1147                                     }
1148
1149                                     if (cbor_value_is_valid(&roleIdMap))
1150                                     {
1151                                         cborFindResult = cbor_value_advance(&roleIdMap);
1152                                         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed advancing role map");
1153                                     }
1154                                 }
1155
1156                                 /* Make sure at least the id is present. */
1157                                 if ('\0' == cred->roleId.id[0])
1158                                 {
1159                                     cborFindResult = CborUnknownError;
1160                                     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "ID for role was not present in role map");
1161                                 }
1162                             }
1163                             // credtype
1164                             if (strcmp(name, OIC_JSON_CREDTYPE_NAME)  == 0)
1165                             {
1166                                 uint64_t credType = 0;
1167                                 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
1168                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding CredType.");
1169                                 cred->credType = (OicSecCredType_t)credType;
1170                             }
1171                             // privatedata
1172                             if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME)  == 0)
1173                             {
1174                                 cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->privateData);
1175                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to read privateData structure");
1176                             }
1177 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1178                             //PublicData -- Not Mandatory
1179                             if (strcmp(name, OIC_JSON_PUBLICDATA_NAME)  == 0)
1180                             {
1181                                 cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->publicData);
1182                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to read publicData structure");
1183                             }
1184                             //OptionalData -- Not Mandatory
1185                             if (strcmp(name, OIC_JSON_OPTDATA_NAME)  == 0)
1186                             {
1187                                 cborFindResult = DeserializeSecOptFromCbor(&credMap, &cred->optionalData);
1188                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed to read optionalData structure");
1189                             }
1190                             //Credusage -- Not Mandatory
1191                             if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
1192                             {
1193                                 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &tempLen, NULL);
1194                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding Period.");
1195                             }
1196 #endif  //__WITH_DTLS__ ||  __WITH_TLS__
1197
1198                             if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
1199                             {
1200                                 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &tempLen, NULL);
1201                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding Period.");
1202                             }
1203
1204 #ifdef MULTIPLE_OWNER
1205                             // Eowner uuid -- Not Mandatory
1206                             if (strcmp(OIC_JSON_EOWNERID_NAME, name)  == 0 && cbor_value_is_text_string(&credMap))
1207                             {
1208                                 char *eowner = NULL;
1209                                 cborFindResult = cbor_value_dup_text_string(&credMap, &eowner, &tempLen, NULL);
1210                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding eownerId Value.");
1211                                 if(NULL == cred->eownerID)
1212                                 {
1213                                     cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1214                                     VERIFY_NOT_NULL(TAG, cred->eownerID, ERROR);
1215                                 }
1216                                 ret = ConvertStrToUuid(eowner, cred->eownerID);
1217                                 //Because cbor using malloc directly
1218                                 //It is required to use free() instead of OICFree
1219                                 free(eowner);
1220                                 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
1221                             }
1222 #endif //MULTIPLE_OWNER
1223
1224                             if (cbor_value_is_valid(&credMap))
1225                             {
1226                                 cborFindResult = cbor_value_advance(&credMap);
1227                                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Advancing CRED Map.");
1228                             }
1229                             //Because cbor using malloc directly
1230                             //It is required to use free() instead of OICFree
1231                             free(name);
1232                             name = NULL;
1233                         }
1234                     }
1235                     cred->next = NULL;
1236                     if (cbor_value_is_valid(&credArray))
1237                     {
1238                         cborFindResult = cbor_value_advance(&credArray);
1239                         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Advancing CRED Array.");
1240                     }
1241                 }
1242             }
1243
1244             //ROwner -- Mandatory
1245             if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0 && cbor_value_is_text_string(&CredRootMap))
1246             {
1247                 char *stRowner = NULL;
1248                 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
1249                 VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding Rownerid Value.");
1250                 *rownerid = (OicUuid_t *) OICCalloc(1, sizeof(OicUuid_t));
1251                 VERIFY_NOT_NULL(TAG, *rownerid, ERROR);
1252                 ret = ConvertStrToUuid(stRowner, *rownerid);
1253                 //Because cbor using malloc directly
1254                 //It is required to use free() instead of OICFree
1255                 free(stRowner);
1256                 VERIFY_SUCCESS(TAG, (ret == OC_STACK_OK), ERROR);
1257             }
1258             //Because cbor using malloc directly
1259             //It is required to use free() instead of OICFree
1260             free(tagName);
1261             tagName = NULL;
1262         }
1263         if (cbor_value_is_valid(&CredRootMap))
1264         {
1265             cborFindResult = cbor_value_advance(&CredRootMap);
1266             VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
1267         }
1268     }
1269
1270     *secCred = headCred;
1271     ret = OC_STACK_OK;
1272
1273 exit:
1274     if (CborNoError != cborFindResult)
1275     {
1276         DeleteCredList(headCred);
1277         headCred = NULL;
1278         *secCred = NULL;
1279         ret = OC_STACK_ERROR;
1280     }
1281
1282     free(tagName);
1283     free(roleIdTagName);
1284     free(name);
1285
1286     return ret;
1287 }
1288
1289 #ifdef MULTIPLE_OWNER
1290 bool IsValidCredentialAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, size_t size)
1291 {
1292     OicSecCred_t* cred = NULL;
1293     bool isValidCred = false;
1294     OicUuid_t *rownerId = NULL;
1295
1296     OIC_LOG_BUFFER(DEBUG, TAG, cborPayload, size);
1297
1298     VERIFY_NOT_NULL(TAG, uuid, ERROR);
1299     VERIFY_NOT_NULL(TAG, cborPayload, ERROR);
1300     VERIFY_SUCCESS(TAG, 0 != size, ERROR);
1301     VERIFY_SUCCESS(TAG, OC_STACK_OK == CBORPayloadToCred(cborPayload, size, &cred, &rownerId), ERROR);
1302     VERIFY_NOT_NULL(TAG, cred, ERROR);
1303     VERIFY_NOT_NULL(TAG, cred->eownerID, ERROR);
1304     VERIFY_NOT_NULL(TAG, rownerId, ERROR);
1305     VERIFY_SUCCESS(TAG, (memcmp(cred->eownerID->id, uuid->id, sizeof(uuid->id)) == 0), ERROR);
1306
1307     isValidCred = true;
1308
1309 exit:
1310     OICFree(rownerId);
1311     DeleteCredList(cred);
1312
1313     return isValidCred;
1314
1315 }
1316 #endif //MULTIPLE_OWNER
1317
1318 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
1319                                   const OicSecKey_t * publicData, const OicSecKey_t* privateData,
1320                                   const OicUuid_t * eownerID)
1321 {
1322     OIC_LOG(DEBUG, TAG, "IN GenerateCredential");
1323
1324     (void)publicData;
1325     OCStackResult ret = OC_STACK_ERROR;
1326
1327     OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
1328     VERIFY_NOT_NULL(TAG, cred, ERROR);
1329     cred->next = NULL;
1330
1331     //CredId is assigned before appending new cred to the existing
1332     //credential list and updating svr database in AddCredential().
1333     cred->credId = 0;
1334
1335     VERIFY_NOT_NULL(TAG, subject, ERROR);
1336     memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
1337
1338     VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
1339             SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
1340     cred->credType = credType;
1341
1342 #ifdef __WITH_DTLS__
1343     if (publicData && publicData->data)
1344     {
1345         cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
1346         VERIFY_NOT_NULL(TAG, cred->publicData.data, ERROR);
1347         memcpy(cred->publicData.data, publicData->data, publicData->len);
1348         cred->publicData.len = publicData->len;
1349         cred->publicData.encoding = publicData->encoding;
1350     }
1351 #endif // __WITH_DTLS__
1352
1353     if (privateData && privateData->data)
1354     {
1355         cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
1356         VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
1357         memcpy(cred->privateData.data, privateData->data, privateData->len);
1358         cred->privateData.len = privateData->len;
1359         cred->privateData.encoding = privateData->encoding;
1360     }
1361
1362 #ifdef MULTIPLE_OWNER
1363     if(eownerID)
1364     {
1365         cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1366         VERIFY_NOT_NULL(TAG, cred->eownerID, ERROR);
1367         memcpy(cred->eownerID->id, eownerID->id, sizeof(eownerID->id));
1368     }
1369 #else
1370     (void)(eownerID);
1371 #endif //MULTIPLE_OWNER_
1372
1373     ret = OC_STACK_OK;
1374
1375     OIC_LOG_V(DEBUG, TAG, "GenerateCredential : result: %d", ret);
1376     OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credId: %d", cred->credId);
1377     OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credType: %d", cred->credType);
1378     OIC_LOG_BUFFER(DEBUG, TAG, cred->subject.id, sizeof(cred->subject.id));
1379     if (cred->privateData.data)
1380     {
1381         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : privateData len: %"PRIuPTR, cred->privateData.len);
1382         OIC_LOG_BUFFER(DEBUG, TAG, cred->privateData.data, cred->privateData.len);
1383     }
1384 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1385     if(cred->credUsage)
1386     {
1387         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credUsage: %s", cred->credUsage);
1388     }
1389     if (cred->publicData.data)
1390     {
1391         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : publicData len: %" PRIuPTR, cred->publicData.len);
1392         OIC_LOG_BUFFER(DEBUG, TAG, cred->publicData.data, cred->publicData.len);
1393
1394     }
1395     if (cred->optionalData.data)
1396     {
1397         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData len: %" PRIuPTR, cred->optionalData.len);
1398         OIC_LOG_BUFFER(DEBUG, TAG, cred->optionalData.data, cred->optionalData.len);
1399         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData revstat: %d", cred->optionalData.revstat);
1400     }
1401 #endif //defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1402
1403 exit:
1404     if (OC_STACK_OK != ret)
1405     {
1406         DeleteCredList(cred);
1407         cred = NULL;
1408     }
1409     OIC_LOG(DEBUG, TAG, "OUT GenerateCredential");
1410     return cred;
1411 }
1412
1413 #ifdef HAVE_WINDOWS_H
1414 /* Helper for UpdatePersistentStorage. */
1415 static OCStackResult CopyPayload(uint8_t **payload, size_t *payloadSize, const DATA_BLOB *source)
1416 {
1417     OCStackResult res = OC_STACK_OK;
1418
1419     if (source->cbData > *payloadSize)
1420     {
1421         /* Need more memory to copy encrypted payload out. */
1422         OICClearMemory(*payload, *payloadSize);
1423         OICFree(*payload);
1424         *payload = OICMalloc(source->cbData);
1425
1426         if (NULL == *payload)
1427         {
1428             OIC_LOG_V(ERROR, TAG, "Failed to OICMalloc for encrypted payload: %u", GetLastError());
1429             res = OC_STACK_NO_MEMORY;
1430         }
1431     }
1432     else if (source->cbData < *payloadSize)
1433     {
1434         /* Zero portion of payload we won't overwrite with the encrypted version. The
1435          * later call to OICClearMemory won't cover this part of the buffer.
1436          */
1437         OICClearMemory(*payload + source->cbData, *payloadSize - source->cbData);
1438     }
1439
1440     if (OC_STACK_OK == res)
1441     {
1442         memcpy(*payload, source->pbData, source->cbData);
1443         *payloadSize = source->cbData;
1444     }
1445
1446     return res;
1447 }
1448 #endif
1449
1450 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
1451 {
1452     bool ret = false;
1453     OIC_LOG(DEBUG, TAG, "IN Cred UpdatePersistentStorage");
1454
1455     // Convert Cred data into JSON for update to persistent storage
1456     if (cred)
1457     {
1458         uint8_t *payload = NULL;
1459         // This added '512' is arbitrary value that is added to cover the name of the resource, map addition and ending
1460         size_t size = GetCredKeyDataSize(cred);
1461         size += (512 * OicSecCredCount(cred));
1462         OIC_LOG_V(DEBUG, TAG, "cred size: %zu", size);
1463
1464         int secureFlag = 0;
1465         OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1466 #ifdef HAVE_WINDOWS_H
1467         /* On Windows, keep the credential resource encrypted on disk to protect symmetric and private keys. Only the
1468          * current user on this system will be able to decrypt it later, to help prevent credential theft.
1469          */
1470         DWORD dwordSize;
1471
1472         if (FAILED(SizeTToDWord(size, &dwordSize)))
1473         {
1474             OIC_LOG(DEBUG, TAG, "Cred size too large.");
1475             res = OC_STACK_ERROR;
1476             ret = false;
1477         }
1478
1479         if ((OC_STACK_OK == res) && payload)
1480         {
1481             DATA_BLOB decryptedPayload;
1482             DATA_BLOB encryptedPayload;
1483             memset(&decryptedPayload, 0, sizeof(decryptedPayload));
1484             memset(&encryptedPayload, 0, sizeof(encryptedPayload));
1485             decryptedPayload.cbData = dwordSize;
1486             decryptedPayload.pbData = payload;
1487
1488             if (CryptProtectData(
1489                 &decryptedPayload,
1490                 NULL,
1491                 NULL,
1492                 NULL,
1493                 NULL,
1494                 CRYPTPROTECT_UI_FORBIDDEN,
1495                 &encryptedPayload))
1496             {
1497                 res = CopyPayload(&payload, &size, &encryptedPayload);
1498                 ret = (OC_STACK_OK == res);
1499
1500                 /* For the returned data from CryptProtectData, LocalFree must be used to free. Don't use OICFree. */
1501                 if (NULL != LocalFree(encryptedPayload.pbData))
1502                 {
1503                     OIC_LOG_V(ERROR, TAG, "LocalFree failed on output from CryptProtectData; memory may be corrupted or leaked. Last error: %u.", GetLastError());
1504                     assert(!"LocalFree failed");
1505                 }
1506             }
1507             else
1508             {
1509                 OIC_LOG_V(ERROR, TAG, "Failed to CryptProtectData cred resource: %u", GetLastError());
1510                 res = OC_STACK_ERROR;
1511                 ret = false;
1512             }
1513         }
1514 #endif
1515
1516         if ((OC_STACK_OK == res) && payload)
1517         {
1518             if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
1519             {
1520                 ret = true;
1521             }
1522         }
1523
1524         OICClearMemory(payload, size);
1525         OICFree(payload);
1526     }
1527     else //Empty cred list
1528     {
1529         if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
1530         {
1531             ret = true;
1532         }
1533     }
1534
1535     OIC_LOG(DEBUG, TAG, "OUT Cred UpdatePersistentStorage");
1536
1537     logCredMetadata();
1538
1539     return ret;
1540 }
1541
1542 /**
1543  * Compare function used LL_SORT for sorting credentials.
1544  *
1545  * @param first pointer to OicSecCred_t struct.
1546  * @param second  pointer to OicSecCred_t struct.
1547  *
1548  *@return -1, if credId of first is less than credId of second.
1549  * 0, if credId of first is equal to credId of second.
1550  * 1, if credId of first is greater than credId of second.
1551  */
1552 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
1553 {
1554     if (first->credId < second->credId)
1555     {
1556         return -1;
1557     }
1558     else if (first->credId > second->credId)
1559     {
1560         return 1;
1561     }
1562     else
1563         return 0;
1564 }
1565
1566 /**
1567  * GetCredId goes through the cred list and returns the next
1568  * available credId. The next credId could be the credId that is
1569  * available due deletion of OicSecCred_t object or one more than
1570  * credId of last credential in the list.
1571  *
1572  * @return next available credId if successful, else 0 for error.
1573  */
1574 static uint16_t GetCredId()
1575 {
1576     //Sorts credential list in incremental order of credId
1577     /** @todo: Remove pragma for VS2013 warning; Investigate fixing LL_SORT macro */
1578 #ifdef _MSC_VER
1579 #pragma warning(suppress:4133)
1580     LL_SORT(gCred, CmpCredId);
1581 #else
1582     LL_SORT(gCred, CmpCredId);
1583 #endif
1584
1585     OicSecCred_t *currentCred = NULL, *credTmp = NULL;
1586     uint16_t nextCredId = 1;
1587
1588     LL_FOREACH_SAFE(gCred, currentCred, credTmp)
1589     {
1590         if (currentCred->credId == nextCredId)
1591         {
1592             nextCredId += 1;
1593         }
1594         else
1595         {
1596             break;
1597         }
1598     }
1599
1600     VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
1601     return nextCredId;
1602
1603 exit:
1604     return 0;
1605 }
1606
1607 /**
1608  * Get the default value.
1609  *
1610  * @return  NULL for now.
1611  */
1612 static OicSecCred_t* GetCredDefault()
1613 {
1614     // TODO:Update it when we finalize the default info.
1615     return NULL;
1616 }
1617
1618 bool IsSameSecOpt(const OicSecOpt_t* sk1, const OicSecOpt_t* sk2)
1619 {
1620     VERIFY_NOT_NULL(TAG, sk1, WARNING);
1621     VERIFY_NOT_NULL(TAG, sk2, WARNING);
1622
1623     VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1624     VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1625     VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1626     return true;
1627 exit:
1628     return false;
1629 }
1630
1631 bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
1632 {
1633     VERIFY_NOT_NULL(TAG, sk1, WARNING);
1634     VERIFY_NOT_NULL(TAG, sk2, WARNING);
1635
1636     VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1637     VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1638     VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1639     return true;
1640 exit:
1641     return false;
1642 }
1643
1644 #if ((defined(__WITH_DTLS__) || defined(__WITH_TLS__)) && defined(MULTIPLE_OWNER))
1645 static bool IsNewPreconfigPinCredential(OicSecCred_t * oldCred, OicSecCred_t * newCred)
1646 {
1647     if (oldCred->credUsage &&
1648         newCred->credUsage &&
1649         (0 == strcmp(PRECONFIG_PIN_CRED, oldCred->credUsage)) &&
1650         (0 == strcmp(PRECONFIG_PIN_CRED, newCred->credUsage)))
1651     {
1652         return true;
1653     }
1654
1655     return false;
1656 }
1657 #endif //(__WITH_DTLS__ or __WITH_TLS__) and MULTIPLE_OWNER
1658
1659 OCStackResult AddCredential(OicSecCred_t * newCred)
1660 {
1661     OCStackResult result = OC_STACK_ERROR;
1662
1663     OicSecCred_t* cred = NULL;
1664     OicSecCred_t* tempCred = NULL;
1665
1666     bool found = false;
1667
1668     OicSecDostype_t dos;
1669
1670     VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDos(&dos), ERROR);
1671     if ((DOS_RESET == dos.state) ||
1672         (DOS_RFNOP == dos.state))
1673     {
1674         OIC_LOG_V(WARNING, TAG, "%s /cred resource is read-only in RESET and RFNOP.", __func__);
1675     }
1676
1677     //leave IOT-1936 fix for preconfig pin
1678 #if ((defined(__WITH_DTLS__) || defined(__WITH_TLS__)) && defined(MULTIPLE_OWNER))
1679     LL_FOREACH_SAFE(gCred, cred, tempCred)
1680     {
1681         if (IsNewPreconfigPinCredential(cred, newCred))
1682         {
1683             //devices can only have one Preconfigured Pin credential at any given time. Check
1684             //if the new credential is an update to an existing Preconfigured Pin credential
1685             //if so, just update existing one.
1686
1687             //save old credid so act like an update
1688             newCred->credId = cred->credId;
1689
1690             LL_DELETE(gCred, cred);
1691             LL_PREPEND(gCred, newCred);
1692
1693             FreeCred(cred);
1694             found = true;
1695             break;
1696         }
1697     }
1698 #endif //(__WITH_DTLS__ or __WITH_TLS__) and MULTIPLE_OWNER
1699
1700     if (found)
1701     {
1702         goto saveToDB;
1703     }
1704
1705     if (newCred->credId != 0)
1706     {
1707         //check if cred with such cred id exists
1708         LL_FOREACH_SAFE(gCred, cred, tempCred)
1709         {
1710             if (cred->credId == newCred->credId)
1711             {
1712                 //remove old cred with same cred id
1713                 LL_DELETE(gCred, cred);
1714                 FreeCred(cred);
1715                 break;
1716             }
1717         }
1718     }
1719     else
1720     {
1721         newCred->credId = GetCredId();
1722     }
1723
1724     OIC_LOG(DEBUG, TAG, "Adding New Cred");
1725     LL_APPEND(gCred, newCred);
1726
1727 saveToDB:
1728     if (UpdatePersistentStorage(gCred))
1729     {
1730         result = OC_STACK_OK;
1731     }
1732 exit:
1733     return result;
1734 }
1735
1736 OCStackResult RemoveCredential(const OicUuid_t *subject)
1737 {
1738     OCStackResult ret = OC_STACK_ERROR;
1739     OicSecCred_t *cred = NULL;
1740     OicSecCred_t *tempCred = NULL;
1741     bool deleteFlag = false;
1742
1743     LL_FOREACH_SAFE(gCred, cred, tempCred)
1744     {
1745         if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1746         {
1747             LL_DELETE(gCred, cred);
1748             FreeCred(cred);
1749             deleteFlag = 1;
1750         }
1751     }
1752
1753     if (deleteFlag)
1754     {
1755         if (UpdatePersistentStorage(gCred))
1756         {
1757             ret = OC_STACK_RESOURCE_DELETED;
1758         }
1759     }
1760     return ret;
1761 }
1762
1763 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1764 {
1765     OCStackResult ret = OC_STACK_ERROR;
1766     OicSecCred_t *cred = NULL;
1767     OicSecCred_t *tempCred = NULL;
1768     bool deleteFlag = false;
1769
1770     OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1771
1772     if ( 0 == credId)
1773     {
1774         return OC_STACK_INVALID_PARAM;
1775     }
1776
1777
1778     LL_FOREACH_SAFE(gCred, cred, tempCred)
1779     {
1780         if (cred->credId == credId)
1781         {
1782             OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1783
1784             LL_DELETE(gCred, cred);
1785             FreeCred(cred);
1786             deleteFlag = true;
1787         }
1788     }
1789
1790     if (deleteFlag)
1791     {
1792         if (UpdatePersistentStorage(gCred))
1793         {
1794             ret = OC_STACK_RESOURCE_DELETED;
1795         }
1796     }
1797     OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1798
1799     return ret;
1800 }
1801
1802 /**
1803  * This method removes cred's corresponding to given list of credid's from the Cred
1804  *
1805  * @param credid's of the Cred
1806  *
1807  * @return
1808  *     ::OC_STACK_RESOURCE_DELETED on success
1809  *     ::OC_STACK_NO_RESOURCE on failure to find the appropriate Cred
1810  *     ::OC_STACK_INVALID_PARAM on invalid parameter
1811  */
1812 static OCStackResult RemoveCredentialByCredIds(CredIdList_t *credIdList)
1813 {
1814     OCStackResult ret = OC_STACK_ERROR;
1815     OicSecCred_t *cred = NULL;
1816     OicSecCred_t *tempCred = NULL;
1817     CredIdList_t *credIdElem = NULL;
1818     bool deleteFlag = false;
1819
1820     OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredIds");
1821
1822     LL_FOREACH(credIdList, credIdElem)
1823     {
1824         LL_FOREACH_SAFE(gCred, cred, tempCred)
1825         {
1826             if (cred->credId == credIdElem->credId)
1827             {
1828                 OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", cred->credId);
1829
1830                 LL_DELETE(gCred, cred);
1831                 FreeCred(cred);
1832                 deleteFlag = true;
1833                 //TODO: add break when cred's will have unique credid (during IOT-2464 fix)
1834             }
1835         }
1836     }
1837
1838     if (deleteFlag)
1839     {
1840         if (UpdatePersistentStorage(gCred))
1841         {
1842             ret = OC_STACK_RESOURCE_DELETED;
1843         }
1844     }
1845     OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredIds");
1846
1847     return ret;
1848 }
1849
1850 /**
1851  * This method parses the query string received for REST requests and
1852  * retrieves the 'credid' field.
1853  *
1854  * @param query querystring passed in REST request
1855  * @param credid cred id parsed from query string
1856  *
1857  * @return true if query parsed successfully and found 'credid', else false.
1858  */
1859 static bool GetCredIdsFromQueryString(const char *query, CredIdList_t **credid)
1860 {
1861     bool found = false;
1862     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1863
1864     ParseQueryIterInit((unsigned char *) query, &parseIter);
1865
1866     while (GetNextQuery (&parseIter))
1867     {
1868         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_CREDID_NAME, parseIter.attrLen) == 0)
1869         {
1870             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1871
1872             //parse credid array value in format "1,2,3"
1873             unsigned char *str = parseIter.valPos;
1874
1875             //remember last symbol (may be '\0' or '&')
1876             unsigned char tmp = str[parseIter.valLen];
1877             //set last symbol to '\0' to use strtok_r
1878             str[parseIter.valLen] = '\0';
1879
1880             char *saveptr = NULL;
1881
1882             for (; ; str = NULL)
1883             {
1884                 char *token = strtok_r((char *)str, ",", &saveptr);
1885                 if (NULL == token)
1886                 {
1887                     break;
1888                 }
1889
1890                 CredIdList_t *newCredIdElem = (CredIdList_t *) OICCalloc(1, sizeof(CredIdList_t));
1891                 if (NULL == newCredIdElem)
1892                 {
1893                     OIC_LOG(ERROR, TAG, "Failed to allocate CredIdList_t element");
1894                     break;
1895                 }
1896                 newCredIdElem->credId = (uint16_t)atoi(token);
1897
1898                 LL_PREPEND(*credid, newCredIdElem);
1899                 found = true;
1900             }
1901
1902             //restore last symbol
1903             parseIter.valPos[parseIter.valLen] = tmp;
1904         }
1905     }
1906
1907 exit:
1908     return found;
1909 }
1910
1911 /**
1912  * Remove all credential data on credential resource and persistent storage
1913  *
1914  * @retval
1915  *     OC_STACK_OK              - no errors
1916  *     OC_STACK_ERROR           - stack process error
1917  */
1918 static OCStackResult RemoveAllCredentials()
1919 {
1920     DeleteCredList(gCred);
1921     gCred = GetCredDefault();
1922
1923     if (!UpdatePersistentStorage(gCred))
1924     {
1925         return OC_STACK_ERROR;
1926     }
1927     return OC_STACK_OK;
1928 }
1929
1930 /**
1931  * This method parses the query string received for REST requests and
1932  * retrieves the 'subjectuuid' field.
1933  *
1934  * @param query querystring passed in REST request
1935  * @param subject subject UUID parsed from query string
1936  *
1937  * @return true if query parsed successfully and found 'subject', else false.
1938  */
1939 static bool GetSubjectFromQueryString(const char *query, OicUuid_t *subject)
1940 {
1941     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1942
1943     ParseQueryIterInit((unsigned char *) query, &parseIter);
1944
1945     while (GetNextQuery (&parseIter))
1946     {
1947         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_SUBJECTID_NAME, parseIter.attrLen) == 0)
1948         {
1949             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1950             //temporary set '\0' symbol instead of copy string
1951             char tmp = parseIter.valPos[parseIter.valLen];
1952             parseIter.valPos[parseIter.valLen] = '\0';
1953
1954             OCStackResult res = ConvertStrToUuid((const char*)parseIter.valPos, subject);
1955             parseIter.valPos[parseIter.valLen] = tmp;
1956             VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
1957             return true;
1958         }
1959     }
1960
1961 exit:
1962     return false;
1963 }
1964
1965 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1966 /**
1967  * Internal function to fill private data of owner PSK.
1968  *
1969  * @param receviedCred recevied owner credential from OBT(PT)
1970  * @param ownerAdd address of OBT(PT)
1971  * @param doxm current device's doxm resource
1972  *
1973  * @return
1974  *     true successfully done and valid ower psk information
1975  *     false Invalid owner psk information or failed to owner psk generation
1976  */
1977 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1978                            const OicSecDoxm_t* doxm)
1979 {
1980     //Derive OwnerPSK locally
1981     const char* oxmLabel = GetOxmString(doxm->oxmSel);
1982     char* b64Buf = NULL;
1983     size_t b64BufSize = 0;
1984     VERIFY_NOT_NULL(TAG, oxmLabel, ERROR);
1985
1986     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1987     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1988         (uint8_t*)oxmLabel, strlen(oxmLabel),
1989         doxm->owner.id, sizeof(doxm->owner.id),
1990         doxm->deviceID.id, sizeof(doxm->deviceID.id),
1991         ownerPSK, OWNER_PSK_LENGTH_128);
1992     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1993
1994     OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1995     OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1996
1997     //Generate owner credential based on recevied credential information
1998
1999     // TODO: Added as workaround, will be replaced soon.
2000     if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
2001     {
2002         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
2003         VERIFY_NOT_NULL(TAG, receviedCred->privateData.data, ERROR);
2004         receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
2005         memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
2006     }
2007     else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
2008     {
2009         B64Result b64res = B64_OK;
2010         size_t b64OutSize = 0;
2011         b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
2012         b64Buf = OICCalloc(1, b64BufSize);
2013         VERIFY_NOT_NULL(TAG, b64Buf, ERROR);
2014
2015         b64res = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
2016         VERIFY_SUCCESS(TAG, B64_OK == b64res, ERROR);
2017
2018         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
2019         VERIFY_NOT_NULL(TAG, receviedCred->privateData.data, ERROR);
2020         receviedCred->privateData.len = b64OutSize;
2021         strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
2022         receviedCred->privateData.data[b64OutSize] = '\0';
2023         OICClearMemory(b64Buf, b64BufSize);
2024         OICFree(b64Buf);
2025         b64Buf = NULL;
2026     }
2027     else
2028     {
2029         OIC_LOG_V(ERROR, TAG, "Unknown credential encoding type: %u.", receviedCred->privateData.encoding);
2030         goto exit;
2031     }
2032
2033     OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
2034
2035     OICClearMemory(ownerPSK, sizeof(ownerPSK));
2036
2037     //Verify OwnerPSK information
2038     return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
2039             receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
2040 exit:
2041     //receviedCred->privateData.data will be deallocated when deleting credential.
2042     OICClearMemory(ownerPSK, sizeof(ownerPSK));
2043     OICClearMemory(b64Buf, b64BufSize);
2044     OICFree(b64Buf);
2045     return false;
2046 }
2047
2048
2049 #ifdef MULTIPLE_OWNER
2050 /**
2051  * Internal function to fill private data of SubOwner PSK.
2052  *
2053  * @param receviedCred recevied owner credential from SubOwner
2054  * @param ownerAdd address of SubOwner
2055  * @param doxm current device's doxm resource
2056  *
2057  * @return
2058  *     true successfully done and valid subower psk information
2059  *     false Invalid subowner psk information or failed to subowner psk generation
2060  */
2061 static bool FillPrivateDataOfSubOwnerPSK(OicSecCred_t* receivedCred, const CAEndpoint_t* ownerAddr,
2062                            const OicSecDoxm_t* doxm, const OicUuid_t* subOwner)
2063 {
2064     char* b64Buf = NULL;
2065     //Derive OwnerPSK locally
2066     const char* oxmLabel = GetOxmString(doxm->oxmSel);
2067     VERIFY_NOT_NULL(TAG, oxmLabel, ERROR);
2068
2069     uint8_t subOwnerPSK[OWNER_PSK_LENGTH_128] = {0};
2070     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
2071         (uint8_t*)oxmLabel, strlen(oxmLabel),
2072         subOwner->id, sizeof(subOwner->id),
2073         doxm->deviceID.id, sizeof(doxm->deviceID.id),
2074         subOwnerPSK, OWNER_PSK_LENGTH_128);
2075     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
2076
2077     OIC_LOG(DEBUG, TAG, "SubOwnerPSK dump :");
2078     OIC_LOG_BUFFER(DEBUG, TAG, subOwnerPSK, OWNER_PSK_LENGTH_128);
2079
2080     //Generate owner credential based on received credential information
2081
2082     if(OIC_ENCODING_RAW == receivedCred->privateData.encoding)
2083     {
2084         receivedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
2085         VERIFY_NOT_NULL(TAG, receivedCred->privateData.data, ERROR);
2086         receivedCred->privateData.len = OWNER_PSK_LENGTH_128;
2087         memcpy(receivedCred->privateData.data, subOwnerPSK, OWNER_PSK_LENGTH_128);
2088     }
2089     else if(OIC_ENCODING_BASE64 == receivedCred->privateData.encoding)
2090     {
2091         size_t b64OutSize = 0;
2092         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
2093         b64Buf = OICCalloc(1, b64BufSize);
2094         VERIFY_NOT_NULL(TAG, b64Buf, ERROR);
2095
2096         VERIFY_SUCCESS(TAG, \
2097                        B64_OK == b64Encode(subOwnerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize), \
2098                        ERROR);
2099
2100         receivedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
2101         VERIFY_NOT_NULL(TAG, receivedCred->privateData.data, ERROR);
2102         receivedCred->privateData.len = b64OutSize;
2103         strncpy((char*)receivedCred->privateData.data, b64Buf, b64OutSize);
2104         receivedCred->privateData.data[b64OutSize] = '\0';
2105     }
2106     else
2107     {
2108         OIC_LOG_V(ERROR, TAG, "Unknown credential encoding type: %u.", receivedCred->privateData.encoding);
2109         goto exit;
2110     }
2111
2112     OIC_LOG(INFO, TAG, "PrivateData of SubOwnerPSK was calculated successfully");
2113     OICFree(b64Buf);
2114     return true;
2115 exit:
2116     //receivedCred->privateData.data will be deallocated when deleting credential.
2117     OICFree(b64Buf);
2118     return false;
2119 }
2120 #endif //MULTIPLE_OWNER
2121 #endif // __WITH_DTLS__ or __WITH_TLS__
2122
2123
2124 static OCEntityHandlerResult HandleNewCredential(OCEntityHandlerRequest *ehRequest, OicSecCred_t *cred, uint16_t previousMsgId)
2125 {
2126     OCEntityHandlerResult ret = OC_EH_INTERNAL_SERVER_ERROR;
2127
2128 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2129     OicUuid_t emptyUuid = {.id={0}};
2130     const OicSecDoxm_t *doxm = GetDoxmResourceData();
2131     if( NO_SECURITY_MODE != cred->credType
2132         && doxm
2133         && false == doxm->owned
2134         && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0
2135         && memcmp(&(doxm->owner), &cred->subject, sizeof(OicUuid_t)) == 0 )
2136     {
2137         //in case of owner PSK
2138         switch(cred->credType)
2139         {
2140             case SYMMETRIC_PAIR_WISE_KEY:
2141             {
2142                 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
2143                 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
2144                 {
2145                     if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
2146                     {
2147                         OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
2148                     }
2149
2150                     OIC_LOG(INFO, TAG, "OwnerPSK was generated successfully.");
2151                     if(OC_STACK_OK == AddCredential(cred))
2152                     {
2153                         ret = OC_EH_CHANGED;
2154                     }
2155                     else
2156                     {
2157                         OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
2158                         ret = OC_EH_ERROR;
2159                     }
2160                 }
2161                 else
2162                 {
2163                     OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPSK.");
2164                     ret = OC_EH_ERROR;
2165                 }
2166
2167                 if(OC_EH_CHANGED == ret)
2168                 {
2169                     /**
2170                         * in case of random PIN based OxM,
2171                         * revert get_psk_info callback of tinyDTLS to use owner credential.
2172                         */
2173                     if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2174                     {
2175                         SetUuidForPinBasedOxm(&emptyUuid);
2176
2177 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2178                         if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
2179                         {
2180                             OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
2181                             ret = OC_EH_ERROR;
2182                             break;
2183                         }
2184 #endif // __WITH_DTLS__ or __WITH_TLS__
2185                     }
2186
2187                     //Select cipher suite to use owner PSK
2188                     if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
2189                     {
2190                         OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
2191                         ret = OC_EH_ERROR;
2192                     }
2193                     else
2194                     {
2195                         OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
2196                     }
2197
2198 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2199                     if(CA_STATUS_OK != CASelectCipherSuite(
2200                                 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
2201                     {
2202                         OIC_LOG(ERROR, TAG, "Failed to enable PSK cipher suite");
2203                         ret = OC_EH_ERROR;
2204                     }
2205                     else
2206                     {
2207                         OIC_LOG(INFO, TAG, "PSK cipher suite is ENABLED");
2208                     }
2209 #endif // __WITH_DTLS__ or __WITH_TLS__
2210                 }
2211
2212                 break;
2213             }
2214             case SYMMETRIC_GROUP_KEY:
2215             case ASYMMETRIC_KEY:
2216             case SIGNED_ASYMMETRIC_KEY:
2217             case PIN_PASSWORD:
2218             case ASYMMETRIC_ENCRYPTION_KEY:
2219             {
2220                 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
2221                 ret = OC_EH_ERROR;
2222                 break;
2223             }
2224             default:
2225             {
2226                 OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
2227                 ret = OC_EH_ERROR;
2228                 break;
2229             }
2230         }
2231
2232         if(OC_EH_CHANGED != ret)
2233         {
2234             /*
2235                 * If some error is occured while ownership transfer,
2236                 * ownership transfer related resource should be revert back to initial status.
2237                 */
2238             const OicSecDoxm_t *ownershipDoxm =  GetDoxmResourceData();
2239             if(ownershipDoxm)
2240             {
2241                 if(!ownershipDoxm->owned)
2242                 {
2243                     OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
2244
2245                     if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
2246                         || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
2247                     {
2248                         RestoreDoxmToInitState();
2249                         RestorePstatToInitState();
2250                         OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
2251                     }
2252                 }
2253             }
2254             else
2255             {
2256                 OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
2257             }
2258         }
2259     }
2260 #ifdef MULTIPLE_OWNER
2261     // In case SubOwner Credential
2262     else if(doxm && doxm->owned && doxm->mom &&
2263             OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
2264             0 == cred->privateData.len &&
2265             0 == cred->optionalData.len &&
2266             0 == cred->publicData.len )
2267     {
2268         switch(cred->credType)
2269         {
2270             case SYMMETRIC_PAIR_WISE_KEY:
2271             {
2272                 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
2273                 if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
2274                 {
2275                     if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
2276                     {
2277                         OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
2278                     }
2279
2280                     OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
2281                     if(OC_STACK_OK == AddCredential(cred))
2282                     {
2283                         ret = OC_EH_CHANGED;
2284                     }
2285                     else
2286                     {
2287                         OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
2288                         ret = OC_EH_ERROR;
2289                     }
2290                 }
2291                 else
2292                 {
2293                     OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
2294                     ret = OC_EH_ERROR;
2295                 }
2296             }
2297             break;
2298
2299             case SYMMETRIC_GROUP_KEY:
2300             case ASYMMETRIC_KEY:
2301             case SIGNED_ASYMMETRIC_KEY:
2302             case PIN_PASSWORD:
2303             case ASYMMETRIC_ENCRYPTION_KEY:
2304             {
2305                 OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
2306                 ret = OC_EH_ERROR;
2307                 break;
2308             }
2309             default:
2310             {
2311                 OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
2312                 ret = OC_EH_ERROR;
2313                 break;
2314             }
2315         }
2316     }
2317 #endif //MULTIPLE_OWNER
2318     else
2319     {
2320         if(IsEmptyCred(cred))
2321         {
2322                     if (UpdatePersistentStorage(gCred))
2323                     {
2324                         ret = OC_EH_CHANGED;
2325                     }
2326                     else
2327                     {
2328                         ret = OC_EH_ERROR;
2329                     }
2330         }
2331         else
2332         {
2333             /*
2334                 * If the post request credential has credId, it will be
2335                 * discarded and the next available credId will be assigned
2336                 * to it before getting appended to the existing credential
2337                 * list and updating svr database.
2338                 */
2339             ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2340         }
2341     }
2342 #else //not __WITH_DTLS__ or __WITH_TLS__
2343     /*
2344         * If the post request credential has credId, it will be
2345         * discarded and the next available credId will be assigned
2346         * to it before getting appended to the existing credential
2347         * list and updating svr database.
2348         */
2349     ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2350     OC_UNUSED(previousMsgId);
2351     OC_UNUSED(ehRequest);
2352 #endif//__WITH_DTLS__ or __WITH_TLS__
2353
2354     return ret;
2355 }
2356
2357 static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest* ehRequest)
2358 {
2359     OCEntityHandlerResult ret = OC_EH_INTERNAL_SERVER_ERROR;
2360     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
2361
2362     OicSecDostype_t dos;
2363     static uint16_t previousMsgId = 0;
2364     // Get binary representation of cbor
2365     OicSecCred_t *cred = NULL;
2366     OicUuid_t     *rownerId = NULL;
2367     uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
2368     size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
2369
2370     OCStackResult res = OC_STACK_OK;
2371
2372     VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDos(&dos), ERROR);
2373     if ((DOS_RESET == dos.state) ||
2374         (DOS_RFNOP == dos.state))
2375     {
2376         OIC_LOG_V(WARNING, TAG, "%s /cred resource is read-only in RESET and RFNOP.", __func__);
2377         ret = OC_EH_NOT_ACCEPTABLE;
2378         goto exit;
2379     }
2380
2381     res = CBORPayloadToCred(payload, size, &cred, &rownerId);
2382
2383     if (OC_STACK_OK == res)
2384     {
2385         OicSecCred_t *newCred = NULL;
2386         OicSecCred_t *newCredTemp = NULL;
2387
2388         LL_FOREACH_SAFE(cred, newCred, newCredTemp)
2389         {
2390             ret = HandleNewCredential(ehRequest, newCred, previousMsgId);
2391
2392             if (OC_EH_CHANGED != ret)
2393             {
2394                 // Remove the credentials added so far.
2395                 OicSecCred_t *removedCred = NULL;
2396                 OicSecCred_t *removedCredTemp = NULL;
2397                 LL_FOREACH_SAFE(cred, removedCred, removedCredTemp)
2398                 {
2399                     if (removedCred == newCred)
2400                     {
2401                         break;
2402                     }
2403
2404                     if (RemoveCredential(&cred->subject) != OC_STACK_OK)
2405                     {
2406                         OIC_LOG(WARNING, TAG, "Failed to remove credential");
2407                     }
2408                 }
2409
2410                 break;
2411             }
2412         }
2413         if (OC_EH_CHANGED == ret && NULL != rownerId)
2414         {
2415             memcpy(&gRownerId, rownerId, sizeof(OicUuid_t));
2416         }
2417     }
2418
2419 exit:
2420     OICFree(rownerId);
2421     if (OC_EH_CHANGED != ret)
2422     {
2423         if (NULL != cred)
2424         {
2425             DeleteCredList(cred);
2426         }
2427     }
2428     else
2429     {
2430         if (OC_ADAPTER_IP == ehRequest->devAddr.adapter)
2431         {
2432             previousMsgId = ehRequest->messageID++;
2433         }
2434     }
2435
2436     // Send response to request originator
2437     ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2438                    OC_EH_OK : OC_EH_ERROR;
2439
2440     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
2441     return ret;
2442 }
2443
2444 /**
2445  * The entity handler determines how to process a GET request.
2446  */
2447 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
2448 {
2449     OIC_LOG(INFO, TAG, "HandleGetRequest  processing GET request");
2450
2451     // Convert Cred data into CBOR for transmission
2452     size_t size = 0;
2453     uint8_t *payload = NULL;
2454     int secureFlag = 1;
2455
2456     const OicSecCred_t *cred = gCred;
2457
2458     // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2459     size = GetCredKeyDataSize(cred);
2460     size += (256 * OicSecCredCount(cred));
2461     OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
2462
2463     // A device should always have a default cred. Therefore, payload should never be NULL.
2464     OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
2465
2466     //Send payload to request originator
2467     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
2468                        OC_EH_OK : OC_EH_ERROR;
2469     OICClearMemory(payload, size);
2470     OICFree(payload);
2471     return ehRet;
2472 }
2473
2474 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
2475 {
2476     OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
2477
2478     OCEntityHandlerResult ehRet = OC_EH_ERROR;
2479     CredIdList_t *credIdList = NULL;
2480     OicUuid_t subject = { .id= { 0 } };
2481
2482     if (NULL == ehRequest->query)
2483     {
2484         return ehRet;
2485     }
2486
2487     if (GetCredIdsFromQueryString(ehRequest->query, &credIdList))
2488     {
2489         if (OC_STACK_RESOURCE_DELETED == RemoveCredentialByCredIds(credIdList))
2490         {
2491             ehRet = OC_EH_RESOURCE_DELETED;
2492         }
2493         DeleteCredIdList(&credIdList);
2494     }
2495     else if (GetSubjectFromQueryString(ehRequest->query, &subject))
2496     {
2497         if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
2498         {
2499             ehRet = OC_EH_RESOURCE_DELETED;
2500         }
2501     }
2502     else
2503     {
2504         if (OC_STACK_OK == RemoveAllCredentials())
2505         {
2506             ehRet = OC_EH_RESOURCE_DELETED;
2507         }
2508     }
2509
2510     //Send response to request originator
2511     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2512                    OC_EH_OK : OC_EH_ERROR;
2513     return ehRet;
2514 }
2515
2516 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
2517                                         OCEntityHandlerRequest * ehRequest,
2518                                         void* callbackParameter)
2519 {
2520     (void)callbackParameter;
2521     OCEntityHandlerResult ret = OC_EH_ERROR;
2522
2523     if (!ehRequest)
2524     {
2525         return OC_EH_ERROR;
2526     }
2527     if (flag & OC_REQUEST_FLAG)
2528     {
2529         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
2530         //TODO :  Remove Handle PUT methods once CTT have changed to POST on OTM
2531         switch (ehRequest->method)
2532         {
2533             case OC_REST_GET:
2534                 ret = HandleGetRequest(ehRequest);
2535                 break;
2536             case OC_REST_PUT:
2537             case OC_REST_POST:
2538                 ret = HandlePostRequest(ehRequest);
2539                 break;
2540             case OC_REST_DELETE:
2541                 ret = HandleDeleteRequest(ehRequest);
2542                 break;
2543             default:
2544                 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2545                                OC_EH_OK : OC_EH_ERROR;
2546                 break;
2547         }
2548     }
2549     return ret;
2550 }
2551
2552 OCStackResult CreateCredResource()
2553 {
2554     OCStackResult ret = OCCreateResource(&gCredHandle,
2555                                          OIC_RSRC_TYPE_SEC_CRED,
2556                                          OC_RSRVD_INTERFACE_DEFAULT,
2557                                          OIC_RSRC_CRED_URI,
2558                                          CredEntityHandler,
2559                                          NULL,
2560                                          OC_SECURE |
2561                                          OC_DISCOVERABLE);
2562
2563     if (OC_STACK_OK != ret)
2564     {
2565         OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2566         DeInitCredResource();
2567     }
2568     return ret;
2569 }
2570
2571 OCStackResult InitCredResource()
2572 {
2573     OCStackResult ret = OC_STACK_ERROR;
2574     OicSecCred_t* cred = NULL;
2575     OicUuid_t   *rownerId = NULL;
2576
2577     //Read Cred resource from PS
2578     uint8_t *data = NULL;
2579     size_t size = 0;
2580     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2581     // If database read failed
2582     if (ret != OC_STACK_OK)
2583     {
2584         OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2585     }
2586
2587     if ((ret == OC_STACK_OK) && data)
2588     {
2589         // Read Cred resource from PS
2590         ret = CBORPayloadToCred(data, size, &gCred, &rownerId);
2591
2592 #ifdef HAVE_WINDOWS_H
2593         /* On Windows, if the credential payload isn't cleartext CBOR, it is encrypted. Decrypt and retry. */
2594         DWORD dwordSize;
2595
2596         if (FAILED(SizeTToDWord(size, &dwordSize)))
2597         {
2598             OIC_LOG(DEBUG, TAG, "Cred size too large.");
2599             ret = OC_STACK_ERROR;
2600         }
2601
2602         if (ret != OC_STACK_OK)
2603         {
2604             DATA_BLOB decryptedPayload;
2605             DATA_BLOB encryptedPayload;
2606             memset(&decryptedPayload, 0, sizeof(decryptedPayload));
2607             memset(&encryptedPayload, 0, sizeof(encryptedPayload));
2608             encryptedPayload.cbData = dwordSize;
2609             encryptedPayload.pbData = data;
2610
2611             if (CryptUnprotectData(
2612                 &encryptedPayload,
2613                 NULL,
2614                 NULL,
2615                 NULL,
2616                 NULL,
2617                 CRYPTPROTECT_UI_FORBIDDEN,
2618                 &decryptedPayload))
2619             {
2620                 ret = CBORPayloadToCred(decryptedPayload.pbData, decryptedPayload.cbData, &gCred, &rownerId);
2621
2622                 /* For the returned data from CryptUnprotectData, LocalFree must be used to free. Don't use OICFree. */
2623                 OICClearMemory(decryptedPayload.pbData, decryptedPayload.cbData);
2624                 if (NULL != LocalFree(decryptedPayload.pbData))
2625                 {
2626                     OIC_LOG_V(ERROR, TAG, "LocalFree failed on output from CryptUnprotectData; memory may be corrupted or leaked. Last error: %u.", GetLastError());
2627                     assert(!"LocalFree failed");
2628                 }
2629             }
2630             else
2631             {
2632                 /* Credential resource is corrupted, or we no longer have access to the encryption key to decrypt it. */
2633                 OIC_LOG_V(ERROR, TAG, "Failed to CryptUnprotectData cred resource: %u", GetLastError());
2634                 ret = OC_STACK_ERROR;
2635             }
2636         }
2637 #endif
2638     }
2639
2640     /*
2641      * If SVR database in persistent storage got corrupted or
2642      * is not available for some reason, a default Cred is created
2643      * which allows user to initiate Cred provisioning again.
2644      */
2645     if (ret != OC_STACK_OK || !data || !gCred)
2646     {
2647         gCred = GetCredDefault();
2648     }
2649
2650     if (gCred)
2651     {
2652         OicUuid_t deviceID;
2653         OicUuid_t emptyUuid = {.id={0}};
2654
2655         ret = GetDoxmDeviceID(&deviceID);
2656         if (ret != OC_STACK_OK)
2657         {
2658             OIC_LOG_V(WARNING, TAG, "%s: GetDoxmDeviceID failed, error %d", __func__, ret);
2659             //Unit tests expect error code OC_STACK_INVALID_PARAM.
2660             ret = OC_STACK_INVALID_PARAM;
2661             goto exit;
2662         }
2663
2664         //Add a log to track the invalid credential.
2665         LL_FOREACH(gCred, cred)
2666         {
2667             if (false == CheckSubjectOfCertificate(cred, deviceID))
2668             {
2669                 OIC_LOG(WARNING, TAG, "Check subject of Certificate was failed while InitCredResource");
2670             }
2671             if (false == IsValidCredential(cred))
2672             {
2673                 OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
2674                 OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
2675             }
2676         }
2677
2678         if (NULL == rownerId || 0 == memcmp(rownerId, &emptyUuid, sizeof(OicUuid_t)))
2679         {
2680             memcpy(&gRownerId, &deviceID, sizeof(OicUuid_t));
2681         }
2682         else
2683         {
2684             memcpy(&gRownerId, rownerId, sizeof(OicUuid_t));
2685         }
2686
2687         if (!UpdatePersistentStorage(gCred))
2688         {
2689             OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
2690         }
2691     }
2692     //Instantiate 'oic.sec.cred'
2693     ret = CreateCredResource();
2694
2695 exit:
2696     OIC_LOG(DEBUG, TAG, "OUT InitCredResource.");
2697     OICClearMemory(data, size);
2698     OICFree(data);
2699     OICFree(rownerId);
2700     return ret;
2701 }
2702
2703 OCStackResult DeInitCredResource()
2704 {
2705     OCStackResult result = OCDeleteResource(gCredHandle);
2706     DeleteCredList(gCred);
2707     gCred = NULL;
2708     return result;
2709 }
2710
2711 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2712 {
2713     OicSecCred_t *cred = NULL;
2714
2715    if ( NULL == subject)
2716     {
2717        return NULL;
2718     }
2719
2720     LL_FOREACH(gCred, cred)
2721     {
2722         if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2723         {
2724             return cred;
2725         }
2726     }
2727     return NULL;
2728 }
2729
2730 const OicSecCred_t* GetCredList()
2731 {
2732     return gCred;
2733 }
2734
2735 OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
2736 {
2737     OicSecCred_t *cred = NULL;
2738     OicSecCred_t *tmpCred = NULL;
2739
2740    if ( 1 > credId)
2741     {
2742        return NULL;
2743     }
2744
2745     LL_FOREACH(gCred, tmpCred)
2746     {
2747         if(tmpCred->credId == credId)
2748         {
2749             cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2750             VERIFY_NOT_NULL(TAG, cred, ERROR);
2751
2752             // common
2753             cred->next = NULL;
2754             cred->credId = tmpCred->credId;
2755             cred->credType = tmpCred->credType;
2756             memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
2757             if (tmpCred->period)
2758             {
2759                 cred->period = OICStrdup(tmpCred->period);
2760             }
2761
2762             // key data
2763             if (tmpCred->privateData.data)
2764             {
2765                 cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
2766                 VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
2767
2768                 memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
2769                 cred->privateData.len = tmpCred->privateData.len;
2770                 cred->privateData.encoding = tmpCred->privateData.encoding;
2771             }
2772 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2773             if (tmpCred->publicData.data)
2774             {
2775                 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
2776                 VERIFY_NOT_NULL(TAG, cred->publicData.data, ERROR);
2777
2778                 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
2779                 cred->publicData.len = tmpCred->publicData.len;
2780                 cred->publicData.encoding = tmpCred->publicData.encoding;
2781             }
2782             if (tmpCred->optionalData.data)
2783             {
2784                 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
2785                 VERIFY_NOT_NULL(TAG, cred->optionalData.data, ERROR);
2786
2787                 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
2788                 cred->optionalData.len = tmpCred->optionalData.len;
2789                 cred->optionalData.encoding = tmpCred->optionalData.encoding;
2790                 cred->optionalData.revstat= tmpCred->optionalData.revstat;
2791             }
2792             if (tmpCred->credUsage)
2793             {
2794                 cred->credUsage = OICStrdup(tmpCred->credUsage);
2795             }
2796 #endif /* __WITH_DTLS__  or __WITH_TLS__*/
2797
2798             return cred;
2799         }
2800     }
2801
2802 exit:
2803     FreeCred(cred);
2804     return NULL;
2805 }
2806
2807 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2808 static bool ValueWithinBounds(uint64_t value, uint64_t maxValue)
2809 {
2810     if (value > maxValue)
2811     {
2812         OIC_LOG_V(ERROR, TAG, "The value (%" PRId64 ") is greater than allowed maximum of %" PRId64 ".", value, maxValue);
2813         return false;
2814     }
2815
2816     return true;
2817 }
2818
2819 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2820               const uint8_t *desc, size_t desc_len,
2821               uint8_t *result, size_t result_length)
2822 {
2823     int32_t ret = -1;
2824
2825     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
2826
2827     if (NULL == result)
2828     {
2829         OIC_LOG_V(DEBUG, TAG, "%s: NULL result param; exiting.", __func__);
2830         goto exit;
2831     }
2832
2833 #ifndef NDEBUG
2834     char strUuidTmp[UUID_STRING_SIZE] = "UUID_ERROR";
2835     if (desc_len == UUID_LENGTH)
2836     {
2837         if (OCConvertUuidToString(desc, strUuidTmp))
2838         {
2839             OIC_LOG_V(DEBUG, TAG, "%s: desc = %s", __func__, strUuidTmp);
2840         }
2841         else
2842         {
2843             OIC_LOG(ERROR, TAG, "failed to convert desc to UUID str.");
2844         }
2845     }
2846 #endif
2847
2848     switch (type)
2849     {
2850         case CA_DTLS_PSK_HINT:
2851         case CA_DTLS_PSK_IDENTITY:
2852             {
2853                 OicUuid_t deviceID = {.id={0}};
2854                 // Retrieve Device ID from doxm resource
2855                 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2856                 {
2857                     OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2858                     goto exit;
2859                 }
2860
2861                 if (result_length < sizeof(deviceID.id))
2862                 {
2863                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2864                     goto exit;
2865                 }
2866                 memcpy(result, deviceID.id, sizeof(deviceID.id));
2867                 return (sizeof(deviceID.id));
2868             }
2869             break;
2870
2871         case CA_DTLS_PSK_KEY:
2872             {
2873                 OicSecCred_t *cred = NULL;
2874                 LL_FOREACH(gCred, cred)
2875                 {
2876                     if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2877                     {
2878                         OIC_LOG_V(DEBUG, TAG, "%s: credid %u not a SYMMETRIC_PAIR_WISE_KEY type... skipping",
2879                             __func__, cred->credId);
2880                         continue;
2881                     }
2882
2883                     if ((desc_len == sizeof(cred->subject.id)) &&
2884                         (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2885                     {
2886 #ifndef NDEBUG
2887                         if (OCConvertUuidToString(cred->subject.id, strUuidTmp))
2888                         {
2889                             OIC_LOG_V(DEBUG, TAG, "%s: credid %u (subject = %s) matches desc; checking validity.",
2890                                 __func__, cred->credId, strUuidTmp);
2891                         }
2892                         else
2893                         {
2894                             OIC_LOG(ERROR, TAG, "failed to convert credid to str.");
2895                         }
2896 #endif
2897                         /*
2898                          * If the credentials are valid for limited time,
2899                          * check their expiry.
2900                          */
2901                         if (cred->period)
2902                         {
2903                             if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2904                             {
2905                                 OIC_LOG (INFO, TAG, "Credentials are expired.");
2906                                 goto exit;
2907                             }
2908                         }
2909
2910                         OIC_LOG_V(DEBUG, TAG, "%s: cred->privateData.encoding = %u", __func__, cred->privateData.encoding);
2911
2912                         // Copy PSK.
2913                         // TODO: Added as workaround. Will be replaced soon.
2914                         if(OIC_ENCODING_RAW == cred->privateData.encoding)
2915                         {
2916                             OIC_LOG_V(DEBUG, TAG, "%s: OIC_ENCODING_RAW detected; copying PSK.", __func__);
2917                             if (ValueWithinBounds(cred->privateData.len, INT32_MAX))
2918                             {
2919                                 size_t len = cred->privateData.len;
2920                                 if (result_length < len)
2921                                 {
2922                                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2923                                     goto exit;
2924                                 }
2925                                 memcpy(result, cred->privateData.data, len);
2926                                 ret = (int32_t)len;
2927                             }
2928                         }
2929                         else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2930                         {
2931                             OIC_LOG_V(DEBUG, TAG, "%s: OIC_ENCODING_BASE64 detected; copying PSK.", __func__);
2932                             size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2933                             uint8_t* outKey = OICCalloc(1, outBufSize);
2934                             size_t outKeySize;
2935                             if(NULL == outKey)
2936                             {
2937                                 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2938                                 goto exit;
2939                             }
2940
2941                             if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2942                             {
2943                                 if (ValueWithinBounds(outKeySize, INT32_MAX))
2944                                 {
2945                                     if (result_length < outKeySize)
2946                                     {
2947                                         OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2948                                         goto exit;
2949                                     }
2950                                     memcpy(result, outKey, outKeySize);
2951                                     ret = (int32_t)outKeySize;
2952                                 }
2953                             }
2954                             else
2955                             {
2956                                 OIC_LOG (ERROR, TAG, "Failed base64 decoding.");
2957                             }
2958
2959                             OICFree(outKey);
2960                         }
2961                         else
2962                         {
2963                             OIC_LOG_V(WARNING, TAG, "%s: unsupported encoding type.", __func__);
2964                         }
2965
2966                         if (OC_STACK_OK != RegisterSymmetricCredentialRole(cred))
2967                         {
2968                             OIC_LOG(WARNING, TAG, "Couldn't RegisterRoleForSubject");
2969                         }
2970
2971                         goto exit;
2972                     }
2973                 }
2974                 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2975
2976 #ifdef MULTIPLE_OWNER
2977                 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2978                 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2979                 {
2980                     // in case of multiple owner transfer authentication
2981                     if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2982                     {
2983                         OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2984                         if(wildCardCred)
2985                         {
2986                             OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2987                             if(PIN_PASSWORD == wildCardCred->credType)
2988                             {
2989                                 //Read PIN/PW
2990                                 char* pinBuffer = NULL;
2991                                 size_t pinLength = 0;
2992                                 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2993                                 {
2994                                     pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2995                                     if(NULL == pinBuffer)
2996                                     {
2997                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2998                                         goto exit;
2999                                     }
3000                                     pinLength = wildCardCred->privateData.len;
3001                                     memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
3002                                 }
3003                                 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
3004                                 {
3005                                     size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
3006                                     pinBuffer = OICCalloc(1, pinBufSize);
3007                                     if(NULL == pinBuffer)
3008                                     {
3009                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
3010                                         goto exit;
3011                                     }
3012
3013                                     if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, (uint8_t*)pinBuffer, pinBufSize, &pinLength))
3014                                     {
3015                                         OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
3016                                         goto exit;
3017                                     }
3018                                 }
3019                                 else
3020                                 {
3021                                     OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
3022                                     goto exit;
3023                                 }
3024
3025                                 //Set the PIN/PW to derive PSK
3026                                 if (OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
3027                                 {
3028                                     OICFree(pinBuffer);
3029                                     OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
3030                                     goto exit;
3031                                 }
3032                                 OICFree(pinBuffer);
3033
3034                                 OicUuid_t myUuid;
3035                                 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
3036                                 {
3037                                     OIC_LOG(ERROR, TAG, "Failed to read device ID");
3038                                     goto exit;
3039                                 }
3040                                 SetUuidForPinBasedOxm(&myUuid);
3041
3042                                 //Calculate PSK using PIN/PW
3043                                 if(0 == DerivePSKUsingPIN((uint8_t*)result))
3044                                 {
3045                                     ret = OWNER_PSK_LENGTH_128;
3046                                 }
3047                                 else
3048                                 {
3049                                     OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
3050                                 }
3051
3052                                 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
3053                                 {
3054                                     OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
3055                                 }
3056                             }
3057                         }
3058                     }
3059                     else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
3060                     {
3061                         if(0 == DerivePSKUsingPIN((uint8_t*)result))
3062                         {
3063                             ret = OWNER_PSK_LENGTH_128;
3064                         }
3065                         else
3066                         {
3067                             OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
3068                             ret = -1;
3069                         }
3070                     }
3071                 }
3072 #endif //MULTIPLE_OWNER
3073             }
3074             break;
3075     }
3076 exit:
3077     OIC_LOG_V(DEBUG, TAG, "%s: OUT; returning %d.", __func__, ret);
3078
3079     return ret;
3080 }
3081
3082 /**
3083  * Add temporal PSK to PIN based OxM
3084  *
3085  * @param[in] tmpSubject UUID of target device
3086  * @param[in] credType Type of credential to be added
3087  * @param[in] pin numeric characters
3088  * @param[in] pinSize length of 'pin'
3089  * @param[in] rownerID Resource owner's UUID
3090  * @param[out] tmpCredSubject Generated credential's subject.
3091  *