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