replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / tool / svrdbeditor_src / svrdbeditordoxm.c
1 /* *****************************************************************
2  *
3  * Copyright 2017 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 "octypes.h"
22 #include "srmresourcestrings.h"
23 #include "oic_malloc.h"
24
25 #include "psinterface.h"
26
27 #include "doxmresource.h"
28 #include "svrdbeditordoxm.h"
29
30 #ifdef MULTIPLE_OWNER
31 #define DOXM_TYPE_CNT (6)
32 #else
33 #define DOXM_TYPE_CNT (5)
34 #endif //MULTIPLE_OWNER
35
36 static const char *DOXM_TYPE_STRING[DOXM_TYPE_CNT] =
37 {
38     "OCFJustWorks", "OCFSharedPin", "OCFMfgCert",
39 #ifdef MULTIPLE_OWNER
40     "PRECONFIG_PIN",
41 #endif //MULTIPLE_OWNER
42     "MV_JUST_WORKS", "CON_MFG_CERT"
43 };
44
45 static const unsigned int DOXM_TYPE_NUMBER[DOXM_TYPE_CNT] =
46 {
47     OIC_JUST_WORKS, OIC_RANDOM_DEVICE_PIN, OIC_MANUFACTURER_CERTIFICATE,
48 #ifdef MULTIPLE_OWNER
49     OIC_PRECONFIG_PIN,
50 #endif //MULTIPLE_OWNER
51     OIC_MV_JUST_WORKS, OIC_CON_MFG_CERT
52 };
53
54 #define DOXM_SCT_CNT (6)
55 static const char *DOXM_SCT_STRING[DOXM_SCT_CNT] =
56 {
57     "SYMMETRIC_PAIR_WISE_KEY", "SYMMETRIC_GROUP_KEY", "ASYMMETRIC_KEY",
58     "SIGNED_ASYMMETRIC_KEY", "PIN_PASSWORD", "ASYMMETRIC_ENCRYPTION_KEY"
59 };
60 static const unsigned int DOXM_SCT_NUMBER[DOXM_SCT_CNT] =
61 {
62     SYMMETRIC_PAIR_WISE_KEY, SYMMETRIC_GROUP_KEY, ASYMMETRIC_KEY, SIGNED_ASYMMETRIC_KEY,
63     PIN_PASSWORD, ASYMMETRIC_ENCRYPTION_KEY
64 };
65
66 typedef enum DoxmModifyType
67 {
68     DOXM_EDIT_OXM = 1,
69     DOXM_EDIT_OXMSEL,
70     DOXM_EDIT_SCT,
71     DOXM_EDIT_OWNED,
72     DOXM_EDIT_DEVICEID,
73     DOXM_EDIT_OWNER,
74     DOXM_EDIT_ROWNERID = 7,
75     DOXM_SAVE = 98,
76     DOXM_CANCEL = 99
77 } DoxmModifyType;
78
79 static OicSecDoxm_t *g_doxm = NULL;
80
81 void DeInitDoxm(void)
82 {
83     DeleteDoxmBinData(g_doxm);
84     g_doxm = NULL;
85 }
86
87 int GetDoxmDevID(OicUuid_t *deviceuuid)
88 {
89     if (deviceuuid && g_doxm)
90     {
91         *deviceuuid = g_doxm->deviceID;
92         return 0;
93     }
94     return -1;
95 }
96
97 #ifdef MULTIPLE_OWNER
98 static void PrintMom(const OicSecMom_t *mom)
99 {
100     if (mom)
101     {
102         PRINT_DATA("%d (", mom->mode);
103
104         switch (mom->mode)
105         {
106             case OIC_MULTIPLE_OWNER_DISABLE:
107                 PRINT_DATA(" OIC_MULTIPLE_OWNER_DISABLE ");
108                 break;
109             case OIC_MULTIPLE_OWNER_ENABLE:
110                 PRINT_DATA(" OIC_MULTIPLE_OWNER_ENABLE ");
111                 break;
112             case OIC_MULTIPLE_OWNER_TIMELY_ENABLE:
113                 PRINT_DATA(" OIC_MULTIPLE_OWNER_TIMELY_ENABLE ");
114                 break;
115             default:
116                 break;
117         }
118
119         PRINT_DATA(") \n");
120     }
121     else
122     {
123         PRINT_DATA("NULL\n");
124     }
125 }
126 #endif
127
128 void RefreshDoxm(void)
129 {
130     OCStackResult ocResult = OC_STACK_ERROR;
131     OicSecDoxm_t *tmpDoxm = NULL;
132     uint8_t *secPayload = NULL;
133     size_t payloadSize = 0;
134
135     ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_DOXM_NAME, &secPayload, &payloadSize);
136     if (OC_STACK_OK != ocResult)
137     {
138         PRINT_WARN("GetSecureVirtualDatabaseFromPS : %d", ocResult);
139         return;
140     }
141     ocResult = CBORPayloadToDoxm(secPayload, payloadSize, &tmpDoxm);
142     if (OC_STACK_OK != ocResult)
143     {
144         PRINT_ERR("Failed CBORPayloadToDoxm");
145         OICFree(secPayload);
146         return;
147     }
148     OICFree(secPayload);
149
150     if (g_doxm)
151     {
152         DeInitDoxm();
153     }
154     g_doxm = tmpDoxm;
155 }
156
157 static void UpdateDoxm(void)
158 {
159     OCStackResult doxmResult = OC_STACK_ERROR;
160     uint8_t *doxmPayload = NULL;
161     size_t doxmPayloadSize = 0;
162
163     doxmResult = DoxmToCBORPayload(g_doxm, &doxmPayload, &doxmPayloadSize, false);
164     if (OC_STACK_OK != doxmResult)
165     {
166         PRINT_ERR("doxmToCBORPayload error : %d", doxmResult);
167         return;
168     }
169     doxmResult = UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, doxmPayload, doxmPayloadSize);
170     if (OC_STACK_OK != doxmResult)
171     {
172         PRINT_ERR("UpdateSecureResourceInPS error : %d", doxmResult);
173         OICFree(doxmPayload);
174         return;
175     }
176     OICFree(doxmPayload);
177 }
178
179 void PrintDoxm(void)
180 {
181     PRINT_INFO("\n\n********************* [%-20s] *********************",
182                "DOXM Resource");
183     if (g_doxm)
184     {
185         PRINT_PROG("%15s : ", OIC_JSON_OWNED_NAME);
186         (g_doxm->owned ? PrintString("True (Owned)") : PrintString("False (Unowned)"));
187
188         PRINT_PROG("%15s : ", OIC_JSON_OXMS_NAME);
189         PrintIntArray((int *)g_doxm->oxm, g_doxm->oxmLen);
190
191         PRINT_PROG("%15s : ", OIC_JSON_OXM_SEL_NAME);
192         PrintInt((int)g_doxm->oxmSel);
193
194         PRINT_PROG("%15s : ", OIC_JSON_SUPPORTED_CRED_TYPE_NAME);
195         PrintInt((int)g_doxm->sct);
196
197 #ifdef MULTIPLE_OWNER
198         PRINT_PROG("%15s : ", OIC_JSON_MOM_NAME);
199         PrintMom(g_doxm->mom);
200
201         // TODO: Print Subowner List
202 #endif //MULTIPLE_OWNER
203
204         PRINT_PROG("%15s : ", OIC_JSON_DEVICE_ID_NAME);
205         PrintUuid(&g_doxm->deviceID);
206
207         PRINT_PROG("%15s : ", OIC_JSON_DEVOWNERID_NAME);
208         PrintUuid(&g_doxm->owner);
209
210         PRINT_PROG("%15s : ", OIC_JSON_ROWNERID_NAME);
211         PrintUuid(&g_doxm->rownerID);
212     }
213     else
214     {
215         PRINT_PROG("doxm is empty.\n");
216         return;
217     }
218     PRINT_INFO("********************* [%-20s] *********************",
219                "DOXM Resource");
220 }
221
222 static int InputOxm(OicSecOxm_t **oxm, size_t *oxmLen)
223 {
224     bool oxmSelected[DOXM_TYPE_CNT] = {false};
225     unsigned int sel = 0;
226     unsigned int *tmpOxm = NULL;
227     size_t tmpLen = 0;
228     size_t oxmIdx = 0;
229
230     PRINT_PROG("\nInput value identifying the owner transfer method\n");
231
232     for (;;)
233     {
234         for (size_t i = 0; i < DOXM_TYPE_CNT; i++)
235         {
236             if (oxmSelected[i])
237             {
238                 PRINT_DATA("\t%zu. %s\n", i, DOXM_TYPE_STRING[i]);
239             }
240             else
241             {
242                 PRINT_NORMAL("\t%zu. %s\n", i, DOXM_TYPE_STRING[i]);
243             }
244         }
245         PRINT_NORMAL("\t%d. Save\n", DOXM_SAVE);
246         PRINT_NORMAL("\t%d. Cancel\n", DOXM_CANCEL);
247         sel = InputNumber("Select number : ");
248         if (sel < DOXM_TYPE_CNT)
249         {
250             if (oxmSelected[sel])
251             {
252                 tmpLen--;
253                 oxmSelected[sel] = false;
254             }
255             else
256             {
257                 tmpLen++;
258                 oxmSelected[sel] = true;
259             }
260         }
261         else if (DOXM_SAVE == sel)
262         {
263             break;
264         }
265         else if (DOXM_CANCEL == sel)
266         {
267             return -1;
268         }
269         else
270         {
271             PRINT_WARN("Wrong number.");
272         }
273     }
274     tmpOxm = (unsigned int *)OICCalloc(tmpLen, sizeof(unsigned int));
275     if (NULL == tmpOxm)
276     {
277         PRINT_ERR("Failed to allocate memory");
278         return -1;
279     }
280     for (size_t i = 0; i < DOXM_TYPE_CNT; i++)
281     {
282         if (oxmSelected[i])
283         {
284             tmpOxm[oxmIdx++] = DOXM_TYPE_NUMBER[i];
285         }
286     }
287     if (*oxm)
288     {
289         OICFree(*oxm);
290     }
291     *oxm = tmpOxm;
292     *oxmLen = tmpLen;
293     return 0;
294 }
295
296 static int InputOxmSel(OicSecOxm_t *oxms, size_t oxmLen, OicSecOxm_t *oxmSel)
297 {
298     bool oxmSelected[DOXM_TYPE_CNT] = {false};
299     unsigned int sel = 0;
300
301     for (size_t i = 0; i < oxmLen; i++)
302     {
303         for (size_t j = 0; j < DOXM_TYPE_CNT; j++)
304         {
305             if (DOXM_TYPE_NUMBER[j] == oxms[i])
306             {
307                 oxmSelected[j] = true;
308                 break;
309             }
310         }
311     }
312
313     PRINT_PROG("\nInput selected owner transfer method\n");
314     PRINT_INFO("You can select CYAN COLOR methods in oxms\n");
315     for (;;)
316     {
317
318         for (size_t i = 0; i < DOXM_TYPE_CNT; i++)
319         {
320             if (oxmSelected[i])
321             {
322                 PRINT_DATA("\t%zu. %s\n", i, DOXM_TYPE_STRING[i]);
323             }
324             else
325             {
326                 PRINT_NORMAL("\t%zu. %s\n", i, DOXM_TYPE_STRING[i]);
327             }
328         }
329         PRINT_NORMAL("\t%d. Cancel\n", DOXM_CANCEL);
330         sel = InputNumber("Select number : ");
331         if (sel < DOXM_TYPE_CNT)
332         {
333             if (oxmSelected[sel])
334             {
335                 *oxmSel = DOXM_TYPE_NUMBER[sel];
336                 break;
337             }
338             else
339             {
340                 PRINT_INFO("You can select CYAN COLOR methods in oxms\n");
341             }
342         }
343         else if (DOXM_CANCEL == sel)
344         {
345             return -1;
346         }
347         else
348         {
349             PRINT_WARN("Wrong number.");
350         }
351     }
352     return 0;
353 }
354
355 static int InputSct(OicSecCredType_t *sct)
356 {
357     unsigned int sel = 0;
358     OicSecCredType_t tmpSct = 0;
359     PRINT_PROG("\nInput the Supported Credential Types\n");
360     for (;;)
361     {
362         for (size_t i = 0; i < DOXM_SCT_CNT; i++)
363         {
364             (tmpSct & DOXM_SCT_NUMBER[i]) ? PRINT_DATA("\t%zu. %s\n", i, DOXM_SCT_STRING[i]) :
365             PRINT_NORMAL("\t%zu. %s\n", i, DOXM_SCT_STRING[i]);
366         }
367         PRINT_NORMAL("\t%d. Save\n", DOXM_SAVE);
368         PRINT_NORMAL("\t%d. Cancel\n", DOXM_CANCEL);
369         sel = InputNumber("Select number: ");
370         if (sel < DOXM_SCT_CNT)
371         {
372             tmpSct ^= DOXM_SCT_NUMBER[sel];
373         }
374         else if (DOXM_SAVE == sel)
375         {
376             break;
377         }
378         else if (DOXM_CANCEL == sel)
379         {
380             return -1;
381         }
382         else
383         {
384             PRINT_WARN("Wrong number.");
385         }
386     }
387     *sct = tmpSct;
388     return 0;
389 }
390
391 static bool InputOwned(void)
392 {
393     char ans = 0;
394     for (;;)
395     {
396         PRINT_NORMAL("\tEnter Owned (y/n): ");
397         for (int ret = 0; 1 != ret; )
398         {
399             ret = scanf("%c", &ans);
400             for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
401             // '0x20<=code' is character region
402         }
403         if ('y' == ans || 'Y' == ans || 'n' == ans || 'N' == ans)
404         {
405             ans &= ~0x20;  // for masking lower case, 'y/n'
406             break;
407         }
408         PRINT_NORMAL("\tEntered Wrong Answer. Please Enter 'y/n' Again\n");
409     }
410     return 'Y' == ans;
411 }
412
413 static OicSecDoxm_t *InputDoxmData(void)
414 {
415     OicSecDoxm_t *doxm = NULL;
416     int ret = 0;
417
418     doxm = (OicSecDoxm_t *)OICCalloc(1, sizeof(OicSecDoxm_t));
419     if (NULL == doxm)
420     {
421         PRINT_ERR("Failed to allocate memory");
422         return NULL;
423     }
424
425     PRINT_PROG("\n\nPlease input the each entity of new doxm.\n");
426
427     ret = InputOxm(&(doxm->oxm), &(doxm->oxmLen));
428     if (0 != ret)
429     {
430         PRINT_ERR("Failed InputOxm\n");
431         DeleteDoxmBinData(doxm);
432         return NULL;
433     }
434     ret = InputOxmSel(doxm->oxm, doxm->oxmLen, &(doxm->oxmSel));
435     if (0 != ret)
436     {
437         PRINT_ERR("Failed InputOxmSel\n");
438         DeleteDoxmBinData(doxm);
439         return NULL;
440     }
441
442     ret = InputSct(&(doxm->sct));
443     if (0 != ret)
444     {
445         PRINT_ERR("Failed InputSct\n");
446         DeleteDoxmBinData(doxm);
447         return NULL;
448     }
449
450     doxm->owned = InputOwned();
451
452     PRINT_PROG(
453         "\tInput the device UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
454     ret = InputUuid(&(doxm->deviceID));
455     if (0 != ret)
456     {
457         PRINT_ERR("InputUuid error");
458         DeleteDoxmBinData(doxm);
459         return NULL;
460     }
461
462     PRINT_PROG(
463         "\tInput the owner UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
464     ret = InputUuid(&(doxm->owner));
465     if (0 != ret)
466     {
467         PRINT_ERR("InputUuid error");
468         DeleteDoxmBinData(doxm);
469         return NULL;
470     }
471
472     PRINT_PROG(
473         "\tInput the ROWNER UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
474     ret = InputUuid(&(doxm->rownerID));
475     if (0 != ret)
476     {
477         PRINT_ERR("InputUuid error");
478         DeleteDoxmBinData(doxm);
479         return NULL;
480     }
481
482     return doxm;
483 }
484
485 static int ModifyDoxm(void)
486 {
487     int ret = 0;
488     int modifyMenu = 0;
489     if (NULL == g_doxm)
490     {
491         PRINT_ERR("Doxm is NULL");
492         return -1;
493     }
494
495     PRINT_PROG("\n\nPlease input the attribute you want to modify\n");
496     PRINT_DATA("\t%2d. Edit oxms\n", DOXM_EDIT_OXM);
497     PRINT_DATA("\t%2d. Edit oxmSel\n", DOXM_EDIT_OXMSEL);
498     PRINT_DATA("\t%2d. Edit sct\n", DOXM_EDIT_SCT);
499     PRINT_DATA("\t%2d. Edit owned\n", DOXM_EDIT_OWNED);
500     PRINT_DATA("\t%2d. Edit deviceID\n", DOXM_EDIT_DEVICEID);
501     PRINT_DATA("\t%2d. Edit owner\n", DOXM_EDIT_OWNER);
502     PRINT_DATA("\t%2d. Edit rownerID\n", DOXM_EDIT_ROWNERID);
503     PRINT_DATA("\t%2d. Cancel\n", DOXM_CANCEL);
504     modifyMenu = InputNumber("Select the menu : ");
505     switch (modifyMenu)
506     {
507         case DOXM_EDIT_OXM:
508             if (0 != InputOxm(&(g_doxm->oxm), &(g_doxm->oxmLen)))
509             {
510                 PRINT_ERR("Failed InputOxm");
511                 return -1;
512             }
513             break;
514         case DOXM_EDIT_OXMSEL:
515             if (0 != InputOxmSel(g_doxm->oxm, g_doxm->oxmLen, &(g_doxm->oxmSel)))
516             {
517                 PRINT_ERR("Failed InputOxmSel");
518                 return -1;
519             }
520             break;
521         case DOXM_EDIT_SCT:
522             if (0 != InputSct(&(g_doxm->sct)))
523             {
524                 PRINT_ERR("Failed InputSct");
525                 return -1;
526             }
527             break;
528         case DOXM_EDIT_OWNED:
529             g_doxm->owned = InputOwned();
530             break;
531         case DOXM_EDIT_DEVICEID:
532             PRINT_PROG(
533                 "\tInput the DEVICE ID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
534             ret = InputUuid(&(g_doxm->deviceID));
535             if (0 != ret)
536             {
537                 PRINT_ERR("InputUuid error");
538                 return ret;
539             }
540             break;
541         case DOXM_EDIT_OWNER:
542             PRINT_PROG(
543                 "\tInput the OWNER ID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
544             ret = InputUuid(&(g_doxm->owner));
545             if (0 != ret)
546             {
547                 PRINT_ERR("InputUuid error");
548                 return ret;
549             }
550             break;
551         case DOXM_EDIT_ROWNERID:
552             PRINT_PROG(
553                 "\tInput the ROWNER ID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
554             ret = InputUuid(&(g_doxm->rownerID));
555             if (0 != ret)
556             {
557                 PRINT_ERR("InputUuid error");
558                 return ret;
559             }
560             break;
561         case DOXM_CANCEL:
562             ret = -1;
563             break;
564         default:
565             PRINT_ERR("Invalid menu");
566             ret = -1;
567             break;
568     }
569     return ret;
570 }
571
572 void HandleDoxmOperation(const SubOperationType_t cmd)
573 {
574     if (SVR_EDIT_IDX_SIZE <= cmd)
575     {
576         PRINT_ERR("Invalid menu");
577         return;
578     }
579     switch (cmd)
580     {
581         case SVR_PRINT:
582             PrintDoxm();
583             break;
584         case SVR_ADD:
585             if (g_doxm)
586             {
587                 PRINT_ERR("Already exist");
588                 return;
589             }
590             else
591             {
592                 g_doxm = InputDoxmData();
593                 if (NULL == g_doxm)
594                 {
595                     PRINT_ERR("Failed to InputDoxmData");
596                     return;
597                 }
598                 UpdateDoxm();
599                 PrintDoxm();
600             }
601             break;
602         case SVR_REMOVE:
603             if (g_doxm)
604             {
605                 OCStackResult doxmResult = OC_STACK_ERROR;
606
607                 DeleteDoxmBinData(g_doxm);
608                 g_doxm = NULL;
609                 doxmResult = UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, NULL, 0);
610                 if (OC_STACK_OK != doxmResult)
611                 {
612                     PRINT_ERR("UpdateSecureResourceInPS error : %d", doxmResult);
613                     return;
614                 }
615             }
616             else
617             {
618                 PRINT_ERR("Not exist");
619                 return;
620             }
621             break;
622         case SVR_MODIFY:
623             if (0 != ModifyDoxm())
624             {
625                 PRINT_ERR("Failed modification");
626                 return;
627             }
628             PRINT_INFO("\n\nDoxm Modified");
629             PrintDoxm();
630             UpdateDoxm();
631             break;
632         default:
633             PRINT_ERR("Invalid menu");
634             break;
635     }
636 }