CTT1.2.2: changed requestHandle value to a request ID
[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(const 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 && previousMsgId != ehRequest->messageID)
1934                     {
1935                         OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
1936                                             "DOXM will be reverted.");
1937                         RestoreDoxmToInitState();
1938                         RestorePstatToInitState();
1939                     }
1940                 }
1941                 else
1942                 {
1943                     OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
1944                 }
1945             }
1946         }
1947 #ifdef _ENABLE_MULTIPLE_OWNER_
1948         // In case SubOwner Credential
1949         else if(doxm && doxm->owned && doxm->mom &&
1950                 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
1951                 0 == cred->privateData.len)
1952         {
1953             switch(cred->credType)
1954             {
1955                 case SYMMETRIC_PAIR_WISE_KEY:
1956                 {
1957                     OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
1958                     if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
1959                     {
1960                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1961                         {
1962                             OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1963                         }
1964
1965                         OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
1966                         if(OC_STACK_OK == AddCredential(cred))
1967                         {
1968                             ret = OC_EH_CHANGED;
1969                         }
1970                         else
1971                         {
1972                             OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
1973                             ret = OC_EH_ERROR;
1974                         }
1975                     }
1976                     else
1977                     {
1978                         OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
1979                         ret = OC_EH_ERROR;
1980                     }
1981                 }
1982                 break;
1983
1984                 case SYMMETRIC_GROUP_KEY:
1985                 case ASYMMETRIC_KEY:
1986                 case SIGNED_ASYMMETRIC_KEY:
1987                 case PIN_PASSWORD:
1988                 case ASYMMETRIC_ENCRYPTION_KEY:
1989                 {
1990                     OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
1991                     ret = OC_EH_ERROR;
1992                     break;
1993                 }
1994                 default:
1995                 {
1996                     OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
1997                     ret = OC_EH_ERROR;
1998                     break;
1999                 }
2000             }
2001         }
2002 #endif //_ENABLE_MULTIPLE_OWNER_
2003         else
2004         {
2005             if(IsEmptyCred(cred))
2006             {
2007                 OicUuid_t emptyUuid = {.id={0}};
2008                 if(memcmp(cred->rownerID.id, emptyUuid.id, sizeof(emptyUuid.id)) != 0)
2009                 {
2010                     OIC_LOG(INFO, TAG, "CRED's rowner will be updated.");
2011                     memcpy(gCred->rownerID.id, cred->rownerID.id, sizeof(cred->rownerID.id));
2012                     if (UpdatePersistentStorage(gCred))
2013                     {
2014                         ret = OC_EH_CHANGED;
2015                     }
2016                     else
2017                     {
2018                         ret = OC_EH_ERROR;
2019                     }
2020                 }
2021                 else
2022                 {
2023                     ret = OC_EH_ERROR;
2024                 }
2025             }
2026             else
2027             {
2028                 /*
2029                  * If the post request credential has credId, it will be
2030                  * discarded and the next available credId will be assigned
2031                  * to it before getting appended to the existing credential
2032                  * list and updating svr database.
2033                  */
2034                 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2035             }
2036         }
2037 #else //not __WITH_DTLS__
2038         /*
2039          * If the post request credential has credId, it will be
2040          * discarded and the next available credId will be assigned
2041          * to it before getting appended to the existing credential
2042          * list and updating svr database.
2043          */
2044         ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2045         OC_UNUSED(previousMsgId);
2046 #endif//__WITH_DTLS__
2047     }
2048
2049     if (OC_EH_CHANGED != ret)
2050     {
2051         if(OC_STACK_OK != RemoveCredential(&cred->subject))
2052         {
2053             OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
2054         }
2055         FreeCred(cred);
2056     }
2057     else
2058     {
2059         previousMsgId = ehRequest->messageID;
2060     }
2061     //Send response to request originator
2062     ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2063                    OC_EH_OK : OC_EH_ERROR;
2064
2065     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
2066     return ret;
2067 }
2068
2069 /**
2070  * The entity handler determines how to process a GET request.
2071  */
2072 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
2073 {
2074     OIC_LOG(INFO, TAG, "HandleGetRequest  processing GET request");
2075
2076     // Convert Cred data into CBOR for transmission
2077     size_t size = 0;
2078     uint8_t *payload = NULL;
2079     int secureFlag = 1;
2080
2081     const OicSecCred_t *cred = gCred;
2082
2083     // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2084     size = GetCredKeyDataSize(cred);
2085     size += (256 * OicSecCredCount(cred));
2086     OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
2087
2088     // A device should always have a default cred. Therefore, payload should never be NULL.
2089     OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
2090
2091
2092     //Send payload to request originator
2093     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
2094                        OC_EH_OK : OC_EH_ERROR;
2095     OICClearMemory(payload, size);
2096     OICFree(payload);
2097     return ehRet;
2098 }
2099
2100 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
2101 {
2102     OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
2103
2104     OCEntityHandlerResult ehRet = OC_EH_ERROR;
2105
2106     if (NULL == ehRequest->query)
2107     {
2108         return ehRet;
2109     }
2110
2111     OicParseQueryIter_t parseIter = { .attrPos=NULL };
2112     OicUuid_t subject = {.id={0}};
2113
2114     //Parsing REST query to get the subject
2115     ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
2116     while (GetNextQuery(&parseIter))
2117     {
2118         if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
2119                 parseIter.attrLen) == 0)
2120         {
2121             OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
2122             VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2123         }
2124     }
2125
2126     if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
2127     {
2128         ehRet = OC_EH_RESOURCE_DELETED;
2129     }
2130     //Send response to request originator
2131     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2132                    OC_EH_OK : OC_EH_ERROR;
2133 exit:
2134     return ehRet;
2135 }
2136
2137 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
2138                                         OCEntityHandlerRequest * ehRequest,
2139                                         void* callbackParameter)
2140 {
2141     (void)callbackParameter;
2142     OCEntityHandlerResult ret = OC_EH_ERROR;
2143
2144     if (!ehRequest)
2145     {
2146         return OC_EH_ERROR;
2147     }
2148     if (flag & OC_REQUEST_FLAG)
2149     {
2150         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
2151         //TODO :  Remove Handle PUT methods once CTT have changed to POST on OTM
2152         switch (ehRequest->method)
2153         {
2154             case OC_REST_GET:
2155                 ret = HandleGetRequest(ehRequest);;
2156                 break;
2157             case OC_REST_PUT:
2158             case OC_REST_POST:
2159                 ret = HandlePostRequest(ehRequest);
2160                 break;
2161             case OC_REST_DELETE:
2162                 ret = HandleDeleteRequest(ehRequest);
2163                 break;
2164             default:
2165                 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2166                                OC_EH_OK : OC_EH_ERROR;
2167                 break;
2168         }
2169     }
2170     return ret;
2171 }
2172
2173 OCStackResult CreateCredResource()
2174 {
2175     OCStackResult ret = OCCreateResource(&gCredHandle,
2176                                          OIC_RSRC_TYPE_SEC_CRED,
2177                                          OC_RSRVD_INTERFACE_DEFAULT,
2178                                          OIC_RSRC_CRED_URI,
2179                                          CredEntityHandler,
2180                                          NULL,
2181                                          OC_SECURE);
2182
2183     if (OC_STACK_OK != ret)
2184     {
2185         OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2186         DeInitCredResource();
2187     }
2188     return ret;
2189 }
2190
2191 OCStackResult InitCredResource()
2192 {
2193     OCStackResult ret = OC_STACK_ERROR;
2194     OicSecCred_t* cred = NULL;
2195
2196     //Read Cred resource from PS
2197     uint8_t *data = NULL;
2198     size_t size = 0;
2199     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2200     // If database read failed
2201     if (ret != OC_STACK_OK)
2202     {
2203         OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2204     }
2205     if (data)
2206     {
2207         // Read ACL resource from PS
2208         ret = CBORPayloadToCred(data, size, &gCred);
2209     }
2210
2211     /*
2212      * If SVR database in persistent storage got corrupted or
2213      * is not available for some reason, a default Cred is created
2214      * which allows user to initiate Cred provisioning again.
2215      */
2216     if (ret != OC_STACK_OK || !data || !gCred)
2217     {
2218         gCred = GetCredDefault();
2219     }
2220
2221     //Add a log to track the invalid credential.
2222     LL_FOREACH(gCred, cred)
2223     {
2224         if (false == IsVaildCredential(cred))
2225         {
2226             OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
2227             OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
2228         }
2229     }
2230
2231     //Instantiate 'oic.sec.cred'
2232     ret = CreateCredResource();
2233     OICClearMemory(data, size);
2234     OICFree(data);
2235     return ret;
2236 }
2237
2238 OCStackResult DeInitCredResource()
2239 {
2240     OCStackResult result = OCDeleteResource(gCredHandle);
2241     DeleteCredList(gCred);
2242     gCred = NULL;
2243     return result;
2244 }
2245
2246 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2247 {
2248     OicSecCred_t *cred = NULL;
2249
2250    if ( NULL == subject)
2251     {
2252        return NULL;
2253     }
2254
2255     LL_FOREACH(gCred, cred)
2256     {
2257         if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2258         {
2259             return cred;
2260         }
2261     }
2262     return NULL;
2263 }
2264
2265 const OicSecCred_t* GetCredList()
2266 {
2267     return gCred;
2268 }
2269
2270 OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
2271 {
2272     OicSecCred_t *cred = NULL;
2273     OicSecCred_t *tmpCred = NULL;
2274
2275    if ( 1 > credId)
2276     {
2277        return NULL;
2278     }
2279
2280     LL_FOREACH(gCred, tmpCred)
2281     {
2282         if(tmpCred->credId == credId)
2283         {
2284             cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2285             VERIFY_NON_NULL(TAG, cred, ERROR);
2286
2287             // common
2288             cred->next = NULL;
2289             cred->credId = tmpCred->credId;
2290             cred->credType = tmpCred->credType;
2291             memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
2292             memcpy(cred->rownerID.id, tmpCred->rownerID.id , sizeof(cred->rownerID.id));
2293             if (tmpCred->period)
2294             {
2295                 cred->period = OICStrdup(tmpCred->period);
2296             }
2297
2298             // key data
2299             if (tmpCred->privateData.data)
2300             {
2301                 cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
2302                 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
2303
2304                 memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
2305                 cred->privateData.len = tmpCred->privateData.len;
2306                 cred->privateData.encoding = tmpCred->privateData.encoding;
2307             }
2308 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
2309             else if (tmpCred->publicData.data)
2310             {
2311                 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
2312                 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
2313
2314                 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
2315                 cred->publicData.len = tmpCred->publicData.len;
2316             }
2317             else if (tmpCred->optionalData.data)
2318             {
2319                 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
2320                 VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR);
2321
2322                 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
2323                 cred->optionalData.len = tmpCred->optionalData.len;
2324                 cred->optionalData.encoding = tmpCred->optionalData.encoding;
2325             }
2326
2327             if (tmpCred->credUsage)
2328             {
2329                 cred->credUsage = OICStrdup(tmpCred->credUsage);
2330             }
2331 #endif /* __WITH_X509__  or __WITH_TLS__*/
2332
2333             return cred;
2334         }
2335     }
2336
2337 exit:
2338     FreeCred(cred);
2339     return NULL;
2340 }
2341
2342 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2343 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2344               const uint8_t *desc, size_t desc_len,
2345               uint8_t *result, size_t result_length)
2346 {
2347     int32_t ret = -1;
2348
2349     if (NULL == result)
2350     {
2351         return ret;
2352     }
2353
2354     switch (type)
2355     {
2356         case CA_DTLS_PSK_HINT:
2357         case CA_DTLS_PSK_IDENTITY:
2358             {
2359                 OicUuid_t deviceID = {.id={0}};
2360                 // Retrieve Device ID from doxm resource
2361                 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2362                 {
2363                     OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2364                     return ret;
2365                 }
2366
2367                 if (result_length < sizeof(deviceID.id))
2368                 {
2369                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2370                     return ret;
2371                 }
2372                 memcpy(result, deviceID.id, sizeof(deviceID.id));
2373                 return (sizeof(deviceID.id));
2374             }
2375             break;
2376
2377         case CA_DTLS_PSK_KEY:
2378             {
2379                 OicSecCred_t *cred = NULL;
2380                 LL_FOREACH(gCred, cred)
2381                 {
2382                     if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2383                     {
2384                         continue;
2385                     }
2386
2387                     if ((desc_len == sizeof(cred->subject.id)) &&
2388                         (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2389                     {
2390                         /*
2391                          * If the credentials are valid for limited time,
2392                          * check their expiry.
2393                          */
2394                         if (cred->period)
2395                         {
2396                             if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2397                             {
2398                                 OIC_LOG (INFO, TAG, "Credentials are expired.");
2399                                 return ret;
2400                             }
2401                         }
2402
2403                         // Copy PSK.
2404                         // TODO: Added as workaround. Will be replaced soon.
2405                         if(OIC_ENCODING_RAW == cred->privateData.encoding)
2406                         {
2407                             ret = cred->privateData.len;
2408                             memcpy(result, cred->privateData.data, ret);
2409                         }
2410                         else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2411                         {
2412                             size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2413                             uint8_t* outKey = OICCalloc(1, outBufSize);
2414                             uint32_t outKeySize;
2415                             if(NULL == outKey)
2416                             {
2417                                 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2418                                 return ret;
2419                             }
2420
2421                             if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2422                             {
2423                                 memcpy(result, outKey, outKeySize);
2424                                 ret = outKeySize;
2425                             }
2426                             else
2427                             {
2428                                 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2429                             }
2430
2431                             OICFree(outKey);
2432                         }
2433
2434                         return ret;
2435                     }
2436                 }
2437                 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2438
2439 #ifdef _ENABLE_MULTIPLE_OWNER_
2440                 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2441                 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2442                 {
2443                     // in case of multiple owner transfer authentication
2444                     if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2445                     {
2446                         OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2447                         if(wildCardCred)
2448                         {
2449                             OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2450                             if(PIN_PASSWORD == wildCardCred->credType)
2451                             {
2452                                 //Read PIN/PW
2453                                 char* pinBuffer = NULL;
2454                                 uint32_t pinLength = 0;
2455                                 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2456                                 {
2457                                     pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2458                                     if(NULL == pinBuffer)
2459                                     {
2460                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2461                                         return ret;
2462                                     }
2463                                     pinLength = wildCardCred->privateData.len;
2464                                     memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2465                                 }
2466                                 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2467                                 {
2468                                     size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2469                                     pinBuffer = OICCalloc(1, pinBufSize);
2470                                     if(NULL == pinBuffer)
2471                                     {
2472                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2473                                         return ret;
2474                                     }
2475
2476                                     if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
2477                                     {
2478                                         OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2479                                         return ret;
2480                                     }
2481                                 }
2482                                 else
2483                                 {
2484                                     OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2485                                     return ret;
2486                                 }
2487
2488                                 //Set the PIN/PW to derive PSK
2489                                 if (OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2490                                 {
2491                                     OICFree(pinBuffer);
2492                                     OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2493                                     return ret;
2494                                 }
2495                                 OICFree(pinBuffer);
2496
2497                                 OicUuid_t myUuid;
2498                                 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2499                                 {
2500                                     OIC_LOG(ERROR, TAG, "Failed to read device ID");
2501                                     return ret;
2502                                 }
2503                                 SetUuidForPinBasedOxm(&myUuid);
2504
2505                                 //Calculate PSK using PIN/PW
2506                                 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2507                                 {
2508                                     ret = OWNER_PSK_LENGTH_128;
2509                                 }
2510                                 else
2511                                 {
2512                                     OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
2513                                 }
2514
2515                                 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
2516                                 {
2517                                     OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
2518                                 }
2519                             }
2520                         }
2521                     }
2522                     else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2523                     {
2524                         if(0 == DerivePSKUsingPIN((uint8_t*)result))
2525                         {
2526                             ret = OWNER_PSK_LENGTH_128;
2527                         }
2528                         else
2529                         {
2530                             OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
2531                             ret = -1;
2532                         }
2533                     }
2534                 }
2535 #endif //_ENABLE_MULTIPLE_OWNER_
2536             }
2537             break;
2538     }
2539
2540     return ret;
2541 }
2542
2543 /**
2544  * Add temporal PSK to PIN based OxM
2545  *
2546  * @param[in] tmpSubject UUID of target device
2547  * @param[in] credType Type of credential to be added
2548  * @param[in] pin numeric characters
2549  * @param[in] pinSize length of 'pin'
2550  * @param[in] rownerID Resource owner's UUID
2551  * @param[out] tmpCredSubject Generated credential's subject.
2552  *
2553  * @return OC_STACK_OK for success and errorcode otherwise.
2554  */
2555 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
2556                             const char * pin, size_t pinSize,
2557                             const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
2558 {
2559     OCStackResult ret = OC_STACK_ERROR;
2560     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
2561
2562     if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
2563     {
2564         return OC_STACK_INVALID_PARAM;
2565     }
2566
2567     uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2568     OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2569     OicSecCred_t* cred = NULL;
2570     int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2571                                               UUID_LENGTH, PBKDF_ITERATIONS,
2572                                               OWNER_PSK_LENGTH_128, privData);
2573     VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2574
2575     cred = GenerateCredential(tmpSubject, credType, NULL,
2576                               &privKey, rownerID, NULL);
2577     OICClearMemory(privData, sizeof(privData));
2578     if(NULL == cred)
2579     {
2580         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2581         return OC_STACK_ERROR;
2582     }
2583
2584     memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2585
2586     ret = AddCredential(cred);
2587     if( OC_STACK_OK != ret)
2588     {
2589         RemoveCredential(tmpSubject);
2590         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2591     }
2592     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2593
2594 exit:
2595     return ret;
2596 }
2597
2598 #endif /* __WITH_DTLS__ */
2599
2600 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2601 {
2602     OCStackResult ret = OC_STACK_ERROR;
2603     uint8_t *cborPayload = NULL;
2604     size_t size = 0;
2605     int secureFlag = 0;
2606     OicUuid_t prevId = {.id={0}};
2607
2608     if(NULL == newROwner)
2609     {
2610         ret = OC_STACK_INVALID_PARAM;
2611     }
2612     if(NULL == gCred)
2613     {
2614         ret = OC_STACK_NO_RESOURCE;
2615     }
2616
2617     if(newROwner && gCred)
2618     {
2619         memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2620         memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2621
2622         // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2623         size = GetCredKeyDataSize(gCred);
2624         size += (256 * OicSecCredCount(gCred));
2625         ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2626         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2627
2628         ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2629         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2630
2631         OICFree(cborPayload);
2632     }
2633
2634     return ret;
2635
2636 exit:
2637     OICFree(cborPayload);
2638     memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2639     return ret;
2640 }
2641
2642 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2643 {
2644     OCStackResult retVal = OC_STACK_ERROR;
2645     if (gCred)
2646     {
2647         *rowneruuid = gCred->rownerID;
2648         retVal = OC_STACK_OK;
2649     }
2650     return retVal;
2651 }
2652
2653 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2654 void GetDerCaCert(ByteArray_t * crt, const char * usage)
2655 {
2656     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2657     if (NULL == crt || NULL == usage)
2658     {
2659         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2660         return;
2661     }
2662     crt->len = 0;
2663     OicSecCred_t * temp = NULL;
2664
2665     LL_FOREACH(gCred, temp)
2666     {
2667         if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2668             0 == strcmp(temp->credUsage, usage))
2669         {
2670             if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2671             {
2672                 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2673                 uint8 * buf = OICCalloc(1, bufSize);
2674                 if(NULL == buf)
2675                 {
2676                     OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2677                     return;
2678                 }
2679                 uint32_t outSize;
2680                 if(B64_OK != b64Decode(temp->optionalData.data, temp->optionalData.len, buf, bufSize, &outSize))
2681                 {
2682                     OICFree(buf);
2683                     OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2684                     return;
2685                 }
2686                 crt->data = OICRealloc(crt->data, crt->len + outSize);
2687                 memcpy(crt->data + crt->len, buf, outSize);
2688                 crt->len += outSize;
2689                 OICFree(buf);
2690             }
2691             else
2692             {
2693                 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2694                 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2695                 crt->len += temp->optionalData.len;
2696             }
2697             OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2698         }
2699     }
2700     if(0 == crt->len)
2701     {
2702         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2703     }
2704     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2705     return;
2706 }
2707
2708 void GetDerOwnCert(ByteArray_t * crt, const char * usage)
2709 {
2710     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2711     if (NULL == crt || NULL == usage)
2712     {
2713         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2714         return;
2715     }
2716     crt->len = 0;
2717     OicSecCred_t * temp = NULL;
2718     LL_FOREACH(gCred, temp)
2719     {
2720         if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2721             0 == strcmp(temp->credUsage, usage))
2722         {
2723             crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2724             memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2725             crt->len += temp->publicData.len;
2726             OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2727         }
2728     }
2729     if(0 == crt->len)
2730     {
2731         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2732     }
2733     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2734     return;
2735 }
2736
2737 void GetDerKey(ByteArray_t * key, const char * usage)
2738 {
2739     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2740     if (NULL == key || NULL == usage)
2741     {
2742         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2743         return;
2744     }
2745
2746     OicSecCred_t * temp = NULL;
2747     key->len = 0;
2748     LL_FOREACH(gCred, temp)
2749     {
2750         if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2751             0 == strcmp(temp->credUsage, usage))
2752         {
2753             key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2754             memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2755             key->len += temp->privateData.len;
2756             OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
2757         }
2758     }
2759     if(0 == key->len)
2760     {
2761         OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
2762     }
2763     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2764 }
2765
2766 void InitCipherSuiteListInternal(bool * list, const char * usage)
2767 {
2768     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2769     if (NULL == list || NULL == usage)
2770     {
2771         OIC_LOG(DEBUG, TAG, "NULL passed");
2772         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2773         return;
2774     }
2775     OicSecCred_t * temp = NULL;
2776     LL_FOREACH(gCred, temp)
2777     {
2778         switch (temp->credType)
2779         {
2780             case PIN_PASSWORD:
2781             {
2782                 list[0] = true;
2783                 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
2784                 break;
2785             }
2786             case SYMMETRIC_PAIR_WISE_KEY:
2787             {
2788                 list[0] = true;
2789                 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2790                 break;
2791             }
2792             case SIGNED_ASYMMETRIC_KEY:
2793             {
2794                 if (0 == strcmp(temp->credUsage, usage))
2795                 {
2796                     list[1] = true;
2797                     OIC_LOG_V(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found for %s", usage);
2798                 }
2799                 break;
2800             }
2801             case SYMMETRIC_GROUP_KEY:
2802             case ASYMMETRIC_KEY:
2803             case ASYMMETRIC_ENCRYPTION_KEY:
2804             {
2805                 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2806                 break;
2807             }
2808             default:
2809             {
2810                 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
2811                 break;
2812             }
2813         }
2814     }
2815     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2816 }
2817 #endif