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