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