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