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