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