4fceee2dc59bbaeaf8750e60e2cc419cd9a3a14d
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_certinfo.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdbool.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7
8 #include <sqlite3.h>
9 #include <glib.h>
10
11 #include <db-util.h>
12
13 #include "pkgmgr-info.h"
14 #include "pkgmgrinfo_debug.h"
15 #include "pkgmgrinfo_private.h"
16 #include "pkgmgr_parser.h"
17
18 typedef struct _pkgmgr_certinfo_x {
19         int for_all_users;
20         char *pkgid;
21         char *cert_value;
22         char *cert_info[MAX_CERT_TYPE]; /*certificate info*/
23         int cert_id[MAX_CERT_TYPE];             /*certificate ID in index table*/
24 } pkgmgr_certinfo_x;
25
26 typedef struct _pkgmgr_instcertinfo_x {
27         char *pkgid;
28         char *cert_info[MAX_CERT_TYPE]; /*certificate data*/
29         int is_new[MAX_CERT_TYPE];              /*whether already exist in table or not*/
30         int ref_count[MAX_CERT_TYPE];           /*reference count of certificate data*/
31         int cert_id[MAX_CERT_TYPE];             /*certificate ID in index table*/
32 } pkgmgr_instcertinfo_x;
33
34 typedef struct _pkgmgr_certindexinfo_x {
35         int cert_id;
36         int cert_ref_count;
37 } pkgmgr_certindexinfo_x;
38
39 typedef struct _pkgmgr_cert_x {
40         char *pkgid;
41         int cert_id;
42 } pkgmgr_cert_x;
43
44 API int pkgmgrinfo_pkginfo_create_certinfo(pkgmgrinfo_certinfo_h *handle)
45 {
46         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
47         pkgmgr_certinfo_x *certinfo = NULL;
48         certinfo = calloc(1, sizeof(pkgmgr_certinfo_x));
49         *handle = NULL;
50         retvm_if(certinfo == NULL, PMINFO_R_ERROR, "Malloc Failed\n");
51         *handle = (void *)certinfo;
52         return PMINFO_R_OK;
53 }
54
55 static int _pkginfo_compare_certinfo(sqlite3 *db, const char *l_pkgid,
56                 const char *r_pkgid,
57                 pkgmgrinfo_cert_compare_result_type_e *result)
58 {
59         static const char query[] =
60                 "SELECT COALESCE(author_signer_cert, -1) FROM package_cert_info "
61                 "WHERE package=?";
62         int ret;
63         sqlite3_stmt *stmt;
64         const char *pkgid[2];
65         int certid[2] = {-1, -1};
66         int i;
67
68         pkgid[0] = l_pkgid;
69         pkgid[1] = r_pkgid;
70
71         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
72         if (ret != SQLITE_OK) {
73                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
74                 return PMINFO_R_ERROR;
75         }
76
77         for (i = 0; i < 2; i++) {
78                 ret = sqlite3_bind_text(stmt, 1, pkgid[i], -1, SQLITE_STATIC);
79                 if (ret != SQLITE_OK) {
80                         _LOGE("bind error: %s", sqlite3_errmsg(db));
81                         sqlite3_finalize(stmt);
82                         return PMINFO_R_ERROR;
83                 }
84
85                 ret = sqlite3_step(stmt);
86                 if (ret == SQLITE_ROW) {
87                         _save_column_int(stmt, 0, &certid[i]);
88                 } else if (ret != SQLITE_DONE) {
89                         _LOGE("step error: %s", sqlite3_errmsg(db));
90                         sqlite3_finalize(stmt);
91                         return PMINFO_R_ERROR;
92                 }
93
94                 sqlite3_reset(stmt);
95                 sqlite3_clear_bindings(stmt);
96         }
97
98         if (certid[0] == -1 && certid[1] == -1)
99                 *result = PMINFO_CERT_COMPARE_BOTH_NO_CERT;
100         else if (certid[0] == -1)
101                 *result = PMINFO_CERT_COMPARE_LHS_NO_CERT;
102         else if (certid[1] == -1)
103                 *result = PMINFO_CERT_COMPARE_RHS_NO_CERT;
104         else if (certid[0] == certid[1])
105                 *result = PMINFO_CERT_COMPARE_MATCH;
106         else
107                 *result = PMINFO_CERT_COMPARE_MISMATCH;
108
109         sqlite3_finalize(stmt);
110         return PMINFO_R_OK;
111 }
112
113 API int pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(const char *lhs_package_id,
114                 const char *rhs_package_id, uid_t uid,
115                 pkgmgrinfo_cert_compare_result_type_e *compare_result)
116 {
117         int ret;
118         sqlite3 *db;
119         char *dbpath;
120
121         if (lhs_package_id == NULL || rhs_package_id == NULL ||
122                         compare_result == NULL) {
123                 _LOGE("invalid parameter");
124                 return PMINFO_R_EINVAL;
125         }
126
127         /* open unified global cert db */
128         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
129         if (dbpath == NULL)
130                 return PMINFO_R_ERROR;
131
132         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
133         if (ret != SQLITE_OK) {
134                 _LOGE("failed to open db: %d", ret);
135                 free(dbpath);
136                 return PMINFO_R_ERROR;
137         }
138         free(dbpath);
139
140         if (_pkginfo_compare_certinfo(db, lhs_package_id, rhs_package_id,
141                                 compare_result)) {
142                 _LOGE("failed to compare certinfo");
143                 sqlite3_close_v2(db);
144                 return PMINFO_R_ERROR;
145         }
146
147         sqlite3_close_v2(db);
148
149         return PMINFO_R_OK;
150 }
151
152 API int pkgmgrinfo_pkginfo_compare_pkg_cert_info(const char *lhs_package_id, const char *rhs_package_id, pkgmgrinfo_cert_compare_result_type_e *compare_result)
153 {
154         return pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(lhs_package_id, rhs_package_id, _getuid(), compare_result);
155 }
156
157 static int _pkginfo_get_pkgid_from_appid(uid_t uid, const char *appid,
158                 char **pkgid)
159 {
160         static const char query[] =
161                 "SELECT package FROM package_app_info WHERE app_id=?";
162         int ret;
163         sqlite3 *db;
164         char *dbpath;
165         sqlite3_stmt *stmt;
166
167         dbpath = getUserPkgParserDBPathUID(uid);
168         if (dbpath == NULL)
169                 return PMINFO_R_ERROR;
170
171         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
172         if (ret != SQLITE_OK) {
173                 _LOGE("failed to open db: %d", ret);
174                 free(dbpath);
175                 return PMINFO_R_ERROR;
176         }
177         free(dbpath);
178
179         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
180         if (ret != SQLITE_OK) {
181                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
182                 sqlite3_close_v2(db);
183                 return PMINFO_R_ERROR;
184         }
185
186         ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_STATIC);
187         if (ret != SQLITE_OK) {
188                 _LOGE("bind error: %s", sqlite3_errmsg(db));
189                 sqlite3_finalize(stmt);
190                 sqlite3_close_v2(db);
191                 return PMINFO_R_ERROR;
192         }
193
194         ret = sqlite3_step(stmt);
195         if (ret == SQLITE_ROW) {
196                 _save_column_str(stmt, 0, pkgid);
197                 ret = PMINFO_R_OK;
198         } else if (ret == SQLITE_DONE) {
199                 _LOGI("cannot find pkgid of app %s for uid %d", appid, (int)uid);
200                 ret = PMINFO_R_ENOENT;
201         } else {
202                 _LOGE("step error: %s", sqlite3_errmsg(db));
203                 ret = PMINFO_R_ERROR;
204         }
205
206         sqlite3_finalize(stmt);
207         sqlite3_close_v2(db);
208
209         return ret;
210 }
211
212 API int pkgmgrinfo_pkginfo_compare_usr_app_cert_info(const char *lhs_app_id,
213                 const char *rhs_app_id, uid_t uid,
214                 pkgmgrinfo_cert_compare_result_type_e *compare_result)
215 {
216         int ret;
217         char *l_pkgid = NULL;
218         char *r_pkgid = NULL;
219
220         if (lhs_app_id == NULL || rhs_app_id == NULL ||
221                         compare_result == NULL) {
222                 _LOGE("invalid parameter");
223                 return PMINFO_R_EINVAL;
224         }
225
226         ret = _pkginfo_get_pkgid_from_appid(uid, lhs_app_id, &l_pkgid);
227         if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
228                 ret = _pkginfo_get_pkgid_from_appid(GLOBAL_USER, lhs_app_id,
229                                 &l_pkgid);
230
231         if (ret != PMINFO_R_OK)
232                 return ret;
233
234         ret = _pkginfo_get_pkgid_from_appid(uid, rhs_app_id, &r_pkgid);
235         if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
236                 ret = _pkginfo_get_pkgid_from_appid(GLOBAL_USER, rhs_app_id,
237                                 &r_pkgid);
238
239         if (ret != PMINFO_R_OK) {
240                 free(l_pkgid);
241                 return ret;
242         }
243
244         ret = pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(l_pkgid, r_pkgid,
245                         uid, compare_result);
246
247         free(l_pkgid);
248         free(r_pkgid);
249
250         return ret;
251 }
252
253 API int pkgmgrinfo_pkginfo_compare_app_cert_info(const char *lhs_app_id,
254                 const char *rhs_app_id,
255                 pkgmgrinfo_cert_compare_result_type_e *compare_result)
256 {
257         return pkgmgrinfo_pkginfo_compare_usr_app_cert_info(lhs_app_id,
258                         rhs_app_id, _getuid(), compare_result);
259 }
260
261 static int _pkginfo_get_cert(sqlite3 *db, int cert_id[],
262                 char *cert_info[])
263 {
264         static const char query[] =
265                 "SELECT cert_info FROM package_cert_index_info WHERE cert_id=?";
266         int ret;
267         sqlite3_stmt *stmt;
268         int i;
269
270         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
271         if (ret != SQLITE_OK) {
272                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
273                 return PMINFO_R_ERROR;
274         }
275
276         for (i = 0; i < MAX_CERT_TYPE; i++) {
277                 ret = sqlite3_bind_int(stmt, 1, cert_id[i]);
278                 if (ret != SQLITE_OK) {
279                         sqlite3_finalize(stmt);
280                         _LOGE("bind failed: %s", sqlite3_errmsg(db));
281                         return PMINFO_R_ERROR;
282                 }
283
284                 ret = sqlite3_step(stmt);
285                 if (ret == SQLITE_DONE) {
286                         sqlite3_reset(stmt);
287                         sqlite3_clear_bindings(stmt);
288                         continue;
289                 } else if (ret != SQLITE_ROW) {
290                         _LOGE("step failed: %s", sqlite3_errmsg(db));
291                         sqlite3_finalize(stmt);
292                         return PMINFO_R_ERROR;
293                 }
294
295                 _save_column_str(stmt, 0, &cert_info[i]);
296                 sqlite3_reset(stmt);
297                 sqlite3_clear_bindings(stmt);
298         }
299
300         sqlite3_finalize(stmt);
301
302         return PMINFO_R_OK;
303 }
304
305 static int _pkginfo_get_certid(sqlite3 *db, const char *pkgid, int cert_id[])
306 {
307         static const char query[] =
308                 "SELECT author_root_cert, author_im_cert, author_signer_cert, "
309                 "dist_root_cert, dist_im_cert, dist_signer_cert, "
310                 "dist2_root_cert, dist2_im_cert, dist2_signer_cert "
311                 "FROM package_cert_info WHERE package=?";
312         int ret;
313         sqlite3_stmt *stmt;
314         int idx;
315
316         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
317         if (ret != SQLITE_OK) {
318                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
319                 return PMINFO_R_ERROR;
320         }
321
322         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
323         if (ret != SQLITE_OK) {
324                 _LOGE("bind failed: %s", sqlite3_errmsg(db));
325                 sqlite3_finalize(stmt);
326                 return PMINFO_R_ERROR;
327         }
328
329         ret = sqlite3_step(stmt);
330         if (ret == SQLITE_DONE) {
331                 sqlite3_finalize(stmt);
332                 return PMINFO_R_ENOENT;
333         } else if (ret != SQLITE_ROW) {
334                 _LOGE("step failed: %s", sqlite3_errmsg(db));
335                 sqlite3_finalize(stmt);
336                 return PMINFO_R_ERROR;
337         }
338
339         idx = 0;
340         _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_ROOT_CERT]);
341         _save_column_int(stmt, idx++,
342                         &cert_id[PMINFO_AUTHOR_INTERMEDIATE_CERT]);
343         _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_SIGNER_CERT]);
344         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_ROOT_CERT]);
345         _save_column_int(stmt, idx++,
346                         &cert_id[PMINFO_DISTRIBUTOR_INTERMEDIATE_CERT]);
347         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_SIGNER_CERT]);
348         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR2_ROOT_CERT]);
349         _save_column_int(stmt, idx++,
350                         &cert_id[PMINFO_DISTRIBUTOR2_INTERMEDIATE_CERT]);
351         _save_column_int(stmt, idx++,
352                         &cert_id[PMINFO_DISTRIBUTOR2_SIGNER_CERT]);
353
354         sqlite3_finalize(stmt);
355
356         return PMINFO_R_OK;
357 }
358
359 static int _pkginfo_get_certinfo(const char *pkgid, pkgmgr_certinfo_x *info)
360 {
361         int ret;
362         sqlite3 *db;
363         char *dbpath;
364
365         /* open unified global cert db */
366         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
367         if (dbpath == NULL)
368                 return PMINFO_R_ERROR;
369
370         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
371         if (ret != SQLITE_OK) {
372                 _LOGE("failed to open db: %d", ret);
373                 free(dbpath);
374                 return PMINFO_R_ERROR;
375         }
376         free(dbpath);
377
378         ret = _pkginfo_get_certid(db, pkgid, info->cert_id);
379         if (ret != PMINFO_R_OK) {
380                 sqlite3_close_v2(db);
381                 return ret;
382         }
383
384         ret = _pkginfo_get_cert(db, info->cert_id, info->cert_info);
385         if (ret != PMINFO_R_OK) {
386                 sqlite3_close_v2(db);
387                 return ret;
388         }
389
390         return PMINFO_R_OK;
391 }
392
393 API int pkgmgrinfo_pkginfo_load_certinfo(const char *pkgid, pkgmgrinfo_certinfo_h handle, uid_t uid)
394 {
395         int ret;
396         pkgmgr_certinfo_x *info = (pkgmgr_certinfo_x *)handle;
397
398         if (pkgid == NULL || handle == NULL) {
399                 _LOGE("invalid parameter");
400                 return PMINFO_R_EINVAL;
401         }
402
403         ret = _pkginfo_get_certinfo(pkgid, info);
404         if (ret != PMINFO_R_OK)
405                 _LOGE("failed to get certinfo of %s ", pkgid);
406
407         return ret;
408 }
409
410 API int pkgmgrinfo_pkginfo_get_cert_value(pkgmgrinfo_certinfo_h handle, pkgmgrinfo_cert_type cert_type, const char **cert_value)
411 {
412         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
413         retvm_if(cert_value == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
414         retvm_if(cert_type < PMINFO_AUTHOR_ROOT_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
415         retvm_if(cert_type > PMINFO_DISTRIBUTOR2_SIGNER_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
416         pkgmgr_certinfo_x *certinfo = NULL;
417         certinfo = (pkgmgr_certinfo_x *)handle;
418         if ((certinfo->cert_info)[cert_type])
419                 *cert_value = (certinfo->cert_info)[cert_type];
420         else
421                 *cert_value = NULL;
422         return PMINFO_R_OK;
423 }
424
425 API int pkgmgrinfo_pkginfo_destroy_certinfo(pkgmgrinfo_certinfo_h handle)
426 {
427         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
428         int i = 0;
429         pkgmgr_certinfo_x *certinfo = NULL;
430         certinfo = (pkgmgr_certinfo_x *)handle;
431         if (certinfo->pkgid) {
432                 free(certinfo->pkgid);
433                 certinfo->pkgid = NULL;
434         }
435         for (i = 0; i < MAX_CERT_TYPE; i++) {
436                 if ((certinfo->cert_info)[i]) {
437                         free((certinfo->cert_info)[i]);
438                         (certinfo->cert_info)[i] = NULL;
439                 }
440         }
441         free(certinfo);
442         certinfo = NULL;
443         return PMINFO_R_OK;
444 }
445
446 API int pkgmgrinfo_create_certinfo_set_handle(pkgmgrinfo_instcertinfo_h *handle)
447 {
448         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
449         pkgmgr_instcertinfo_x *certinfo = NULL;
450         *handle = NULL;
451         certinfo = calloc(1, sizeof(pkgmgr_instcertinfo_x));
452         retvm_if(certinfo == NULL, PMINFO_R_ERROR, "Malloc Failed\n");
453         *handle = (void *)certinfo;
454         return PMINFO_R_OK;
455 }
456
457 API int pkgmgrinfo_set_cert_value(pkgmgrinfo_instcertinfo_h handle, pkgmgrinfo_instcert_type cert_type, char *cert_value)
458 {
459         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
460         retvm_if(cert_value == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
461         retvm_if(cert_type < PMINFO_SET_AUTHOR_ROOT_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
462         retvm_if(cert_type > PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
463         pkgmgr_instcertinfo_x *certinfo = NULL;
464         certinfo = (pkgmgr_instcertinfo_x *)handle;
465         (certinfo->cert_info)[cert_type] = strdup(cert_value);
466         return PMINFO_R_OK;
467 }
468
469 static int _pkginfo_save_cert_info(sqlite3 *db, const char *pkgid,
470                 char *cert_info[])
471 {
472         static const char query_insert[] =
473                 "INSERT INTO package_cert_info (package, package_count,"
474                 " author_root_cert, author_im_cert, author_signer_cert,"
475                 " dist_root_cert, dist_im_cert, dist_signer_cert,"
476                 " dist2_root_cert, dist2_im_cert, dist2_signer_cert) "
477                 "VALUES(?, 1,"
478                 " (SELECT cert_id FROM package_cert_index_info"
479                 "  WHERE cert_info=?),"
480                 " (SELECT cert_id FROM package_cert_index_info"
481                 "  WHERE cert_info=?),"
482                 " (SELECT cert_id FROM package_cert_index_info"
483                 "  WHERE cert_info=?),"
484                 " (SELECT cert_id FROM package_cert_index_info"
485                 "  WHERE cert_info=?),"
486                 " (SELECT cert_id FROM package_cert_index_info"
487                 "  WHERE cert_info=?),"
488                 " (SELECT cert_id FROM package_cert_index_info"
489                 "  WHERE cert_info=?),"
490                 " (SELECT cert_id FROM package_cert_index_info"
491                 "  WHERE cert_info=?),"
492                 " (SELECT cert_id FROM package_cert_index_info"
493                 "  WHERE cert_info=?),"
494                 " (SELECT cert_id FROM package_cert_index_info"
495                 "  WHERE cert_info=?))";
496         static const char query_update[] =
497                 "UPDATE package_cert_info "
498                 "SET package_count = package_count + 1 "
499                 "WHERE package=?";
500         int ret;
501         sqlite3_stmt *stmt;
502         int i;
503         int idx;
504
505         ret = sqlite3_prepare_v2(db, query_insert, strlen(query_insert),
506                         &stmt, NULL);
507         if (ret != SQLITE_OK) {
508                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
509                 return PMINFO_R_ERROR;
510         }
511
512         idx = 1;
513         sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_STATIC);
514         for (i = 0; i < MAX_CERT_TYPE; i++) {
515                 if (sqlite3_bind_text(stmt, idx++, cert_info[i], -1,
516                                 SQLITE_STATIC)) {
517                         _LOGE("bind error: %s", sqlite3_errmsg(db));
518                         sqlite3_finalize(stmt);
519                         return PMINFO_R_ERROR;
520                 }
521         }
522
523         ret = sqlite3_step(stmt);
524         sqlite3_finalize(stmt);
525         if (ret == SQLITE_CONSTRAINT) {
526                 ret = sqlite3_prepare_v2(db, query_update, strlen(query_update),
527                                 &stmt, NULL);
528                 if (ret != SQLITE_OK) {
529                         _LOGE("prepare error: %s", sqlite3_errmsg(db));
530                         return PMINFO_R_ERROR;
531                 }
532                 sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
533                 ret = sqlite3_step(stmt);
534                 sqlite3_finalize(stmt);
535         }
536
537         if (ret != SQLITE_DONE) {
538                 _LOGE("step error: %s", sqlite3_errmsg(db));
539                 return PMINFO_R_ERROR;
540         }
541
542         return PMINFO_R_OK;
543 }
544
545 static int _pkginfo_save_cert_index_info(sqlite3 *db, char *cert_info[])
546 {
547         static const char query[] =
548                 "INSERT OR REPLACE INTO package_cert_index_info "
549                 "(cert_info, cert_id, cert_ref_count) "
550                 "VALUES ( "
551                 " ?, "
552                 " (SELECT cert_id FROM package_cert_index_info "
553                 "  WHERE cert_info=?), "
554                 " COALESCE( "
555                 "  ((SELECT cert_ref_count FROM package_cert_index_info "
556                 "    WHERE cert_info=?) + 1), 1))";
557         int ret;
558         sqlite3_stmt *stmt;
559         int i;
560         int idx;
561
562         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
563         if (ret != SQLITE_OK) {
564                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
565                 return PMINFO_R_ERROR;
566         }
567
568         for (i = 0; i < MAX_CERT_TYPE; i++) {
569                 if (cert_info[i] == NULL)
570                         continue;
571                 idx = 1;
572                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
573                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
574                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
575
576                 ret = sqlite3_step(stmt);
577                 if (ret != SQLITE_DONE) {
578                         _LOGE("step failed: %s", sqlite3_errmsg(db));
579                         sqlite3_finalize(stmt);
580                         return PMINFO_R_ERROR;
581                 }
582
583                 sqlite3_reset(stmt);
584                 sqlite3_clear_bindings(stmt);
585         }
586
587         sqlite3_finalize(stmt);
588
589         return PMINFO_R_OK;
590 }
591
592 API int pkgmgrinfo_save_certinfo(const char *pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid)
593 {
594         int ret;
595         sqlite3 *db;
596         char *dbpath;
597         pkgmgr_instcertinfo_x *info = (pkgmgr_instcertinfo_x *)handle;
598
599         if (pkgid == NULL || handle == NULL) {
600                 _LOGE("invalid parameter");
601                 return PMINFO_R_EINVAL;
602         }
603
604         /* open unified global cert db */
605         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
606         if (dbpath == NULL)
607                 return PMINFO_R_ERROR;
608
609         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READWRITE, NULL);
610         if (ret != SQLITE_OK) {
611                 _LOGE("failed to open db: %d", ret);
612                 free(dbpath);
613                 return PMINFO_R_ERROR;
614         }
615         free(dbpath);
616
617         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
618         if (ret != SQLITE_OK) {
619                 _LOGE("failed to begin transaction");
620                 sqlite3_close_v2(db);
621                 return PMINFO_R_ERROR;
622         }
623
624         _check_create_cert_db(db);
625
626         if (_pkginfo_save_cert_index_info(db, info->cert_info)) {
627                 _LOGE("failed to save cert index info, rollback now");
628                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
629                 sqlite3_close_v2(db);
630                 return PMINFO_R_ERROR;
631         }
632
633         if (_pkginfo_save_cert_info(db, pkgid, info->cert_info)) {
634                 _LOGE("failed to save cert info, rollback now");
635                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
636                 sqlite3_close_v2(db);
637                 return PMINFO_R_ERROR;
638         }
639
640         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
641         if (ret != SQLITE_OK) {
642                 _LOGE("failed to commit transaction, rollback now");
643                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
644                 sqlite3_close_v2(db);
645                 return PMINFO_R_ERROR;
646         }
647
648         sqlite3_close_v2(db);
649
650         return PMINFO_R_OK;
651 }
652
653 API int pkgmgrinfo_destroy_certinfo_set_handle(pkgmgrinfo_instcertinfo_h handle)
654 {
655         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
656         int i = 0;
657         pkgmgr_instcertinfo_x *certinfo = NULL;
658         certinfo = (pkgmgr_instcertinfo_x *)handle;
659         if (certinfo->pkgid) {
660                 free(certinfo->pkgid);
661                 certinfo->pkgid = NULL;
662         }
663         for (i = 0; i < MAX_CERT_TYPE; i++) {
664                 if ((certinfo->cert_info)[i]) {
665                         free((certinfo->cert_info)[i]);
666                         (certinfo->cert_info)[i] = NULL;
667                 }
668         }
669         free(certinfo);
670         certinfo = NULL;
671         return PMINFO_R_OK;
672 }
673
674 static int _pkginfo_delete_certinfo(sqlite3 *db, const char *pkgid)
675 {
676         static const char query[] =
677                 "UPDATE package_cert_info "
678                 "SET package_count = package_count - 1 "
679                 "WHERE package=?";
680         int ret;
681         sqlite3_stmt *stmt;
682
683         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
684         if (ret != SQLITE_OK) {
685                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
686                 return PMINFO_R_ERROR;
687         }
688
689         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
690         if (ret != SQLITE_OK) {
691                 _LOGE("bind error: %s", sqlite3_errmsg(db));
692                 sqlite3_finalize(stmt);
693                 return PMINFO_R_ERROR;
694         }
695
696         ret = sqlite3_step(stmt);
697         sqlite3_finalize(stmt);
698         if (ret != SQLITE_DONE) {
699                 _LOGE("step error: %s", sqlite3_errmsg(db));
700                 return PMINFO_R_ERROR;
701         }
702
703         return PMINFO_R_OK;
704 }
705
706 API int pkgmgrinfo_delete_usr_certinfo(const char *pkgid, uid_t uid)
707 {
708         int ret;
709         sqlite3 *db;
710         char *dbpath;
711
712         if (pkgid == NULL) {
713                 _LOGE("invalid parameter");
714                 return PMINFO_R_EINVAL;
715         }
716
717         /* open unified global cert db */
718         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
719         if (dbpath == NULL)
720                 return PMINFO_R_ERROR;
721
722         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READWRITE, NULL);
723         if (ret != SQLITE_OK) {
724                 _LOGE("failed to open db: %d", ret);
725                 free(dbpath);
726                 return PMINFO_R_ERROR;
727         }
728         free(dbpath);
729
730         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
731         if (ret != SQLITE_OK) {
732                 _LOGE("failed to begin transaction");
733                 sqlite3_close_v2(db);
734                 return PMINFO_R_ERROR;
735         }
736
737         if (_pkginfo_delete_certinfo(db, pkgid)) {
738                 _LOGE("failed to delete certinfo of %s, rollback now", pkgid);
739                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
740                 sqlite3_close_v2(db);
741                 return PMINFO_R_ERROR;
742         }
743
744         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
745         if (ret != SQLITE_OK) {
746                 _LOGE("failed to commit transaction, rollback now");
747                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
748                 sqlite3_close_v2(db);
749                 return PMINFO_R_ERROR;
750         }
751
752         sqlite3_close_v2(db);
753
754         return PMINFO_R_OK;
755 }
756
757 API int pkgmgrinfo_delete_certinfo(const char *pkgid)
758 {
759         return pkgmgrinfo_delete_usr_certinfo(pkgid, _getuid());
760 }
761