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