Remove unnecessary define and files for SSL
[platform/upstream/iotivity.git] / resource / csdk / security / src / credresource.c
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #define __STDC_LIMIT_MACROS
22
23 #include "iotivity_config.h"
24 #include <stdlib.h>
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28 #ifdef HAVE_STRINGS_H
29 #include <strings.h>
30 #endif
31 #include <stdint.h>
32 #include <stdbool.h>
33
34 #include "cainterface.h"
35 #include "payload_logging.h"
36 #include "ocstack.h"
37 #include "ocrandom.h"
38 #include "base64.h"
39 #include "ocserverrequest.h"
40 #include "oic_malloc.h"
41 #include "ocpayload.h"
42 #include "utlist.h"
43 #include "credresource.h"
44 #include "doxmresource.h"
45 #include "pstatresource.h"
46 #include "iotvticalendar.h"
47 #include "pbkdf2.h"
48 #include "resourcemanager.h"
49 #include "srmresourcestrings.h"
50 #include "srmutility.h"
51 #include "psinterface.h"
52 #include "pinoxmcommon.h"
53
54 #ifdef __unix__
55 #include <sys/types.h>
56 #include <sys/stat.h>
57 #include <fcntl.h>
58 #include <unistd.h>
59 #endif
60
61 #ifdef __WITH_DTLS__
62 #include "global.h"
63 #endif
64
65 #define TAG  "SRM-CREDL"
66
67 /** Max credential types number used for TLS */
68 #define MAX_TYPE 2
69 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
70  * The value of payload size is increased until reaching belox max cbor size. */
71 static const uint16_t CBOR_SIZE = 2048;
72
73 /** Max cbor size payload. */
74 static const uint16_t CBOR_MAX_SIZE = 4400;
75
76 /** CRED size - Number of mandatory items. */
77 static const uint8_t CRED_ROOT_MAP_SIZE = 4;
78 static const uint8_t CRED_MAP_SIZE = 3;
79
80
81 static OicSecCred_t        *gCred = NULL;
82 static OCResourceHandle    gCredHandle = NULL;
83
84 typedef enum CredCompareResult{
85     CRED_CMP_EQUAL = 0,
86     CRED_CMP_NOT_EQUAL = 1,
87     CRED_CMP_ERROR = 2
88 }CredCompareResult_t;
89
90 /**
91  * This function frees OicSecCred_t object's fields and object itself.
92  */
93 static void FreeCred(OicSecCred_t *cred)
94 {
95     if(NULL == cred)
96     {
97         OIC_LOG(ERROR, TAG, "Invalid Parameter");
98         return;
99     }
100     //Note: Need further clarification on roleID data type
101 #if 0
102     //Clean roleIds
103     OICFree(cred->roleIds);
104 #endif
105
106     //Clean PublicData/OptionalData/Credusage
107 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
108      // TODO: Need to check credUsage.
109     OICFree(cred->publicData.data);
110     OICFree(cred->optionalData.data);
111     OICFree(cred->credUsage);
112
113 #endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
114
115     //Clean PrivateData
116     OICFree(cred->privateData.data);
117
118     //Clean Period
119     OICFree(cred->period);
120
121     //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_DTLS__) || 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_DTLS__) || 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_DTLS__ ||  __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_DTLS__) || 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_DTLS__ ||  __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_DTLS__) || 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_DTLS__ ||  __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             else if (NULL != gCred)
952             {
953                 memcpy(&(headCred->rownerID), &(gCred->rownerID), sizeof(OicUuid_t));
954             }
955             OICFree(tagName);
956         }
957         if (cbor_value_is_valid(&CredRootMap))
958         {
959             cborFindResult = cbor_value_advance(&CredRootMap);
960             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
961         }
962     }
963
964     *secCred = headCred;
965     ret = OC_STACK_OK;
966
967 exit:
968     if (CborNoError != cborFindResult)
969     {
970         DeleteCredList(headCred);
971         headCred = NULL;
972         *secCred = NULL;
973         ret = OC_STACK_ERROR;
974     }
975
976     return ret;
977 }
978
979 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
980                                   const OicSecCert_t * publicData, const OicSecKey_t* privateData,
981                                   const OicUuid_t * rownerID)
982 {
983     (void)publicData;
984     OCStackResult ret = OC_STACK_ERROR;
985
986     OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
987     VERIFY_NON_NULL(TAG, cred, ERROR);
988
989     //CredId is assigned before appending new cred to the existing
990     //credential list and updating svr database in AddCredential().
991     cred->credId = 0;
992
993     VERIFY_NON_NULL(TAG, subject, ERROR);
994     memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
995
996     VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
997             SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
998     cred->credType = credType;
999
1000 #ifdef __WITH_DTLS__
1001     if (publicData && publicData->data)
1002     {
1003         cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
1004         VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
1005         memcpy(cred->publicData.data, publicData->data, publicData->len);
1006         cred->publicData.len = publicData->len;
1007     }
1008 #endif // __WITH_DTLS__
1009
1010     if (privateData && privateData->data)
1011     {
1012         cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
1013         VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
1014         memcpy(cred->privateData.data, privateData->data, privateData->len);
1015         cred->privateData.len = privateData->len;
1016
1017         // TODO: Added as workaround. Will be replaced soon.
1018         cred->privateData.encoding = OIC_ENCODING_RAW;
1019
1020 #if 0
1021         // NOTE: Test codes to use base64 for credential.
1022         uint32_t outSize = 0;
1023         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
1024         char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
1025         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1026         b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);
1027
1028         OICFree( cred->privateData.data );
1029         cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
1030         VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
1031
1032         strcpy(cred->privateData.data, b64Buf);
1033         cred->privateData.encoding = OIC_ENCODING_BASE64;
1034         cred->privateData.len = outSize;
1035         OICFree(b64Buf);
1036 #endif //End of Test codes
1037
1038     }
1039
1040     VERIFY_NON_NULL(TAG, rownerID, ERROR);
1041     memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
1042
1043     ret = OC_STACK_OK;
1044 exit:
1045     if (OC_STACK_OK != ret)
1046     {
1047         DeleteCredList(cred);
1048         cred = NULL;
1049     }
1050     return cred;
1051 }
1052
1053 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
1054 {
1055     bool ret = false;
1056
1057     // Convert Cred data into JSON for update to persistent storage
1058     if (cred)
1059     {
1060         uint8_t *payload = NULL;
1061         // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
1062         size_t size = GetCredKeyDataSize(cred);
1063         size += (256 * OicSecCredCount(cred));
1064         int secureFlag = 0;
1065         OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1066         if ((OC_STACK_OK == res) && payload)
1067         {
1068             if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
1069             {
1070                 ret = true;
1071             }
1072             OICFree(payload);
1073         }
1074     }
1075     else //Empty cred list
1076     {
1077         if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
1078         {
1079             ret = true;
1080         }
1081     }
1082     return ret;
1083 }
1084
1085 /**
1086  * Compare function used LL_SORT for sorting credentials.
1087  *
1088  * @param first pointer to OicSecCred_t struct.
1089  * @param second  pointer to OicSecCred_t struct.
1090  *
1091  *@return -1, if credId of first is less than credId of second.
1092  * 0, if credId of first is equal to credId of second.
1093  * 1, if credId of first is greater than credId of second.
1094  */
1095 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
1096 {
1097     if (first->credId < second->credId)
1098     {
1099         return -1;
1100     }
1101     else if (first->credId > second->credId)
1102     {
1103         return 1;
1104     }
1105     else
1106         return 0;
1107 }
1108
1109 /**
1110  * GetCredId goes through the cred list and returns the next
1111  * available credId. The next credId could be the credId that is
1112  * available due deletion of OicSecCred_t object or one more than
1113  * credId of last credential in the list.
1114  *
1115  * @return next available credId if successful, else 0 for error.
1116  */
1117 static uint16_t GetCredId()
1118 {
1119     //Sorts credential list in incremental order of credId
1120     LL_SORT(gCred, CmpCredId);
1121
1122     OicSecCred_t *currentCred = NULL, *credTmp = NULL;
1123     uint16_t nextCredId = 1;
1124
1125     LL_FOREACH_SAFE(gCred, currentCred, credTmp)
1126     {
1127         if (currentCred->credId == nextCredId)
1128         {
1129             nextCredId += 1;
1130         }
1131         else
1132         {
1133             break;
1134         }
1135     }
1136
1137     VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
1138     return nextCredId;
1139
1140 exit:
1141     return 0;
1142 }
1143
1144 /**
1145  * Get the default value.
1146  *
1147  * @return  NULL for now.
1148  */
1149 static OicSecCred_t* GetCredDefault()
1150 {
1151     // TODO:Update it when we finalize the default info.
1152     return NULL;
1153 }
1154
1155 static bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
1156 {
1157     VERIFY_NON_NULL(TAG, sk1, WARNING);
1158     VERIFY_NON_NULL(TAG, sk2, WARNING);
1159
1160     VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1161     VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1162     VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1163     return true;
1164 exit:
1165     return false;
1166 }
1167
1168 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1169 static bool IsSameCert(const OicSecCert_t* cert1, const OicSecCert_t* cert2)
1170 {
1171     VERIFY_NON_NULL(TAG, cert1, WARNING);
1172     VERIFY_NON_NULL(TAG, cert2, WARNING);
1173
1174     VERIFY_SUCCESS(TAG, (cert1->len == cert2->len), INFO);
1175     VERIFY_SUCCESS(TAG, (0 == memcmp(cert1->data, cert2->data, cert1->len)), INFO);
1176     return true;
1177 exit:
1178     return false;
1179 }
1180 #endif //#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1181
1182 /**
1183  * Compares credential
1184  *
1185  * @return CRED_CMP_EQUAL if credentials are equal
1186  *         CRED_CMP_NOT_EQUAL if not equal
1187  *         otherwise error.
1188  */
1189
1190 static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSecCred_t * r)
1191 {
1192     CredCompareResult_t cmpResult = CRED_CMP_ERROR;
1193     bool isCompared = false;
1194     OIC_LOG(DEBUG, TAG, "IN CompareCredetial");
1195
1196     VERIFY_NON_NULL(TAG, l, ERROR);
1197     VERIFY_NON_NULL(TAG, r, ERROR);
1198
1199     cmpResult = CRED_CMP_NOT_EQUAL;
1200
1201     VERIFY_SUCCESS(TAG, (l->credType == r->credType), INFO);
1202     VERIFY_SUCCESS(TAG, (0 == memcmp(l->subject.id, r->subject.id, sizeof(l->subject.id))), INFO);
1203
1204     switch(l->credType)
1205     {
1206         case SYMMETRIC_PAIR_WISE_KEY:
1207         case SYMMETRIC_GROUP_KEY:
1208         case PIN_PASSWORD:
1209         {
1210             if(l->privateData.data && r->privateData.data)
1211             {
1212                 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1213                 isCompared = true;
1214             }
1215             break;
1216         }
1217 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1218         case ASYMMETRIC_KEY:
1219         case SIGNED_ASYMMETRIC_KEY:
1220         {
1221             if(l->publicData.data && r->publicData.data)
1222             {
1223                 VERIFY_SUCCESS(TAG, IsSameCert(&l->publicData, &r->publicData), INFO);
1224                 isCompared = true;
1225             }
1226
1227             if(l->optionalData.data && r->optionalData.data)
1228             {
1229                 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->optionalData, &r->optionalData), INFO);
1230                 isCompared = true;
1231             }
1232
1233             if(l->credUsage && r->credUsage)
1234             {
1235                 VERIFY_SUCCESS(TAG, (strlen(l->credUsage) == strlen(r->credUsage)), INFO);
1236                 VERIFY_SUCCESS(TAG, (0 == strncmp(l->credUsage, r->credUsage, strlen(l->credUsage))), INFO);
1237                 isCompared = true;
1238             }
1239             break;
1240         }
1241         case ASYMMETRIC_ENCRYPTION_KEY:
1242         {
1243             if(l->privateData.data && r->privateData.data)
1244             {
1245                 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1246                 isCompared = true;
1247             }
1248
1249             if(l->publicData.data && r->publicData.data)
1250             {
1251                 VERIFY_SUCCESS(TAG, IsSameCert(&l->publicData, &r->publicData), INFO);
1252                 isCompared = true;
1253             }
1254
1255             if(l->optionalData.data && r->optionalData.data)
1256             {
1257                 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->optionalData, &r->optionalData), INFO);
1258                 isCompared = true;
1259             }
1260
1261             break;
1262         }
1263 #endif //__WITH_DTLS__ or __WITH_TLS__
1264         default:
1265         {
1266             cmpResult = CRED_CMP_ERROR;
1267             break;
1268         }
1269     }
1270
1271     if(isCompared)
1272     {
1273         OIC_LOG(DEBUG, TAG, "Same Credentials");
1274         cmpResult = CRED_CMP_EQUAL;
1275     }
1276     else
1277     {
1278         OIC_LOG(DEBUG, TAG, "Can not find the key data in credential");
1279         cmpResult = CRED_CMP_ERROR;
1280     }
1281 exit:
1282     OIC_LOG(DEBUG, TAG, "OUT CompareCredetial");
1283
1284     return cmpResult;
1285 }
1286
1287 OCStackResult AddCredential(OicSecCred_t * newCred)
1288 {
1289     OCStackResult ret = OC_STACK_ERROR;
1290     OicSecCred_t * temp = NULL;
1291     bool validFlag = true;
1292     VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
1293
1294     //Assigning credId to the newCred
1295     newCred->credId = GetCredId();
1296     VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
1297
1298     LL_FOREACH(gCred, temp)
1299     {
1300         CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
1301         if(CRED_CMP_EQUAL == cmpRes)
1302         {
1303             OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
1304                       "new credential's ID will be replaced.", temp->credId);
1305             newCred->credId = temp->credId;
1306             ret = OC_STACK_OK;
1307             validFlag = false;
1308             break;
1309         }
1310
1311         if (CRED_CMP_ERROR == cmpRes)
1312         {
1313             OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
1314             ret = OC_STACK_ERROR;
1315             validFlag = false;
1316             break;
1317         }
1318     }
1319
1320     //Append the new Cred to existing list if new Cred is valid
1321     if (validFlag)
1322     {
1323         LL_APPEND(gCred, newCred);
1324     }
1325
1326     memcpy(&(gCred->rownerID), &(newCred->rownerID), sizeof(OicUuid_t));
1327     if (UpdatePersistentStorage(gCred))
1328     {
1329         ret = OC_STACK_OK;
1330     }
1331
1332 exit:
1333     return ret;
1334 }
1335
1336 OCStackResult RemoveCredential(const OicUuid_t *subject)
1337 {
1338     OCStackResult ret = OC_STACK_ERROR;
1339     OicSecCred_t *cred = NULL;
1340     OicSecCred_t *tempCred = NULL;
1341     bool deleteFlag = false;
1342
1343     LL_FOREACH_SAFE(gCred, cred, tempCred)
1344     {
1345         if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1346         {
1347             LL_DELETE(gCred, cred);
1348             FreeCred(cred);
1349             deleteFlag = 1;
1350         }
1351     }
1352
1353     if (deleteFlag)
1354     {
1355         if (UpdatePersistentStorage(gCred))
1356         {
1357             ret = OC_STACK_RESOURCE_DELETED;
1358         }
1359     }
1360     return ret;
1361
1362 }
1363
1364 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1365 {
1366     OCStackResult ret = OC_STACK_ERROR;
1367     OicSecCred_t *cred = NULL;
1368     OicSecCred_t *tempCred = NULL;
1369     bool deleteFlag = false;
1370
1371     OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1372
1373     if ( 0 == credId)
1374     {
1375         return OC_STACK_INVALID_PARAM;
1376     }
1377
1378
1379     LL_FOREACH_SAFE(gCred, cred, tempCred)
1380     {
1381         if (cred->credId == credId)
1382         {
1383             OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1384
1385             LL_DELETE(gCred, cred);
1386             FreeCred(cred);
1387             deleteFlag = true;
1388         }
1389     }
1390
1391     if (deleteFlag)
1392     {
1393         if (UpdatePersistentStorage(gCred))
1394         {
1395             ret = OC_STACK_RESOURCE_DELETED;
1396         }
1397     }
1398     OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1399
1400     return ret;
1401
1402 }
1403
1404 /**
1405  * Remove all credential data on credential resource and persistent storage
1406  *
1407  * @retval
1408  *     OC_STACK_OK              - no errors
1409  *     OC_STACK_ERROR           - stack process error
1410  */
1411 OCStackResult RemoveAllCredentials(void)
1412 {
1413     DeleteCredList(gCred);
1414     gCred = GetCredDefault();
1415
1416     if (!UpdatePersistentStorage(gCred))
1417     {
1418         return OC_STACK_ERROR;
1419     }
1420     return OC_STACK_OK;
1421 }
1422
1423 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1424 /**
1425  * Internal function to fill private data of owner PSK.
1426  *
1427  * @param receviedCred recevied owner credential from OBT(PT)
1428  * @param ownerAdd address of OBT(PT)
1429  * @param doxm current device's doxm resource
1430  *
1431  * @return
1432  *     true successfully done and valid ower psk information
1433  *     false Invalid owner psk information or failed to owner psk generation
1434  */
1435 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1436                            const OicSecDoxm_t* doxm)
1437 {
1438     //Derive OwnerPSK locally
1439     const char* oxmLabel = GetOxmString(doxm->oxmSel);
1440     VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1441
1442     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1443     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1444         (uint8_t*)oxmLabel, strlen(oxmLabel),
1445         doxm->owner.id, sizeof(doxm->owner.id),
1446         doxm->deviceID.id, sizeof(doxm->deviceID.id),
1447         ownerPSK, OWNER_PSK_LENGTH_128);
1448     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1449
1450     OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1451     OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1452
1453     //Generate owner credential based on recevied credential information
1454
1455     // TODO: Added as workaround, will be replaced soon.
1456     if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1457     {
1458         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1459         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1460         receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1461         memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1462     }
1463     else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1464     {
1465         uint32_t b64OutSize = 0;
1466         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1467         char* b64Buf = OICCalloc(1, b64BufSize);
1468         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1469
1470         b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1471
1472         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1473         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1474         receviedCred->privateData.len = b64OutSize;
1475         strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1476         receviedCred->privateData.data[b64OutSize] = '\0';
1477     }
1478     else
1479     {
1480         // TODO: error
1481         VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1482     }
1483
1484     OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1485
1486     //Verify OwnerPSK information
1487     return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1488             receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1489 exit:
1490     //receviedCred->privateData.data will be deallocated when deleting credential.
1491     return false;
1492 }
1493
1494 #endif // __WITH_DTLS__ or __WITH_TLS__
1495
1496 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
1497 {
1498     OCEntityHandlerResult ret = OC_EH_ERROR;
1499     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1500
1501     static uint16_t previousMsgId = 0;
1502     //Get binary representation of cbor
1503     OicSecCred_t *cred  = NULL;
1504     uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1505     size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1506
1507     OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1508     if (res == OC_STACK_OK)
1509     {
1510 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1511         OicUuid_t emptyUuid = {.id={0}};
1512         const OicSecDoxm_t* doxm = GetDoxmResourceData();
1513         if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1514         {
1515             //in case of owner PSK
1516             switch(cred->credType)
1517             {
1518                 case SYMMETRIC_PAIR_WISE_KEY:
1519                 {
1520                     OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1521                     if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1522                     {
1523                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1524                         {
1525                             OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1526                         }
1527
1528                         OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1529                         if(OC_STACK_OK == AddCredential(cred))
1530                         {
1531                             ret = OC_EH_CHANGED;
1532                         }
1533                         else
1534                         {
1535                             OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1536                             ret = OC_EH_ERROR;
1537                         }
1538                     }
1539                     else
1540                     {
1541                         OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1542                         ret = OC_EH_ERROR;
1543                     }
1544
1545                     if(OC_EH_CHANGED == ret)
1546                     {
1547                         /**
1548                          * in case of random PIN based OxM,
1549                          * revert get_psk_info callback of tinyDTLS to use owner credential.
1550                          */
1551                         if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1552                         {
1553                             OicUuid_t emptyUuid = { .id={0}};
1554                             SetUuidForRandomPinOxm(&emptyUuid);
1555
1556 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1557                             if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1558                             {
1559                                 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1560                                 ret = OC_EH_ERROR;
1561                                 break;
1562                             }
1563 #endif // __WITH_DTLS__ or __WITH_TLS__
1564                         }
1565
1566                         //Select cipher suite to use owner PSK
1567                         if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1568                         {
1569                             OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1570                             ret = OC_EH_ERROR;
1571                         }
1572                         else
1573                         {
1574                             OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1575                         }
1576
1577                         if(CA_STATUS_OK !=
1578                            CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter))
1579                         {
1580                             OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
1581                             ret = OC_EH_ERROR;
1582                         }
1583                     }
1584
1585                     break;
1586                 }
1587                 case SYMMETRIC_GROUP_KEY:
1588                 case ASYMMETRIC_KEY:
1589                 case SIGNED_ASYMMETRIC_KEY:
1590                 case PIN_PASSWORD:
1591                 case ASYMMETRIC_ENCRYPTION_KEY:
1592                 {
1593                     OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1594                     ret = OC_EH_ERROR;
1595                     break;
1596                 }
1597                 default:
1598                 {
1599                     OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
1600                     ret = OC_EH_ERROR;
1601                     break;
1602                 }
1603             }
1604
1605             if(OC_EH_CHANGED != ret)
1606             {
1607                 /*
1608                   * If some error is occured while ownership transfer,
1609                   * ownership transfer related resource should be revert back to initial status.
1610                   */
1611                 const OicSecDoxm_t* doxm =  GetDoxmResourceData();
1612                 if(doxm)
1613                 {
1614                     if(!doxm->owned && previousMsgId != ehRequest->messageID)
1615                     {
1616                         OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
1617                                             "DOXM will be reverted.");
1618                         RestoreDoxmToInitState();
1619                         RestorePstatToInitState();
1620                     }
1621                 }
1622                 else
1623                 {
1624                     OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
1625                 }
1626             }
1627         }
1628         else
1629         {
1630             /*
1631              * If the post request credential has credId, it will be
1632              * discarded and the next available credId will be assigned
1633              * to it before getting appended to the existing credential
1634              * list and updating svr database.
1635              */
1636             ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1637         }
1638 #else //not __WITH_DTLS__
1639         /*
1640          * If the post request credential has credId, it will be
1641          * discarded and the next available credId will be assigned
1642          * to it before getting appended to the existing credential
1643          * list and updating svr database.
1644          */
1645         ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1646         OC_UNUSED(previousMsgId);
1647 #endif//__WITH_DTLS__
1648     }
1649
1650     if (OC_EH_CHANGED != ret)
1651     {
1652         if(OC_STACK_OK != RemoveCredential(&cred->subject))
1653         {
1654             OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
1655         }
1656         FreeCred(cred);
1657     }
1658     else
1659     {
1660         previousMsgId = ehRequest->messageID;
1661     }
1662     //Send response to request originator
1663     ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1664                    OC_EH_OK : OC_EH_ERROR;
1665
1666     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
1667     return ret;
1668 }
1669
1670 /**
1671  * The entity handler determines how to process a GET request.
1672  */
1673 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
1674 {
1675     OIC_LOG(INFO, TAG, "HandleGetRequest  processing GET request");
1676
1677     // Convert Cred data into CBOR for transmission
1678     size_t size = 0;
1679     uint8_t *payload = NULL;
1680     int secureFlag = 1;
1681
1682     const OicSecCred_t *cred = gCred;
1683
1684     // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
1685     size = GetCredKeyDataSize(cred);
1686     size += (256 * OicSecCredCount(cred));
1687     OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1688
1689     // A device should always have a default cred. Therefore, payload should never be NULL.
1690     OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
1691
1692
1693     //Send payload to request originator
1694     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1695                        OC_EH_OK : OC_EH_ERROR;
1696     OICFree(payload);
1697     return ehRet;
1698 }
1699
1700 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1701 {
1702     OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1703
1704     OCEntityHandlerResult ehRet = OC_EH_ERROR;
1705
1706     if (NULL == ehRequest->query)
1707     {
1708         return ehRet;
1709     }
1710
1711     OicParseQueryIter_t parseIter = { .attrPos=NULL };
1712     OicUuid_t subject = {.id={0}};
1713
1714     //Parsing REST query to get the subject
1715     ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
1716     while (GetNextQuery(&parseIter))
1717     {
1718         if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
1719                 parseIter.attrLen) == 0)
1720         {
1721             OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
1722             VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1723         }
1724     }
1725
1726     if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
1727     {
1728         ehRet = OC_EH_RESOURCE_DELETED;
1729     }
1730     //Send response to request originator
1731     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1732                    OC_EH_OK : OC_EH_ERROR;
1733 exit:
1734     return ehRet;
1735 }
1736
1737 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1738                                         OCEntityHandlerRequest * ehRequest,
1739                                         void* callbackParameter)
1740 {
1741     (void)callbackParameter;
1742     OCEntityHandlerResult ret = OC_EH_ERROR;
1743
1744     if (!ehRequest)
1745     {
1746         return OC_EH_ERROR;
1747     }
1748     if (flag & OC_REQUEST_FLAG)
1749     {
1750         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1751         //TODO :  Remove Handle PUT methods once CTT have changed to POST on OTM
1752         switch (ehRequest->method)
1753         {
1754             case OC_REST_GET:
1755                 ret = HandleGetRequest(ehRequest);;
1756                 break;
1757             case OC_REST_PUT:
1758             case OC_REST_POST:
1759                 ret = HandlePostRequest(ehRequest);
1760                 break;
1761             case OC_REST_DELETE:
1762                 ret = HandleDeleteRequest(ehRequest);
1763                 break;
1764             default:
1765                 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1766                                OC_EH_OK : OC_EH_ERROR;
1767                 break;
1768         }
1769     }
1770     return ret;
1771 }
1772
1773 OCStackResult CreateCredResource()
1774 {
1775     OCStackResult ret = OCCreateResource(&gCredHandle,
1776                                          OIC_RSRC_TYPE_SEC_CRED,
1777                                          OC_RSRVD_INTERFACE_DEFAULT,
1778                                          OIC_RSRC_CRED_URI,
1779                                          CredEntityHandler,
1780                                          NULL,
1781                                          OC_SECURE);
1782
1783     if (OC_STACK_OK != ret)
1784     {
1785         OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
1786         DeInitCredResource();
1787     }
1788     return ret;
1789 }
1790
1791 OCStackResult InitCredResource()
1792 {
1793     OCStackResult ret = OC_STACK_ERROR;
1794
1795     //Read Cred resource from PS
1796     uint8_t *data = NULL;
1797     size_t size = 0;
1798     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
1799     // If database read failed
1800     if (ret != OC_STACK_OK)
1801     {
1802         OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
1803     }
1804     if (data)
1805     {
1806         // Read ACL resource from PS
1807         ret = CBORPayloadToCred(data, size, &gCred);
1808     }
1809
1810     /*
1811      * If SVR database in persistent storage got corrupted or
1812      * is not available for some reason, a default Cred is created
1813      * which allows user to initiate Cred provisioning again.
1814      */
1815     if (ret != OC_STACK_OK || !data || !gCred)
1816     {
1817         gCred = GetCredDefault();
1818     }
1819     //Instantiate 'oic.sec.cred'
1820     ret = CreateCredResource();
1821     OICFree(data);
1822     return ret;
1823 }
1824
1825 OCStackResult DeInitCredResource()
1826 {
1827     OCStackResult result = OCDeleteResource(gCredHandle);
1828     DeleteCredList(gCred);
1829     gCred = NULL;
1830     return result;
1831 }
1832
1833 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
1834 {
1835     OicSecCred_t *cred = NULL;
1836
1837    if ( NULL == subject)
1838     {
1839        return NULL;
1840     }
1841
1842     LL_FOREACH(gCred, cred)
1843     {
1844         if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1845         {
1846             return cred;
1847         }
1848     }
1849     return NULL;
1850 }
1851
1852 const OicSecCred_t* GetCredList()
1853 {
1854     return gCred;
1855 }
1856
1857 OicSecCred_t* GetCredResourceDataByCredId(const uint16_t credId)
1858 {
1859     OicSecCred_t *cred = NULL;
1860
1861    if ( 1 > credId)
1862     {
1863        return NULL;
1864     }
1865
1866     LL_FOREACH(gCred, cred)
1867     {
1868         if(cred->credId == credId)
1869         {
1870             return cred;
1871         }
1872     }
1873     return NULL;
1874 }
1875
1876 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1877 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
1878               const uint8_t *desc, size_t desc_len,
1879               uint8_t *result, size_t result_length)
1880 {
1881     int32_t ret = -1;
1882
1883     if (NULL == result)
1884     {
1885         return ret;
1886     }
1887
1888     switch (type)
1889     {
1890         case CA_DTLS_PSK_HINT:
1891         case CA_DTLS_PSK_IDENTITY:
1892             {
1893                 OicUuid_t deviceID = {.id={0}};
1894                 // Retrieve Device ID from doxm resource
1895                 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
1896                 {
1897                     OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
1898                     return ret;
1899                 }
1900
1901                 if (result_length < sizeof(deviceID.id))
1902                 {
1903                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
1904                     return ret;
1905                 }
1906                 memcpy(result, deviceID.id, sizeof(deviceID.id));
1907                 return (sizeof(deviceID.id));
1908             }
1909             break;
1910
1911         case CA_DTLS_PSK_KEY:
1912             {
1913                 OicSecCred_t *cred = NULL;
1914                 LL_FOREACH(gCred, cred)
1915                 {
1916                     if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
1917                     {
1918                         continue;
1919                     }
1920
1921                     if ((desc_len == sizeof(cred->subject.id)) &&
1922                         (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
1923                     {
1924                         /*
1925                          * If the credentials are valid for limited time,
1926                          * check their expiry.
1927                          */
1928                         if (cred->period)
1929                         {
1930                             if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
1931                             {
1932                                 OIC_LOG (INFO, TAG, "Credentials are expired.");
1933                                 return ret;
1934                             }
1935                         }
1936
1937                         // Copy PSK.
1938                         // TODO: Added as workaround. Will be replaced soon.
1939                         if(OIC_ENCODING_RAW == cred->privateData.encoding)
1940                         {
1941                             ret = cred->privateData.len;
1942                             memcpy(result, cred->privateData.data, ret);
1943                         }
1944                         else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
1945                         {
1946                             size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
1947                             uint8_t* outKey = OICCalloc(1, outBufSize);
1948                             uint32_t outKeySize;
1949                             if(NULL == outKey)
1950                             {
1951                                 OIC_LOG (ERROR, TAG, "Failed to memoray allocation.");
1952                                 return ret;
1953                             }
1954
1955                             if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
1956                             {
1957                                 memcpy(result, outKey, outKeySize);
1958                                 ret = outKeySize;
1959                             }
1960                             else
1961                             {
1962                                 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
1963                             }
1964
1965                             OICFree(outKey);
1966                         }
1967
1968                         return ret;
1969                     }
1970                 }
1971             }
1972             break;
1973     }
1974
1975     return ret;
1976 }
1977
1978 /**
1979  * Add temporal PSK to PIN based OxM
1980  *
1981  * @param[in] tmpSubject UUID of target device
1982  * @param[in] credType Type of credential to be added
1983  * @param[in] pin numeric characters
1984  * @param[in] pinSize length of 'pin'
1985  * @param[in] rownerID Resource owner's UUID
1986  * @param[out] tmpCredSubject Generated credential's subject.
1987  *
1988  * @return OC_STACK_OK for success and errorcode otherwise.
1989  */
1990 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
1991                             const char * pin, size_t pinSize,
1992                             const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
1993 {
1994     OCStackResult ret = OC_STACK_ERROR;
1995     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
1996
1997     if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
1998     {
1999         return OC_STACK_INVALID_PARAM;
2000     }
2001
2002     uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2003     OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2004     OicSecCred_t* cred = NULL;
2005     int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2006                                               UUID_LENGTH, PBKDF_ITERATIONS,
2007                                               OWNER_PSK_LENGTH_128, privData);
2008     VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2009
2010     cred = GenerateCredential(tmpSubject, credType, NULL,
2011                               &privKey, rownerID);
2012     if(NULL == cred)
2013     {
2014         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2015         return OC_STACK_ERROR;
2016     }
2017
2018     memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2019
2020     ret = AddCredential(cred);
2021     if( OC_STACK_OK != ret)
2022     {
2023         RemoveCredential(tmpSubject);
2024         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2025     }
2026     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2027
2028 exit:
2029     return ret;
2030 }
2031
2032 #endif /* __WITH_DTLS__ */
2033
2034 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2035 {
2036     OCStackResult ret = OC_STACK_ERROR;
2037     uint8_t *cborPayload = NULL;
2038     size_t size = 0;
2039     int secureFlag = 0;
2040     OicUuid_t prevId = {.id={0}};
2041
2042     if(NULL == newROwner)
2043     {
2044         ret = OC_STACK_INVALID_PARAM;
2045     }
2046     if(NULL == gCred)
2047     {
2048         ret = OC_STACK_NO_RESOURCE;
2049     }
2050
2051     if(newROwner && gCred)
2052     {
2053         memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2054         memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2055
2056         // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2057         size = GetCredKeyDataSize(gCred);
2058         size += (256 * OicSecCredCount(gCred));
2059         ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2060         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2061
2062         ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2063         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2064
2065         OICFree(cborPayload);
2066     }
2067
2068     return ret;
2069
2070 exit:
2071     OICFree(cborPayload);
2072     memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2073     return ret;
2074 }
2075
2076 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2077 {
2078     OCStackResult retVal = OC_STACK_ERROR;
2079     if (gCred)
2080     {
2081         *rowneruuid = gCred->rownerID;
2082         retVal = OC_STACK_OK;
2083     }
2084     return retVal;
2085 }
2086
2087 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2088 void GetDerCaCert(ByteArray_t * crt)
2089 {
2090     if (NULL == crt)
2091     {
2092         return;
2093     }
2094     uint8_t *data = NULL;
2095     crt->len = 0;
2096     OCStackResult ret = OC_STACK_ERROR;
2097     OicSecCred_t * cred;
2098     OicSecCred_t * temp = NULL;
2099     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2100     LL_FOREACH(gCred, temp)
2101     {
2102         if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), TRUST_CA, strlen(TRUST_CA) + 1))
2103         {
2104             OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->optionalData.len, crt->len);
2105             if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2106             {
2107                 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2108                 uint8 * buf = OICCalloc(1, bufSize);
2109                 if(NULL == buf)
2110                 {
2111                     OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2112                     return;
2113                 }
2114                 uint32_t outSize;
2115                 if(B64_OK != b64Decode(temp->optionalData.data, temp->optionalData.len, buf, bufSize, &outSize))
2116                 {
2117                     OICFree(buf);
2118                     OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2119                     return;
2120                 }
2121                 crt->data = OICRealloc(crt->data, crt->len + outSize);
2122                 memcpy(crt->data + crt->len, buf, outSize);
2123                 crt->len += outSize;
2124                 OICFree(buf);
2125             }
2126             else
2127             {
2128                 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2129                 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2130                 crt->len += temp->optionalData.len;
2131             }
2132             OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2133         }
2134     }
2135     if(0 == crt->len)
2136     {
2137         OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2138     }
2139     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2140     return;
2141 }
2142
2143 void GetDerOwnCert(ByteArray_t * crt)
2144 {
2145     if (NULL == crt)
2146     {
2147         return;
2148     }
2149     crt->len = 0;
2150     uint8_t *data = NULL;
2151     OicSecCred_t * temp = NULL;
2152     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2153     LL_FOREACH(gCred, temp)
2154     {
2155         if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, strlen(PRIMARY_CERT) + 1))
2156         {
2157             OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->publicData.len, crt->len);
2158             crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2159             memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2160             crt->len += temp->publicData.len;
2161
2162             OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2163         }
2164     }
2165     if(0 == crt->len)
2166     {
2167         OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2168     }
2169     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2170     return;
2171 }
2172
2173 void GetDerKey(ByteArray_t * key)
2174 {
2175     if (NULL == key)
2176     {
2177         return;
2178     }
2179
2180     uint8_t *data = NULL;
2181     OicSecCred_t * temp = NULL;
2182     key->len = 0;
2183     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2184     LL_FOREACH(gCred, temp)
2185     {
2186         if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, strlen(PRIMARY_CERT) + 1))
2187         {
2188             OIC_LOG_V(DEBUG, TAG, "len: %d, key len: %d", temp->privateData.len, key->len);
2189             key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2190             memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2191             key->len += temp->privateData.len;
2192
2193             OIC_LOG_V(DEBUG, TAG, "Key Found!! %d", key->len);
2194         }
2195     }
2196     if(0 == key->len)
2197     {
2198         OIC_LOG(DEBUG, TAG, "Key Not Found!!");
2199     }
2200     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2201 }
2202
2203 void InitCipherSuiteList(bool * list)
2204 {
2205     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2206     if (NULL == list)
2207     {
2208         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2209         OIC_LOG(DEBUG, TAG, "NULL list param");
2210         return;
2211     }
2212     OicSecCred_t * temp = NULL;
2213     LL_FOREACH(gCred, temp)
2214     {
2215         switch (temp->credType)
2216         {
2217             case SYMMETRIC_PAIR_WISE_KEY:
2218             {
2219                 list[0] = true;
2220                 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2221                 break;
2222             }
2223             case SIGNED_ASYMMETRIC_KEY:
2224             {
2225                 list[1] = true;
2226                 OIC_LOG(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found");
2227                 break;
2228             }
2229             case SYMMETRIC_GROUP_KEY:
2230             case ASYMMETRIC_KEY:
2231             case PIN_PASSWORD:
2232             case ASYMMETRIC_ENCRYPTION_KEY:
2233             {
2234                 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2235                 break;
2236             }
2237             default:
2238             {
2239                 OIC_LOG(WARNING, TAG, "Unknow credential type for TLS.");
2240                 break;
2241             }
2242         }
2243     }
2244     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2245 }
2246 #endif