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