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