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