Prevent empty credential to be added
[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     OicUuid_t emptyOwner = { .id = {0} };
1375     VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
1376
1377     //Assigning credId to the newCred
1378     newCred->credId = GetCredId();
1379     VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
1380
1381     //the newCred is not valid if it is empty
1382
1383     if (memcmp(&(newCred->subject.id), &emptyOwner, UUID_IDENTITY_SIZE) == 0)
1384     {
1385         validFlag = false;
1386     }
1387     else
1388     {
1389         LL_FOREACH(gCred, temp)
1390         {
1391             CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
1392             if(CRED_CMP_EQUAL == cmpRes)
1393             {
1394                 OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
1395                           "new credential's ID will be replaced.", temp->credId);
1396                 newCred->credId = temp->credId;
1397                 ret = OC_STACK_OK;
1398                 validFlag = false;
1399                 break;
1400             }
1401
1402             if (CRED_CMP_ERROR == cmpRes)
1403             {
1404                 OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
1405                 ret = OC_STACK_ERROR;
1406                 validFlag = false;
1407                 break;
1408             }
1409         }
1410     }
1411
1412     //Append the new Cred to existing list if new Cred is valid
1413     if (validFlag)
1414     {
1415         LL_APPEND(gCred, newCred);
1416     }
1417
1418     memcpy(&(gCred->rownerID), &(newCred->rownerID), sizeof(OicUuid_t));
1419     if (UpdatePersistentStorage(gCred))
1420     {
1421         ret = OC_STACK_OK;
1422     }
1423
1424 exit:
1425     return ret;
1426 }
1427
1428 OCStackResult RemoveCredential(const OicUuid_t *subject)
1429 {
1430     OCStackResult ret = OC_STACK_ERROR;
1431     OicSecCred_t *cred = NULL;
1432     OicSecCred_t *tempCred = NULL;
1433     bool deleteFlag = false;
1434
1435     LL_FOREACH_SAFE(gCred, cred, tempCred)
1436     {
1437         if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1438         {
1439             LL_DELETE(gCred, cred);
1440             FreeCred(cred);
1441             deleteFlag = 1;
1442         }
1443     }
1444
1445     if (deleteFlag)
1446     {
1447         if (UpdatePersistentStorage(gCred))
1448         {
1449             ret = OC_STACK_RESOURCE_DELETED;
1450         }
1451     }
1452     return ret;
1453
1454 }
1455
1456 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1457 {
1458     OCStackResult ret = OC_STACK_ERROR;
1459     OicSecCred_t *cred = NULL;
1460     OicSecCred_t *tempCred = NULL;
1461     bool deleteFlag = false;
1462
1463     OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1464
1465     if ( 0 == credId)
1466     {
1467         return OC_STACK_INVALID_PARAM;
1468     }
1469
1470
1471     LL_FOREACH_SAFE(gCred, cred, tempCred)
1472     {
1473         if (cred->credId == credId)
1474         {
1475             OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1476
1477             LL_DELETE(gCred, cred);
1478             FreeCred(cred);
1479             deleteFlag = true;
1480         }
1481     }
1482
1483     if (deleteFlag)
1484     {
1485         if (UpdatePersistentStorage(gCred))
1486         {
1487             ret = OC_STACK_RESOURCE_DELETED;
1488         }
1489     }
1490     OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1491
1492     return ret;
1493
1494 }
1495
1496 /**
1497  * Remove all credential data on credential resource and persistent storage
1498  *
1499  * @retval
1500  *     OC_STACK_OK              - no errors
1501  *     OC_STACK_ERROR           - stack process error
1502  */
1503 OCStackResult RemoveAllCredentials(void)
1504 {
1505     DeleteCredList(gCred);
1506     gCred = GetCredDefault();
1507
1508     if (!UpdatePersistentStorage(gCred))
1509     {
1510         return OC_STACK_ERROR;
1511     }
1512     return OC_STACK_OK;
1513 }
1514
1515 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1516 /**
1517  * Internal function to fill private data of owner PSK.
1518  *
1519  * @param receviedCred recevied owner credential from OBT(PT)
1520  * @param ownerAdd address of OBT(PT)
1521  * @param doxm current device's doxm resource
1522  *
1523  * @return
1524  *     true successfully done and valid ower psk information
1525  *     false Invalid owner psk information or failed to owner psk generation
1526  */
1527 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1528                            const OicSecDoxm_t* doxm)
1529 {
1530     //Derive OwnerPSK locally
1531     const char* oxmLabel = GetOxmString(doxm->oxmSel);
1532     VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1533
1534     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1535     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1536         (uint8_t*)oxmLabel, strlen(oxmLabel),
1537         doxm->owner.id, sizeof(doxm->owner.id),
1538         doxm->deviceID.id, sizeof(doxm->deviceID.id),
1539         ownerPSK, OWNER_PSK_LENGTH_128);
1540     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1541
1542     OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1543     OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1544
1545     //Generate owner credential based on recevied credential information
1546
1547     // TODO: Added as workaround, will be replaced soon.
1548     if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1549     {
1550         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1551         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1552         receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1553         memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1554     }
1555     else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1556     {
1557         uint32_t b64OutSize = 0;
1558         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1559         char* b64Buf = OICCalloc(1, b64BufSize);
1560         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1561
1562         b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1563
1564         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1565         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1566         receviedCred->privateData.len = b64OutSize;
1567         strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1568         receviedCred->privateData.data[b64OutSize] = '\0';
1569     }
1570     else
1571     {
1572         VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1573     }
1574
1575     OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1576
1577     //Verify OwnerPSK information
1578     return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1579             receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1580 exit:
1581     //receviedCred->privateData.data will be deallocated when deleting credential.
1582     return false;
1583 }
1584
1585
1586 #ifdef _ENABLE_MULTIPLE_OWNER_
1587 /**
1588  * Internal function to fill private data of SubOwner PSK.
1589  *
1590  * @param receviedCred recevied owner credential from SubOwner
1591  * @param ownerAdd address of SubOwner
1592  * @param doxm current device's doxm resource
1593  *
1594  * @return
1595  *     true successfully done and valid subower psk information
1596  *     false Invalid subowner psk information or failed to subowner psk generation
1597  */
1598 static bool FillPrivateDataOfSubOwnerPSK(OicSecCred_t* receivedCred, const CAEndpoint_t* ownerAddr,
1599                            const OicSecDoxm_t* doxm, const OicUuid_t* subOwner)
1600 {
1601     char* b64Buf = NULL;
1602     //Derive OwnerPSK locally
1603     const char* oxmLabel = GetOxmString(doxm->oxmSel);
1604     VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1605
1606     uint8_t subOwnerPSK[OWNER_PSK_LENGTH_128] = {0};
1607     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1608         (uint8_t*)oxmLabel, strlen(oxmLabel),
1609         subOwner->id, sizeof(subOwner->id),
1610         doxm->deviceID.id, sizeof(doxm->deviceID.id),
1611         subOwnerPSK, OWNER_PSK_LENGTH_128);
1612     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1613
1614     OIC_LOG(DEBUG, TAG, "SubOwnerPSK dump :");
1615     OIC_LOG_BUFFER(DEBUG, TAG, subOwnerPSK, OWNER_PSK_LENGTH_128);
1616
1617     //Generate owner credential based on received credential information
1618
1619     if(OIC_ENCODING_RAW == receivedCred->privateData.encoding)
1620     {
1621         receivedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1622         VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1623         receivedCred->privateData.len = OWNER_PSK_LENGTH_128;
1624         memcpy(receivedCred->privateData.data, subOwnerPSK, OWNER_PSK_LENGTH_128);
1625     }
1626     else if(OIC_ENCODING_BASE64 == receivedCred->privateData.encoding)
1627     {
1628         uint32_t b64OutSize = 0;
1629         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1630         b64Buf = OICCalloc(1, b64BufSize);
1631         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1632
1633         VERIFY_SUCCESS(TAG, \
1634                        B64_OK == b64Encode(subOwnerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize), \
1635                        ERROR);
1636
1637         receivedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1638         VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1639         receivedCred->privateData.len = b64OutSize;
1640         strncpy((char*)receivedCred->privateData.data, b64Buf, b64OutSize);
1641         receivedCred->privateData.data[b64OutSize] = '\0';
1642     }
1643     else
1644     {
1645         OIC_LOG(INFO, TAG, "Unknown credential encoding type.");
1646         VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1647     }
1648
1649     OIC_LOG(INFO, TAG, "PrivateData of SubOwnerPSK was calculated successfully");
1650     OICFree(b64Buf);
1651     return true;
1652 exit:
1653     //receivedCred->privateData.data will be deallocated when deleting credential.
1654     OICFree(b64Buf);
1655     return false;
1656 }
1657 #endif //_ENABLE_MULTIPLE_OWNER_
1658 #endif // __WITH_DTLS__ or __WITH_TLS__
1659
1660 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
1661 {
1662     OCEntityHandlerResult ret = OC_EH_ERROR;
1663     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1664
1665     static uint16_t previousMsgId = 0;
1666     //Get binary representation of cbor
1667     OicSecCred_t *cred  = NULL;
1668     uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1669     size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1670
1671     OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1672     if (res == OC_STACK_OK)
1673     {
1674 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1675         OicUuid_t emptyUuid = {.id={0}};
1676         const OicSecDoxm_t* doxm = GetDoxmResourceData();
1677         if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1678         {
1679             //in case of owner PSK
1680             switch(cred->credType)
1681             {
1682                 case SYMMETRIC_PAIR_WISE_KEY:
1683                 {
1684                     OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1685                     if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1686                     {
1687                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1688                         {
1689                             OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1690                         }
1691
1692                         OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1693                         if(OC_STACK_OK == AddCredential(cred))
1694                         {
1695                             ret = OC_EH_CHANGED;
1696                         }
1697                         else
1698                         {
1699                             OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1700                             ret = OC_EH_ERROR;
1701                         }
1702                     }
1703                     else
1704                     {
1705                         OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1706                         ret = OC_EH_ERROR;
1707                     }
1708
1709                     if(OC_EH_CHANGED == ret)
1710                     {
1711                         /**
1712                          * in case of random PIN based OxM,
1713                          * revert get_psk_info callback of tinyDTLS to use owner credential.
1714                          */
1715                         if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1716                         {
1717                             OicUuid_t emptyUuid = { .id={0}};
1718                             SetUuidForPinBasedOxm(&emptyUuid);
1719
1720 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1721                             if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1722                             {
1723                                 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1724                                 ret = OC_EH_ERROR;
1725                                 break;
1726                             }
1727 #endif // __WITH_DTLS__ or __WITH_TLS__
1728                         }
1729
1730                         //Select cipher suite to use owner PSK
1731                         if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1732                         {
1733                             OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1734                             ret = OC_EH_ERROR;
1735                         }
1736                         else
1737                         {
1738                             OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1739                         }
1740
1741                         if(CA_STATUS_OK !=
1742                            CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter))
1743                         {
1744                             OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
1745                             ret = OC_EH_ERROR;
1746                         }
1747                     }
1748
1749                     break;
1750                 }
1751                 case SYMMETRIC_GROUP_KEY:
1752                 case ASYMMETRIC_KEY:
1753                 case SIGNED_ASYMMETRIC_KEY:
1754                 case PIN_PASSWORD:
1755                 case ASYMMETRIC_ENCRYPTION_KEY:
1756                 {
1757                     OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1758                     ret = OC_EH_ERROR;
1759                     break;
1760                 }
1761                 default:
1762                 {
1763                     OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
1764                     ret = OC_EH_ERROR;
1765                     break;
1766                 }
1767             }
1768
1769             if(OC_EH_CHANGED != ret)
1770             {
1771                 /*
1772                   * If some error is occured while ownership transfer,
1773                   * ownership transfer related resource should be revert back to initial status.
1774                   */
1775                 const OicSecDoxm_t* doxm =  GetDoxmResourceData();
1776                 if(doxm)
1777                 {
1778                     if(!doxm->owned && previousMsgId != ehRequest->messageID)
1779                     {
1780                         OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
1781                                             "DOXM will be reverted.");
1782                         RestoreDoxmToInitState();
1783                         RestorePstatToInitState();
1784                     }
1785                 }
1786                 else
1787                 {
1788                     OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
1789                 }
1790             }
1791         }
1792 #ifdef _ENABLE_MULTIPLE_OWNER_
1793         // In case SubOwner Credential
1794         else if(doxm && doxm->owned && doxm->mom &&
1795                 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
1796                 0 == cred->privateData.len)
1797         {
1798             switch(cred->credType)
1799             {
1800                 case SYMMETRIC_PAIR_WISE_KEY:
1801                 {
1802                     OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1803                     if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
1804                     {
1805                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1806                         {
1807                             OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1808                         }
1809
1810                         OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
1811                         if(OC_STACK_OK == AddCredential(cred))
1812                         {
1813                             ret = OC_EH_CHANGED;
1814                         }
1815                         else
1816                         {
1817                             OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
1818                             ret = OC_EH_ERROR;
1819                         }
1820                     }
1821                     else
1822                     {
1823                         OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
1824                         ret = OC_EH_ERROR;
1825                     }
1826                 }
1827                 break;
1828
1829                 case SYMMETRIC_GROUP_KEY:
1830                 case ASYMMETRIC_KEY:
1831                 case SIGNED_ASYMMETRIC_KEY:
1832                 case PIN_PASSWORD:
1833                 case ASYMMETRIC_ENCRYPTION_KEY:
1834                 {
1835                     OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
1836                     ret = OC_EH_ERROR;
1837                     break;
1838                 }
1839                 default:
1840                 {
1841                     OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
1842                     ret = OC_EH_ERROR;
1843                     break;
1844                 }
1845             }
1846         }
1847 #endif //_ENABLE_MULTIPLE_OWNER_
1848         else
1849         {
1850             /*
1851              * If the post request credential has credId, it will be
1852              * discarded and the next available credId will be assigned
1853              * to it before getting appended to the existing credential
1854              * list and updating svr database.
1855              */
1856             ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1857         }
1858 #else //not __WITH_DTLS__
1859         /*
1860          * If the post request credential has credId, it will be
1861          * discarded and the next available credId will be assigned
1862          * to it before getting appended to the existing credential
1863          * list and updating svr database.
1864          */
1865         ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1866         OC_UNUSED(previousMsgId);
1867 #endif//__WITH_DTLS__
1868     }
1869
1870     if (OC_EH_CHANGED != ret)
1871     {
1872         if(OC_STACK_OK != RemoveCredential(&cred->subject))
1873         {
1874             OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
1875         }
1876         FreeCred(cred);
1877     }
1878     else
1879     {
1880         previousMsgId = ehRequest->messageID;
1881     }
1882     //Send response to request originator
1883     ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1884                    OC_EH_OK : OC_EH_ERROR;
1885
1886     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
1887     return ret;
1888 }
1889
1890 /**
1891  * The entity handler determines how to process a GET request.
1892  */
1893 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
1894 {
1895     OIC_LOG(INFO, TAG, "HandleGetRequest  processing GET request");
1896
1897     // Convert Cred data into CBOR for transmission
1898     size_t size = 0;
1899     uint8_t *payload = NULL;
1900     int secureFlag = 1;
1901
1902     const OicSecCred_t *cred = gCred;
1903
1904     // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
1905     size = GetCredKeyDataSize(cred);
1906     size += (256 * OicSecCredCount(cred));
1907     OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1908
1909     // A device should always have a default cred. Therefore, payload should never be NULL.
1910     OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
1911
1912
1913     //Send payload to request originator
1914     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1915                        OC_EH_OK : OC_EH_ERROR;
1916     OICFree(payload);
1917     return ehRet;
1918 }
1919
1920 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1921 {
1922     OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1923
1924     OCEntityHandlerResult ehRet = OC_EH_ERROR;
1925
1926     if (NULL == ehRequest->query)
1927     {
1928         return ehRet;
1929     }
1930
1931     OicParseQueryIter_t parseIter = { .attrPos=NULL };
1932     OicUuid_t subject = {.id={0}};
1933
1934     //Parsing REST query to get the subject
1935     ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
1936     while (GetNextQuery(&parseIter))
1937     {
1938         if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
1939                 parseIter.attrLen) == 0)
1940         {
1941             OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
1942             VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1943         }
1944     }
1945
1946     if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
1947     {
1948         ehRet = OC_EH_RESOURCE_DELETED;
1949     }
1950     //Send response to request originator
1951     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1952                    OC_EH_OK : OC_EH_ERROR;
1953 exit:
1954     return ehRet;
1955 }
1956
1957 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1958                                         OCEntityHandlerRequest * ehRequest,
1959                                         void* callbackParameter)
1960 {
1961     (void)callbackParameter;
1962     OCEntityHandlerResult ret = OC_EH_ERROR;
1963
1964     if (!ehRequest)
1965     {
1966         return OC_EH_ERROR;
1967     }
1968     if (flag & OC_REQUEST_FLAG)
1969     {
1970         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1971         //TODO :  Remove Handle PUT methods once CTT have changed to POST on OTM
1972         switch (ehRequest->method)
1973         {
1974             case OC_REST_GET:
1975                 ret = HandleGetRequest(ehRequest);;
1976                 break;
1977             case OC_REST_PUT:
1978             case OC_REST_POST:
1979                 ret = HandlePostRequest(ehRequest);
1980                 break;
1981             case OC_REST_DELETE:
1982                 ret = HandleDeleteRequest(ehRequest);
1983                 break;
1984             default:
1985                 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1986                                OC_EH_OK : OC_EH_ERROR;
1987                 break;
1988         }
1989     }
1990     return ret;
1991 }
1992
1993 OCStackResult CreateCredResource()
1994 {
1995     OCStackResult ret = OCCreateResource(&gCredHandle,
1996                                          OIC_RSRC_TYPE_SEC_CRED,
1997                                          OC_RSRVD_INTERFACE_DEFAULT,
1998                                          OIC_RSRC_CRED_URI,
1999                                          CredEntityHandler,
2000                                          NULL,
2001                                          OC_SECURE);
2002
2003     if (OC_STACK_OK != ret)
2004     {
2005         OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2006         DeInitCredResource();
2007     }
2008     return ret;
2009 }
2010
2011 OCStackResult InitCredResource()
2012 {
2013     OCStackResult ret = OC_STACK_ERROR;
2014
2015     //Read Cred resource from PS
2016     uint8_t *data = NULL;
2017     size_t size = 0;
2018     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2019     // If database read failed
2020     if (ret != OC_STACK_OK)
2021     {
2022         OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2023     }
2024     if (data)
2025     {
2026         // Read ACL resource from PS
2027         ret = CBORPayloadToCred(data, size, &gCred);
2028     }
2029
2030     /*
2031      * If SVR database in persistent storage got corrupted or
2032      * is not available for some reason, a default Cred is created
2033      * which allows user to initiate Cred provisioning again.
2034      */
2035     if (ret != OC_STACK_OK || !data || !gCred)
2036     {
2037         gCred = GetCredDefault();
2038     }
2039     //Instantiate 'oic.sec.cred'
2040     ret = CreateCredResource();
2041     OICFree(data);
2042     return ret;
2043 }
2044
2045 OCStackResult DeInitCredResource()
2046 {
2047     OCStackResult result = OCDeleteResource(gCredHandle);
2048     DeleteCredList(gCred);
2049     gCred = NULL;
2050     return result;
2051 }
2052
2053 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2054 {
2055     OicSecCred_t *cred = NULL;
2056
2057    if ( NULL == subject)
2058     {
2059        return NULL;
2060     }
2061
2062     LL_FOREACH(gCred, cred)
2063     {
2064         if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2065         {
2066             return cred;
2067         }
2068     }
2069     return NULL;
2070 }
2071
2072 const OicSecCred_t* GetCredList()
2073 {
2074     return gCred;
2075 }
2076
2077 OicSecCred_t* GetCredResourceDataByCredId(const uint16_t credId)
2078 {
2079     OicSecCred_t *cred = NULL;
2080     if ( 1 > credId)
2081     {
2082        return NULL;
2083     }
2084
2085     LL_FOREACH(gCred, cred)
2086     {
2087         if(cred->credId == credId)
2088         {
2089             return cred;
2090         }
2091     }
2092     return NULL;
2093 }
2094
2095 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2096 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2097               const uint8_t *desc, size_t desc_len,
2098               uint8_t *result, size_t result_length)
2099 {
2100     int32_t ret = -1;
2101
2102     if (NULL == result)
2103     {
2104         return ret;
2105     }
2106
2107     switch (type)
2108     {
2109         case CA_DTLS_PSK_HINT:
2110         case CA_DTLS_PSK_IDENTITY:
2111             {
2112                 OicUuid_t deviceID = {.id={0}};
2113                 // Retrieve Device ID from doxm resource
2114                 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2115                 {
2116                     OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2117                     return ret;
2118                 }
2119
2120                 if (result_length < sizeof(deviceID.id))
2121                 {
2122                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2123                     return ret;
2124                 }
2125                 memcpy(result, deviceID.id, sizeof(deviceID.id));
2126                 return (sizeof(deviceID.id));
2127             }
2128             break;
2129
2130         case CA_DTLS_PSK_KEY:
2131             {
2132                 OicSecCred_t *cred = NULL;
2133                 LL_FOREACH(gCred, cred)
2134                 {
2135                     if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2136                     {
2137                         continue;
2138                     }
2139
2140                     if ((desc_len == sizeof(cred->subject.id)) &&
2141                         (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2142                     {
2143                         /*
2144                          * If the credentials are valid for limited time,
2145                          * check their expiry.
2146                          */
2147                         if (cred->period)
2148                         {
2149                             if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2150                             {
2151                                 OIC_LOG (INFO, TAG, "Credentials are expired.");
2152                                 return ret;
2153                             }
2154                         }
2155
2156                         // Copy PSK.
2157                         // TODO: Added as workaround. Will be replaced soon.
2158                         if(OIC_ENCODING_RAW == cred->privateData.encoding)
2159                         {
2160                             ret = cred->privateData.len;
2161                             memcpy(result, cred->privateData.data, ret);
2162                         }
2163                         else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2164                         {
2165                             size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2166                             uint8_t* outKey = OICCalloc(1, outBufSize);
2167                             uint32_t outKeySize;
2168                             if(NULL == outKey)
2169                             {
2170                                 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2171                                 return ret;
2172                             }
2173
2174                             if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2175                             {
2176                                 memcpy(result, outKey, outKeySize);
2177                                 ret = outKeySize;
2178                             }
2179                             else
2180                             {
2181                                 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2182                             }
2183
2184                             OICFree(outKey);
2185                         }
2186
2187                         return ret;
2188                     }
2189                 }
2190                 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2191
2192 #ifdef _ENABLE_MULTIPLE_OWNER_
2193                 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2194                 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2195                 {
2196                     // in case of multiple owner transfer authentication
2197                     if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2198                     {
2199                         OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2200                         if(wildCardCred)
2201                         {
2202                             OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2203                             if(PIN_PASSWORD == wildCardCred->credType)
2204                             {
2205                                 //Read PIN/PW
2206                                 char* pinBuffer = NULL;
2207                                 uint32_t pinLength = 0;
2208                                 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2209                                 {
2210                                     pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2211                                     if(NULL == pinBuffer)
2212                                     {
2213                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2214                                         return ret;
2215                                     }
2216                                     pinLength = wildCardCred->privateData.len;
2217                                     memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2218                                 }
2219                                 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2220                                 {
2221                                     size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2222                                     pinBuffer = OICCalloc(1, pinBufSize);
2223                                     if(NULL == pinBuffer)
2224                                     {
2225                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2226                                         return ret;
2227                                     }
2228
2229                                     if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
2230                                     {
2231                                         OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2232                                         return ret;
2233                                     }
2234                                 }
2235                                 else
2236                                 {
2237                                     OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2238                                     return ret;
2239                                 }
2240
2241                                 //Set the PIN/PW to derive PSK
2242                                 if(OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2243                                 {
2244                                     OICFree(pinBuffer);
2245                                     OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2246                                     return ret;
2247                                 }
2248                                 OICFree(pinBuffer);
2249
2250                                 OicUuid_t myUuid;
2251                                 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2252                                 {
2253                                     OIC_LOG(ERROR, TAG, "Failed to read device ID");
2254                                     return ret;
2255                                 }
2256                                 SetUuidForPinBasedOxm(&myUuid);
2257
2258                                 //Calculate PSK using PIN/PW
2259                                 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2260                                 {
2261                                     ret = OWNER_PSK_LENGTH_128;
2262                                 }
2263                                 else
2264                                 {
2265                                     OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
2266                                 }
2267
2268                                 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
2269                                 {
2270                                     OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
2271                                 }
2272                             }
2273                         }
2274                     }
2275                     else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2276                     {
2277                         if(0 == DerivePSKUsingPIN((uint8_t*)result))
2278                         {
2279                             ret = OWNER_PSK_LENGTH_128;
2280                         }
2281                         else
2282                         {
2283                             OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
2284                             ret = -1;
2285                         }
2286                     }
2287                 }
2288 #endif //_ENABLE_MULTIPLE_OWNER_
2289             }
2290             break;
2291     }
2292
2293     return ret;
2294 }
2295
2296 /**
2297  * Add temporal PSK to PIN based OxM
2298  *
2299  * @param[in] tmpSubject UUID of target device
2300  * @param[in] credType Type of credential to be added
2301  * @param[in] pin numeric characters
2302  * @param[in] pinSize length of 'pin'
2303  * @param[in] rownerID Resource owner's UUID
2304  * @param[out] tmpCredSubject Generated credential's subject.
2305  *
2306  * @return OC_STACK_OK for success and errorcode otherwise.
2307  */
2308 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
2309                             const char * pin, size_t pinSize,
2310                             const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
2311 {
2312     OCStackResult ret = OC_STACK_ERROR;
2313     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
2314
2315     if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
2316     {
2317         return OC_STACK_INVALID_PARAM;
2318     }
2319
2320     uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2321     OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2322     OicSecCred_t* cred = NULL;
2323     int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2324                                               UUID_LENGTH, PBKDF_ITERATIONS,
2325                                               OWNER_PSK_LENGTH_128, privData);
2326     VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2327
2328     cred = GenerateCredential(tmpSubject, credType, NULL,
2329                               &privKey, rownerID, NULL);
2330     if(NULL == cred)
2331     {
2332         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2333         return OC_STACK_ERROR;
2334     }
2335
2336     memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2337
2338     ret = AddCredential(cred);
2339     if( OC_STACK_OK != ret)
2340     {
2341         RemoveCredential(tmpSubject);
2342         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2343     }
2344     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2345
2346 exit:
2347     return ret;
2348 }
2349
2350 #endif /* __WITH_DTLS__ */
2351
2352 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2353 {
2354     OCStackResult ret = OC_STACK_ERROR;
2355     uint8_t *cborPayload = NULL;
2356     size_t size = 0;
2357     int secureFlag = 0;
2358     OicUuid_t prevId = {.id={0}};
2359
2360     if(NULL == newROwner)
2361     {
2362         ret = OC_STACK_INVALID_PARAM;
2363     }
2364     if(NULL == gCred)
2365     {
2366         ret = OC_STACK_NO_RESOURCE;
2367     }
2368
2369     if(newROwner && gCred)
2370     {
2371         memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2372         memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2373
2374         // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2375         size = GetCredKeyDataSize(gCred);
2376         size += (256 * OicSecCredCount(gCred));
2377         ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2378         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2379
2380         ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2381         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2382
2383         OICFree(cborPayload);
2384     }
2385
2386     return ret;
2387
2388 exit:
2389     OICFree(cborPayload);
2390     memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2391     return ret;
2392 }
2393
2394 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2395 {
2396     OCStackResult retVal = OC_STACK_ERROR;
2397     if (gCred)
2398     {
2399         *rowneruuid = gCred->rownerID;
2400         retVal = OC_STACK_OK;
2401     }
2402     return retVal;
2403 }
2404
2405 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2406 void GetDerCaCert(ByteArray_t * crt)
2407 {
2408     if (NULL == crt)
2409     {
2410         return;
2411     }
2412     uint8_t *data = NULL;
2413     crt->len = 0;
2414     OCStackResult ret = OC_STACK_ERROR;
2415     OicSecCred_t * cred;
2416     OicSecCred_t * temp = NULL;
2417     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2418     LL_FOREACH(gCred, temp)
2419     {
2420         if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), TRUST_CA, strlen(TRUST_CA) + 1))
2421         {
2422             OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->optionalData.len, crt->len);
2423             if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2424             {
2425                 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2426                 uint8 * buf = OICCalloc(1, bufSize);
2427                 if(NULL == buf)
2428                 {
2429                     OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2430                     return;
2431                 }
2432                 uint32_t outSize;
2433                 if(B64_OK != b64Decode(temp->optionalData.data, temp->optionalData.len, buf, bufSize, &outSize))
2434                 {
2435                     OICFree(buf);
2436                     OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2437                     return;
2438                 }
2439                 crt->data = OICRealloc(crt->data, crt->len + outSize);
2440                 memcpy(crt->data + crt->len, buf, outSize);
2441                 crt->len += outSize;
2442                 OICFree(buf);
2443             }
2444             else
2445             {
2446                 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2447                 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2448                 crt->len += temp->optionalData.len;
2449             }
2450             OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2451         }
2452     }
2453     if(0 == crt->len)
2454     {
2455         OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2456     }
2457     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2458     return;
2459 }
2460
2461 void GetDerOwnCert(ByteArray_t * crt)
2462 {
2463     if (NULL == crt)
2464     {
2465         return;
2466     }
2467     crt->len = 0;
2468     uint8_t *data = NULL;
2469     OicSecCred_t * temp = NULL;
2470     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2471     LL_FOREACH(gCred, temp)
2472     {
2473         if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, strlen(PRIMARY_CERT) + 1))
2474         {
2475             OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->publicData.len, crt->len);
2476             crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2477             memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2478             crt->len += temp->publicData.len;
2479
2480             OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2481         }
2482     }
2483     if(0 == crt->len)
2484     {
2485         OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2486     }
2487     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2488     return;
2489 }
2490
2491 void GetDerKey(ByteArray_t * key)
2492 {
2493     if (NULL == key)
2494     {
2495         return;
2496     }
2497
2498     uint8_t *data = NULL;
2499     OicSecCred_t * temp = NULL;
2500     key->len = 0;
2501     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2502     LL_FOREACH(gCred, temp)
2503     {
2504         if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, strlen(PRIMARY_CERT) + 1))
2505         {
2506             OIC_LOG_V(DEBUG, TAG, "len: %d, key len: %d", temp->privateData.len, key->len);
2507             key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2508             memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2509             key->len += temp->privateData.len;
2510
2511             OIC_LOG_V(DEBUG, TAG, "Key Found!! %d", key->len);
2512         }
2513     }
2514     if(0 == key->len)
2515     {
2516         OIC_LOG(DEBUG, TAG, "Key Not Found!!");
2517     }
2518     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2519 }
2520
2521 void InitCipherSuiteList(bool * list)
2522 {
2523     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2524     if (NULL == list)
2525     {
2526         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2527         OIC_LOG(DEBUG, TAG, "NULL list param");
2528         return;
2529     }
2530     OicSecCred_t * temp = NULL;
2531     LL_FOREACH(gCred, temp)
2532     {
2533         switch (temp->credType)
2534         {
2535             case PIN_PASSWORD:
2536             {
2537                 list[0] = true;
2538                 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
2539                 break;
2540             }
2541             case SYMMETRIC_PAIR_WISE_KEY:
2542             {
2543                 list[0] = true;
2544                 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2545                 break;
2546             }
2547             case SIGNED_ASYMMETRIC_KEY:
2548             {
2549                 list[1] = true;
2550                 OIC_LOG(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found");
2551                 break;
2552             }
2553             case SYMMETRIC_GROUP_KEY:
2554             case ASYMMETRIC_KEY:
2555             case ASYMMETRIC_ENCRYPTION_KEY:
2556             {
2557                 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2558                 break;
2559             }
2560             default:
2561             {
2562                 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
2563                 break;
2564             }
2565         }
2566     }
2567     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2568 }
2569 #endif