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