4099071c8b3d095bf217f28ebf1291914996c0a1
[iotivity.git] / resource / csdk / security / tool / json2cbor.c
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics 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 #include <stdlib.h>
22 #include <string.h>
23 #include <inttypes.h>
24 #include "utlist.h"
25 #include "cJSON.h"
26 #include "cainterface.h"
27 #include "ocstack.h"
28 #include "oic_malloc.h"
29 #include "oic_string.h"
30 #include "ocpayload.h"
31 #include "ocpayloadcbor.h"
32 #include "experimental/payload_logging.h"
33 #include "secureresourcemanager.h"
34 #include "srmresourcestrings.h"
35 #include "srmutility.h"
36 #include "aclresource.h"
37 #include "pstatresource.h"
38 #include "spresource.h"
39 #include "experimental/doxmresource.h"
40 #include "amaclresource.h"
41 #include "credresource.h"
42 #include "security_internals.h"
43 #include "ocresourcehandler.h"
44
45 #define TAG  "OIC_JSON2CBOR"
46 #define MAX_RANGE   SIZE_MAX
47 //SVR database buffer block size
48
49 #define DB_FILE_SIZE_BLOCK 1023
50 #define DELTA_ERROR 0.0000001
51
52 static OicSecPstat_t *JSONToPstatBin(const char *jsonStr);
53 static OicSecSp_t *JSONToSpBin(const char *jsonStr);
54 static OicSecDoxm_t *JSONToDoxmBin(const char *jsonStr);
55 static OicSecAcl_t *JSONToAclBin(OicSecAclVersion_t *aclVersion,
56                                  const char *jsonStr);
57 static OicSecAmacl_t *JSONToAmaclBin(const char *jsonStr);
58 static OicSecCred_t *JSONToCredBinWithRowner(const char *jsonStr,OicUuid_t *rownerId);
59 static OCDeviceProperties *JSONToDPBin(const char *jsonStr);
60
61 static size_t GetJSONFileSize(const char *jsonFileName)
62 {
63     size_t size = 0;
64     size_t bytesRead  = 0;
65     char buffer[DB_FILE_SIZE_BLOCK];
66     FILE *fp = fopen(jsonFileName, "r");
67     if (fp)
68     {
69         do
70         {
71             bytesRead = fread(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
72             if (bytesRead >= (MAX_RANGE - size))
73             {
74                 fclose(fp);
75                 return 0;
76             }
77             size += bytesRead;
78         }
79         while (bytesRead > 0);
80         fclose(fp);
81     }
82     return size;
83 }
84
85 /** @return OC_STACK_OK on success **/
86 static OCStackResult ReadBufferFromFile(const char *fileName, uint8_t **buffer, size_t *bufferSize)
87 {
88     OCStackResult ret = OC_STACK_ERROR;
89     FILE *fp = NULL;
90     size_t size = 0;
91     VERIFY_NOT_NULL(TAG, buffer, FATAL);
92     VERIFY_NOT_NULL(TAG, bufferSize, FATAL);
93
94     size = GetJSONFileSize(fileName);
95     if (0 == size)
96     {
97         OIC_LOG(ERROR, TAG, "Unable to get file size");
98         return OC_STACK_ERROR;
99     }
100     fp = fopen(fileName, "r");
101     if (fp)
102     {
103         *buffer = (uint8_t *)OICMalloc(size + 1);
104         VERIFY_NOT_NULL(TAG, *buffer, FATAL);
105         size_t bytesRead = fread(*buffer, 1, size, fp);
106         (*buffer)[bytesRead] = '\0';
107         OIC_LOG_V(DEBUG, TAG, "Read %" PRIuPTR " bytes", bytesRead);
108         if (bytesRead)
109         {
110             ret = OC_STACK_OK;
111             *bufferSize = bytesRead + 1;
112         }
113     }
114     else
115     {
116         OIC_LOG(ERROR, TAG, "Unable to open JSON file!!");
117     }
118 exit:
119     if (OC_STACK_OK != ret)
120     {
121         OIC_LOG_V(ERROR, TAG, "%s: exiting (%d)", __func__, ret);
122         *bufferSize = 0;
123         OICFreeAndSetToNull((void**)buffer);
124     }
125     if(fp)
126     {
127         if (0 != fclose(fp))
128         {
129             OIC_LOG_V(ERROR, TAG, "Failed to close file \"%s\"", fileName);
130         }
131     }
132     return ret;
133 }
134
135 /** @return OC_STACK_OK on success **/
136 static OCStackResult WriteBufferToFile(const char *fileName, uint8_t *buffer, size_t size)
137 {
138     OCStackResult ret = OC_STACK_ERROR;
139     if ((fileName == NULL) || (buffer == NULL) || (size == 0))
140     {
141         OIC_LOG(ERROR, TAG, "Invalid Parameters to WriteBufferToFile");
142         return OC_STACK_ERROR;
143     }
144     FILE *fp = fopen(fileName, "wb");
145     if (fp)
146     {
147         size_t bytesWritten = fwrite(buffer, 1, size, fp);
148         if (bytesWritten == size)
149         {
150             OIC_LOG_V(DEBUG, TAG, "Written %" PRIuPTR " bytes", bytesWritten);
151             ret = OC_STACK_OK;
152         }
153         else
154         {
155             OIC_LOG_V(ERROR, TAG, "Failed writing %" PRIuPTR " bytes - Error: %d",
156                       size, ferror(fp));
157         }
158         if (0 != fclose(fp))
159         {
160             OIC_LOG_V(ERROR, TAG, "Failed to close file \"%s\"", fileName);
161             ret = OC_STACK_ERROR;
162         }
163     }
164     else
165     {
166         OIC_LOG_V(ERROR, TAG, "Error opening file [%s] for Write", fileName);
167     }
168     return ret;
169 }
170
171 CborError EncodeJson(CborEncoder *encoder, cJSON *jsonObj)
172 {
173     CborError err = CborNoError;
174     switch (jsonObj->type)
175     {
176         case cJSON_Object:
177             {
178                 CborEncoder rootMap;
179                 err = cbor_encoder_create_map(encoder, &rootMap, CborIndefiniteLength);
180                 if (CborNoError == err)
181                 {
182                     cJSON *child = jsonObj->child;
183                     while (child)
184                     {
185                         err = cbor_encode_text_string(&rootMap, child->string, strlen(child->string));
186                         if (CborNoError != err)
187                         {
188                             break;
189                         }
190                         err = EncodeJson(&rootMap, child);
191                         if (CborNoError != err)
192                         {
193                             break;
194                         }
195                         child = child->next;
196                     }
197                 }
198                 if (CborNoError == err)
199                 {
200                     err = cbor_encoder_close_container(encoder, &rootMap);
201                 }
202             }
203             break;
204         case cJSON_Array:
205             {
206                 CborEncoder cborArray;
207                 err = cbor_encoder_create_array(encoder, &cborArray, CborIndefiniteLength);
208                 if (CborNoError == err)
209                 {
210                     cJSON *child = jsonObj->child;
211                     while (child)
212                     {
213                         err = EncodeJson(&cborArray, child);
214                         if (CborNoError != err)
215                         {
216                             break;
217                         }
218                         child = child->next;
219                     }
220                 }
221                 if (CborNoError == err)
222                 {
223                     err = cbor_encoder_close_container(encoder, &cborArray);
224                 }
225             }
226             break;
227         case cJSON_String:
228             err = cbor_encode_text_string(encoder, jsonObj->valuestring,
229                                           strlen(jsonObj->valuestring));
230             break;
231         case cJSON_Number:
232             if ((jsonObj->valuedouble - jsonObj->valueint) > DELTA_ERROR)
233             {
234                 err = cbor_encode_double(encoder, jsonObj->valuedouble);
235             }
236             else
237             {
238                 err = cbor_encode_int(encoder, jsonObj->valueint);
239             }
240             break;
241         case cJSON_NULL:
242             err = cbor_encode_null(encoder);
243             break;
244         case cJSON_True:
245             err = cbor_encode_boolean(encoder, true);
246             break;
247         case cJSON_False:
248             err = cbor_encode_boolean(encoder, false);
249             break;
250         default:
251             OIC_LOG(ERROR, TAG, "Unknown cjson type");
252             break;
253     }
254     return err;
255 }
256
257 /** @return OC_STACK_OK on success **/
258 static OCStackResult ConvertJSONStringToCBORFile(const char *jsonStr, const char *cborFileName)
259 {
260     OCStackResult ret = OC_STACK_ERROR;
261     CborEncoder encoder;
262     CborError err;
263     cJSON *jsonObj = NULL;
264     uint8_t *buffer = NULL;
265     size_t size = 0;
266
267     OIC_LOG_V(INFO, TAG, "%s: enterring ", __func__);
268     jsonObj = cJSON_Parse(jsonStr);
269     if (jsonObj == NULL)
270     {
271         OIC_LOG(ERROR, TAG, "Unable to parse JSON string");
272         goto exit;
273     }
274     size = strlen(jsonStr) + 1;
275     size_t bufferSize = 0;
276     buffer = (uint8_t *)OICMalloc(size);
277     if (!buffer)
278     {
279         OIC_LOG(ERROR, TAG, "Unable to allocate enough memory");
280         goto exit;
281     }
282
283     cbor_encoder_init(&encoder, buffer, size, 0);
284
285     err = EncodeJson(&encoder, jsonObj);
286     if (CborNoError != err)
287     {
288         OIC_LOG(ERROR, TAG, "Error encoding json");
289         goto exit;
290     }
291     else
292     {
293         bufferSize = cbor_encoder_get_buffer_size(&encoder, buffer);
294     }
295     ret = WriteBufferToFile(cborFileName, buffer, bufferSize);
296 exit:
297     if (OC_STACK_OK != ret)
298     {
299         OIC_LOG_V(ERROR, TAG, "%s: exiting (%d)", __func__, ret);
300     }
301     if (jsonObj)
302     {
303         cJSON_Delete(jsonObj);
304     }
305     OICFree(buffer);
306     return ret;
307 }
308
309
310 /** @return ::OC_STACK_OK on success **/
311 static OCStackResult ConvertOCJSONStringToCBORFile(const char *jsonStr, const char *cborFileName)
312 {
313     OCStackResult ret = OC_STACK_ERROR;
314     uint8_t *aclCbor = NULL;
315     uint8_t *pstatCbor = NULL;
316     uint8_t *spCbor = NULL;
317     uint8_t *doxmCbor = NULL;
318     uint8_t *amaclCbor = NULL;
319     uint8_t *credCbor = NULL;
320     uint8_t *dpCbor = NULL;
321     cJSON *jsonRoot = NULL;
322     OCDeviceProperties *deviceProps = NULL;
323     uint8_t *outPayload = NULL;
324     jsonRoot = cJSON_Parse(jsonStr);
325     cJSON *value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_ACL_NAME);
326     char *text = cJSON_PrintUnformatted(value);
327     printf("/acl json : \n%s\n", text);
328     OICFree(text);
329     size_t aclCborSize = 0;
330     if (value)
331     {
332         OicSecAclVersion_t version = OIC_SEC_ACL_V2; // default to V2
333         OicSecAcl_t *acl = JSONToAclBin(&version, jsonStr);
334         VERIFY_NOT_NULL(TAG, acl, FATAL);
335         ret = AclToCBORPayload(acl, version, &aclCbor, &aclCborSize);
336         if (OC_STACK_OK != ret)
337         {
338             OIC_LOG (ERROR, TAG, "Failed converting Acl to Cbor Payload");
339             DeleteACLList(acl);
340             goto exit;
341         }
342         printf("ACL Cbor Size: %" PRIuPTR "\n", aclCborSize);
343         DeleteACLList(acl);
344     }
345     else
346     {
347         printf("JSON contains no /acl\n");
348     }
349
350     value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_PSTAT_NAME);
351     text = cJSON_PrintUnformatted(value);
352     printf("/pstat json : \n%s\n", text);
353     OICFree(text);
354     size_t pstatCborSize = 0;
355     if (NULL != value)
356     {
357         OicSecPstat_t *pstat = JSONToPstatBin(jsonStr);
358         VERIFY_NOT_NULL(TAG, pstat, FATAL);
359         ret = PstatToCBORPayload(pstat, &pstatCbor, &pstatCborSize);
360         if (OC_STACK_OK != ret)
361         {
362             OIC_LOG (ERROR, TAG, "Failed converting Pstat to Cbor Payload");
363             DeletePstatBinData(pstat);
364             goto exit;
365         }
366         printf("PSTAT Cbor Size: %" PRIuPTR "\n", pstatCborSize);
367         DeletePstatBinData(pstat);
368     }
369     else
370     {
371         printf("JSON contains no /pstat\n");
372     }
373
374     value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_SP_NAME);
375     text = cJSON_PrintUnformatted(value);
376     printf("/sp json : \n%s\n", text);
377     size_t spCborSize = 0;
378     OICFree(text);
379     if (NULL != value)
380     {
381         OicSecSp_t *sp = JSONToSpBin(jsonStr);;
382         VERIFY_NOT_NULL(TAG, sp, FATAL);
383
384         ret = SpToCBORPayload(sp, &spCbor, &spCborSize);
385         if (OC_STACK_OK != ret)
386         {
387             OIC_LOG (ERROR, TAG, "Failed converting sp to Cbor Payload");
388             DeleteSpBinData(sp);
389             goto exit;
390         }
391         printf("SP Cbor Size: %" PRIuPTR "\n", spCborSize);
392         DeleteSpBinData(sp);
393     }
394     else
395     {
396         printf("JSON contains no /sp\n");
397     }
398
399     value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_DOXM_NAME);
400     text = cJSON_PrintUnformatted(value);
401     printf("/doxm json : \n%s\n", text);
402     OICFree(text);
403     size_t doxmCborSize = 0;
404     if (NULL != value)
405     {
406         OicSecDoxm_t *doxm = JSONToDoxmBin(jsonStr);
407         VERIFY_NOT_NULL(TAG, doxm, FATAL);
408         ret = DoxmToCBORPayload(doxm, &doxmCbor, &doxmCborSize);
409         if (OC_STACK_OK != ret)
410         {
411             OIC_LOG (ERROR, TAG, "Failed converting Doxm to Cbor Payload");
412             DeleteDoxmBinData(doxm);
413             goto exit;
414         }
415         printf("DOXM Cbor Size: %" PRIuPTR "\n", doxmCborSize);
416         DeleteDoxmBinData(doxm);
417     }
418     else
419     {
420         printf("JSON contains no /doxm\n");
421     }
422
423     value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME);
424     printf("/amacl json : \n%s\n", cJSON_PrintUnformatted(value));
425     size_t amaclCborSize = 0;
426     if (NULL != value)
427     {
428         OicSecAmacl_t *amacl = JSONToAmaclBin(jsonStr);
429         VERIFY_NOT_NULL(TAG, amacl, FATAL);
430         ret = AmaclToCBORPayload(amacl, &amaclCbor, &amaclCborSize);
431         if (OC_STACK_OK != ret)
432         {
433             OIC_LOG (ERROR, TAG, "Failed converting Amacl to Cbor Payload");
434             DeleteAmaclList(amacl);
435             goto exit;
436         }
437         printf("AMACL Cbor Size: %" PRIuPTR "\n", amaclCborSize);
438         DeleteAmaclList(amacl);
439     }
440     else
441     {
442         printf("JSON contains no /amacl\n");
443     }
444
445     value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRED_NAME);
446     printf("/cred json : \n%s\n", cJSON_PrintUnformatted(value));
447     size_t credCborSize = 0;
448     int secureFlag = 0;
449     if (NULL != value)
450     {
451         OicUuid_t rownerId;
452         OicSecCred_t *cred = JSONToCredBinWithRowner(jsonStr,&rownerId);
453         VERIFY_NOT_NULL(TAG, cred, FATAL);
454         // The source code line below is just a workaround for IOT-2407.
455         // It should be deleted when IOT-2407 gets fixed. There is no clear
456         // correlation between strlen(jsonStr) and the CBOR size, but
457         // CredToCBORPayload happens to work better when initializing
458         // credCborSize this way.
459         credCborSize = strlen(jsonStr);
460         ret = CredToCBORPayloadWithRowner(cred, &rownerId,&credCbor, &credCborSize, secureFlag);
461         if (OC_STACK_OK != ret)
462         {
463             OIC_LOG (ERROR, TAG, "Failed converting Cred to Cbor Payload");
464             DeleteCredList(cred);
465             goto exit;
466         }
467         printf("CRED Cbor Size: %" PRIuPTR "\n", credCborSize);
468         DeleteCredList(cred);
469     }
470     else
471     {
472         printf("JSON contains no /cred\n");
473     }
474
475     value = cJSON_GetObjectItem(jsonRoot, OC_JSON_DEVICE_PROPS_NAME);
476     size_t dpCborSize = 0;
477     if (NULL != value)
478     {
479         deviceProps = JSONToDPBin(jsonStr);
480         VERIFY_NOT_NULL(TAG, deviceProps, FATAL);
481         ret = DevicePropertiesToCBORPayload(deviceProps, &dpCbor, &dpCborSize);
482         if (OC_STACK_OK != ret)
483         {
484             OIC_LOG(ERROR, TAG, "Failed converting OCDeviceProperties to Cbor Payload");
485             goto exit;
486         }
487         printf("Device Properties Cbor Size: %" PRIuPTR "\n", dpCborSize);
488     }
489     else
490     {
491         printf("JSON contains no deviceProps\n");
492     }
493
494     CborEncoder encoder;
495     size_t cborSize = aclCborSize + pstatCborSize + spCborSize + doxmCborSize +
496                       credCborSize + amaclCborSize + dpCborSize;
497
498     printf("Total Cbor Size : %" PRIuPTR "\n", cborSize);
499     cborSize += 255; // buffer margin for adding map and byte string
500     outPayload = (uint8_t *)OICCalloc(1, cborSize);
501     VERIFY_NOT_NULL(TAG, outPayload, ERROR);
502     cbor_encoder_init(&encoder, outPayload, cborSize, 0);
503     CborEncoder map;
504     CborError cborEncoderResult = cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength);
505     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Creating Main Map.");
506     if ((spCborSize > 0) && spCbor)
507     {
508         cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_SP_NAME, strlen(OIC_JSON_SP_NAME));
509         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding SP Name.");
510         cborEncoderResult = cbor_encode_byte_string(&map, spCbor, spCborSize);
511         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding SP Value.");
512     }
513     if ((aclCborSize > 0) && aclCbor)
514     {
515         cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
516         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding ACL Name.");
517         cborEncoderResult = cbor_encode_byte_string(&map, aclCbor, aclCborSize);
518         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding ACL Value.");
519     }
520     if ((pstatCborSize > 0) && pstatCbor)
521     {
522         cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
523         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
524         cborEncoderResult = cbor_encode_byte_string(&map, pstatCbor, pstatCborSize);
525         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
526     }
527     if ((doxmCborSize > 0) && doxmCbor)
528     {
529         cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
530         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding DOXM Name.");
531         cborEncoderResult = cbor_encode_byte_string(&map, doxmCbor, doxmCborSize);
532         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding DOXM Value.");
533     }
534     if ((amaclCborSize > 0) && amaclCbor)
535     {
536         cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
537         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding AMACL Name.");
538         cborEncoderResult = cbor_encode_byte_string(&map, amaclCbor, amaclCborSize);
539         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding AMACL Value.");
540     }
541     if ((credCborSize > 0) && credCbor)
542     {
543         cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
544         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding CRED Name.");
545         cborEncoderResult = cbor_encode_byte_string(&map, credCbor, credCborSize);
546         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding CRED Value.");
547     }
548     if ((dpCborSize > 0) && dpCbor)
549     {
550         cborEncoderResult = cbor_encode_text_string(&map, OC_JSON_DEVICE_PROPS_NAME,
551                             strlen(OC_JSON_DEVICE_PROPS_NAME));
552         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Device Properties Name.");
553         cborEncoderResult = cbor_encode_byte_string(&map, dpCbor, dpCborSize);
554         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Adding Device Properties Value.");
555     }
556
557     cborEncoderResult = cbor_encoder_close_container(&encoder, &map);
558     VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborEncoderResult, "Failed Closing Container.");
559
560     size_t s = cbor_encoder_get_buffer_size(&encoder, outPayload);
561     OIC_LOG_V(DEBUG, TAG, "Payload size %" PRIuPTR, s);
562     ret = WriteBufferToFile(cborFileName, outPayload, s);
563 exit:
564     if (OC_STACK_OK != ret)
565     {
566         OIC_LOG_V(ERROR, TAG, "%s: exiting (%d)", __func__, ret);
567     }
568     cJSON_Delete(jsonRoot);
569     OICFree(outPayload);
570     OICFree(aclCbor);
571     OICFree(doxmCbor);
572     OICFree(pstatCbor);
573     OICFree(spCbor);
574     OICFree(amaclCbor);
575     OICFree(credCbor);
576     OICFree(dpCbor);
577     CleanUpDeviceProperties(&deviceProps);
578     return ret;
579 }
580
581 OicSecAcl_t *JSONToAclBin(OicSecAclVersion_t *aclVersion, const char *jsonStr)
582 {
583     if (NULL == jsonStr)
584     {
585         return NULL;
586     }
587
588     OCStackResult ret = OC_STACK_ERROR;
589     OicSecAcl_t *headAcl = (OicSecAcl_t *)OICCalloc(1, sizeof(OicSecAcl_t));
590     VERIFY_NOT_NULL_RETURN(TAG, headAcl, ERROR, NULL);
591     cJSON *jsonRoot = NULL;
592
593     VERIFY_NOT_NULL(TAG, jsonStr, ERROR);
594
595     jsonRoot = cJSON_Parse(jsonStr);
596     VERIFY_NOT_NULL(TAG, jsonRoot, ERROR);
597
598     cJSON *jsonAclMap = cJSON_GetObjectItem(jsonRoot, OIC_JSON_ACL_NAME);
599     VERIFY_NOT_NULL(TAG, jsonAclMap, ERROR);
600
601     cJSON *jsonAclObj = NULL;
602
603     jsonAclObj = cJSON_GetObjectItem(jsonAclMap, OIC_JSON_ACLIST_NAME);
604     if (jsonAclObj)
605     {
606         printf("Found 'aclist' tag... resource is oic.r.acl type.\n");
607         *aclVersion = OIC_SEC_ACL_V1;
608     }
609     else
610     {
611         jsonAclObj = cJSON_GetObjectItem(jsonAclMap, OIC_JSON_ACLIST2_NAME);
612         VERIFY_NOT_NULL(TAG, jsonAclObj, ERROR);
613         printf("Found 'aclist2' tag... resource is oic.r.acl2 type.\n");
614         *aclVersion = OIC_SEC_ACL_V2;
615     }
616     VERIFY_NOT_NULL(TAG, jsonAclObj, ERROR);
617
618     cJSON *jsonAclArray = NULL;
619
620     if (OIC_SEC_ACL_V1 == *aclVersion) // aclist-aces
621     {
622         jsonAclArray = cJSON_GetObjectItem(jsonAclObj, OIC_JSON_ACES_NAME);
623         VERIFY_NOT_NULL(TAG, jsonAclArray, ERROR);
624     }
625     else
626     {
627         jsonAclArray = jsonAclObj;
628     }
629
630     if (cJSON_Array == jsonAclArray->type)
631     {
632
633         size_t numAcl = cJSON_GetArraySize(jsonAclArray);
634         size_t idx = 0;
635
636         VERIFY_SUCCESS(TAG, numAcl > 0, INFO);
637         do
638         {
639             cJSON *jsonAcl = cJSON_GetArrayItem(jsonAclArray, idx);
640             VERIFY_NOT_NULL(TAG, jsonAcl, ERROR);
641
642             OicSecAce_t *ace = (OicSecAce_t *)OICCalloc(1, sizeof(OicSecAce_t));
643             VERIFY_NOT_NULL(TAG, ace, ERROR);
644             LL_APPEND(headAcl->aces, ace);
645
646             cJSON *jsonObj = NULL;
647
648             if (OIC_SEC_ACL_V2 == *aclVersion)
649             {
650                 jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_ACEID_NAME);
651                 VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
652                 VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
653                 VERIFY_SUCCESS(TAG, jsonObj->valueint <= UINT16_MAX, ERROR);
654                 ace->aceid = (uint16_t)jsonObj->valueint;
655             }
656
657             if (OIC_SEC_ACL_V1 == *aclVersion)
658             {
659                 jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_SUBJECTID_NAME);
660                 VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
661                 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
662
663                 if (strcmp(jsonObj->valuestring, WILDCARD_RESOURCE_URI) == 0)
664                 {
665                     ace->subjectuuid.id[0] = '*';
666                 }
667                 else
668                 {
669                     ret = ConvertStrToUuid(jsonObj->valuestring, &ace->subjectuuid);
670                     VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
671                 }
672                 ace->subjectType = OicSecAceUuidSubject;
673             }
674             else // v2
675             {
676                 jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_SUBJECT_NAME);
677                 VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
678                 VERIFY_SUCCESS(TAG, cJSON_Object == jsonObj->type, ERROR);
679
680                 // Enter the object and get "uuid" string...
681                 cJSON *uuidJson = NULL;
682                 uuidJson = cJSON_GetObjectItem(jsonObj, OIC_JSON_UUID_NAME);
683                 if (uuidJson) // "uuid" type
684                 {
685                     VERIFY_NOT_NULL(TAG, uuidJson, ERROR);
686                     VERIFY_SUCCESS(TAG, cJSON_String == uuidJson->type, ERROR);
687                     ret = ConvertStrToUuid(uuidJson->valuestring, &ace->subjectuuid);
688                     VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
689                     ace->subjectType = OicSecAceUuidSubject;
690                 }
691                 else // "conntype"
692                 {
693                     cJSON *conntypeJson = NULL;
694                     conntypeJson = cJSON_GetObjectItem(jsonObj, OIC_JSON_CONNTYPE_NAME);
695                     VERIFY_NOT_NULL(TAG, conntypeJson, ERROR);
696                     VERIFY_SUCCESS(TAG, cJSON_String == conntypeJson->type, ERROR);
697                     char *connTypeStr = NULL;
698                     connTypeStr = OICStrdup(conntypeJson->valuestring);
699                     VERIFY_NOT_NULL(TAG, connTypeStr, ERROR);
700                     if (0 == strcmp(connTypeStr, OIC_JSON_ANONCLEAR_NAME))
701                     {
702                         ace->subjectConn = ANON_CLEAR;
703                         ace->subjectType = OicSecAceConntypeSubject;
704                     }
705                     else if (0 == strcmp(connTypeStr, OIC_JSON_AUTHCRYPT_NAME))
706                     {
707                         ace->subjectConn = AUTH_CRYPT;
708                         ace->subjectType = OicSecAceConntypeSubject;
709                     }
710                     OICFree(connTypeStr);
711                     VERIFY_SUCCESS(TAG, ace->subjectType == OicSecAceConntypeSubject, ERROR);
712                 }
713             }
714             // Resources -- Mandatory
715             jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_RESOURCES_NAME);
716             VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
717             VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
718
719             size_t resourcesLen = cJSON_GetArraySize(jsonObj);
720             VERIFY_SUCCESS(TAG, resourcesLen > 0, ERROR);
721
722             for (size_t idxx = 0; idxx < resourcesLen; idxx++)
723             {
724                 OicSecRsrc_t *rsrc = (OicSecRsrc_t *)OICCalloc(1, sizeof(OicSecRsrc_t));
725                 VERIFY_NOT_NULL(TAG, rsrc, ERROR);
726
727 // Needs to be removed once IOT-1746 is resolved.
728 #ifdef _MSC_VER
729 #pragma warning(suppress : 4267)
730                 cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
731
732 #else
733                 cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
734
735 #endif
736                 VERIFY_NOT_NULL(TAG, jsonRsrc, ERROR);
737
738                 //href
739                 cJSON *jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_HREF_NAME);
740                 if (NULL != jsonRsrcObj)
741                 {
742                     VERIFY_SUCCESS(TAG, cJSON_String == jsonRsrcObj->type, ERROR);
743                     rsrc->href = OICStrdup(jsonRsrcObj->valuestring);
744                     VERIFY_NOT_NULL(TAG, (rsrc->href), ERROR);
745                     rsrc->wildcard = NO_WILDCARD; // normally if href != NULL, then no wc
746                     if (0 == strcmp(WILDCARD_RESOURCE_URI, rsrc->href))
747                     {
748                         free(rsrc->href);
749                         rsrc->href = NULL;
750                         rsrc->wildcard = ALL_NCRS;
751                         OIC_LOG_V(DEBUG, TAG, "%s: replaced \"*\" href with wildcard = ALL_NCRS.",
752                                   __func__);
753                     }
754                 }
755
756                 //rel
757                 jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_REL_NAME);
758                 if (NULL != jsonRsrcObj)
759                 {
760                     rsrc->rel = OICStrdup(jsonRsrcObj->valuestring);
761                     VERIFY_NOT_NULL(TAG, (rsrc->rel), ERROR);
762                 }
763
764                 //rt
765                 jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_RT_NAME);
766                 if ((NULL != jsonRsrcObj) && (cJSON_Array == jsonRsrcObj->type))
767                 {
768                     rsrc->typeLen = cJSON_GetArraySize(jsonRsrcObj);
769                     VERIFY_SUCCESS(TAG, (0 < rsrc->typeLen), ERROR);
770                     rsrc->types = (char **)OICCalloc(rsrc->typeLen, sizeof(char *));
771                     VERIFY_NOT_NULL(TAG, (rsrc->types), ERROR);
772                     for (size_t i = 0; i < rsrc->typeLen; i++)
773                     {
774 // Needs to be removed once IOT-1746 is resolved.
775 #ifdef _MSC_VER
776 #pragma warning(suppress : 4267)
777                         cJSON *jsonRsrcType = cJSON_GetArrayItem(jsonRsrcObj, i);
778
779 #else
780                         cJSON *jsonRsrcType = cJSON_GetArrayItem(jsonRsrcObj, i);
781
782 #endif
783                         VERIFY_NOT_NULL(TAG, jsonRsrcType, ERROR);
784                         rsrc->types[i] = OICStrdup(jsonRsrcType->valuestring);
785                         VERIFY_NOT_NULL(TAG, (rsrc->types[i]), ERROR);
786                     }
787                 }
788
789                 //if
790                 jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_IF_NAME);
791                 if ((NULL != jsonRsrcObj) && (cJSON_Array == jsonRsrcObj->type))
792                 {
793                     rsrc->interfaceLen = cJSON_GetArraySize(jsonRsrcObj);
794                     VERIFY_SUCCESS(TAG, (0 < rsrc->interfaceLen), ERROR);
795                     rsrc->interfaces = (char **)OICCalloc(rsrc->interfaceLen, sizeof(char *));
796                     VERIFY_NOT_NULL(TAG, (rsrc->interfaces), ERROR);
797                     for (size_t i = 0; i < rsrc->interfaceLen; i++)
798                     {
799 // Needs to be removed once IOT-1746 is resolved.
800 #ifdef _MSC_VER
801 #pragma warning(suppress : 4267)
802                         cJSON *jsonInterface = cJSON_GetArrayItem(jsonRsrcObj, i);
803
804 #else
805                         cJSON *jsonInterface = cJSON_GetArrayItem(jsonRsrcObj, i);
806
807 #endif
808                         VERIFY_NOT_NULL(TAG, jsonInterface, ERROR);
809                         rsrc->interfaces[i] = OICStrdup(jsonInterface->valuestring);
810                         VERIFY_NOT_NULL(TAG, (rsrc->interfaces[i]), ERROR);
811                     }
812                 }
813
814                 //wc
815                 jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_WC_NAME);
816                 if (NULL != jsonRsrcObj)
817                 {
818                     char *wc = NULL;
819                     VERIFY_SUCCESS(TAG, cJSON_String == jsonRsrcObj->type, ERROR);
820                     wc = OICStrdup(jsonRsrcObj->valuestring);
821                     VERIFY_NOT_NULL(TAG, wc, ERROR);
822                     if (0 == strcmp(OIC_JSON_WC_ASTERISK_NAME, wc))
823                     {
824                         rsrc->wildcard = ALL_NCRS;
825                     }
826                     else if (0 == strcmp(OIC_JSON_WC_PLUS_NAME, wc))
827                     {
828                         rsrc->wildcard = ALL_DISCOVERABLE_NCRS_WITH_OC_SECURE;
829                     }
830                     else if (0 == strcmp(OIC_JSON_WC_MINUS_NAME, wc))
831                     {
832                         rsrc->wildcard = ALL_DISCOVERABLE_NCRS_WITH_OC_NONSECURE;
833                     }
834                     else
835                     {
836                         rsrc->wildcard = NO_WILDCARD;
837                     }
838                     OICFree(wc);
839                 }
840                 LL_APPEND(ace->resources, rsrc);
841             }
842
843             // Permissions -- Mandatory
844             jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_PERMISSION_NAME);
845             VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
846             VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
847             VERIFY_SUCCESS(TAG, jsonObj->valueint <= UINT16_MAX, ERROR);
848             ace->permission = (uint16_t)jsonObj->valueint;
849
850             //Validity -- Not Mandatory
851             cJSON *jsonValidityObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_VALIDITY_NAME);
852             if (jsonValidityObj)
853             {
854                 VERIFY_SUCCESS(TAG, cJSON_Array == jsonValidityObj->type, ERROR);
855                 size_t validityLen = cJSON_GetArraySize(jsonValidityObj);
856                 VERIFY_SUCCESS(TAG, (0 < validityLen), ERROR);
857
858                 cJSON *jsonValidity = NULL;
859                 for (size_t i = 0; i < validityLen; i++)
860                 {
861 // Needs to be removed once IOT-1746 is resolved.
862 #ifdef _MSC_VER
863 #pragma warning(suppress : 4267)
864                     jsonValidity = cJSON_GetArrayItem(jsonValidityObj, i);
865
866 #else
867                     jsonValidity = cJSON_GetArrayItem(jsonValidityObj, i);
868
869 #endif
870                     VERIFY_NOT_NULL(TAG, jsonValidity, ERROR);
871                     VERIFY_SUCCESS(TAG, (jsonValidity->type == cJSON_Array), ERROR);
872
873                     OicSecValidity_t *validity = (OicSecValidity_t *)OICCalloc(1, sizeof(OicSecValidity_t));
874                     VERIFY_NOT_NULL(TAG, validity, ERROR);
875                     LL_APPEND(ace->validities, validity);
876
877                     //Period
878                     cJSON *jsonPeriod = cJSON_GetArrayItem(jsonValidity, 0);
879                     if (jsonPeriod)
880                     {
881                         VERIFY_SUCCESS(TAG, (cJSON_String == jsonPeriod->type), ERROR);
882
883                         validity->period = OICStrdup(jsonPeriod->valuestring);
884                         VERIFY_NOT_NULL(TAG, validity->period, ERROR);
885                     }
886
887                     //Recurrence
888                     cJSON *jsonRecurObj = cJSON_GetArrayItem(jsonValidity, 1);
889                     if (jsonRecurObj)
890                     {
891                         VERIFY_SUCCESS(TAG, (cJSON_Array == jsonRecurObj->type), ERROR);
892                         validity->recurrenceLen = cJSON_GetArraySize(jsonRecurObj);
893                         VERIFY_SUCCESS(TAG, (0 < validity->recurrenceLen), ERROR);
894
895                         validity->recurrences = (char **)OICCalloc(validity->recurrenceLen, sizeof(char *));
896                         VERIFY_NOT_NULL(TAG, validity->recurrences, ERROR);
897
898                         cJSON *jsonRecur = NULL;
899                         for (size_t j = 0; j < validity->recurrenceLen; j++)
900                         {
901 // Needs to be removed once IOT-1746 is resolved.
902 #ifdef _MSC_VER
903 #pragma warning(suppress : 4267)
904                             jsonRecur = cJSON_GetArrayItem(jsonRecurObj, j);
905
906 #else
907                             jsonRecur = cJSON_GetArrayItem(jsonRecurObj, j);
908
909 #endif
910                             VERIFY_NOT_NULL(TAG, jsonRecur, ERROR);
911                             validity->recurrences[j] = OICStrdup(jsonRecur->valuestring);
912                             VERIFY_NOT_NULL(TAG, validity->recurrences[j], ERROR);
913                         }
914                     }
915                 }
916             }
917         }
918         while ( ++idx < numAcl);
919     }
920
921
922     // rownerid
923     jsonAclObj = cJSON_GetObjectItem(jsonAclMap, OIC_JSON_ROWNERID_NAME);
924     VERIFY_NOT_NULL(TAG, jsonAclObj, ERROR);
925     VERIFY_SUCCESS(TAG, cJSON_String == jsonAclObj->type, ERROR);
926     ret = ConvertStrToUuid(jsonAclObj->valuestring, &headAcl->rownerID);
927     VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
928
929     ret = OC_STACK_OK;
930
931 exit:
932     cJSON_Delete(jsonRoot);
933     if (OC_STACK_OK != ret)
934     {
935         OIC_LOG_V(ERROR, TAG, "%s: exiting (%d)", __func__, ret);
936         DeleteACLList(headAcl);
937         headAcl = NULL;
938     }
939     printf("OUT %s: %s\n", __func__, (headAcl != NULL) ? "success" : "failure");
940     return headAcl;
941 }
942
943 OicSecDoxm_t *JSONToDoxmBin(const char *jsonStr)
944 {
945     printf("IN JSONToDoxmBin\n");
946     if (NULL == jsonStr)
947     {
948         return NULL;
949     }
950
951     OCStackResult ret = OC_STACK_ERROR;
952     OicSecDoxm_t *doxm =  NULL;
953     cJSON *jsonDoxm = NULL;
954     cJSON *jsonObj = NULL;
955     cJSON *jsonRoot = NULL;
956
957     doxm = (OicSecDoxm_t *)OICCalloc(1, sizeof(OicSecDoxm_t));
958     VERIFY_NOT_NULL(TAG, doxm, ERROR);
959
960     jsonRoot = cJSON_Parse(jsonStr);
961     VERIFY_NOT_NULL(TAG, jsonRoot, ERROR);
962
963     jsonDoxm = cJSON_GetObjectItem(jsonRoot, OIC_JSON_DOXM_NAME);
964     VERIFY_NOT_NULL(TAG, jsonDoxm, ERROR);
965
966     //Oxm -- not Mandatory
967     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXMS_NAME);
968     if (jsonObj && cJSON_Array == jsonObj->type)
969     {
970         doxm->oxmLen = cJSON_GetArraySize(jsonObj);
971         VERIFY_SUCCESS(TAG, doxm->oxmLen > 0, ERROR);
972
973         doxm->oxm = (OicSecOxm_t *)OICCalloc(doxm->oxmLen, sizeof(OicSecOxm_t));
974         VERIFY_NOT_NULL(TAG, doxm->oxm, ERROR);
975
976         for (size_t i  = 0; i < doxm->oxmLen ; i++)
977         {
978 // Needs to be removed once IOT-1746 is resolved.
979 #ifdef _MSC_VER
980 #pragma warning(suppress : 4267)
981             cJSON *jsonOxm = cJSON_GetArrayItem(jsonObj, i);
982
983 #else
984             cJSON *jsonOxm = cJSON_GetArrayItem(jsonObj, i);
985
986 #endif
987             VERIFY_NOT_NULL(TAG, jsonOxm, ERROR);
988             doxm->oxm[i] = (OicSecOxm_t)jsonOxm->valueint;
989         }
990     }
991
992     //OxmSel -- Mandatory
993 // Needs to be removed once IOT-1746 is resolved.
994 #ifdef _MSC_VER
995 #pragma warning(suppress : 4267)
996     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_SEL_NAME);
997
998 #else
999     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_SEL_NAME);
1000
1001 #endif
1002     if (jsonObj)
1003     {
1004         VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
1005         doxm->oxmSel = (OicSecOxm_t)jsonObj->valueint;
1006     }
1007
1008     //sct -- Mandatory
1009     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_SUPPORTED_CRED_TYPE_NAME);
1010     if (jsonObj)
1011     {
1012         VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
1013         doxm->sct = (OicSecCredType_t)jsonObj->valueint;
1014     }
1015
1016     //Owned -- Mandatory
1017     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNED_NAME);
1018     if (jsonObj)
1019     {
1020         VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type), ERROR);
1021         doxm->owned = jsonObj->valueint;
1022     }
1023
1024 #ifdef MULTIPLE_OWNER
1025     //mom -- Not Mandatory
1026     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_MOM_NAME);
1027     if (jsonObj)
1028     {
1029         VERIFY_SUCCESS(TAG, (cJSON_Number == jsonObj->type), ERROR);
1030         doxm->mom = (OicSecMom_t *)OICCalloc(1, sizeof(OicSecMom_t));
1031         VERIFY_NOT_NULL(TAG, doxm->mom, ERROR);
1032         doxm->mom->mode = (OicSecMomType_t)jsonObj->valueint;
1033     }
1034 #endif //MULTIPLE_OWNER
1035
1036     //DeviceId -- Mandatory
1037     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_DEVICE_ID_NAME);
1038     if (jsonObj)
1039     {
1040         VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
1041         if (cJSON_String == jsonObj->type)
1042         {
1043             //Check for empty string, in case DeviceId field has not been set yet
1044             if (jsonObj->valuestring[0])
1045             {
1046                 ret = ConvertStrToUuid(jsonObj->valuestring, &doxm->deviceID);
1047                 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1048             }
1049         }
1050     }
1051
1052     //rowner -- Mandatory
1053     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_ROWNERID_NAME);
1054     if (true == doxm->owned)
1055     {
1056         VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1057     }
1058     if (jsonObj)
1059     {
1060         ret = ConvertStrToUuid(jsonObj->valuestring, &doxm->rownerID);
1061         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1062     }
1063
1064     //Owner -- will be empty when device status is unowned.
1065     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_DEVOWNERID_NAME);
1066     if (true == doxm->owned)
1067     {
1068         VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1069     }
1070     if (jsonObj)
1071     {
1072         ret = ConvertStrToUuid(jsonObj->valuestring, &doxm->owner);
1073         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1074     }
1075
1076     ret = OC_STACK_OK;
1077
1078 exit:
1079     if (NULL != jsonRoot)
1080     {
1081         cJSON_Delete(jsonRoot);
1082     }
1083     if (OC_STACK_OK != ret)
1084     {
1085         DeleteDoxmBinData(doxm);
1086         doxm = NULL;
1087     }
1088     printf("OUT %s: %s\n", __func__, (doxm != NULL) ? "success" : "failure");
1089     return doxm;
1090 }
1091
1092 OicSecPstat_t *JSONToPstatBin(const char *jsonStr)
1093 {
1094     OCStackResult ret = OC_STACK_ERROR;
1095     OicSecPstat_t *pstat = NULL;
1096     cJSON *jsonObj = NULL;
1097     cJSON *jsonPstat = NULL;
1098     cJSON *jsonDos = NULL;
1099     cJSON *jsonDosObj = NULL;
1100     cJSON *jsonRoot = NULL;
1101
1102     VERIFY_NOT_NULL(TAG, jsonStr, INFO);
1103     jsonRoot = cJSON_Parse(jsonStr);
1104     VERIFY_NOT_NULL(TAG, jsonRoot, INFO);
1105     OIC_LOG(INFO, TAG, "Using pstat with mandatory .dos object.");
1106     jsonPstat = cJSON_GetObjectItem(jsonRoot, OIC_JSON_PSTAT_NAME);
1107     VERIFY_NOT_NULL(TAG, jsonPstat, INFO);
1108     pstat = (OicSecPstat_t *)OICCalloc(1, sizeof(OicSecPstat_t));
1109     VERIFY_NOT_NULL(TAG, pstat, INFO);
1110
1111     jsonDos = cJSON_GetObjectItem(jsonPstat, OIC_JSON_DOS_NAME);
1112     if (jsonDos) // do not abort if no .dos found, but print warning
1113     {
1114         OIC_LOG(INFO, TAG, "pstat.dos object found in jsonPstat");
1115
1116         jsonDosObj = cJSON_GetObjectItem(jsonDos, OIC_JSON_S_NAME);
1117         VERIFY_NOT_NULL(TAG, jsonDosObj, ERROR);
1118         OIC_LOG(INFO, TAG, "pstat.dos.s object found in jsonDos");
1119         pstat->dos.state = jsonDosObj->valueint;
1120         OIC_LOG_V(INFO, TAG, "pstat.dos.s = %d", pstat->dos.state);
1121
1122         jsonDosObj = cJSON_GetObjectItem(jsonDos, OIC_JSON_P_NAME);
1123         VERIFY_NOT_NULL(TAG, jsonDosObj, ERROR);
1124         OIC_LOG(INFO, TAG, "pstat.dos.p object found in jsonDos");
1125         VERIFY_SUCCESS(TAG, (cJSON_True == jsonDosObj->type || cJSON_False == jsonDosObj->type) , ERROR);
1126         pstat->dos.pending = (bool)jsonDosObj->valueint;
1127         OIC_LOG_V(INFO, TAG, "pstat.dos.p = %s", pstat->dos.pending ? "true" : "false");
1128     }
1129     else
1130     {
1131         pstat->dos.state = DOS_RFOTM;
1132         pstat->dos.pending = false;
1133         printf("\n***** Pstat.dos Property not found in JSON file. *****\
1134             \n***** Pstat.dos Property is MANDATORY as of OCF 1.0 *****\
1135             \n***** Using default .dos vals: s = %d, p = %s *****\n\n", pstat->dos.state, \
1136                pstat->dos.pending ? "true" : "false");
1137     }
1138
1139     jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_ISOP_NAME);
1140     VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1141     VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type) , ERROR);
1142     pstat->isOp = jsonObj->valueint;
1143
1144     jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_ROWNERID_NAME);
1145     VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1146     VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
1147     ret = ConvertStrToUuid(jsonObj->valuestring, &pstat->rownerID);
1148     VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1149
1150     jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_CM_NAME);
1151     VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1152     VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
1153     pstat->cm  = (OicSecDpm_t)jsonObj->valueint;
1154
1155     jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_TM_NAME);
1156     VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1157     VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
1158     pstat->tm  = (OicSecDpm_t)jsonObj->valueint;
1159
1160     jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_OM_NAME);
1161     VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1162     VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
1163     pstat->om  = (OicSecDpom_t)jsonObj->valueint;
1164
1165     jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_SM_NAME);
1166     VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1167     VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
1168     pstat->smLen = 1;
1169     pstat->sm = (OicSecDpom_t *)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
1170     VERIFY_NOT_NULL(TAG, pstat->sm, ERROR);
1171     pstat->sm[0] = (OicSecDpom_t)jsonObj->valueint;
1172
1173     ret = OC_STACK_OK;
1174
1175 exit:
1176     cJSON_Delete(jsonRoot);
1177     if (OC_STACK_OK != ret)
1178     {
1179         DeletePstatBinData(pstat);
1180         pstat = NULL;
1181     }
1182     printf("OUT %s: %s\n", __func__, (pstat != NULL) ? "success" : "failure");
1183     return pstat;
1184 }
1185
1186 static OicSecSp_t *JSONToSpBin(const char *jsonStr)
1187 {
1188     OCStackResult ret = OC_STACK_ERROR;
1189
1190     cJSON *jsonRoot = NULL;
1191     cJSON *jsonSp = NULL;
1192     cJSON *jsonActiveProfileName = NULL;
1193     cJSON *jsonSupportedProfilesArray = NULL;
1194     cJSON *jsonProfileName = NULL;
1195     cJSON *jsonCredid = NULL;
1196
1197     OicSecSp_t *sp = NULL;
1198
1199     VERIFY_NOT_NULL(TAG, jsonStr, INFO);
1200     jsonRoot = cJSON_Parse(jsonStr);
1201     VERIFY_NOT_NULL(TAG, jsonRoot, INFO);
1202     jsonSp = cJSON_GetObjectItem(jsonRoot, OIC_JSON_SP_NAME);
1203     VERIFY_NOT_NULL(TAG, jsonSp, INFO);
1204     sp = (OicSecSp_t *)OICCalloc(1, sizeof(OicSecSp_t));
1205     VERIFY_NOT_NULL(TAG, sp, INFO);
1206
1207     // Supported Profiles
1208
1209     jsonSupportedProfilesArray = cJSON_GetObjectItem(jsonSp, OIC_JSON_SUPPORTED_SP_NAME);
1210     VERIFY_NOT_NULL(TAG, jsonSupportedProfilesArray, ERROR);
1211     VERIFY_SUCCESS(TAG, (cJSON_Array == jsonSupportedProfilesArray->type), ERROR);
1212     sp->supportedLen = cJSON_GetArraySize(jsonSupportedProfilesArray);
1213     VERIFY_SUCCESS(TAG, (0 < sp->supportedLen), ERROR);
1214     sp->supportedProfiles = (char **)OICCalloc(sp->supportedLen, sizeof(char *));
1215     VERIFY_NOT_NULL(TAG, (sp->supportedProfiles), ERROR);
1216
1217     for (size_t i = 0; i < sp->supportedLen; i++)
1218     {
1219         jsonProfileName = cJSON_GetArrayItem(jsonSupportedProfilesArray, i);
1220         VERIFY_NOT_NULL(TAG, jsonProfileName, ERROR);
1221         sp->supportedProfiles[i] = OICStrdup(jsonProfileName->valuestring);
1222         VERIFY_NOT_NULL(TAG, (sp->supportedProfiles[i]), ERROR);
1223     }
1224
1225     // Active Profile
1226
1227     jsonActiveProfileName = cJSON_GetObjectItem(jsonSp, OIC_JSON_ACTIVE_SP_NAME);
1228     VERIFY_NOT_NULL(TAG, jsonActiveProfileName, ERROR);
1229     VERIFY_SUCCESS(TAG, (cJSON_String == jsonActiveProfileName->type), ERROR);
1230     sp->activeProfile = OICStrdup(jsonActiveProfileName->valuestring);
1231     VERIFY_NOT_NULL(TAG, (sp->activeProfile), ERROR);
1232
1233     if (0 > ProfileIdx(sp->supportedLen, sp->supportedProfiles, sp->activeProfile))
1234     {
1235         OIC_LOG_V(ERROR, TAG, "sp active profile %s not contained in supported profile list", sp->activeProfile);
1236         goto exit;
1237     }
1238
1239     // credid
1240
1241     jsonCredid = cJSON_GetObjectItem(jsonSp, OIC_JSON_SP_CREDID_NAME);
1242     if (NULL == jsonCredid)
1243     {
1244         if (true == SpRequiresCred(sp->activeProfile))
1245         {
1246             OIC_LOG(ERROR, TAG, "sp active profile requires cred, but credid not present in json");
1247             goto exit;
1248         }
1249         else
1250         {
1251             sp->credid = 0;
1252         }
1253     }
1254     else
1255     {
1256         VERIFY_SUCCESS(TAG, (cJSON_Number == jsonCredid->type), ERROR);
1257         sp->credid = (uint16_t)jsonCredid->valueint;
1258     }
1259
1260     ret = OC_STACK_OK;
1261
1262 exit:
1263     cJSON_Delete(jsonRoot);
1264     if (OC_STACK_OK != ret)
1265     {
1266         DeleteSpBinData(sp);
1267         sp = NULL;
1268     }
1269     printf("OUT %s: %s\n", __func__, (sp != NULL) ? "success" : "failure");
1270     return sp;
1271 }
1272
1273 static OicEncodingType_t GetEncodingTypeFromStr(const char *encodingType)
1274 {
1275     if (strcmp(OIC_SEC_ENCODING_RAW, encodingType) == 0)
1276     {
1277         return OIC_ENCODING_RAW;
1278     }
1279     if (strcmp(OIC_SEC_ENCODING_BASE64, encodingType) == 0)
1280     {
1281         return OIC_ENCODING_BASE64;
1282     }
1283     if (strcmp(OIC_SEC_ENCODING_PEM, encodingType) == 0)
1284     {
1285         return OIC_ENCODING_PEM;
1286     }
1287     if (strcmp(OIC_SEC_ENCODING_DER, encodingType) == 0)
1288     {
1289         return OIC_ENCODING_DER;
1290     }
1291     OIC_LOG(WARNING, TAG, "Unknown encoding type dectected!");
1292     OIC_LOG(WARNING, TAG, "json2cbor will use \"oic.sec.encoding.raw\" as default encoding type.");
1293     return OIC_ENCODING_RAW;
1294 }
1295
1296 static OicSecCred_t *JSONToCredBinWithRowner(const char *jsonStr,OicUuid_t *rownerId)
1297 {
1298     if (NULL == jsonStr)
1299     {
1300         OIC_LOG(ERROR, TAG, "JSONToCredBin jsonStr in NULL");
1301         return NULL;
1302     }
1303
1304     OicSecCred_t *headCred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
1305     OCStackResult ret = OC_STACK_ERROR;
1306     cJSON *jsonRoot = NULL;
1307     VERIFY_NOT_NULL(TAG, headCred, ERROR);
1308
1309     jsonRoot = cJSON_Parse(jsonStr);
1310     VERIFY_NOT_NULL(TAG, jsonRoot, ERROR);
1311
1312     cJSON *jsonCredMap = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRED_NAME);
1313     VERIFY_NOT_NULL(TAG, jsonCredMap, ERROR);
1314
1315     // creds
1316     cJSON *jsonCredArray = NULL;
1317     jsonCredArray = cJSON_GetObjectItem(jsonCredMap, OIC_JSON_CREDS_NAME);
1318     VERIFY_NOT_NULL(TAG, jsonCredArray, ERROR);
1319
1320     if (cJSON_Array == jsonCredArray->type)
1321     {
1322         size_t numCred = cJSON_GetArraySize(jsonCredArray);
1323         VERIFY_SUCCESS(TAG, numCred > 0, ERROR);
1324         size_t idx = 0;
1325         do
1326         {
1327             cJSON *jsonCred = cJSON_GetArrayItem(jsonCredArray, idx);
1328             VERIFY_NOT_NULL(TAG, jsonCred, ERROR);
1329
1330             OicSecCred_t *cred = NULL;
1331             if (idx == 0)
1332             {
1333                 cred = headCred;
1334             }
1335             else
1336             {
1337                 cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
1338                 VERIFY_NOT_NULL(TAG, cred, ERROR);
1339                 OicSecCred_t *temp = headCred;
1340                 while (temp->next)
1341                 {
1342                     temp = temp->next;
1343                 }
1344                 temp->next = cred;
1345             }
1346             VERIFY_NOT_NULL(TAG, cred, ERROR);
1347
1348             size_t jsonObjLen = 0;
1349             cJSON *jsonObj = NULL;
1350
1351             //CredId -- Mandatory
1352             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDID_NAME);
1353             if (jsonObj)
1354             {
1355                 VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
1356                 VERIFY_SUCCESS(TAG, jsonObj->valueint <= UINT16_MAX, ERROR);
1357                 cred->credId = (uint16_t)jsonObj->valueint;
1358             }
1359
1360             //subject -- Mandatory
1361             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_SUBJECTID_NAME);
1362             VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1363             VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
1364             if (strcmp(jsonObj->valuestring, WILDCARD_RESOURCE_URI) == 0)
1365             {
1366                 cred->subject.id[0] = '*';
1367             }
1368             else
1369             {
1370                 ret = ConvertStrToUuid(jsonObj->valuestring, &cred->subject);
1371                 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1372             }
1373
1374             //CredType -- Mandatory
1375             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDTYPE_NAME);
1376             VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1377             VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
1378             cred->credType = (OicSecCredType_t)jsonObj->valueint;
1379             //PrivateData is mandatory for some of the credential types listed below.
1380             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PRIVATEDATA_NAME);
1381
1382             if (NULL != jsonObj)
1383             {
1384                 cJSON *jsonPriv = cJSON_GetObjectItem(jsonObj, OIC_JSON_DATA_NAME);
1385                 VERIFY_NOT_NULL(TAG, jsonPriv, ERROR);
1386                 jsonObjLen = strlen(jsonPriv->valuestring);
1387
1388                 ret = (jsonObjLen % 2 == 0) ? ret : OC_STACK_ERROR;
1389
1390                 char tmp[3];
1391                 char *buf = (char *)OICCalloc(1, jsonObjLen/2);
1392                 VERIFY_NOT_NULL(TAG, buf, ERROR);
1393                 for(size_t i = 0, p = 0 ; i < jsonObjLen; i+=2, ++p)
1394                 {
1395                     snprintf(tmp, sizeof(tmp), "%c%c", jsonPriv->valuestring[i], jsonPriv->valuestring[i+1]);
1396                     buf[p] = (char)strtol(tmp, NULL, 16);
1397                 }
1398                 cred->privateData.len = jsonObjLen/2;
1399                 cred->privateData.data = (uint8_t *)OICCalloc(1, cred->privateData.len);
1400                 VERIFY_NOT_NULL(TAG, (cred->privateData.data), ERROR);
1401                 memcpy(cred->privateData.data, buf, cred->privateData.len);
1402                 OICFree(buf);
1403
1404                 cJSON *jsonEncoding = cJSON_GetObjectItem(jsonObj, OIC_JSON_ENCODING_NAME);
1405                 VERIFY_NOT_NULL(TAG, jsonEncoding, ERROR);
1406                 cred->privateData.encoding = GetEncodingTypeFromStr(jsonEncoding->valuestring);
1407             }
1408 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1409             //PublicData is mandatory only for SIGNED_ASYMMETRIC_KEY credentials type.
1410             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PUBLICDATA_NAME);
1411             if (NULL != jsonObj)
1412             {
1413                 cJSON *jsonPub = cJSON_GetObjectItem(jsonObj, OIC_JSON_DATA_NAME);
1414                 VERIFY_NOT_NULL(TAG, jsonPub, ERROR);
1415                 jsonObjLen = strlen(jsonPub->valuestring);
1416
1417                 ret = (jsonObjLen % 2 == 0) ? ret : OC_STACK_ERROR;
1418
1419                 char tmp[3];
1420                 char *buf = (char *)OICCalloc(1, jsonObjLen/2);
1421                 VERIFY_NOT_NULL(TAG, buf, ERROR);
1422                 for(size_t i = 0, p = 0 ; i < jsonObjLen; i+=2, ++p)
1423                 {
1424                     snprintf(tmp, sizeof(tmp), "%c%c", jsonPub->valuestring[i], jsonPub->valuestring[i+1]);
1425                     buf[p] = (char)strtol(tmp, NULL, 16);
1426                 }
1427                 cred->publicData.len = jsonObjLen/2;
1428                 cred->publicData.data = (uint8_t *)OICCalloc(1, cred->publicData.len);
1429                 VERIFY_NOT_NULL(TAG, (cred->publicData.data), ERROR);
1430                 memcpy(cred->publicData.data, buf, cred->publicData.len);
1431                 OICFree(buf);
1432
1433                 cJSON *jsonEncoding = cJSON_GetObjectItem(jsonObj, OIC_JSON_ENCODING_NAME);
1434
1435                 VERIFY_NOT_NULL(TAG, jsonEncoding, ERROR);
1436                 cred->publicData.encoding = GetEncodingTypeFromStr(jsonEncoding->valuestring);
1437             }
1438
1439             //Optional Data
1440             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_OPTDATA_NAME);
1441             if (NULL != jsonObj)
1442             {
1443                 cJSON *jsonOpt = cJSON_GetObjectItem(jsonObj, OIC_JSON_DATA_NAME);
1444                 VERIFY_NOT_NULL(TAG, jsonOpt, ERROR);
1445                 jsonObjLen = strlen(jsonOpt->valuestring);
1446
1447                 ret = (jsonObjLen % 2 == 0) ? ret : OC_STACK_ERROR;
1448                 char tmp[3];
1449                 char *buf = (char *)OICCalloc(1, jsonObjLen/2);
1450                 VERIFY_NOT_NULL(TAG, buf, ERROR);
1451                 for(size_t i = 0, p = 0; i < jsonObjLen; i+=2, ++p)
1452                 {
1453                     snprintf(tmp, sizeof(tmp), "%c%c", jsonOpt->valuestring[i], jsonOpt->valuestring[i+1]);
1454                     buf[p] = (char)strtol(tmp, NULL, 16);
1455                 }
1456                 cred->optionalData.len = jsonObjLen/2;
1457
1458                 cred->optionalData.data =  (uint8_t *)OICCalloc(1, cred->optionalData.len);
1459                 VERIFY_NOT_NULL(TAG, (cred->optionalData.data), ERROR);
1460                 memcpy(cred->optionalData.data, buf, cred->optionalData.len);
1461                 OICFree(buf);
1462
1463                 cJSON *jsonEncoding = cJSON_GetObjectItem(jsonObj, OIC_JSON_ENCODING_NAME);
1464                 VERIFY_NOT_NULL(TAG, jsonEncoding, ERROR);
1465                 cred->optionalData.encoding = GetEncodingTypeFromStr(jsonEncoding->valuestring);
1466                 cJSON *jsonRevstat = cJSON_GetObjectItem(jsonObj, OIC_JSON_REVOCATION_STATUS_NAME);
1467                 VERIFY_NOT_NULL(TAG, jsonRevstat, ERROR);
1468                 cred->optionalData.revstat = jsonObj->valueint;
1469             }
1470
1471             //CredUsage
1472             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDUSAGE_NAME);
1473             if (NULL != jsonObj)
1474             {
1475                 jsonObjLen = strlen(jsonObj->valuestring);
1476                 cred->credUsage = OICStrdup(jsonObj->valuestring);
1477                 VERIFY_NOT_NULL(TAG, (cred->credUsage), ERROR);
1478             }
1479
1480 #endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1481
1482             //Period -- Not Mandatory
1483             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PERIOD_NAME);
1484             if (jsonObj && cJSON_String == jsonObj->type)
1485             {
1486                 cred->period = OICStrdup(jsonObj->valuestring);
1487                 VERIFY_NOT_NULL(TAG, cred->period, ERROR);
1488             }
1489             cred->next = NULL;
1490         }
1491         while ( ++idx < numCred);
1492     }
1493
1494     // rownerid
1495     cJSON *jsonCredObj = cJSON_GetObjectItem(jsonCredMap, OIC_JSON_ROWNERID_NAME);
1496     VERIFY_NOT_NULL(TAG, jsonCredObj, ERROR);
1497     VERIFY_SUCCESS(TAG, cJSON_String == jsonCredObj->type, ERROR);
1498     ret = ConvertStrToUuid(jsonCredObj->valuestring, rownerId);
1499     VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1500     ret = OC_STACK_OK;
1501
1502 exit:
1503     cJSON_Delete(jsonRoot);
1504     if (OC_STACK_OK != ret)
1505     {
1506         DeleteCredList(headCred);
1507         headCred = NULL;
1508     }
1509     return headCred;
1510 }
1511
1512 static OicSecAmacl_t *JSONToAmaclBin(const char *jsonStr)
1513 {
1514     OCStackResult ret = OC_STACK_ERROR;
1515     OicSecAmacl_t *headAmacl = (OicSecAmacl_t *)OICCalloc(1, sizeof(OicSecAmacl_t));
1516     VERIFY_NOT_NULL_RETURN(TAG, headAmacl, ERROR, NULL);
1517     cJSON *jsonRoot = NULL;
1518     cJSON *jsonAmacl = NULL;
1519
1520     VERIFY_NOT_NULL(TAG, jsonStr, ERROR);
1521
1522     jsonRoot = cJSON_Parse(jsonStr);
1523     VERIFY_NOT_NULL(TAG, jsonRoot, ERROR);
1524
1525     jsonAmacl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME);
1526     VERIFY_NOT_NULL(TAG, jsonAmacl, INFO);
1527
1528     cJSON *jsonObj = NULL;
1529
1530     // Resources -- Mandatory
1531     jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_RESOURCES_NAME);
1532     VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1533
1534     // Rlist
1535     cJSON *jsonRlistArray = cJSON_GetObjectItem(jsonObj, OIC_JSON_RLIST_NAME);
1536     VERIFY_NOT_NULL(TAG, jsonRlistArray, ERROR);
1537     VERIFY_SUCCESS(TAG, cJSON_Array == jsonRlistArray->type, ERROR);
1538
1539     headAmacl->resourcesLen = cJSON_GetArraySize(jsonRlistArray);
1540     headAmacl->resources = (char **)OICCalloc(headAmacl->resourcesLen, sizeof(char *));
1541     VERIFY_NOT_NULL(TAG, headAmacl->resources, ERROR);
1542     size_t idxx = 0;
1543     do
1544     {
1545 // Needs to be removed once IOT-1746 is resolved.
1546 #ifdef _MSC_VER
1547 #pragma warning(suppress : 4267)
1548         cJSON *jsonRsrc = cJSON_GetArrayItem(jsonRlistArray, idxx);
1549
1550 #else
1551         cJSON *jsonRsrc = cJSON_GetArrayItem(jsonRlistArray, idxx);
1552
1553 #endif
1554         VERIFY_NOT_NULL(TAG, jsonRsrc, ERROR);
1555
1556         cJSON *jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_HREF_NAME);
1557         VERIFY_NOT_NULL(TAG, jsonRsrcObj, ERROR);
1558         VERIFY_SUCCESS(TAG, cJSON_String == jsonRsrcObj->type, ERROR);
1559
1560         headAmacl->resources[idxx] = OICStrdup(jsonRsrcObj->valuestring);
1561         VERIFY_NOT_NULL(TAG, (headAmacl->resources[idxx]), ERROR);
1562
1563     }
1564     while ( ++idxx < headAmacl->resourcesLen);
1565
1566     // Rowner -- Mandatory
1567     jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_ROWNERID_NAME);
1568     VERIFY_NOT_NULL(TAG, jsonObj, ERROR);
1569     VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
1570
1571     ret = OC_STACK_OK;
1572
1573 exit:
1574     cJSON_Delete(jsonRoot);
1575     if (OC_STACK_OK != ret)
1576     {
1577         DeleteAmaclList(headAmacl);
1578         headAmacl = NULL;
1579     }
1580     return headAmacl;
1581 }
1582
1583 OCDeviceProperties *JSONToDPBin(const char *jsonStr)
1584 {
1585     OIC_LOG(DEBUG, TAG, "JSONToDPBin IN");
1586     if (NULL == jsonStr)
1587     {
1588         return NULL;
1589     }
1590
1591     OCStackResult ret = OC_STACK_ERROR;
1592     OCDeviceProperties *deviceProps = NULL;
1593     cJSON *jsonDeviceProps = NULL;
1594     cJSON *jsonObj = NULL;
1595
1596     cJSON *jsonRoot = cJSON_Parse(jsonStr);
1597     VERIFY_NOT_NULL(TAG, jsonRoot, ERROR);
1598
1599     jsonDeviceProps = cJSON_GetObjectItem(jsonRoot, OC_JSON_DEVICE_PROPS_NAME);
1600     VERIFY_NOT_NULL(TAG, jsonDeviceProps, ERROR);
1601
1602     deviceProps = (OCDeviceProperties *)OICCalloc(1, sizeof(OCDeviceProperties));
1603     VERIFY_NOT_NULL(TAG, deviceProps, ERROR);
1604
1605     // Protocol Independent ID -- Mandatory
1606     jsonObj = cJSON_GetObjectItem(jsonDeviceProps, OC_RSRVD_PROTOCOL_INDEPENDENT_ID);
1607     if (jsonObj && (cJSON_String == jsonObj->type))
1608     {
1609         OICStrcpy(deviceProps->protocolIndependentId, UUID_STRING_SIZE, jsonObj->valuestring);
1610     }
1611
1612     ret = OC_STACK_OK;
1613
1614 exit:
1615     cJSON_Delete(jsonRoot);
1616     if (OC_STACK_OK != ret)
1617     {
1618         CleanUpDeviceProperties(&deviceProps);
1619     }
1620     OIC_LOG_V(DEBUG, TAG, "OUT %s: %s\n", __func__, (deviceProps != NULL) ? "success" : "failure");
1621
1622     return deviceProps;
1623 }
1624
1625 /** @return OC_STACK_OK on success **/
1626 static OCStackResult ConvertJSONFileToCBORFile(const char *jsonFileName, const char *cborFileName)
1627 {
1628     OCStackResult ret = OC_STACK_ERROR;
1629     char *jsonStr = NULL;
1630     size_t size = 0;
1631     ret = ReadBufferFromFile(jsonFileName, (uint8_t **)&jsonStr, &size);
1632     if ((size == 0) || !jsonStr || (OC_STACK_OK != ret))
1633     {
1634         OIC_LOG(ERROR, TAG, "Failed to read from file");
1635         goto exit;
1636     }
1637     cJSON *jsonRoot = NULL;
1638     jsonRoot = cJSON_Parse(jsonStr);
1639     if (!jsonRoot)
1640     {
1641         OIC_LOG(ERROR, TAG, "Failed to parse file");
1642         goto exit;
1643     }
1644     //TODO: It's assumed that no such field is used in non swagger files
1645     cJSON *value = cJSON_GetObjectItem(jsonRoot, "swagger");
1646     OICFree(jsonRoot);
1647     if (value)
1648     {
1649         OICFree(value);
1650         ret = ConvertJSONStringToCBORFile(jsonStr, cborFileName);
1651     }
1652     else
1653     {
1654         ret = ConvertOCJSONStringToCBORFile(jsonStr, cborFileName);
1655     }
1656 exit:
1657     if (OC_STACK_OK != ret)
1658     {
1659         OIC_LOG_V(ERROR, TAG, "%s: exiting (%d)", __func__, ret);
1660     }
1661     OICFree(jsonStr);
1662     return ret;
1663 }
1664
1665 /** @return 0 on success **/
1666 int main(int argc, char *argv[])
1667 {
1668     OCStackResult status = OC_STACK_ERROR;
1669     if (argc == 3)
1670     {
1671         printf("JSON File Name: %s\n CBOR File Name: %s \n", argv[1], argv[2]);
1672         status = ConvertJSONFileToCBORFile(argv[1], argv[2]);
1673     }
1674     else
1675     {
1676         printf("This program requires two inputs:\n");
1677         printf("1. First input is a json file that will be converted to cbor. \n");
1678         printf("2. Second input is a resulting cbor file that will store converted cbor. \n");
1679         printf("Usage: json2cbor <json_file_name> <cbor_file_name>\n");
1680     }
1681     return (OC_STACK_OK != status);
1682 }