Update the OTM module to guarantee uniqueness of OwnerPSK on the PT side.
[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 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1354 {
1355     OCStackResult ret = OC_STACK_ERROR;
1356     OicSecCred_t *cred = NULL;
1357     OicSecCred_t *tempCred = NULL;
1358     bool deleteFlag = false;
1359
1360     OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1361
1362     if ( 0 == credId)
1363     {
1364         return OC_STACK_INVALID_PARAM;
1365     }
1366
1367
1368     LL_FOREACH_SAFE(gCred, cred, tempCred)
1369     {
1370         if (cred->credId == credId)
1371         {
1372             OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1373
1374             LL_DELETE(gCred, cred);
1375             FreeCred(cred);
1376             deleteFlag = true;
1377         }
1378     }
1379
1380     if (deleteFlag)
1381     {
1382         if (UpdatePersistentStorage(gCred))
1383         {
1384             ret = OC_STACK_RESOURCE_DELETED;
1385         }
1386     }
1387     OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1388
1389     return ret;
1390
1391 }
1392
1393 /**
1394  * Remove all credential data on credential resource and persistent storage
1395  *
1396  * @retval
1397  *     OC_STACK_OK              - no errors
1398  *     OC_STACK_ERROR           - stack process error
1399  */
1400 OCStackResult RemoveAllCredentials(void)
1401 {
1402     DeleteCredList(gCred);
1403     gCred = GetCredDefault();
1404
1405     if (!UpdatePersistentStorage(gCred))
1406     {
1407         return OC_STACK_ERROR;
1408     }
1409     return OC_STACK_OK;
1410 }
1411
1412 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1413 /**
1414  * Internal function to fill private data of owner PSK.
1415  *
1416  * @param receviedCred recevied owner credential from OBT(PT)
1417  * @param ownerAdd address of OBT(PT)
1418  * @param doxm current device's doxm resource
1419  *
1420  * @return
1421  *     true successfully done and valid ower psk information
1422  *     false Invalid owner psk information or failed to owner psk generation
1423  */
1424 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1425                            const OicSecDoxm_t* doxm)
1426 {
1427     //Derive OwnerPSK locally
1428     const char* oxmLabel = GetOxmString(doxm->oxmSel);
1429     VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1430
1431     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1432     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1433         (uint8_t*)oxmLabel, strlen(oxmLabel),
1434         doxm->owner.id, sizeof(doxm->owner.id),
1435         doxm->deviceID.id, sizeof(doxm->deviceID.id),
1436         ownerPSK, OWNER_PSK_LENGTH_128);
1437     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1438
1439     OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1440     OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1441
1442     //Generate owner credential based on recevied credential information
1443
1444     // TODO: Added as workaround, will be replaced soon.
1445     if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1446     {
1447         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1448         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1449         receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1450         memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1451     }
1452     else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1453     {
1454         uint32_t b64OutSize = 0;
1455         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1456         char* b64Buf = OICCalloc(1, b64BufSize);
1457         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1458
1459         b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1460
1461         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1462         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1463         receviedCred->privateData.len = b64OutSize;
1464         strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1465         receviedCred->privateData.data[b64OutSize] = '\0';
1466     }
1467     else
1468     {
1469         // TODO: error
1470         VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1471     }
1472
1473     OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1474
1475     //Verify OwnerPSK information
1476     return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1477             receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1478 exit:
1479     //receviedCred->privateData.data will be deallocated when deleting credential.
1480     return false;
1481 }
1482
1483 #endif //__WITH_DTLS__
1484
1485 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
1486 {
1487     OCEntityHandlerResult ret = OC_EH_ERROR;
1488     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1489
1490     static uint16_t previousMsgId = 0;
1491     //Get binary representation of cbor
1492     OicSecCred_t *cred  = NULL;
1493     uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1494     size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1495
1496     OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1497     if (res == OC_STACK_OK)
1498     {
1499 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1500         OicUuid_t emptyUuid = {.id={0}};
1501         const OicSecDoxm_t* doxm = GetDoxmResourceData();
1502         if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1503         {
1504             //in case of owner PSK
1505             switch(cred->credType)
1506             {
1507                 case SYMMETRIC_PAIR_WISE_KEY:
1508                 {
1509                     OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1510                     if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1511                     {
1512                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1513                         {
1514                             OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1515                         }
1516
1517                         OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1518                         if(OC_STACK_OK == AddCredential(cred))
1519                         {
1520                             ret = OC_EH_CHANGED;
1521                         }
1522                         else
1523                         {
1524                             OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1525                             ret = OC_EH_ERROR;
1526                         }
1527                     }
1528                     else
1529                     {
1530                         OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1531                         ret = OC_EH_ERROR;
1532                     }
1533
1534                     if(OC_EH_CHANGED == ret)
1535                     {
1536                         /**
1537                          * in case of random PIN based OxM,
1538                          * revert get_psk_info callback of tinyDTLS to use owner credential.
1539                          */
1540                         if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1541                         {
1542                             OicUuid_t emptyUuid = { .id={0}};
1543                             SetUuidForRandomPinOxm(&emptyUuid);
1544
1545 #ifdef __WITH_TLS__
1546                             if(CA_STATUS_OK != CAregisterTlsCredentialsHandler(GetDtlsPskCredentials))
1547                             {
1548                                 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1549                                 ret = OC_EH_ERROR;
1550                                 break;
1551                             }
1552 #endif
1553                             if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
1554                             {
1555                                 OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1556                                 ret = OC_EH_ERROR;
1557                                 break;
1558                             }
1559                         }
1560
1561                         //Select cipher suite to use owner PSK
1562                         if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1563                         {
1564                             OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1565                             ret = OC_EH_ERROR;
1566                         }
1567                         else
1568                         {
1569                             OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1570                         }
1571
1572                         if(CA_STATUS_OK !=
1573                            CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter))
1574                         {
1575                             OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
1576                             ret = OC_EH_ERROR;
1577                         }
1578                     }
1579
1580                     break;
1581                 }
1582                 case SYMMETRIC_GROUP_KEY:
1583                 case ASYMMETRIC_KEY:
1584                 case SIGNED_ASYMMETRIC_KEY:
1585                 case PIN_PASSWORD:
1586                 case ASYMMETRIC_ENCRYPTION_KEY:
1587                 {
1588                     OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1589                     ret = OC_EH_ERROR;
1590                     break;
1591                 }
1592                 default:
1593                 {
1594                     OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
1595                     ret = OC_EH_ERROR;
1596                     break;
1597                 }
1598             }
1599
1600             if(OC_EH_CHANGED != ret)
1601             {
1602                 /*
1603                   * If some error is occured while ownership transfer,
1604                   * ownership transfer related resource should be revert back to initial status.
1605                   */
1606                 const OicSecDoxm_t* doxm =  GetDoxmResourceData();
1607                 if(doxm)
1608                 {
1609                     if(!doxm->owned && previousMsgId != ehRequest->messageID)
1610                     {
1611                         OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
1612                                             "DOXM will be reverted.");
1613                         RestoreDoxmToInitState();
1614                         RestorePstatToInitState();
1615                     }
1616                 }
1617                 else
1618                 {
1619                     OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
1620                 }
1621             }
1622         }
1623         else
1624         {
1625             /*
1626              * If the post request credential has credId, it will be
1627              * discarded and the next available credId will be assigned
1628              * to it before getting appended to the existing credential
1629              * list and updating svr database.
1630              */
1631             ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1632         }
1633 #else //not __WITH_DTLS__
1634         /*
1635          * If the post request credential has credId, it will be
1636          * discarded and the next available credId will be assigned
1637          * to it before getting appended to the existing credential
1638          * list and updating svr database.
1639          */
1640         ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1641         OC_UNUSED(previousMsgId);
1642 #endif//__WITH_DTLS__
1643     }
1644
1645     if (OC_EH_CHANGED != ret)
1646     {
1647         if(OC_STACK_OK != RemoveCredential(&cred->subject))
1648         {
1649             OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
1650         }
1651         FreeCred(cred);
1652     }
1653     else
1654     {
1655         previousMsgId = ehRequest->messageID;
1656     }
1657     //Send response to request originator
1658     ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1659                    OC_EH_OK : OC_EH_ERROR;
1660
1661     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
1662     return ret;
1663 }
1664
1665 /**
1666  * The entity handler determines how to process a GET request.
1667  */
1668 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
1669 {
1670     OIC_LOG(INFO, TAG, "HandleGetRequest  processing GET request");
1671
1672     // Convert Cred data into CBOR for transmission
1673     size_t size = 0;
1674     uint8_t *payload = NULL;
1675     int secureFlag = 1;
1676
1677     const OicSecCred_t *cred = gCred;
1678
1679     // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
1680     size = GetCredKeyDataSize(cred);
1681     size += (256 * OicSecCredCount(cred));
1682     OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1683
1684     // A device should always have a default cred. Therefore, payload should never be NULL.
1685     OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
1686
1687
1688     //Send payload to request originator
1689     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1690                        OC_EH_OK : OC_EH_ERROR;
1691     OICFree(payload);
1692     return ehRet;
1693 }
1694
1695 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1696 {
1697     OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1698
1699     OCEntityHandlerResult ehRet = OC_EH_ERROR;
1700
1701     if (NULL == ehRequest->query)
1702     {
1703         return ehRet;
1704     }
1705
1706     OicParseQueryIter_t parseIter = { .attrPos=NULL };
1707     OicUuid_t subject = {.id={0}};
1708
1709     //Parsing REST query to get the subject
1710     ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
1711     while (GetNextQuery(&parseIter))
1712     {
1713         if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
1714                 parseIter.attrLen) == 0)
1715         {
1716             OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
1717             VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1718         }
1719     }
1720
1721     if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
1722     {
1723         ehRet = OC_EH_RESOURCE_DELETED;
1724     }
1725     //Send response to request originator
1726     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1727                    OC_EH_OK : OC_EH_ERROR;
1728 exit:
1729     return ehRet;
1730 }
1731
1732 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1733                                         OCEntityHandlerRequest * ehRequest,
1734                                         void* callbackParameter)
1735 {
1736     (void)callbackParameter;
1737     OCEntityHandlerResult ret = OC_EH_ERROR;
1738
1739     if (!ehRequest)
1740     {
1741         return OC_EH_ERROR;
1742     }
1743     if (flag & OC_REQUEST_FLAG)
1744     {
1745         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1746         //TODO :  Remove Handle PUT methods once CTT have changed to POST on OTM
1747         switch (ehRequest->method)
1748         {
1749             case OC_REST_GET:
1750                 ret = HandleGetRequest(ehRequest);;
1751                 break;
1752             case OC_REST_PUT:
1753             case OC_REST_POST:
1754                 ret = HandlePostRequest(ehRequest);
1755                 break;
1756             case OC_REST_DELETE:
1757                 ret = HandleDeleteRequest(ehRequest);
1758                 break;
1759             default:
1760                 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1761                                OC_EH_OK : OC_EH_ERROR;
1762                 break;
1763         }
1764     }
1765     return ret;
1766 }
1767
1768 OCStackResult CreateCredResource()
1769 {
1770     OCStackResult ret = OCCreateResource(&gCredHandle,
1771                                          OIC_RSRC_TYPE_SEC_CRED,
1772                                          OC_RSRVD_INTERFACE_DEFAULT,
1773                                          OIC_RSRC_CRED_URI,
1774                                          CredEntityHandler,
1775                                          NULL,
1776                                          OC_SECURE);
1777
1778     if (OC_STACK_OK != ret)
1779     {
1780         OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
1781         DeInitCredResource();
1782     }
1783     return ret;
1784 }
1785
1786 OCStackResult InitCredResource()
1787 {
1788     OCStackResult ret = OC_STACK_ERROR;
1789
1790     //Read Cred resource from PS
1791     uint8_t *data = NULL;
1792     size_t size = 0;
1793     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
1794     // If database read failed
1795     if (ret != OC_STACK_OK)
1796     {
1797         OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
1798     }
1799     if (data)
1800     {
1801         // Read ACL resource from PS
1802         ret = CBORPayloadToCred(data, size, &gCred);
1803     }
1804
1805     /*
1806      * If SVR database in persistent storage got corrupted or
1807      * is not available for some reason, a default Cred is created
1808      * which allows user to initiate Cred provisioning again.
1809      */
1810     if (ret != OC_STACK_OK || !data || !gCred)
1811     {
1812         gCred = GetCredDefault();
1813     }
1814     //Instantiate 'oic.sec.cred'
1815     ret = CreateCredResource();
1816     OICFree(data);
1817     return ret;
1818 }
1819
1820 OCStackResult DeInitCredResource()
1821 {
1822     OCStackResult result = OCDeleteResource(gCredHandle);
1823     DeleteCredList(gCred);
1824     gCred = NULL;
1825     return result;
1826 }
1827
1828 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
1829 {
1830     OicSecCred_t *cred = NULL;
1831
1832    if ( NULL == subject)
1833     {
1834        return NULL;
1835     }
1836
1837     LL_FOREACH(gCred, cred)
1838     {
1839         if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1840         {
1841             return cred;
1842         }
1843     }
1844     return NULL;
1845 }
1846
1847 const OicSecCred_t* GetCredList()
1848 {
1849     return gCred;
1850 }
1851
1852 OicSecCred_t* GetCredResourceDataByCredId(const uint16_t credId)
1853 {
1854     OicSecCred_t *cred = NULL;
1855
1856    if ( 1 > credId)
1857     {
1858        return NULL;
1859     }
1860
1861     LL_FOREACH(gCred, cred)
1862     {
1863         if(cred->credId == credId)
1864         {
1865             return cred;
1866         }
1867     }
1868     return NULL;
1869 }
1870
1871 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1872 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
1873               const uint8_t *desc, size_t desc_len,
1874               uint8_t *result, size_t result_length)
1875 {
1876     int32_t ret = -1;
1877
1878     if (NULL == result)
1879     {
1880         return ret;
1881     }
1882
1883     switch (type)
1884     {
1885         case CA_DTLS_PSK_HINT:
1886         case CA_DTLS_PSK_IDENTITY:
1887             {
1888                 OicUuid_t deviceID = {.id={0}};
1889                 // Retrieve Device ID from doxm resource
1890                 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
1891                 {
1892                     OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
1893                     return ret;
1894                 }
1895
1896                 if (result_length < sizeof(deviceID.id))
1897                 {
1898                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
1899                     return ret;
1900                 }
1901                 memcpy(result, deviceID.id, sizeof(deviceID.id));
1902                 return (sizeof(deviceID.id));
1903             }
1904             break;
1905
1906         case CA_DTLS_PSK_KEY:
1907             {
1908                 OicSecCred_t *cred = NULL;
1909                 LL_FOREACH(gCred, cred)
1910                 {
1911                     if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
1912                     {
1913                         continue;
1914                     }
1915
1916                     if ((desc_len == sizeof(cred->subject.id)) &&
1917                         (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
1918                     {
1919                         /*
1920                          * If the credentials are valid for limited time,
1921                          * check their expiry.
1922                          */
1923                         if (cred->period)
1924                         {
1925                             if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
1926                             {
1927                                 OIC_LOG (INFO, TAG, "Credentials are expired.");
1928                                 return ret;
1929                             }
1930                         }
1931
1932                         // Copy PSK.
1933                         // TODO: Added as workaround. Will be replaced soon.
1934                         if(OIC_ENCODING_RAW == cred->privateData.encoding)
1935                         {
1936                             ret = cred->privateData.len;
1937                             memcpy(result, cred->privateData.data, ret);
1938                         }
1939                         else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
1940                         {
1941                             size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
1942                             uint8_t* outKey = OICCalloc(1, outBufSize);
1943                             uint32_t outKeySize;
1944                             if(NULL == outKey)
1945                             {
1946                                 OIC_LOG (ERROR, TAG, "Failed to memoray allocation.");
1947                                 return ret;
1948                             }
1949
1950                             if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
1951                             {
1952                                 memcpy(result, outKey, outKeySize);
1953                                 ret = outKeySize;
1954                             }
1955                             else
1956                             {
1957                                 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
1958                             }
1959
1960                             OICFree(outKey);
1961                         }
1962
1963                         return ret;
1964                     }
1965                 }
1966             }
1967             break;
1968     }
1969
1970     return ret;
1971 }
1972
1973 /**
1974  * Add temporal PSK to PIN based OxM
1975  *
1976  * @param[in] tmpSubject UUID of target device
1977  * @param[in] credType Type of credential to be added
1978  * @param[in] pin numeric characters
1979  * @param[in] pinSize length of 'pin'
1980  * @param[in] rownerID Resource owner's UUID
1981  * @param[out] tmpCredSubject Generated credential's subject.
1982  *
1983  * @return OC_STACK_OK for success and errorcode otherwise.
1984  */
1985 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
1986                             const char * pin, size_t pinSize,
1987                             const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
1988 {
1989     OCStackResult ret = OC_STACK_ERROR;
1990     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
1991
1992     if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
1993     {
1994         return OC_STACK_INVALID_PARAM;
1995     }
1996
1997     uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
1998     OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
1999     OicSecCred_t* cred = NULL;
2000     int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2001                                               UUID_LENGTH, PBKDF_ITERATIONS,
2002                                               OWNER_PSK_LENGTH_128, privData);
2003     VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2004
2005     cred = GenerateCredential(tmpSubject, credType, NULL,
2006                               &privKey, rownerID);
2007     if(NULL == cred)
2008     {
2009         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2010         return OC_STACK_ERROR;
2011     }
2012
2013     memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2014
2015     ret = AddCredential(cred);
2016     if( OC_STACK_OK != ret)
2017     {
2018         RemoveCredential(tmpSubject);
2019         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2020     }
2021     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2022
2023 exit:
2024     return ret;
2025 }
2026
2027 #endif /* __WITH_DTLS__ */
2028 #ifdef __WITH_X509__
2029 #define CERT_LEN_PREFIX (3)
2030 #define BYTE_SIZE (8) //bits
2031 #define PUB_KEY_X_COORD ("x")
2032 #define PUB_KEY_Y_COORD ("y")
2033 #define CERTIFICATE ("x5c")
2034 #define PRIVATE_KEY ("d")
2035
2036 static uint32_t parseCertPrefix(uint8_t *prefix)
2037 {
2038     uint32_t res = 0;
2039     if (NULL != prefix)
2040     {
2041         for (int i = 0; i < CERT_LEN_PREFIX; ++i)
2042         {
2043             res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
2044         }
2045     }
2046     return res;
2047 }
2048
2049 static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo)
2050 {
2051     OCStackResult ret = OC_STACK_ERROR;
2052     uint8_t *ccPtr = credInfo->certificateChain;
2053     for (uint8_t i = 0; i < credInfo->chainLen - 1; ++i)
2054     {
2055         ccPtr += CERT_LEN_PREFIX + parseCertPrefix(ccPtr);
2056     }
2057
2058     ByteArray cert = { .data = ccPtr + CERT_LEN_PREFIX, .len = parseCertPrefix(ccPtr) };
2059     CertificateX509 certStruct;
2060
2061     VERIFY_SUCCESS(TAG, PKI_SUCCESS == DecodeCertificate(cert, &certStruct), ERROR);
2062
2063     INC_BYTE_ARRAY(certStruct.pubKey, 2);
2064
2065     memcpy(credInfo->rootPublicKeyX, certStruct.pubKey.data, PUBLIC_KEY_SIZE / 2);
2066     memcpy(credInfo->rootPublicKeyY, certStruct.pubKey.data + PUBLIC_KEY_SIZE / 2, PUBLIC_KEY_SIZE / 2);
2067
2068     ret = OC_STACK_OK;
2069     exit:
2070     return ret;
2071 }
2072
2073 int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo)
2074 {
2075     int ret = 1;
2076     VERIFY_NON_NULL(TAG, credInfo, ERROR);
2077     if (NULL == gCred)
2078     {
2079         VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
2080     }
2081
2082     OicSecCred_t *cred = NULL;
2083     LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY);
2084     VERIFY_NON_NULL(TAG, cred, ERROR);
2085
2086     if (cred->publicData.len > MAX_CERT_MESSAGE_LEN || cred->privateData.len > PRIVATE_KEY_SIZE)
2087     {
2088         goto exit;
2089     }
2090     credInfo->chainLen = 2;
2091     memcpy(credInfo->certificateChain, cred->publicData.data, cred->publicData.len);
2092     memcpy(credInfo->devicePrivateKey, cred->privateData.data, cred->privateData.len);
2093     credInfo->certificateChainLen = cred->publicData.len;
2094     GetCAPublicKeyData(credInfo);
2095     ret = 0;
2096
2097 exit:
2098
2099     return ret;
2100 }
2101 #undef CERT_LEN_PREFIX
2102 #endif /* __WITH_X509__ */
2103
2104 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2105 {
2106     OCStackResult ret = OC_STACK_ERROR;
2107     uint8_t *cborPayload = NULL;
2108     size_t size = 0;
2109     int secureFlag = 0;
2110     OicUuid_t prevId = {.id={0}};
2111
2112     if(NULL == newROwner)
2113     {
2114         ret = OC_STACK_INVALID_PARAM;
2115     }
2116     if(NULL == gCred)
2117     {
2118         ret = OC_STACK_NO_RESOURCE;
2119     }
2120
2121     if(newROwner && gCred)
2122     {
2123         memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2124         memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2125
2126         // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2127         size = GetCredKeyDataSize(gCred);
2128         size += (256 * OicSecCredCount(gCred));
2129         ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2130         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2131
2132         ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2133         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2134
2135         OICFree(cborPayload);
2136     }
2137
2138     return ret;
2139
2140 exit:
2141     OICFree(cborPayload);
2142     memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2143     return ret;
2144 }
2145
2146 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2147 {
2148     OCStackResult retVal = OC_STACK_ERROR;
2149     if (gCred)
2150     {
2151         *rowneruuid = gCred->rownerID;
2152         retVal = OC_STACK_OK;
2153     }
2154     return retVal;
2155 }
2156
2157 #ifdef __WITH_TLS__
2158 void GetDerCaCert(ByteArray * crt)
2159 {
2160     if (NULL == crt)
2161     {
2162         return;
2163     }
2164     uint8_t *data = NULL;
2165     crt->len = 0;
2166     OCStackResult ret = OC_STACK_ERROR;
2167     OicSecCred_t * cred;
2168     OicSecCred_t * temp = NULL;
2169     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2170     LL_FOREACH(gCred, temp)
2171     {
2172         if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), TRUST_CA, strlen(TRUST_CA) + 1))
2173         {
2174             OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->optionalData.len, crt->len);
2175             if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2176             {
2177                 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2178                 uint8 * buf = OICCalloc(1, bufSize);
2179                 if(NULL == buf)
2180                 {
2181                     OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2182                     return;
2183                 }
2184                 uint32_t outSize;
2185                 if(B64_OK != b64Decode(temp->optionalData.data, temp->optionalData.len, buf, bufSize, &outSize))
2186                 {
2187                     OICFree(buf);
2188                     OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2189                     return;
2190                 }
2191                 crt->data = OICRealloc(crt->data, crt->len + outSize);
2192                 memcpy(crt->data + crt->len, buf, outSize);
2193                 crt->len += outSize;
2194                 OICFree(buf);
2195             }
2196             else
2197             {
2198                 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2199                 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2200                 crt->len += temp->optionalData.len;
2201             }
2202             OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2203         }
2204     }
2205     if(0 == crt->len)
2206     {
2207         OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2208     }
2209     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2210     return;
2211 }
2212
2213 void GetDerOwnCert(ByteArray * crt)
2214 {
2215     if (NULL == crt)
2216     {
2217         return;
2218     }
2219     crt->len = 0;
2220     uint8_t *data = NULL;
2221     OicSecCred_t * temp = NULL;
2222     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2223     LL_FOREACH(gCred, temp)
2224     {
2225         if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, strlen(PRIMARY_CERT) + 1))
2226         {
2227             OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->publicData.len, crt->len);
2228             crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2229             memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2230             crt->len += temp->publicData.len;
2231
2232             OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2233         }
2234     }
2235     if(0 == crt->len)
2236     {
2237         OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2238     }
2239     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2240     return;
2241 }
2242
2243 void GetDerKey(ByteArray * key)
2244 {
2245     if (NULL == key)
2246     {
2247         return;
2248     }
2249
2250     uint8_t *data = NULL;
2251     OicSecCred_t * temp = NULL;
2252     key->len = 0;
2253     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2254     LL_FOREACH(gCred, temp)
2255     {
2256         if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, strlen(PRIMARY_CERT) + 1))
2257         {
2258             OIC_LOG_V(DEBUG, TAG, "len: %d, key len: %d", temp->privateData.len, key->len);
2259             key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2260             memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2261             key->len += temp->privateData.len;
2262
2263             OIC_LOG_V(DEBUG, TAG, "Key Found!! %d", key->len);
2264         }
2265     }
2266     if(0 == key->len)
2267     {
2268         OIC_LOG(DEBUG, TAG, "Key Not Found!!");
2269     }
2270     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2271 }
2272
2273 void InitCipherSuiteList(bool * list)
2274 {
2275     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2276     if (NULL == list)
2277     {
2278         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2279         OIC_LOG(DEBUG, TAG, "NULL list param");
2280         return;
2281     }
2282     OicSecCred_t * temp = NULL;
2283     LL_FOREACH(gCred, temp)
2284     {
2285         switch (temp->credType)
2286         {
2287             case SYMMETRIC_PAIR_WISE_KEY:
2288             {
2289                 list[0] = true;
2290                 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2291                 break;
2292             }
2293             case SIGNED_ASYMMETRIC_KEY:
2294             {
2295                 list[1] = true;
2296                 OIC_LOG(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found");
2297                 break;
2298             }
2299             case SYMMETRIC_GROUP_KEY:
2300             case ASYMMETRIC_KEY:
2301             case PIN_PASSWORD:
2302             case ASYMMETRIC_ENCRYPTION_KEY:
2303             {
2304                 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2305                 break;
2306             }
2307             default:
2308             {
2309                 OIC_LOG(WARNING, TAG, "Unknow credential type for TLS.");
2310                 break;
2311             }
2312         }
2313     }
2314     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2315 }
2316 #endif