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