94cd79eb1145609cd7453931aff494a0e6c04e63
[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     //leave IOT-1936 fix for preconfig pin
1684 #if ((defined(__WITH_DTLS__) || defined(__WITH_TLS__)) && defined(MULTIPLE_OWNER))
1685     LL_FOREACH_SAFE(gCred, cred, tempCred)
1686     {
1687         if (IsNewPreconfigPinCredential(cred, newCred))
1688         {
1689             //devices can only have one Preconfigured Pin credential at any given time. Check
1690             //if the new credential is an update to an existing Preconfigured Pin credential
1691             //if so, just update existing one.
1692
1693             //save old credid so act like an update
1694             newCred->credId = cred->credId;
1695
1696             LL_DELETE(gCred, cred);
1697             LL_PREPEND(gCred, newCred);
1698
1699             FreeCred(cred);
1700             found = true;
1701             break;
1702         }
1703     }
1704 #endif //(__WITH_DTLS__ or __WITH_TLS__) and MULTIPLE_OWNER
1705
1706     if (found)
1707     {
1708         goto saveToDB;
1709     }
1710
1711     if (newCred->credId != 0)
1712     {
1713         //check if cred with such cred id exists
1714         LL_FOREACH_SAFE(gCred, cred, tempCred)
1715         {
1716             if (cred->credId == newCred->credId)
1717             {
1718                 //remove old cred with same cred id
1719                 LL_DELETE(gCred, cred);
1720                 FreeCred(cred);
1721                 break;
1722             }
1723         }
1724     }
1725     else
1726     {
1727         newCred->credId = GetCredId();
1728     }
1729
1730     OIC_LOG(DEBUG, TAG, "Adding New Cred");
1731     LL_APPEND(gCred, newCred);
1732
1733
1734     OicUuid_t emptyOwner = { .id = {0} };
1735     if (memcmp(&(newCred->rownerID), &emptyOwner, sizeof(OicUuid_t)) != 0)
1736     {
1737         memcpy(&(gRownerId), &(newCred->rownerID), sizeof(OicUuid_t));
1738     }
1739
1740 saveToDB:
1741
1742     if (UpdatePersistentStorage(gCred))
1743     {
1744         result = OC_STACK_OK;
1745     }
1746
1747     return result;
1748 }
1749
1750 OCStackResult RemoveCredential(const OicUuid_t *subject)
1751 {
1752     OCStackResult ret = OC_STACK_ERROR;
1753     OicSecCred_t *cred = NULL;
1754     OicSecCred_t *tempCred = NULL;
1755     bool deleteFlag = false;
1756
1757     LL_FOREACH_SAFE(gCred, cred, tempCred)
1758     {
1759         if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1760         {
1761             LL_DELETE(gCred, cred);
1762             FreeCred(cred);
1763             deleteFlag = 1;
1764         }
1765     }
1766
1767     if (deleteFlag)
1768     {
1769         if (UpdatePersistentStorage(gCred))
1770         {
1771             ret = OC_STACK_RESOURCE_DELETED;
1772         }
1773     }
1774     return ret;
1775 }
1776
1777 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1778 {
1779     OCStackResult ret = OC_STACK_ERROR;
1780     OicSecCred_t *cred = NULL;
1781     OicSecCred_t *tempCred = NULL;
1782     bool deleteFlag = false;
1783
1784     OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1785
1786     if ( 0 == credId)
1787     {
1788         return OC_STACK_INVALID_PARAM;
1789     }
1790
1791
1792     LL_FOREACH_SAFE(gCred, cred, tempCred)
1793     {
1794         if (cred->credId == credId)
1795         {
1796             OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1797
1798             LL_DELETE(gCred, cred);
1799             FreeCred(cred);
1800             deleteFlag = true;
1801         }
1802     }
1803
1804     if (deleteFlag)
1805     {
1806         if (UpdatePersistentStorage(gCred))
1807         {
1808             ret = OC_STACK_RESOURCE_DELETED;
1809         }
1810     }
1811     OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1812
1813     return ret;
1814 }
1815
1816 /**
1817  * This method removes cred's corresponding to given list of credid's from the Cred
1818  *
1819  * @param credid's of the Cred
1820  *
1821  * @return
1822  *     ::OC_STACK_RESOURCE_DELETED on success
1823  *     ::OC_STACK_NO_RESOURCE on failure to find the appropriate Cred
1824  *     ::OC_STACK_INVALID_PARAM on invalid parameter
1825  */
1826 static OCStackResult RemoveCredentialByCredIds(CredIdList_t *credIdList)
1827 {
1828     OCStackResult ret = OC_STACK_ERROR;
1829     OicSecCred_t *cred = NULL;
1830     OicSecCred_t *tempCred = NULL;
1831     CredIdList_t *credIdElem = NULL;
1832     bool deleteFlag = false;
1833
1834     OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredIds");
1835
1836     LL_FOREACH(credIdList, credIdElem)
1837     {
1838         LL_FOREACH_SAFE(gCred, cred, tempCred)
1839         {
1840             if (cred->credId == credIdElem->credId)
1841             {
1842                 OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", cred->credId);
1843
1844                 LL_DELETE(gCred, cred);
1845                 FreeCred(cred);
1846                 deleteFlag = true;
1847                 //TODO: add break when cred's will have unique credid (during IOT-2464 fix)
1848             }
1849         }
1850     }
1851
1852     if (deleteFlag)
1853     {
1854         if (UpdatePersistentStorage(gCred))
1855         {
1856             ret = OC_STACK_RESOURCE_DELETED;
1857         }
1858     }
1859     OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredIds");
1860
1861     return ret;
1862 }
1863
1864 /**
1865  * This method parses the query string received for REST requests and
1866  * retrieves the 'credid' field.
1867  *
1868  * @param query querystring passed in REST request
1869  * @param credid cred id parsed from query string
1870  *
1871  * @return true if query parsed successfully and found 'credid', else false.
1872  */
1873 static bool GetCredIdsFromQueryString(const char *query, CredIdList_t **credid)
1874 {
1875     bool found = false;
1876     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1877
1878     ParseQueryIterInit((unsigned char *) query, &parseIter);
1879
1880     while (GetNextQuery (&parseIter))
1881     {
1882         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_CREDID_NAME, parseIter.attrLen) == 0)
1883         {
1884             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1885
1886             //parse credid array value in format "1,2,3"
1887             unsigned char *str = parseIter.valPos;
1888
1889             //remember last symbol (may be '\0' or '&')
1890             unsigned char tmp = str[parseIter.valLen];
1891             //set last symbol to '\0' to use strtok_r
1892             str[parseIter.valLen] = '\0';
1893
1894             char *saveptr = NULL;
1895
1896             for (; ; str = NULL)
1897             {
1898                 char *token = strtok_r((char *)str, ",", &saveptr);
1899                 if (NULL == token)
1900                 {
1901                     break;
1902                 }
1903
1904                 CredIdList_t *newCredIdElem = (CredIdList_t *) OICCalloc(1, sizeof(CredIdList_t));
1905                 if (NULL == newCredIdElem)
1906                 {
1907                     OIC_LOG(ERROR, TAG, "Failed to allocate CredIdList_t element");
1908                     break;
1909                 }
1910                 newCredIdElem->credId = (uint16_t)atoi(token);
1911
1912                 LL_PREPEND(*credid, newCredIdElem);
1913                 found = true;
1914             }
1915
1916             //restore last symbol
1917             parseIter.valPos[parseIter.valLen] = tmp;
1918         }
1919     }
1920
1921 exit:
1922     return found;
1923 }
1924
1925 /**
1926  * Remove all credential data on credential resource and persistent storage
1927  *
1928  * @retval
1929  *     OC_STACK_OK              - no errors
1930  *     OC_STACK_ERROR           - stack process error
1931  */
1932 static OCStackResult RemoveAllCredentials()
1933 {
1934     DeleteCredList(gCred);
1935     gCred = GetCredDefault();
1936
1937     if (!UpdatePersistentStorage(gCred))
1938     {
1939         return OC_STACK_ERROR;
1940     }
1941     return OC_STACK_OK;
1942 }
1943
1944 /**
1945  * This method parses the query string received for REST requests and
1946  * retrieves the 'subjectuuid' field.
1947  *
1948  * @param query querystring passed in REST request
1949  * @param subject subject UUID parsed from query string
1950  *
1951  * @return true if query parsed successfully and found 'subject', else false.
1952  */
1953 static bool GetSubjectFromQueryString(const char *query, OicUuid_t *subject)
1954 {
1955     OicParseQueryIter_t parseIter = { .attrPos = NULL };
1956
1957     ParseQueryIterInit((unsigned char *) query, &parseIter);
1958
1959     while (GetNextQuery (&parseIter))
1960     {
1961         if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_SUBJECTID_NAME, parseIter.attrLen) == 0)
1962         {
1963             VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1964             //temporary set '\0' symbol instead of copy string
1965             char tmp = parseIter.valPos[parseIter.valLen];
1966             parseIter.valPos[parseIter.valLen] = '\0';
1967
1968             OCStackResult res = ConvertStrToUuid((const char*)parseIter.valPos, subject);
1969             parseIter.valPos[parseIter.valLen] = tmp;
1970             VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
1971             return true;
1972         }
1973     }
1974
1975 exit:
1976     return false;
1977 }
1978
1979 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1980 /**
1981  * Internal function to fill private data of owner PSK.
1982  *
1983  * @param receviedCred recevied owner credential from OBT(PT)
1984  * @param ownerAdd address of OBT(PT)
1985  * @param doxm current device's doxm resource
1986  *
1987  * @return
1988  *     true successfully done and valid ower psk information
1989  *     false Invalid owner psk information or failed to owner psk generation
1990  */
1991 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1992                            const OicSecDoxm_t* doxm)
1993 {
1994     //Derive OwnerPSK locally
1995     const char* oxmLabel = GetOxmString(doxm->oxmSel);
1996     char* b64Buf = NULL;
1997     size_t b64BufSize = 0;
1998     VERIFY_NOT_NULL(TAG, oxmLabel, ERROR);
1999
2000     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
2001     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
2002         (uint8_t*)oxmLabel, strlen(oxmLabel),
2003         doxm->owner.id, sizeof(doxm->owner.id),
2004         doxm->deviceID.id, sizeof(doxm->deviceID.id),
2005         ownerPSK, OWNER_PSK_LENGTH_128);
2006     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
2007
2008     OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
2009     OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
2010
2011     //Generate owner credential based on recevied credential information
2012
2013     // TODO: Added as workaround, will be replaced soon.
2014     if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
2015     {
2016         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
2017         VERIFY_NOT_NULL(TAG, receviedCred->privateData.data, ERROR);
2018         receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
2019         memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
2020     }
2021     else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
2022     {
2023         B64Result b64res = B64_OK;
2024         size_t b64OutSize = 0;
2025         b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
2026         b64Buf = OICCalloc(1, b64BufSize);
2027         VERIFY_NOT_NULL(TAG, b64Buf, ERROR);
2028
2029         b64res = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
2030         VERIFY_SUCCESS(TAG, B64_OK == b64res, ERROR);
2031
2032         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
2033         VERIFY_NOT_NULL(TAG, receviedCred->privateData.data, ERROR);
2034         receviedCred->privateData.len = b64OutSize;
2035         strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
2036         receviedCred->privateData.data[b64OutSize] = '\0';
2037         OICClearMemory(b64Buf, b64BufSize);
2038         OICFree(b64Buf);
2039         b64Buf = NULL;
2040     }
2041     else
2042     {
2043         OIC_LOG_V(ERROR, TAG, "Unknown credential encoding type: %u.", receviedCred->privateData.encoding);
2044         goto exit;
2045     }
2046
2047     OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
2048
2049     OICClearMemory(ownerPSK, sizeof(ownerPSK));
2050
2051     //Verify OwnerPSK information
2052     return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
2053             receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
2054 exit:
2055     //receviedCred->privateData.data will be deallocated when deleting credential.
2056     OICClearMemory(ownerPSK, sizeof(ownerPSK));
2057     OICClearMemory(b64Buf, b64BufSize);
2058     OICFree(b64Buf);
2059     return false;
2060 }
2061
2062
2063 #ifdef MULTIPLE_OWNER
2064 /**
2065  * Internal function to fill private data of SubOwner PSK.
2066  *
2067  * @param receviedCred recevied owner credential from SubOwner
2068  * @param ownerAdd address of SubOwner
2069  * @param doxm current device's doxm resource
2070  *
2071  * @return
2072  *     true successfully done and valid subower psk information
2073  *     false Invalid subowner psk information or failed to subowner psk generation
2074  */
2075 static bool FillPrivateDataOfSubOwnerPSK(OicSecCred_t* receivedCred, const CAEndpoint_t* ownerAddr,
2076                            const OicSecDoxm_t* doxm, const OicUuid_t* subOwner)
2077 {
2078     char* b64Buf = NULL;
2079     //Derive OwnerPSK locally
2080     const char* oxmLabel = GetOxmString(doxm->oxmSel);
2081     VERIFY_NOT_NULL(TAG, oxmLabel, ERROR);
2082
2083     uint8_t subOwnerPSK[OWNER_PSK_LENGTH_128] = {0};
2084     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
2085         (uint8_t*)oxmLabel, strlen(oxmLabel),
2086         subOwner->id, sizeof(subOwner->id),
2087         doxm->deviceID.id, sizeof(doxm->deviceID.id),
2088         subOwnerPSK, OWNER_PSK_LENGTH_128);
2089     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
2090
2091     OIC_LOG(DEBUG, TAG, "SubOwnerPSK dump :");
2092     OIC_LOG_BUFFER(DEBUG, TAG, subOwnerPSK, OWNER_PSK_LENGTH_128);
2093
2094     //Generate owner credential based on received credential information
2095
2096     if(OIC_ENCODING_RAW == receivedCred->privateData.encoding)
2097     {
2098         receivedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
2099         VERIFY_NOT_NULL(TAG, receivedCred->privateData.data, ERROR);
2100         receivedCred->privateData.len = OWNER_PSK_LENGTH_128;
2101         memcpy(receivedCred->privateData.data, subOwnerPSK, OWNER_PSK_LENGTH_128);
2102     }
2103     else if(OIC_ENCODING_BASE64 == receivedCred->privateData.encoding)
2104     {
2105         size_t b64OutSize = 0;
2106         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
2107         b64Buf = OICCalloc(1, b64BufSize);
2108         VERIFY_NOT_NULL(TAG, b64Buf, ERROR);
2109
2110         VERIFY_SUCCESS(TAG, \
2111                        B64_OK == b64Encode(subOwnerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize), \
2112                        ERROR);
2113
2114         receivedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
2115         VERIFY_NOT_NULL(TAG, receivedCred->privateData.data, ERROR);
2116         receivedCred->privateData.len = b64OutSize;
2117         strncpy((char*)receivedCred->privateData.data, b64Buf, b64OutSize);
2118         receivedCred->privateData.data[b64OutSize] = '\0';
2119     }
2120     else
2121     {
2122         OIC_LOG_V(ERROR, TAG, "Unknown credential encoding type: %u.", receivedCred->privateData.encoding);
2123         goto exit;
2124     }
2125
2126     OIC_LOG(INFO, TAG, "PrivateData of SubOwnerPSK was calculated successfully");
2127     OICFree(b64Buf);
2128     return true;
2129 exit:
2130     //receivedCred->privateData.data will be deallocated when deleting credential.
2131     OICFree(b64Buf);
2132     return false;
2133 }
2134 #endif //MULTIPLE_OWNER
2135 #endif // __WITH_DTLS__ or __WITH_TLS__
2136
2137
2138 static OCEntityHandlerResult HandleNewCredential(OCEntityHandlerRequest *ehRequest, OicSecCred_t *cred, uint16_t previousMsgId)
2139 {
2140     OCEntityHandlerResult ret = OC_EH_INTERNAL_SERVER_ERROR;
2141
2142 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2143     OicUuid_t emptyUuid = {.id={0}};
2144     const OicSecDoxm_t *doxm = GetDoxmResourceData();
2145     if(NO_SECURITY_MODE != cred->credType && doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
2146     {
2147         //in case of owner PSK
2148         switch(cred->credType)
2149         {
2150             case SYMMETRIC_PAIR_WISE_KEY:
2151             {
2152                 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
2153                 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
2154                 {
2155                     if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
2156                     {
2157                         OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
2158                     }
2159
2160                     OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
2161                     if(OC_STACK_OK == AddCredential(cred))
2162                     {
2163                         ret = OC_EH_CHANGED;
2164                     }
2165                     else
2166                     {
2167                         OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
2168                         ret = OC_EH_ERROR;
2169                     }
2170                 }
2171                 else
2172                 {
2173                     OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
2174                     ret = OC_EH_ERROR;
2175                 }
2176
2177                 if(OC_EH_CHANGED == ret)
2178                 {
2179                     /**
2180                         * in case of random PIN based OxM,
2181                         * revert get_psk_info callback of tinyDTLS to use owner credential.
2182                         */
2183                     if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2184                     {
2185                         SetUuidForPinBasedOxm(&emptyUuid);
2186
2187 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2188                         if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
2189                         {
2190                             OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
2191                             ret = OC_EH_ERROR;
2192                             break;
2193                         }
2194 #endif // __WITH_DTLS__ or __WITH_TLS__
2195                     }
2196
2197                     //Select cipher suite to use owner PSK
2198                     if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
2199                     {
2200                         OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
2201                         ret = OC_EH_ERROR;
2202                     }
2203                     else
2204                     {
2205                         OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
2206                     }
2207
2208 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2209                     if(CA_STATUS_OK != CASelectCipherSuite(
2210                                 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
2211                     {
2212                         OIC_LOG(ERROR, TAG, "Failed to enable PSK cipher suite");
2213                         ret = OC_EH_ERROR;
2214                     }
2215                     else
2216                     {
2217                         OIC_LOG(INFO, TAG, "PSK cipher suite is ENABLED");
2218                     }
2219 #endif // __WITH_DTLS__ or __WITH_TLS__
2220                 }
2221
2222                 break;
2223             }
2224             case SYMMETRIC_GROUP_KEY:
2225             case ASYMMETRIC_KEY:
2226             case SIGNED_ASYMMETRIC_KEY:
2227             case PIN_PASSWORD:
2228             case ASYMMETRIC_ENCRYPTION_KEY:
2229             {
2230                 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
2231                 ret = OC_EH_ERROR;
2232                 break;
2233             }
2234             default:
2235             {
2236                 OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
2237                 ret = OC_EH_ERROR;
2238                 break;
2239             }
2240         }
2241
2242         if(OC_EH_CHANGED != ret)
2243         {
2244             /*
2245                 * If some error is occured while ownership transfer,
2246                 * ownership transfer related resource should be revert back to initial status.
2247                 */
2248             const OicSecDoxm_t *ownershipDoxm =  GetDoxmResourceData();
2249             if(ownershipDoxm)
2250             {
2251                 if(!ownershipDoxm->owned)
2252                 {
2253                     OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
2254
2255                     if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
2256                         || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
2257                     {
2258                         RestoreDoxmToInitState();
2259                         RestorePstatToInitState();
2260                         OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
2261                     }
2262                 }
2263             }
2264             else
2265             {
2266                 OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
2267             }
2268         }
2269     }
2270 #ifdef MULTIPLE_OWNER
2271     // In case SubOwner Credential
2272     else if(doxm && doxm->owned && doxm->mom &&
2273             OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
2274             0 == cred->privateData.len &&
2275             0 == cred->optionalData.len &&
2276             0 == cred->publicData.len )
2277     {
2278         switch(cred->credType)
2279         {
2280             case SYMMETRIC_PAIR_WISE_KEY:
2281             {
2282                 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
2283                 if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
2284                 {
2285                     if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
2286                     {
2287                         OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
2288                     }
2289
2290                     OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
2291                     if(OC_STACK_OK == AddCredential(cred))
2292                     {
2293                         ret = OC_EH_CHANGED;
2294                     }
2295                     else
2296                     {
2297                         OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
2298                         ret = OC_EH_ERROR;
2299                     }
2300                 }
2301                 else
2302                 {
2303                     OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
2304                     ret = OC_EH_ERROR;
2305                 }
2306             }
2307             break;
2308
2309             case SYMMETRIC_GROUP_KEY:
2310             case ASYMMETRIC_KEY:
2311             case SIGNED_ASYMMETRIC_KEY:
2312             case PIN_PASSWORD:
2313             case ASYMMETRIC_ENCRYPTION_KEY:
2314             {
2315                 OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
2316                 ret = OC_EH_ERROR;
2317                 break;
2318             }
2319             default:
2320             {
2321                 OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
2322                 ret = OC_EH_ERROR;
2323                 break;
2324             }
2325         }
2326     }
2327 #endif //MULTIPLE_OWNER
2328     else
2329     {
2330         if(IsEmptyCred(cred))
2331         {
2332                     if (UpdatePersistentStorage(gCred))
2333                     {
2334                         ret = OC_EH_CHANGED;
2335                     }
2336                     else
2337                     {
2338                         ret = OC_EH_ERROR;
2339                     }
2340         }
2341         else
2342         {
2343             /*
2344                 * If the post request credential has credId, it will be
2345                 * discarded and the next available credId will be assigned
2346                 * to it before getting appended to the existing credential
2347                 * list and updating svr database.
2348                 */
2349             ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2350         }
2351     }
2352 #else //not __WITH_DTLS__
2353     /*
2354         * If the post request credential has credId, it will be
2355         * discarded and the next available credId will be assigned
2356         * to it before getting appended to the existing credential
2357         * list and updating svr database.
2358         */
2359     ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2360     OC_UNUSED(previousMsgId);
2361     OC_UNUSED(ehRequest);
2362 #endif//__WITH_DTLS__
2363
2364     return ret;
2365 }
2366
2367 static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest* ehRequest)
2368 {
2369     OCEntityHandlerResult ret = OC_EH_INTERNAL_SERVER_ERROR;
2370     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
2371
2372     OicSecDostype_t dos;
2373     static uint16_t previousMsgId = 0;
2374     // Get binary representation of cbor
2375     OicSecCred_t *cred = NULL;
2376     OicUuid_t     *rownerId = NULL;
2377     uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
2378     size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
2379
2380     OCStackResult res = OC_STACK_OK;
2381
2382     VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDos(&dos), ERROR);
2383     if ((DOS_RESET == dos.state) ||
2384         (DOS_RFNOP == dos.state))
2385     {
2386         OIC_LOG_V(WARNING, TAG, "%s /cred resource is read-only in RESET and RFNOP.", __func__);
2387         ret = OC_EH_NOT_ACCEPTABLE;
2388         goto exit;
2389     }
2390
2391     res = CBORPayloadToCred(payload, size, &cred, &rownerId);
2392
2393     if (OC_STACK_OK == res)
2394     {
2395         OicSecCred_t *newCred = NULL;
2396         OicSecCred_t *newCredTemp = NULL;
2397
2398         LL_FOREACH_SAFE(cred, newCred, newCredTemp)
2399         {
2400             ret = HandleNewCredential(ehRequest, newCred, previousMsgId);
2401
2402             if (OC_EH_CHANGED != ret)
2403             {
2404                 // Remove the credentials added so far.
2405                 OicSecCred_t *removedCred = NULL;
2406                 OicSecCred_t *removedCredTemp = NULL;
2407                 LL_FOREACH_SAFE(cred, removedCred, removedCredTemp)
2408                 {
2409                     if (removedCred == newCred)
2410                     {
2411                         break;
2412                     }
2413
2414                     if (RemoveCredential(&cred->subject) != OC_STACK_OK)
2415                     {
2416                         OIC_LOG(WARNING, TAG, "Failed to remove credential");
2417                     }
2418                 }
2419
2420                 break;
2421             }
2422         }
2423         if (OC_EH_CHANGED == ret && NULL != rownerId)
2424         {
2425             memcpy(&gRownerId, rownerId, sizeof(OicUuid_t));
2426         }
2427     }
2428
2429 exit:
2430     OICFree(rownerId);
2431     if (OC_EH_CHANGED != ret)
2432     {
2433         if (NULL != cred)
2434         {
2435             DeleteCredList(cred);
2436         }
2437     }
2438     else
2439     {
2440         if (OC_ADAPTER_IP == ehRequest->devAddr.adapter)
2441         {
2442             previousMsgId = ehRequest->messageID++;
2443         }
2444     }
2445
2446     // Send response to request originator
2447     ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2448                    OC_EH_OK : OC_EH_ERROR;
2449
2450     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
2451     return ret;
2452 }
2453
2454 /**
2455  * The entity handler determines how to process a GET request.
2456  */
2457 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
2458 {
2459     OIC_LOG(INFO, TAG, "HandleGetRequest  processing GET request");
2460
2461     // Convert Cred data into CBOR for transmission
2462     size_t size = 0;
2463     uint8_t *payload = NULL;
2464     int secureFlag = 1;
2465
2466     const OicSecCred_t *cred = gCred;
2467
2468     // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2469     size = GetCredKeyDataSize(cred);
2470     size += (256 * OicSecCredCount(cred));
2471     OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
2472
2473     // A device should always have a default cred. Therefore, payload should never be NULL.
2474     OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
2475
2476     //Send payload to request originator
2477     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
2478                        OC_EH_OK : OC_EH_ERROR;
2479     OICClearMemory(payload, size);
2480     OICFree(payload);
2481     return ehRet;
2482 }
2483
2484 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
2485 {
2486     OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
2487
2488     OCEntityHandlerResult ehRet = OC_EH_ERROR;
2489     CredIdList_t *credIdList = NULL;
2490     OicUuid_t subject = { .id= { 0 } };
2491
2492     if (NULL == ehRequest->query)
2493     {
2494         return ehRet;
2495     }
2496
2497     if (GetCredIdsFromQueryString(ehRequest->query, &credIdList))
2498     {
2499         if (OC_STACK_RESOURCE_DELETED == RemoveCredentialByCredIds(credIdList))
2500         {
2501             ehRet = OC_EH_RESOURCE_DELETED;
2502         }
2503         DeleteCredIdList(&credIdList);
2504     }
2505     else if (GetSubjectFromQueryString(ehRequest->query, &subject))
2506     {
2507         if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
2508         {
2509             ehRet = OC_EH_RESOURCE_DELETED;
2510         }
2511     }
2512     else
2513     {
2514         if (OC_STACK_OK == RemoveAllCredentials())
2515         {
2516             ehRet = OC_EH_RESOURCE_DELETED;
2517         }
2518     }
2519
2520     //Send response to request originator
2521     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2522                    OC_EH_OK : OC_EH_ERROR;
2523     return ehRet;
2524 }
2525
2526 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
2527                                         OCEntityHandlerRequest * ehRequest,
2528                                         void* callbackParameter)
2529 {
2530     (void)callbackParameter;
2531     OCEntityHandlerResult ret = OC_EH_ERROR;
2532
2533     if (!ehRequest)
2534     {
2535         return OC_EH_ERROR;
2536     }
2537     if (flag & OC_REQUEST_FLAG)
2538     {
2539         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
2540         //TODO :  Remove Handle PUT methods once CTT have changed to POST on OTM
2541         switch (ehRequest->method)
2542         {
2543             case OC_REST_GET:
2544                 ret = HandleGetRequest(ehRequest);
2545                 break;
2546             case OC_REST_PUT:
2547             case OC_REST_POST:
2548                 ret = HandlePostRequest(ehRequest);
2549                 break;
2550             case OC_REST_DELETE:
2551                 ret = HandleDeleteRequest(ehRequest);
2552                 break;
2553             default:
2554                 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2555                                OC_EH_OK : OC_EH_ERROR;
2556                 break;
2557         }
2558     }
2559     return ret;
2560 }
2561
2562 OCStackResult CreateCredResource()
2563 {
2564     OCStackResult ret = OCCreateResource(&gCredHandle,
2565                                          OIC_RSRC_TYPE_SEC_CRED,
2566                                          OC_RSRVD_INTERFACE_DEFAULT,
2567                                          OIC_RSRC_CRED_URI,
2568                                          CredEntityHandler,
2569                                          NULL,
2570                                          OC_SECURE |
2571                                          OC_DISCOVERABLE);
2572
2573     if (OC_STACK_OK != ret)
2574     {
2575         OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2576         DeInitCredResource();
2577     }
2578     return ret;
2579 }
2580
2581 OCStackResult InitCredResource()
2582 {
2583     OCStackResult ret = OC_STACK_ERROR;
2584     OicSecCred_t* cred = NULL;
2585     OicUuid_t   *rownerId = NULL;
2586
2587     //Read Cred resource from PS
2588     uint8_t *data = NULL;
2589     size_t size = 0;
2590     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2591     // If database read failed
2592     if (ret != OC_STACK_OK)
2593     {
2594         OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2595     }
2596
2597     if ((ret == OC_STACK_OK) && data)
2598     {
2599         // Read Cred resource from PS
2600         ret = CBORPayloadToCred(data, size, &gCred, &rownerId);
2601
2602 #ifdef HAVE_WINDOWS_H
2603         /* On Windows, if the credential payload isn't cleartext CBOR, it is encrypted. Decrypt and retry. */
2604         DWORD dwordSize;
2605
2606         if (FAILED(SizeTToDWord(size, &dwordSize)))
2607         {
2608             OIC_LOG(DEBUG, TAG, "Cred size too large.");
2609             ret = OC_STACK_ERROR;
2610         }
2611
2612         if (ret != OC_STACK_OK)
2613         {
2614             DATA_BLOB decryptedPayload;
2615             DATA_BLOB encryptedPayload;
2616             memset(&decryptedPayload, 0, sizeof(decryptedPayload));
2617             memset(&encryptedPayload, 0, sizeof(encryptedPayload));
2618             encryptedPayload.cbData = dwordSize;
2619             encryptedPayload.pbData = data;
2620
2621             if (CryptUnprotectData(
2622                 &encryptedPayload,
2623                 NULL,
2624                 NULL,
2625                 NULL,
2626                 NULL,
2627                 CRYPTPROTECT_UI_FORBIDDEN,
2628                 &decryptedPayload))
2629             {
2630                 ret = CBORPayloadToCred(decryptedPayload.pbData, decryptedPayload.cbData, &gCred, &rownerId);
2631
2632                 /* For the returned data from CryptUnprotectData, LocalFree must be used to free. Don't use OICFree. */
2633                 OICClearMemory(decryptedPayload.pbData, decryptedPayload.cbData);
2634                 if (NULL != LocalFree(decryptedPayload.pbData))
2635                 {
2636                     OIC_LOG_V(ERROR, TAG, "LocalFree failed on output from CryptUnprotectData; memory may be corrupted or leaked. Last error: %u.", GetLastError());
2637                     assert(!"LocalFree failed");
2638                 }
2639             }
2640             else
2641             {
2642                 /* Credential resource is corrupted, or we no longer have access to the encryption key to decrypt it. */
2643                 OIC_LOG_V(ERROR, TAG, "Failed to CryptUnprotectData cred resource: %u", GetLastError());
2644                 ret = OC_STACK_ERROR;
2645             }
2646         }
2647 #endif
2648     }
2649
2650     /*
2651      * If SVR database in persistent storage got corrupted or
2652      * is not available for some reason, a default Cred is created
2653      * which allows user to initiate Cred provisioning again.
2654      */
2655     if (ret != OC_STACK_OK || !data || !gCred)
2656     {
2657         gCred = GetCredDefault();
2658     }
2659
2660     if (gCred)
2661     {
2662         OicUuid_t deviceID;
2663         OicUuid_t emptyUuid = {.id={0}};
2664
2665         ret = GetDoxmDeviceID(&deviceID);
2666         if (ret != OC_STACK_OK)
2667         {
2668             OIC_LOG_V(WARNING, TAG, "%s: GetDoxmDeviceID failed, error %d", __func__, ret);
2669             //Unit tests expect error code OC_STACK_INVALID_PARAM.
2670             ret = OC_STACK_INVALID_PARAM;
2671             goto exit;
2672         }
2673
2674         //Add a log to track the invalid credential.
2675         LL_FOREACH(gCred, cred)
2676         {
2677             if (false == CheckSubjectOfCertificate(cred, deviceID))
2678             {
2679                 OIC_LOG(WARNING, TAG, "Check subject of Certificate was failed while InitCredResource");
2680             }
2681             if (false == IsValidCredential(cred))
2682             {
2683                 OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
2684                 OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
2685             }
2686         }
2687
2688         if (NULL == rownerId || 0 == memcmp(rownerId, &emptyUuid, sizeof(OicUuid_t)))
2689         {
2690             memcpy(&gRownerId, &deviceID, sizeof(OicUuid_t));
2691         }
2692         else
2693         {
2694             memcpy(&gRownerId, rownerId, sizeof(OicUuid_t));
2695         }
2696
2697         if (!UpdatePersistentStorage(gCred))
2698         {
2699             OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
2700         }
2701     }
2702     //Instantiate 'oic.sec.cred'
2703     ret = CreateCredResource();
2704
2705 exit:
2706     OIC_LOG(DEBUG, TAG, "OUT InitCredResource.");
2707     OICClearMemory(data, size);
2708     OICFree(data);
2709     OICFree(rownerId);
2710     return ret;
2711 }
2712
2713 OCStackResult DeInitCredResource()
2714 {
2715     OCStackResult result = OCDeleteResource(gCredHandle);
2716     DeleteCredList(gCred);
2717     gCred = NULL;
2718     return result;
2719 }
2720
2721 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2722 {
2723     OicSecCred_t *cred = NULL;
2724
2725    if ( NULL == subject)
2726     {
2727        return NULL;
2728     }
2729
2730     LL_FOREACH(gCred, cred)
2731     {
2732         if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2733         {
2734             return cred;
2735         }
2736     }
2737     return NULL;
2738 }
2739
2740 const OicSecCred_t* GetCredList()
2741 {
2742     return gCred;
2743 }
2744
2745 OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
2746 {
2747     OicSecCred_t *cred = NULL;
2748     OicSecCred_t *tmpCred = NULL;
2749
2750    if ( 1 > credId)
2751     {
2752        return NULL;
2753     }
2754
2755     LL_FOREACH(gCred, tmpCred)
2756     {
2757         if(tmpCred->credId == credId)
2758         {
2759             cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2760             VERIFY_NOT_NULL(TAG, cred, ERROR);
2761
2762             // common
2763             cred->next = NULL;
2764             cred->credId = tmpCred->credId;
2765             cred->credType = tmpCred->credType;
2766             memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
2767             if (tmpCred->period)
2768             {
2769                 cred->period = OICStrdup(tmpCred->period);
2770             }
2771
2772             // key data
2773             if (tmpCred->privateData.data)
2774             {
2775                 cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
2776                 VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
2777
2778                 memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
2779                 cred->privateData.len = tmpCred->privateData.len;
2780                 cred->privateData.encoding = tmpCred->privateData.encoding;
2781             }
2782 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2783             if (tmpCred->publicData.data)
2784             {
2785                 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
2786                 VERIFY_NOT_NULL(TAG, cred->publicData.data, ERROR);
2787
2788                 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
2789                 cred->publicData.len = tmpCred->publicData.len;
2790                 cred->publicData.encoding = tmpCred->publicData.encoding;
2791             }
2792             if (tmpCred->optionalData.data)
2793             {
2794                 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
2795                 VERIFY_NOT_NULL(TAG, cred->optionalData.data, ERROR);
2796
2797                 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
2798                 cred->optionalData.len = tmpCred->optionalData.len;
2799                 cred->optionalData.encoding = tmpCred->optionalData.encoding;
2800                 cred->optionalData.revstat= tmpCred->optionalData.revstat;
2801             }
2802             if (tmpCred->credUsage)
2803             {
2804                 cred->credUsage = OICStrdup(tmpCred->credUsage);
2805             }
2806 #endif /* __WITH_DTLS__  or __WITH_TLS__*/
2807
2808             return cred;
2809         }
2810     }
2811
2812 exit:
2813     FreeCred(cred);
2814     return NULL;
2815 }
2816
2817 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2818 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2819               const uint8_t *desc, size_t desc_len,
2820               uint8_t *result, size_t result_length)
2821 {
2822     int32_t ret = -1;
2823
2824     if (NULL == result)
2825     {
2826         return ret;
2827     }
2828
2829     switch (type)
2830     {
2831         case CA_DTLS_PSK_HINT:
2832         case CA_DTLS_PSK_IDENTITY:
2833             {
2834                 OicUuid_t deviceID = {.id={0}};
2835                 // Retrieve Device ID from doxm resource
2836                 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2837                 {
2838                     OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2839                     return ret;
2840                 }
2841
2842                 if (result_length < sizeof(deviceID.id))
2843                 {
2844                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2845                     return ret;
2846                 }
2847                 memcpy(result, deviceID.id, sizeof(deviceID.id));
2848                 return (sizeof(deviceID.id));
2849             }
2850             break;
2851
2852         case CA_DTLS_PSK_KEY:
2853             {
2854                 OicSecCred_t *cred = NULL;
2855                 LL_FOREACH(gCred, cred)
2856                 {
2857                     if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2858                     {
2859                         continue;
2860                     }
2861
2862                     if ((desc_len == sizeof(cred->subject.id)) &&
2863                         (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2864                     {
2865                         /*
2866                          * If the credentials are valid for limited time,
2867                          * check their expiry.
2868                          */
2869                         if (cred->period)
2870                         {
2871                             if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2872                             {
2873                                 OIC_LOG (INFO, TAG, "Credentials are expired.");
2874                                 return ret;
2875                             }
2876                         }
2877
2878                         // Copy PSK.
2879                         // TODO: Added as workaround. Will be replaced soon.
2880                         if(OIC_ENCODING_RAW == cred->privateData.encoding)
2881                         {
2882                             if (ValueWithinBounds(cred->privateData.len, INT32_MAX))
2883                             {
2884                                 size_t len = cred->privateData.len;
2885                                 if (result_length < len)
2886                                 {
2887                                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2888                                     return ret;
2889                                 }
2890                                 memcpy(result, cred->privateData.data, len);
2891                                 ret = (int32_t)len;
2892                             }
2893                         }
2894                         else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2895                         {
2896                             size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2897                             uint8_t* outKey = OICCalloc(1, outBufSize);
2898                             size_t outKeySize;
2899                             if(NULL == outKey)
2900                             {
2901                                 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2902                                 return ret;
2903                             }
2904
2905                             if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2906                             {
2907                                 if (ValueWithinBounds(outKeySize, INT32_MAX))
2908                                 {
2909                                     if (result_length < outKeySize)
2910                                     {
2911                                         OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2912                                         return ret;
2913                                     }
2914                                     memcpy(result, outKey, outKeySize);
2915                                     ret = (int32_t)outKeySize;
2916                                 }
2917                             }
2918                             else
2919                             {
2920                                 OIC_LOG (ERROR, TAG, "Failed base64 decoding.");
2921                             }
2922
2923                             OICFree(outKey);
2924                         }
2925
2926                         if (OC_STACK_OK != RegisterSymmetricCredentialRole(cred))
2927                         {
2928                             OIC_LOG(WARNING, TAG, "Couldn't RegisterRoleForSubject");
2929                         }
2930
2931                         return ret;
2932                     }
2933                 }
2934                 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2935
2936 #ifdef MULTIPLE_OWNER
2937                 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2938                 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2939                 {
2940                     // in case of multiple owner transfer authentication
2941                     if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2942                     {
2943                         OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2944                         if(wildCardCred)
2945                         {
2946                             OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2947                             if(PIN_PASSWORD == wildCardCred->credType)
2948                             {
2949                                 //Read PIN/PW
2950                                 char* pinBuffer = NULL;
2951                                 size_t pinLength = 0;
2952                                 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2953                                 {
2954                                     pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2955                                     if(NULL == pinBuffer)
2956                                     {
2957                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2958                                         return ret;
2959                                     }
2960                                     pinLength = wildCardCred->privateData.len;
2961                                     memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2962                                 }
2963                                 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2964                                 {
2965                                     size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2966                                     pinBuffer = OICCalloc(1, pinBufSize);
2967                                     if(NULL == pinBuffer)
2968                                     {
2969                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2970                                         return ret;
2971                                     }
2972
2973                                     if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, (uint8_t*)pinBuffer, pinBufSize, &pinLength))
2974                                     {
2975                                         OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2976                                         return ret;
2977                                     }
2978                                 }
2979                                 else
2980                                 {
2981                                     OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2982                                     return ret;
2983                                 }
2984
2985                                 //Set the PIN/PW to derive PSK
2986                                 if (OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2987                                 {
2988                                     OICFree(pinBuffer);
2989                                     OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2990                                     return ret;
2991                                 }
2992                                 OICFree(pinBuffer);
2993
2994                                 OicUuid_t myUuid;
2995                                 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2996                                 {
2997                                     OIC_LOG(ERROR, TAG, "Failed to read device ID");
2998                                     return ret;
2999                                 }
3000                                 SetUuidForPinBasedOxm(&myUuid);
3001
3002                                 //Calculate PSK using PIN/PW
3003                                 if(0 == DerivePSKUsingPIN((uint8_t*)result))
3004                                 {
3005                                     ret = OWNER_PSK_LENGTH_128;
3006                                 }
3007                                 else
3008                                 {
3009                                     OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
3010                                 }
3011
3012                                 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
3013                                 {
3014                                     OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
3015                                 }
3016                             }
3017                         }
3018                     }
3019                     else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
3020                     {
3021                         if(0 == DerivePSKUsingPIN((uint8_t*)result))
3022                         {
3023                             ret = OWNER_PSK_LENGTH_128;
3024                         }
3025                         else
3026                         {
3027                             OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
3028                             ret = -1;
3029                         }
3030                     }
3031                 }
3032 #endif //MULTIPLE_OWNER
3033             }
3034             break;
3035     }
3036
3037     return ret;
3038 }
3039
3040 /**
3041  * Add temporal PSK to PIN based OxM
3042  *
3043  * @param[in] tmpSubject UUID of target device
3044  * @param[in] credType Type of credential to be added
3045  * @param[in] pin numeric characters
3046  * @param[in] pinSize length of 'pin'
3047  * @param[in] rownerID Resource owner's UUID
3048  * @param[out] tmpCredSubject Generated credential's subject.
3049  *
3050  * @return OC_STACK_OK for success and errorcode otherwise.
3051  */
3052 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
3053                             const char * pin, size_t pinSize,
3054                             const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
3055 {
3056     OCStackResult ret = OC_STACK_ERROR;
3057     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
3058
3059     if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
3060     {
3061         return OC_STACK_INVALID_PARAM;
3062     }
3063
3064     uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
3065     OicSecKey_t privKey;
3066     memset(&privKey, 0, sizeof(privKey));
3067     privKey.data = privData;
3068     privKey.len = OWNER_PSK_LENGTH_128;
3069     privKey.encoding = OIC_ENCODING_RAW;
3070
3071     OicSecCred_t* cred = NULL;
3072     int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
3073                                               UUID_LENGTH, PBKDF_ITERATIONS,
3074                                               OWNER_PSK_LENGTH_128, privData);
3075     VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
3076
3077     cred = GenerateCredential(tmpSubject, credType, NULL,
3078                               &privKey, rownerID, NULL);
3079     OICClearMemory(privData, sizeof(privData));
3080     if(NULL == cred)
3081     {
3082         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
3083         return OC_STACK_ERROR;
3084     }
3085
3086     memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
3087
3088     ret = AddCredential(cred);
3089     if( OC_STACK_OK != ret)
3090     {
3091         RemoveCredential(tmpSubject);
3092         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
3093     }
3094     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
3095
3096 exit:
3097     return ret;
3098 }
3099
3100 #endif /* __WITH_DTLS__ */
3101
3102 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
3103 {
3104     OCStackResult ret = OC_STACK_ERROR;
3105     OicUuid_t prevId = {.id={0}};
3106
3107     if(NULL == newROwner)
3108     {
3109         ret = OC_STACK_INVALID_PARAM;
3110     }
3111
3112     if (newROwner)
3113     {
3114         memcpy(prevId.id, gRownerId.id, sizeof(prevId.id));
3115         memcpy(gRownerId.id, newROwner->id, sizeof(newROwner->id));
3116
3117         VERIFY_SUCCESS(TAG, UpdatePersistentStorage(gCred), ERROR);
3118
3119         ret = OC_STACK_OK;
3120     }
3121
3122     return ret;
3123
3124 exit:
3125     memcpy(gRownerId.id, prevId.id, sizeof(prevId.id));
3126     return ret;
3127 }
3128
3129 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
3130 {
3131     if (rowneruuid)
3132     {
3133         memcpy(&(rowneruuid->id), &(gRownerId.id), sizeof(rowneruuid->id));
3134         return OC_STACK_OK;
3135     }
3136     return OC_STACK_ERROR;
3137 }
3138
3139 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
3140 /* Caller must call OICFree on *der when finished. */
3141 static int ConvertPemCertToDer(const char *pem, size_t pemLen, uint8_t** der, size_t* derLen)
3142 {
3143     const char* pemHeader = "-----BEGIN CERTIFICATE-----"; /* no newlines allowed here */
3144     const char* pemFooter = "-----END CERTIFICATE-----";
3145
3146     mbedtls_pem_context ctx;
3147     int ret;
3148
3149     OC_UNUSED(pemLen);
3150
3151     mbedtls_pem_init(&ctx);
3152     size_t usedLen;
3153     ret = mbedtls_pem_read_buffer(&ctx, pemHeader, pemFooter, (const uint8_t*) pem, NULL, 0, &usedLen);
3154     if (ret != 0)
3155     {
3156         OIC_LOG_V(ERROR, TAG, "%s: failed reading PEM cert", __func__);
3157         goto exit;
3158     }
3159
3160     uint8_t *buf = OICCalloc(1, ctx.buflen);
3161     if (NULL == buf)
3162     {
3163         OIC_LOG(ERROR, TAG, "Failed to allocate memory");
3164         ret = -1;
3165         goto exit;
3166     }
3167
3168     memcpy(buf, ctx.buf, ctx.buflen);
3169
3170     *der = buf;
3171     *derLen = ctx.buflen;
3172
3173 exit:
3174     mbedtls_pem_free(&ctx);
3175
3176     return ret;
3177 }
3178
3179 /* Caller must call OICFree on *pem when finished. */
3180 static int ConvertDerCertToPem(const uint8_t* der, size_t derLen, uint8_t** pem)
3181 {
3182     const char* pemHeader = "-----BEGIN CERTIFICATE-----\n";
3183     const char* pemFooter = "-----END CERTIFICATE-----\n";
3184
3185     /* Get the length required for output */
3186     size_t pemLen;
3187     int ret = mbedtls_pem_write_buffer(pemHeader,
3188         pemFooter,
3189         der,
3190         derLen,
3191         NULL,
3192         0,
3193         &pemLen);
3194     if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL)
3195     {
3196         OIC_LOG_V(ERROR, TAG, "Couldn't convert cert into PEM, failed getting required length: %d", ret);
3197         return ret;
3198     }
3199
3200     *pem = OICCalloc(1, pemLen + 1);
3201     if (*pem == NULL)
3202     {
3203         OIC_LOG(ERROR, TAG, "Failed to allocate memory for PEM cert");
3204         return ret;
3205     }
3206
3207     /* Try the conversion */
3208     ret = mbedtls_pem_write_buffer(pemHeader,
3209         pemFooter,
3210         der,
3211         derLen,
3212         *pem,
3213         pemLen,
3214         &pemLen);
3215     if (ret < 0)
3216     {
3217         OIC_LOG_V(ERROR, TAG, "Couldn't convert cert into PEM, failed writing PEM: %d", ret);
3218         OICFreeAndSetToNull((void **) pem);
3219         return ret;
3220     }
3221
3222     return 0;
3223 }
3224
3225 static OCStackResult GetCaCert(ByteArray_t * crt, const char * usage, OicEncodingType_t desiredEncoding)
3226 {
3227     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
3228     if (NULL == crt || NULL == usage)
3229     {
3230         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
3231         return OC_STACK_INVALID_PARAM;
3232     }
3233
3234     switch (desiredEncoding)
3235     {
3236     case OIC_ENCODING_PEM:
3237     case OIC_ENCODING_DER:
3238     case OIC_ENCODING_BASE64:
3239         break;
3240     default:
3241         OIC_LOG_V(ERROR, TAG, "%s: Unsupported encoding %d", __func__, desiredEncoding);
3242         return OC_STACK_INVALID_PARAM;
3243     }
3244
3245     crt->len = 0;
3246     OicSecCred_t* temp = NULL;
3247
3248     LL_FOREACH(gCred, temp)
3249     {
3250         if ((SIGNED_ASYMMETRIC_KEY == temp->credType) &&
3251             (temp->credUsage != NULL) &&
3252             (0 == strcmp(temp->credUsage, usage)) && (false == temp->optionalData.revstat))
3253         {
3254
3255             if ((OIC_ENCODING_BASE64 != temp->publicData.encoding) &&
3256                 (OIC_ENCODING_PEM != temp->publicData.encoding) &&
3257                 (OIC_ENCODING_DER != temp->publicData.encoding))
3258             {
3259                 OIC_LOG_V(WARNING, TAG, "%s: Unknown encoding type", __func__);
3260                 continue;
3261             }
3262
3263             if (OIC_ENCODING_DER == desiredEncoding)
3264             {
3265                 if ((OIC_ENCODING_BASE64 == temp->publicData.encoding) ||
3266                     (OIC_ENCODING_PEM == temp->publicData.encoding))
3267                 {
3268                     uint8_t* buf = NULL;
3269                     size_t outSize = 0;
3270                     int ret = ConvertPemCertToDer((const char*)temp->publicData.data, temp->publicData.len, &buf, &outSize);
3271                     if (0 > ret)
3272                     {
3273                         OIC_LOG(ERROR, TAG, "Could not convert PEM cert to DER");
3274                         return OC_STACK_ERROR;
3275                     }
3276
3277                     uint8_t *savePtr = crt->data;
3278                     crt->data = OICRealloc(crt->data, crt->len + outSize);
3279                     if (NULL == crt->data)
3280                     {
3281                         OIC_LOG(ERROR, TAG, "No memory reallocating crt->data");
3282                         OICFree(savePtr);
3283                         OICFree(buf);
3284                         return OC_STACK_NO_MEMORY;
3285                     }
3286                     memcpy(crt->data + crt->len, buf, outSize);
3287                     crt->len += outSize;
3288                     OICFree(buf);
3289                 }
3290                 else
3291                 {
3292                     uint8_t *savePtr = crt->data;
3293                     crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
3294                     if (NULL == crt->data)
3295                     {
3296                         OIC_LOG(ERROR, TAG, "No memory reallocating crt->data");
3297                         OICFree(savePtr);
3298                         return OC_STACK_NO_MEMORY;
3299                     }
3300                     memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
3301                     crt->len += temp->publicData.len;
3302                 }
3303                 OIC_LOG_V(DEBUG, TAG, "%s found", usage);
3304             }
3305             else
3306             {
3307                 /* PEM/Base64 */
3308                 uint8_t *pem = NULL;
3309                 size_t pemLen = 0;
3310                 if ((OIC_ENCODING_BASE64 == temp->publicData.encoding) ||
3311                     (OIC_ENCODING_PEM == temp->publicData.encoding))
3312                 {
3313                     pem = temp->publicData.data;
3314                     pemLen = temp->publicData.len;
3315                 }
3316                 else
3317                 {
3318                     int ret = ConvertDerCertToPem(temp->publicData.data, temp->publicData.len, &pem);
3319                     if (0 > ret)
3320                     {
3321                         OIC_LOG_V(ERROR, TAG, "Failed converting DER cert to PEM: %d", ret);
3322                         return OC_STACK_ERROR;
3323                     }
3324                     pemLen = strlen((char *)pem) + 1;
3325                 }
3326
3327                 uint8_t *oldData = crt->data;
3328                 crt->data = OICRealloc(crt->data, crt->len + pemLen);
3329                 if (NULL == crt->data)
3330                 {
3331                     OIC_LOG(ERROR, TAG, "No memory reallocating crt->data");
3332                     OICFree(oldData);
3333                     return OC_STACK_NO_MEMORY;
3334                 }
3335                 memcpy(crt->data + crt->len, pem, pemLen);
3336                 crt->len += pemLen;
3337             }
3338         }
3339     }
3340     if(0 == crt->len)
3341     {
3342         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
3343         return OC_STACK_NO_RESOURCE;
3344     }
3345
3346     if (OIC_ENCODING_PEM == desiredEncoding)
3347     {
3348         /* mbedtls_x509_crt_parse requires a null terminator to determine that the format is PEM */
3349         size_t crtLength = crt->len;
3350         bool addNull = (crt->data[crtLength - 1] != 0);
3351
3352         if (addNull)
3353         {
3354             OIC_LOG_V(DEBUG, TAG, "%s: adding null terminator at the end of the cert", __func__);
3355             uint8_t *oldData = crt->data;
3356             crt->data = OICRealloc(crt->data, crtLength + 1);
3357             if (NULL == crt->data)
3358             {
3359                 OIC_LOG(ERROR, TAG, "No memory reallocating crt->data");
3360                 OICFree(oldData);
3361                 return OC_STACK_NO_MEMORY;
3362             }
3363             crt->data[crtLength] = 0;
3364             crt->len = crtLength + 1;
3365         }
3366     }
3367
3368     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
3369     return OC_STACK_OK;
3370 }
3371
3372 OCStackResult GetPemCaCert(ByteArray_t * crt, const char * usage)
3373 {
3374     return GetCaCert(crt, usage, OIC_ENCODING_PEM);
3375 }
3376
3377 static int cloneSecKey(OicSecKey_t * dst, OicSecKey_t * src)
3378 {
3379     if ((src == NULL) || (dst == NULL))
3380     {
3381         return -1;
3382     }
3383
3384     if (src->len > 0)
3385     {
3386         dst->data = OICCalloc(src->len, 1);
3387         if (dst->data == NULL)
3388         {
3389             OIC_LOG_V(ERROR, TAG, "%s memory allocation failed", __func__);
3390             return -1;
3391         }
3392         memcpy(dst->data, src->data, src->len);
3393     }
3394     else
3395     {
3396         dst->data = NULL;
3397     }
3398
3399     dst->len = src->len;
3400     dst->encoding = src->encoding;
3401
3402     return 0;
3403 }
3404
3405 /* Caller must call FreeRoleCertChainList on roleEntries when finished. */
3406 OCStackResult GetAllRoleCerts(RoleCertChain_t ** output)
3407 {
3408     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
3409
3410     *output = NULL;
3411
3412     OicSecCred_t * temp = NULL;
3413     LL_FOREACH(gCred, temp)
3414     {
3415         if ((SIGNED_ASYMMETRIC_KEY == temp->credType) &&
3416             (temp->credUsage != NULL) &&
3417             (0 == strcmp(temp->credUsage, ROLE_CERT)))
3418         {
3419             if (temp->publicData.data == NULL)
3420             {
3421                 OIC_LOG_V(WARNING, TAG, "%s missing certificate data in role certificate", __func__);
3422                 continue;
3423             }
3424
3425             RoleCertChain_t * add = (RoleCertChain_t *) OICCalloc(1, sizeof(RoleCertChain_t));
3426             if (add == NULL)
3427             {
3428                 OIC_LOG_V(ERROR, TAG, "%s Failed to allocate memory", __func__);
3429                 goto error;
3430             }
3431             LL_APPEND(*output, add);
3432             add->credId = temp->credId;
3433             if (cloneSecKey(&add->certificate, &temp->publicData) != 0)
3434             {
3435                 OIC_LOG_V(ERROR, TAG, "%s failed to copy certificate data", __func__);
3436                 goto error;
3437             }
3438         }
3439     }
3440
3441     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
3442     return OC_STACK_OK;
3443
3444 error:
3445     FreeRoleCertChainList(*output);
3446     *output = NULL;
3447     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
3448     return OC_STACK_ERROR;
3449 }
3450
3451 void GetPemOwnCert(ByteArray_t * crt, const char * usage)
3452 {
3453     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
3454     if (NULL == crt || NULL == usage)
3455     {
3456         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
3457         return;
3458     }
3459     crt->len = 0;
3460     OicSecCred_t * temp = NULL;
3461     LL_FOREACH(gCred, temp)
3462     {
3463         if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
3464             temp->credUsage != NULL &&
3465             0 == strcmp(temp->credUsage, usage))
3466         {
3467             uint8_t *p = NULL;
3468             int mbedRet = 0;
3469             uint8_t *pem = NULL;
3470             size_t pemLen = 0;
3471             bool mustFreePem = false;
3472             bool mustAddNull = true;
3473
3474             switch (temp->publicData.encoding)
3475             {
3476             case OIC_ENCODING_DER:
3477             case OIC_ENCODING_RAW:
3478                 mbedRet = ConvertDerCertToPem(temp->publicData.data, temp->publicData.len, &pem);
3479                 if (0 > mbedRet)
3480                 {
3481                     OIC_LOG_V(ERROR, TAG, "Failed to ConvertDerCertToPem: %d", mbedRet);
3482                     return;
3483                 }
3484                 mustFreePem = true;
3485                 mustAddNull = false; /* mbedTLS always NULL-terminates. */
3486                 pemLen = strlen((char *)pem) + 1;
3487                 break;
3488
3489             case OIC_ENCODING_PEM:
3490             case OIC_ENCODING_BASE64:
3491                 pem = temp->publicData.data;
3492                 pemLen = temp->publicData.len;
3493
3494                 /* Make sure the buffer has a terminating NULL. If not, make sure we add one later. */
3495                 for (size_t i = pemLen - 1; i > 0; i--)
3496                 {
3497                     if ('\0' == (char)pem[i])
3498                     {
3499                         mustAddNull = false;
3500                         break;
3501                     }
3502                 }
3503                 break;
3504
3505             default:
3506                 OIC_LOG_V(ERROR, TAG, "Unsupported encoding %d", temp->publicData.encoding);
3507                 return;
3508             }
3509
3510             p = crt->data;
3511             crt->data = OICRealloc(crt->data, crt->len + pemLen + (mustAddNull ? 1 : 0));
3512             if (NULL == crt->data)
3513             {
3514                 OIC_LOG(ERROR, TAG, "No memory reallocating crt->data");
3515                 OICFree(p);
3516                 if (mustFreePem)
3517                 {
3518                     OICFree(pem);
3519                 }
3520                 return;
3521             }
3522
3523             /* If we're appending, subtract one from crt->len below so we overwrite the current terminating
3524              * NULL with the beginning of the new data.
3525              */
3526             if (0 < crt->len)
3527             {
3528                 assert(crt->data[crt->len - 1] == '\0');
3529                 memcpy(crt->data + crt->len - 1, pem, pemLen);
3530                 crt->len += pemLen - 1;
3531             }
3532             else
3533             {
3534                 memcpy(crt->data, pem, pemLen);
3535                 crt->len = pemLen;
3536             }
3537
3538             /* If pem doesn't contain a terminating NULL, add one. */
3539             if (mustAddNull)
3540             {
3541                 assert(crt->data[crt->len - 1] != '\0');
3542                 crt->data[crt->len] = '\0';
3543                 crt->len += 1;
3544             }
3545
3546             if (mustFreePem)
3547             {
3548                 OICFree(pem);
3549             }
3550
3551             OIC_LOG_V(DEBUG, TAG, "%s found", usage);
3552         }
3553     }
3554     if(0 == crt->len)
3555     {
3556         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
3557     }
3558     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
3559     return;
3560 }
3561
3562 void GetDerKey(ByteArray_t * key, const char * usage)
3563 {
3564     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
3565     if (NULL == key || NULL == usage)
3566     {
3567         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
3568         return;
3569     }
3570
3571     OicSecCred_t * temp = NULL;
3572     key->len = 0;
3573     LL_FOREACH(gCred, temp)
3574     {
3575         if ((SIGNED_ASYMMETRIC_KEY == temp->credType || ASYMMETRIC_KEY == temp->credType) &&
3576             temp->privateData.len > 0 &&
3577             NULL != temp->credUsage &&
3578             0 == strcmp(temp->credUsage, usage))
3579         {
3580
3581             if (temp->privateData.encoding == OIC_ENCODING_PEM)
3582             {
3583                 /* Convert PEM to DER */
3584                 const char* pemHeader = "-----BEGIN EC PRIVATE KEY-----"; /* no newlines allowed here */
3585                 const char* pemFooter = "-----END EC PRIVATE KEY-----";
3586                 uint8_t *data = temp->privateData.data;
3587                 size_t length = temp->privateData.len;
3588                 bool freeData = false;
3589
3590                 if (data[length - 1] != 0)
3591                 {
3592                     /* Add a null terminator, because mbedtls_pem_read_buffer requires it */
3593                     OIC_LOG_V(DEBUG, TAG, "%s: adding null terminator to privateData", __func__);
3594
3595                     data = OICMalloc(length + 1);
3596                     if (NULL == data)
3597                     {
3598                         OIC_LOG(ERROR, TAG, "Failed to allocate memory");
3599                         return;
3600                     }
3601
3602                     memcpy(data, temp->privateData.data, length);
3603                     data[length] = 0;
3604                     freeData = true;
3605                 }
3606
3607                 mbedtls_pem_context ctx;
3608                 int ret;
3609                 size_t usedLen;
3610
3611                 mbedtls_pem_init(&ctx);
3612                 ret = mbedtls_pem_read_buffer(&ctx, pemHeader, pemFooter, data, NULL, 0, &usedLen);
3613
3614                 if (freeData)
3615                 {
3616                     OICFree(data);
3617                 }
3618
3619                 if (ret != 0)
3620                 {
3621                     OIC_LOG_V(ERROR, TAG, "%s: failed reading PEM key", __func__);
3622                     mbedtls_pem_free(&ctx);
3623                     return;
3624                 }
3625
3626                 uint8_t *tmp = OICRealloc(key->data, ctx.buflen);
3627                 if (NULL == tmp)
3628                 {
3629                     OICFree(key->data);
3630                     key->data = NULL;
3631                     OIC_LOG(ERROR, TAG, "Failed to allocate memory");
3632                     mbedtls_pem_free(&ctx);
3633                     return;
3634                 }
3635                 key->data = tmp;
3636
3637                 memcpy(key->data, ctx.buf, ctx.buflen);
3638                 key->len = ctx.buflen;
3639                 mbedtls_pem_free(&ctx);
3640                 break;
3641             }
3642             else if(temp->privateData.encoding == OIC_ENCODING_DER || temp->privateData.encoding == OIC_ENCODING_RAW)
3643             {
3644                 uint8_t *tmp = OICRealloc(key->data, key->len + temp->privateData.len);
3645                 if (NULL == tmp)
3646                 {
3647                     OICFree(key->data);
3648                     key->data = NULL;
3649                     OIC_LOG(ERROR, TAG, "Failed to allocate memory");
3650                     return;
3651                 }
3652                 key->data = tmp;
3653                 memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
3654                 key->len += temp->privateData.len;
3655                 OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
3656                 break;
3657             }
3658             else
3659             {
3660                 OIC_LOG_V(WARNING, TAG, "Key for %s found, but it has an unknown encoding (%d)", usage, temp->privateData.encoding);
3661             }
3662         }
3663     }
3664     if(0 == key->len)
3665     {
3666         OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
3667     }
3668     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
3669 }
3670
3671 void InitCipherSuiteListInternal(bool * list, const char * usage, const char *deviceId)
3672 {
3673     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
3674     if (NULL == list || NULL == usage)
3675     {
3676         OIC_LOG(DEBUG, TAG, "NULL passed");
3677         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
3678         return;
3679     }
3680     OicSecCred_t * temp = NULL;
3681     LL_FOREACH(gCred, temp)
3682     {
3683         switch (temp->credType)
3684         {
3685             case PIN_PASSWORD:
3686             {
3687                 list[0] = true;
3688                 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
3689                 break;
3690             }
3691             case SYMMETRIC_PAIR_WISE_KEY:
3692             {
3693                 OicUuid_t uuid;
3694
3695                 if (NULL == deviceId || deviceId[0] == '\0' ||
3696                     OC_STACK_OK != ConvertStrToUuid(deviceId, &uuid) ||
3697                     0 == memcmp(uuid.id, temp->subject.id, sizeof(uuid.id)))
3698                 {
3699                     list[0] = true;
3700                     OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
3701                 }
3702                 break;
3703             }
3704             case SIGNED_ASYMMETRIC_KEY:
3705             {
3706                 if (NULL != temp->credUsage && 0 == strcmp(temp->credUsage, usage))
3707                 {
3708                     list[1] = true;
3709                     OIC_LOG_V(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found for %s", usage);
3710                 }
3711                 break;
3712             }
3713             case SYMMETRIC_GROUP_KEY:
3714             case ASYMMETRIC_KEY:
3715             case ASYMMETRIC_ENCRYPTION_KEY:
3716             {
3717                 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
3718                 break;
3719             }
3720             default:
3721             {
3722                 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
3723                 break;
3724             }
3725         }
3726     }
3727     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
3728 }
3729 #endif