Apply coding style of tizen by astyle
[platform/core/security/libwebappenc.git] / srcs / key_handler.c
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  *
16  *
17  * @file        key_handler.c
18  * @author      Dongsun Lee (ds73.lee@samsung.com)
19  * @version     1.0
20  * @brief       Key manupulatation.
21  */
22 #include "key_handler.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <dirent.h>
28 #include <unistd.h>
29
30 #include <ckmc/ckmc-manager.h>
31 #include <tzplatform_config.h>
32
33 #include "wae_log.h"
34 #include "web_app_enc.h"
35 #include "crypto_service.h"
36
37 #define RANDOM_FILE                 "/dev/urandom"
38 #define WRT_INSTALLER_LABEL         "/User"
39 #define APP_DEK_KEK_PRIKEY_PASSWORD "wae_appdek_kek_1q2w3e4r"
40 #define APP_DEK_ALIAS_PFX           "APP_DEK_"
41 #define APP_DEK_LOADING_DONE_ALIAS  "APP_DEKS_LOADING_FINISHED"
42 #define APP_DEK_FILE_PFX            "WAE_APP_DEK"
43 #define APP_DEK_KEK_ALIAS           "WAE_APP_DEK_KEK"
44
45 #define DEK_LEN        32
46 #define MAX_ALIAS_LEN  256
47 #define MAX_PKGID_LEN  256
48 #define MAX_CACHE_SIZE 100
49
50 typedef struct _dek_cache_element {
51         char pkgId[MAX_PKGID_LEN];
52         unsigned char dek[DEK_LEN];
53 } dek_cache_element;
54
55 dek_cache_element APP_DEK_CACHE[MAX_CACHE_SIZE];
56 int NEXT_CACHE_IDX = -1;
57
58 void _initialize_cache()
59 {
60         NEXT_CACHE_IDX = 0;
61         memset(APP_DEK_CACHE, 0, sizeof(dek_cache_element)*MAX_CACHE_SIZE);
62 }
63
64 unsigned char *_get_app_dek_from_cache(const char *pkgId)
65 {
66         if (NEXT_CACHE_IDX < 0)
67                 _initialize_cache();
68
69         for (int i = 0; i < MAX_CACHE_SIZE; i++) {
70                 //WAE_SLOGI("CACHED APP_DEK[%d]=%s", i, APP_DEK_CACHE[i].pkgId);
71                 if (strlen(APP_DEK_CACHE[i].pkgId) == strlen(pkgId) &&
72                                 strncmp(pkgId, APP_DEK_CACHE[i].pkgId, strlen(pkgId)) == 0) {
73                         return APP_DEK_CACHE[i].dek;
74                 }
75         }
76
77         return NULL;
78 }
79
80 void _add_app_dek_to_cache(const char *pkgId, unsigned char *dek)
81 {
82         if (NEXT_CACHE_IDX < 0)
83                 _initialize_cache();
84
85         // if existing one has the same pkgid
86         for (int i = 0; i < MAX_CACHE_SIZE; i++) {
87                 if (strlen(APP_DEK_CACHE[i].pkgId) == strlen(pkgId) &&
88                                 strncmp(pkgId, APP_DEK_CACHE[i].pkgId, strlen(pkgId)) == 0) {
89                         memcpy(APP_DEK_CACHE[i].dek, dek, DEK_LEN);
90                         return;
91                 }
92         }
93
94         // for new pkgid
95         strncpy(APP_DEK_CACHE[NEXT_CACHE_IDX].pkgId, pkgId, strlen(pkgId));
96         memcpy(APP_DEK_CACHE[NEXT_CACHE_IDX].dek, dek, DEK_LEN);
97
98         NEXT_CACHE_IDX++;
99
100         if (NEXT_CACHE_IDX >= MAX_CACHE_SIZE)
101                 NEXT_CACHE_IDX = 0;
102 }
103
104 void _remove_app_dek_from_cache(const char *pkgId)
105 {
106         for (int i = 0; i < MAX_CACHE_SIZE; i++) {
107                 if (strlen(APP_DEK_CACHE[i].pkgId) == strlen(pkgId) &&
108                                 strncmp(pkgId, APP_DEK_CACHE[i].pkgId, strlen(pkgId)) == 0) {
109                         memset(APP_DEK_CACHE[i].pkgId, 0, sizeof(APP_DEK_CACHE[i].pkgId));
110                         return;
111                 }
112         }
113
114 }
115
116 int _to_wae_error(int key_manager_error)
117 {
118         switch (key_manager_error) {
119         case CKMC_ERROR_NONE:
120                 return WAE_ERROR_NONE;
121
122         case CKMC_ERROR_INVALID_PARAMETER:
123                 return WAE_ERROR_INVALID_PARAMETER;
124
125         case CKMC_ERROR_PERMISSION_DENIED:
126                 return WAE_ERROR_PERMISSION_DENIED;
127
128         case CKMC_ERROR_DB_ALIAS_UNKNOWN:
129                 return WAE_ERROR_NO_KEY;
130
131         case CKMC_ERROR_DB_ALIAS_EXISTS:
132                 return WAE_ERROR_KEY_EXISTS;
133
134         default:
135                 return WAE_ERROR_KEY_MANAGER;
136         }
137 }
138
139 int _get_random(size_t length, unsigned char *random)
140 {
141         FILE *f = NULL;
142         size_t i = 0;
143         int ch = 0;
144
145         //read random file
146         if ((f = fopen(RANDOM_FILE, "r")) != NULL) {
147                 while (i < length) {
148                         if ((ch = fgetc(f)) == EOF) {
149                                 break;
150                         }
151
152                         random[i] = (unsigned char) ch;
153                         i++;
154                 }
155         }
156
157         if (f != NULL)
158                 fclose(f);
159
160         return WAE_ERROR_NONE;
161 }
162
163 void _get_alias(const char *pPkgId, wae_app_type_e appType, bool forSave, char *alias, size_t buff_len)
164 {
165         if (appType == WAE_DOWNLOADED_NORMAL_APP) {
166                 if (forSave) {
167                         snprintf(alias, buff_len, "%s%s",
168                                          APP_DEK_ALIAS_PFX,
169                                          pPkgId);
170                 } else {
171                         snprintf(alias, buff_len, "%s%s%s%s",
172                                          WRT_INSTALLER_LABEL,
173                                          ckmc_owner_id_separator,
174                                          APP_DEK_ALIAS_PFX,
175                                          pPkgId);
176                 }
177         } else { // system alias
178                 snprintf(alias, buff_len, "%s%s%s%s",
179                                  ckmc_owner_id_system,
180                                  ckmc_owner_id_separator,
181                                  APP_DEK_ALIAS_PFX,
182                                  pPkgId);
183         }
184 }
185
186 void _get_dek_kek_alias(char *alias, size_t buff_len)
187 {
188         snprintf(alias, buff_len, "%s%s%s",
189                          ckmc_owner_id_system,
190                          ckmc_owner_id_separator,
191                          APP_DEK_KEK_ALIAS);
192 }
193
194 void _get_dek_loading_done_alias(char *alias, size_t buff_len)
195 {
196         snprintf(alias, buff_len, "%s%s%s",
197                          ckmc_owner_id_system,
198                          ckmc_owner_id_separator,
199                          APP_DEK_LOADING_DONE_ALIAS);
200 }
201
202 const char *_get_dek_kek_pub_key_path()
203 {
204         return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PublicKey.pem");
205 }
206
207 const char *_get_dek_kek_pri_key_path()
208 {
209         return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PrivateKey.pem");
210 }
211
212 const char *_get_dek_store_path()
213 {
214         return tzplatform_mkpath3(TZ_SYS_SHARE, "wae", "app_dek");
215 }
216
217 int _add_dek_to_key_manager(const char *pPkgId, wae_app_type_e appType, const unsigned char *pDek, size_t len)
218 {
219         int ret = WAE_ERROR_NONE;
220         char alias[MAX_ALIAS_LEN] = {0,};
221         ckmc_raw_buffer_s buff;
222         ckmc_policy_s policy;
223
224         buff.data = (unsigned char *)pDek;
225         buff.size = len;
226
227         policy.password = NULL;
228         policy.extractable = true;
229
230         // save app_dek in key_manager
231         _get_alias(pPkgId, appType, true, alias, sizeof(alias));
232
233         // even if it fails to remove, ignore it.
234         ret = _to_wae_error(ckmc_remove_alias(alias));
235
236         ret = _to_wae_error(ckmc_save_data(alias, buff, policy));
237
238         if (ret != WAE_ERROR_NONE) {
239                 WAE_SLOGE("WAE: Fail to add APP_DEK to key-manager. pkgId=%s, alias=%s, ret=%d", pPkgId, alias, ret);
240                 return ret;
241         }
242
243         // share app_dek for web app laucher to use app_dek
244         ret = _to_wae_error(ckmc_set_permission(alias, pPkgId, CKMC_PERMISSION_READ));
245
246         if (ret != WAE_ERROR_NONE) {
247                 WAE_SLOGE("WAE: Fail to set_permission to APP_DEK. pkgId=%s, ret=%d", pPkgId, ret);
248                 return ret;
249         }
250
251         WAE_SLOGI("WAE: Success to add APP_DEK to key-manager. pkgId=%s, alias=%s", pPkgId, alias);
252
253         return ret;
254 }
255
256 int _get_preloaded_app_dek_file_path(const char *pPkgId, size_t size, char *path)
257 {
258         int ret = snprintf(path, size, "%s/%s_%s.adek",
259                                    _get_dek_store_path(), APP_DEK_FILE_PFX, pPkgId);
260
261         if (ret < 0)
262                 return WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */
263
264         return WAE_ERROR_NONE;
265 }
266
267 int _extract_pkg_id_from_file_name(const char *fileName, char *pkgId)
268 {
269         char *start = strstr(fileName, APP_DEK_FILE_PFX);
270
271         if (start == NULL) {
272                 WAE_SLOGE("WAE: Fail to extract pkgid from APP_DEK file. fileName=%s", fileName);
273                 return WAE_ERROR_FILE;
274         }
275
276         start = start + strlen(APP_DEK_FILE_PFX) + 1;
277         char *end = strstr(fileName, ".adek");
278
279         if (start == NULL) {
280                 WAE_SLOGE("WAE: Fail to extract pkgid from APP_DEK file. fileName=%s", fileName);
281                 return WAE_ERROR_FILE;
282         }
283
284         strncpy(pkgId, start, end - start);
285         pkgId[end - start] = 0; //terminate string
286
287         return WAE_ERROR_NONE;
288 }
289
290 int _read_encrypted_app_dek_from_file(const char *pPkgId, unsigned char **encrypted_app_dek, size_t *len)
291 {
292         char path[MAX_PATH_LEN] = {0,};
293         _get_preloaded_app_dek_file_path(pPkgId, sizeof(path), path);
294         return _read_from_file(path, encrypted_app_dek, len);
295 }
296
297 int _write_encrypted_app_dek_to_file(const char *pPkgId, const unsigned char *encrypted_app_dek, size_t len)
298 {
299         char path[MAX_PATH_LEN] = {0,};
300         _get_preloaded_app_dek_file_path(pPkgId, sizeof(path), path);
301         return _write_to_file(path, encrypted_app_dek, len);
302 }
303
304 int _read_from_file(const char *path, unsigned char **data, size_t *len)
305 {
306         int ret = WAE_ERROR_NONE;
307         int file_len = -1;
308         unsigned char *file_contents = NULL;
309         int ch = 0;
310         int i = 0;
311
312         FILE *f = fopen(path, "r");
313
314         if (f == NULL) {
315                 WAE_SLOGE("WAE: Fail to open a file. file=%s", path);
316                 return WAE_ERROR_FILE;
317         }
318
319         fseek(f, 0, SEEK_END); // move to the end of a file
320         file_len = ftell(f);
321
322         if (file_len <= 0) {
323                 WAE_SLOGE("WAE: Failed to get file size by ftell. ret: %d", file_len);
324                 ret = WAE_ERROR_FILE;
325                 goto error;
326         }
327
328         fseek(f, 0, SEEK_SET); // move to the start of a file
329
330         file_contents = (unsigned char *) malloc(file_len);
331
332         if (file_contents == NULL) {
333                 WAE_SLOGE("WAE: Fail to allocate memory for encrypted_app_dek");
334                 ret = WAE_ERROR_MEMORY;
335                 goto error;
336         }
337
338         memset(file_contents, 0x00, file_len);
339
340         while ((ch = fgetc(f)) != EOF) {
341                 file_contents[i++] = (char)ch;
342         }
343
344         *data = file_contents;
345         *len = file_len;
346
347 error:
348         if (f != NULL)
349                 fclose(f);
350
351         if (ret != WAE_ERROR_NONE && file_contents != NULL)
352                 free(file_contents);
353
354         return ret;
355 }
356
357 int _write_to_file(const char *path, const unsigned char *data, size_t len)
358 {
359         int ret = WAE_ERROR_NONE;
360
361         int write_len = -1;
362
363         FILE *f = fopen(path, "w");
364
365         if (f == NULL) {
366                 WAE_SLOGE("WAE: Fail to open a file. file=%s", path);
367                 return WAE_ERROR_FILE;
368         }
369
370         write_len = fwrite(data, 1, len, f);
371
372         if (write_len != (int) len) {
373                 WAE_SLOGE("WAE: Fail to write a file. file=%s", path);
374                 ret = WAE_ERROR_FILE;
375                 goto error;
376         }
377
378 error:
379         if (f != NULL)
380                 fclose(f);
381
382         return ret;
383 }
384
385 int get_app_dek(const char *pPkgId, wae_app_type_e appType, unsigned char **ppDek, size_t *dekLen)
386 {
387         int ret = WAE_ERROR_NONE;
388
389         char *password = NULL;
390         ckmc_raw_buffer_s *pDekBuffer = NULL;
391         char alias[MAX_ALIAS_LEN] = {0,};
392         unsigned char *pDek = NULL;
393
394         unsigned char *cached_dek = _get_app_dek_from_cache(pPkgId);
395
396         if (cached_dek == NULL) {
397                 // get APP_DEK from system database
398                 _get_alias(pPkgId, appType, false, alias, sizeof(alias));
399
400                 ret = _to_wae_error(ckmc_get_data(alias, password, &pDekBuffer));
401
402                 if (ret != WAE_ERROR_NONE) {
403                         WAE_SLOGI("WAE: Fail to get APP_DEK from key-manager. pkgId=%s, alias=%s, ret=%d",
404                                           pPkgId, alias, ret);
405                         goto error;
406                 }
407         }
408
409         pDek = (unsigned char *) malloc(DEK_LEN);
410
411         if (pDek == NULL) {
412                 WAE_SLOGE("Fail to allocate a memory");
413                 ret = WAE_ERROR_MEMORY;
414                 goto error;
415         }
416
417         memcpy(pDek, (cached_dek != NULL) ? cached_dek : pDekBuffer->data, DEK_LEN);
418
419         *ppDek = pDek;
420         *dekLen = DEK_LEN;
421         WAE_SLOGI("WAE: Success to get APP_DEK from key-manager. pkgId=%s, alias=%s", pPkgId, alias);
422
423 error:
424         if (pDekBuffer != NULL)
425                 ckmc_buffer_free(pDekBuffer);
426
427         if (ret != WAE_ERROR_NONE && pDek != NULL)
428                 free(pDek);
429
430         return ret;
431 }
432
433 int create_app_dek(const char *pPkgId, wae_app_type_e appType, unsigned char **ppDek, size_t *dekLen)
434 {
435         unsigned char *dek = (unsigned char *) malloc(DEK_LEN);
436
437         if (dek == NULL)
438                 return WAE_ERROR_MEMORY;
439
440         int ret = _get_random(DEK_LEN, dek);
441
442         if (ret != WAE_ERROR_NONE) {
443                 WAE_SLOGE("WAE: Fail to get random for APP_DEK. pkgId=%s, ret=%d", pPkgId, ret);
444                 goto error;
445         }
446
447         // save app_dek in key_manager
448         ret = _add_dek_to_key_manager(pPkgId, appType, dek, DEK_LEN);
449
450         if (ret != WAE_ERROR_NONE) {
451                 goto error;
452         }
453
454         // store APP_DEK in cache
455         _add_app_dek_to_cache(pPkgId, dek);
456
457         *ppDek = dek;
458         *dekLen = DEK_LEN;
459
460         WAE_SLOGI("WAE: Success to create APP_DEK and store it in key-manager. pkgId=%s", pPkgId);
461
462 error:
463         if (ret != WAE_ERROR_NONE && dek != NULL)
464                 free(dek);
465
466         return ret;
467 }
468
469 int get_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t *dekLen)
470 {
471         int ret = WAE_ERROR_NONE;
472
473         unsigned char *cached_dek = _get_app_dek_from_cache(pPkgId);
474
475         if (cached_dek == NULL) {
476                 WAE_SLOGE("WAE: Fail to get APP_DEK from cache for preloaded app");
477                 return WAE_ERROR_NO_KEY;
478         }
479
480         unsigned char *dek = (unsigned char *) malloc(DEK_LEN);
481
482         if (dek == NULL) {
483                 WAE_SLOGE("WAE: Fail to allocate memory for preloaded app dek");
484                 ret = WAE_ERROR_MEMORY;
485                 goto error;
486         }
487
488         memcpy(dek, cached_dek, DEK_LEN);
489
490         *ppDek = dek;
491         *dekLen = DEK_LEN;
492
493 error:
494         if (ret != WAE_ERROR_NONE && dek != NULL)
495                 free(dek);
496
497         return ret;
498 }
499
500 int create_preloaded_app_dek(const char *pPkgId, unsigned char **ppDek, size_t *dekLen)
501 {
502         unsigned char *encrypted_app_dek = NULL;
503         size_t encrypted_app_dek_len = 0;
504         unsigned char *pubKey = NULL;
505         size_t pubKeyLen = 0;
506
507         // create APP_DEK
508         unsigned char *dek = (unsigned char *)malloc(DEK_LEN);
509
510         if (dek == NULL)
511                 return WAE_ERROR_MEMORY;
512
513         int ret = _get_random(DEK_LEN, dek);
514
515         if (ret != WAE_ERROR_NONE)
516                 goto error;
517
518         // encrypt APP_DEK with APP_DEK_KEK
519         ret = _read_from_file(_get_dek_kek_pub_key_path(), &pubKey, &pubKeyLen);
520
521         if (ret != WAE_ERROR_NONE) {
522                 WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Public Key");
523                 goto error;
524         }
525
526         ret = encrypt_app_dek(pubKey, pubKeyLen, dek, DEK_LEN, &encrypted_app_dek, &encrypted_app_dek_len);
527
528         if (ret != WAE_ERROR_NONE) {
529                 WAE_SLOGE("WAE: Fail to encrypt APP_DEK with APP_DEK_KEK");
530                 goto error;
531         }
532
533         // write APP_DEK in a file
534         ret = _write_encrypted_app_dek_to_file(pPkgId, encrypted_app_dek, encrypted_app_dek_len);
535
536         if (ret != WAE_ERROR_NONE) {
537                 WAE_SLOGE("WAE: Fail to write encrypted APP_DEK. pkgId=%s", pPkgId);
538                 goto error;
539         }
540
541         // store APP_DEK in cache
542         _add_app_dek_to_cache(pPkgId, dek);
543
544         *ppDek = dek;
545         *dekLen = DEK_LEN;
546         WAE_SLOGI("WAE: Success to create preleaded APP_DEK and write it in initail value file. pkgId=%s", pPkgId);
547
548 error:
549         if (pubKey != NULL)
550                 free(pubKey);
551
552         if (encrypted_app_dek != NULL)
553                 free(encrypted_app_dek);
554
555         if (ret != WAE_ERROR_NONE && dek != NULL)
556                 free(dek);
557
558         return ret;
559 }
560
561 int _get_app_dek_kek(unsigned char **ppDekKek, size_t *kekLen)
562 {
563         int ret = _read_from_file(_get_dek_kek_pri_key_path(), ppDekKek, kekLen);
564
565         if (ret != WAE_ERROR_NONE) {
566                 WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Private Key");
567                 return ret;
568         }
569
570         /*
571             char* password = NULL;
572             ckmc_raw_buffer_s *pKekBuffer = NULL;
573             unsigned char* pKek = NULL;
574
575             char dek_kek_alias[MAX_ALIAS_LEN] = {0, };
576             _get_dek_kek_alias(dek_kek_alias, sizeof(dek_kek_alias));
577
578             ret = _to_wae_error(ckmc_get_data(dek_kek_alias, password, &pKekBuffer));
579             if(ret != WAE_ERROR_NONE) {
580                 WAE_SLOGE("Fail to get APP_DEK_KEK from key-manager. alias=%s, ret=%d", APP_DEK_KEK_ALIAS, ret);
581                 goto error;
582             }
583
584             pKek = (unsigned char*) malloc(pKekBuffer->size);
585             if(pKek == NULL) {
586                 WAE_SLOGE("Fail to allocate a memory");
587                 ret = WAE_ERROR_MEMORY;
588                 goto error;
589             }
590             memcpy(pKek, pKekBuffer->data, pKekBuffer->size);
591
592             *ppDekKek = pKek;
593             *kekLen = pKekBuffer->size;
594             WAE_SLOGI("Success to get APP_DEK_KEK from key-manager.");
595         error:
596             if(pKekBuffer != NULL)
597                 ckmc_buffer_free(pKekBuffer);
598             if(ret != WAE_ERROR_NONE && pKek != NULL)
599                 free(pKek);
600         */
601         return ret;
602 }
603
604 int _get_app_deks_loaded()
605 {
606         char loading_done_alias[MAX_ALIAS_LEN] = {0, };
607         _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias));
608
609         ckmc_raw_buffer_s *pBuffer = NULL;
610         int ret = _to_wae_error(ckmc_get_data(loading_done_alias, NULL, &pBuffer));
611
612         if (ret == WAE_ERROR_NO_KEY)
613                 WAE_SLOGI("WAE: APP_DEK_LOADING was not done");
614         else if (ret == WAE_ERROR_NONE)
615                 WAE_SLOGI("WAE: APP_DEK_LOADING was already done");
616         else
617                 WAE_SLOGE("WAE: Fail to get information from key-manager about APP_DEK_LOADING_DONE_ALIAS. ret=%d", ret);
618
619         if (pBuffer != NULL)
620                 ckmc_buffer_free(pBuffer);
621
622         return ret;
623 }
624
625 int _set_app_deks_loaded()
626 {
627         ckmc_raw_buffer_s buff;
628         ckmc_policy_s policy;
629         unsigned char dummyData[1] =  {0};
630
631         buff.data = dummyData;
632         buff.size = sizeof(dummyData);
633
634         policy.password = NULL;
635         policy.extractable = true;
636
637         char loading_done_alias[MAX_ALIAS_LEN] = {0, };
638         _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias));
639
640         int ret = _to_wae_error(ckmc_save_data(loading_done_alias, buff, policy));
641
642         if (ret == WAE_ERROR_KEY_EXISTS) {
643                 WAE_SLOGI("WAE: APP_DEK_LOADING was already done");
644                 ret = WAE_ERROR_NONE;
645         } else if (ret == WAE_ERROR_NONE) {
646                 WAE_SLOGI("Success to set APP_DEK_LOADING_DONE_ALIAS to key-manager.");
647         } else {
648                 WAE_SLOGE("WAE: Fail to set APP_DEK_LOADING_DONE_ALIAS to key-manager. ret=%d", ret);
649         }
650
651         return ret;
652 }
653
654 int _clear_app_deks_loaded()
655 {
656         char loading_done_alias[MAX_ALIAS_LEN] = {0, };
657         _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias));
658
659         int ret = _to_wae_error(ckmc_remove_alias(loading_done_alias));
660
661         if (ret == WAE_ERROR_NO_KEY) {
662                 WAE_SLOGI("APP_DEK_LOADING_DONE_ALIAS was not set to key-manager before.");
663                 ret = WAE_ERROR_NONE;
664         } else if (ret == WAE_ERROR_NONE) {
665                 WAE_SLOGI("Success to clear app deks loaded");
666         } else {
667                 WAE_SLOGE("Fail to clear APP_DEK_LOADING_DONE_ALIAS to key-manager. ret=%d", ret);
668         }
669
670         return ret;
671 }
672
673 int load_preloaded_app_deks(bool reload)
674 {
675         int ret = WAE_ERROR_NONE;
676
677         char pkgId[MAX_PKGID_LEN] = {0, };
678
679         DIR *dir = NULL;
680         struct dirent entry;
681         struct dirent *result;
682         int error;
683         char file_path_buff[MAX_PATH_LEN];
684         unsigned char *encrypted_app_dek = NULL;
685         size_t encrypted_app_dek_len = 0;
686         unsigned char *app_dek = NULL;
687         size_t app_dek_len = 0;
688         unsigned char *priKey = NULL;
689         size_t priKeyLen = 0;
690
691         int error_during_loading = 0;
692
693         if (!reload) {
694                 // check if all deks were already loaded into key-manager.
695                 ret = _get_app_deks_loaded();
696
697                 if (ret == WAE_ERROR_NONE)
698                         return ret;
699         }
700
701         ret = _get_app_dek_kek(&priKey, &priKeyLen);
702
703         if (ret != WAE_ERROR_NONE) {
704                 WAE_SLOGE("Fail to get APP_DEK_KEK Private Key");
705                 return ret;
706         }
707
708         dir = opendir(_get_dek_store_path());
709
710         if (dir == NULL) {
711                 WAE_SLOGE("Fail to open dir. dir=%s", _get_dek_store_path());
712                 ret = WAE_ERROR_FILE;
713                 goto error;
714         }
715
716         while (true) {
717                 error = readdir_r(dir, &entry, &result);
718
719                 if (error != 0) {
720                         ret = WAE_ERROR_FILE;
721                         goto error;
722                 }
723
724                 // readdir_r returns NULL in *result if the end
725                 // of the directory stream is reached
726                 if (result == NULL)
727                         break;
728
729                 // regular file && start with KEY_MANAGER_INITIAL_VALUE_FILE_PFX
730                 if (entry.d_type == DT_REG && strstr(entry.d_name, APP_DEK_FILE_PFX) != NULL) {
731                         memset(file_path_buff, 0, sizeof(file_path_buff));
732                         ret = snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s",
733                                                    _get_dek_store_path(), entry.d_name);
734
735                         if (ret < 0) {
736                                 WAE_SLOGE("Failed to make file path by snprintf.");
737                                 ret = WAE_ERROR_INVALID_PARAMETER; /* buffer size too small */
738                                 goto error;
739                         }
740
741                         ret = _extract_pkg_id_from_file_name(entry.d_name, pkgId);
742
743                         if (ret != WAE_ERROR_NONE) {
744                                 WAE_SLOGW("Fail to extract pkgid from file. It will be ignored. file=%s", file_path_buff);
745                                 continue;
746                         }
747
748                         ret = _read_from_file(file_path_buff, &encrypted_app_dek, &encrypted_app_dek_len);
749
750                         if (ret != WAE_ERROR_NONE || encrypted_app_dek == NULL) {
751                                 error_during_loading++;
752                                 WAE_SLOGW("Fail to read file. It will be ignored. file=%s", file_path_buff);
753                                 continue;
754                         }
755
756                         ret = decrypt_app_dek(priKey, priKeyLen, APP_DEK_KEK_PRIKEY_PASSWORD,
757                                                                   encrypted_app_dek, encrypted_app_dek_len,
758                                                                   &app_dek, &app_dek_len);
759
760                         if (ret != WAE_ERROR_NONE || app_dek == NULL) {
761                                 error_during_loading++;
762                                 WAE_SLOGW("Fail to decrypt APP DEK. It will be ignored. file=%s", file_path_buff);
763                                 continue;
764                         }
765
766                         // save app_dek in key_manager
767                         ret = _add_dek_to_key_manager(pkgId, WAE_PRELOADED_APP, app_dek, app_dek_len);
768                         // free temp objects
769                         free(app_dek);
770                         free(encrypted_app_dek);
771                         app_dek = NULL;
772                         encrypted_app_dek = NULL;
773
774                         if (ret == WAE_ERROR_KEY_EXISTS) {
775                                 WAE_SLOGI("Key Manager already has APP_DEK. It will be ignored. file=%s", file_path_buff);
776                                 continue;
777                         } else if (ret != WAE_ERROR_NONE) {
778                                 error_during_loading++;
779                                 WAE_SLOGW("Fail to add APP DEK to key-manager. file=%s", file_path_buff);
780                                 continue;
781                         }
782                 }
783         }
784
785         ret = _set_app_deks_loaded();
786
787         if (ret == WAE_ERROR_NONE) {
788                 WAE_SLOGI("Success to load_preloaded_app_deks");
789                 ret = WAE_ERROR_NONE;
790         } else {
791                 WAE_SLOGW("Fail to _set_app_deks_loaded to key-manager. ret=%d", ret);
792         }
793
794 error:
795         if (priKey != NULL)
796                 free(priKey);
797
798         return ret;
799 }
800
801 int remove_app_dek(const char *pPkgId, wae_app_type_e appType)
802 {
803         char alias[MAX_ALIAS_LEN] = {0,};
804
805         _get_alias(pPkgId, appType, true, alias, sizeof(alias));
806
807         int ret = _to_wae_error(ckmc_remove_alias(alias));
808
809         if (ret != WAE_ERROR_NONE) {
810                 WAE_SLOGE("Fail to remove APP_DEK from  key-manager. pkgId=%s, alias=%s, ret=%d", pPkgId, alias, ret);
811                 return ret;
812         }
813
814         _remove_app_dek_from_cache(pPkgId);
815         WAE_SLOGI("Success to remove APP_DEK from  key-manager. pkgId=%s", pPkgId);
816
817         return WAE_ERROR_NONE;
818 }