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