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