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