Fix some outdated sqlite query logic
[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 = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
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 = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
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 = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
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         sqlite3_close_v2(db);
391
392         return PMINFO_R_OK;
393 }
394
395 API int pkgmgrinfo_pkginfo_load_certinfo(const char *pkgid, pkgmgrinfo_certinfo_h handle, uid_t uid)
396 {
397         int ret;
398         pkgmgr_certinfo_x *info = (pkgmgr_certinfo_x *)handle;
399
400         if (pkgid == NULL || handle == NULL) {
401                 _LOGE("invalid parameter");
402                 return PMINFO_R_EINVAL;
403         }
404
405         ret = _pkginfo_get_certinfo(pkgid, info);
406         if (ret != PMINFO_R_OK)
407                 _LOGE("failed to get certinfo of %s ", pkgid);
408
409         return ret;
410 }
411
412 API int pkgmgrinfo_pkginfo_get_cert_value(pkgmgrinfo_certinfo_h handle, pkgmgrinfo_cert_type cert_type, const char **cert_value)
413 {
414         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
415         retvm_if(cert_value == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
416         retvm_if(cert_type < PMINFO_AUTHOR_ROOT_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
417         retvm_if(cert_type > PMINFO_DISTRIBUTOR2_SIGNER_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
418         pkgmgr_certinfo_x *certinfo = NULL;
419         certinfo = (pkgmgr_certinfo_x *)handle;
420         if ((certinfo->cert_info)[cert_type])
421                 *cert_value = (certinfo->cert_info)[cert_type];
422         else
423                 *cert_value = NULL;
424         return PMINFO_R_OK;
425 }
426
427 API int pkgmgrinfo_pkginfo_destroy_certinfo(pkgmgrinfo_certinfo_h handle)
428 {
429         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
430         int i = 0;
431         pkgmgr_certinfo_x *certinfo = NULL;
432         certinfo = (pkgmgr_certinfo_x *)handle;
433         if (certinfo->pkgid) {
434                 free(certinfo->pkgid);
435                 certinfo->pkgid = NULL;
436         }
437         for (i = 0; i < MAX_CERT_TYPE; i++) {
438                 if ((certinfo->cert_info)[i]) {
439                         free((certinfo->cert_info)[i]);
440                         (certinfo->cert_info)[i] = NULL;
441                 }
442         }
443         free(certinfo);
444         certinfo = NULL;
445         return PMINFO_R_OK;
446 }
447
448 API int pkgmgrinfo_create_certinfo_set_handle(pkgmgrinfo_instcertinfo_h *handle)
449 {
450         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
451         pkgmgr_instcertinfo_x *certinfo = NULL;
452         *handle = NULL;
453         certinfo = calloc(1, sizeof(pkgmgr_instcertinfo_x));
454         retvm_if(certinfo == NULL, PMINFO_R_ERROR, "Malloc Failed\n");
455         *handle = (void *)certinfo;
456         return PMINFO_R_OK;
457 }
458
459 API int pkgmgrinfo_set_cert_value(pkgmgrinfo_instcertinfo_h handle, pkgmgrinfo_instcert_type cert_type, char *cert_value)
460 {
461         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
462         retvm_if(cert_value == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
463         retvm_if(cert_type < PMINFO_SET_AUTHOR_ROOT_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
464         retvm_if(cert_type > PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
465         pkgmgr_instcertinfo_x *certinfo = NULL;
466         certinfo = (pkgmgr_instcertinfo_x *)handle;
467         (certinfo->cert_info)[cert_type] = strdup(cert_value);
468         return PMINFO_R_OK;
469 }
470
471 static int _pkginfo_save_cert_info(sqlite3 *db, const char *pkgid,
472                 char *cert_info[])
473 {
474         static const char query_insert[] =
475                 "INSERT INTO package_cert_info (package, package_count,"
476                 " author_root_cert, author_im_cert, author_signer_cert,"
477                 " dist_root_cert, dist_im_cert, dist_signer_cert,"
478                 " dist2_root_cert, dist2_im_cert, dist2_signer_cert) "
479                 "VALUES(?, 1,"
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                 " (SELECT cert_id FROM package_cert_index_info"
497                 "  WHERE cert_info=?))";
498         static const char query_update[] =
499                 "UPDATE package_cert_info "
500                 "SET package_count = package_count + 1 "
501                 "WHERE package=?";
502         int ret;
503         sqlite3_stmt *stmt;
504         int i;
505         int idx;
506
507         ret = sqlite3_prepare_v2(db, query_insert, strlen(query_insert),
508                         &stmt, NULL);
509         if (ret != SQLITE_OK) {
510                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
511                 return PMINFO_R_ERROR;
512         }
513
514         idx = 1;
515         sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_STATIC);
516         for (i = 0; i < MAX_CERT_TYPE; i++) {
517                 if (sqlite3_bind_text(stmt, idx++, cert_info[i], -1,
518                                 SQLITE_STATIC)) {
519                         _LOGE("bind error: %s", sqlite3_errmsg(db));
520                         sqlite3_finalize(stmt);
521                         return PMINFO_R_ERROR;
522                 }
523         }
524
525         ret = sqlite3_step(stmt);
526         sqlite3_finalize(stmt);
527         if (ret == SQLITE_CONSTRAINT) {
528                 ret = sqlite3_prepare_v2(db, query_update, strlen(query_update),
529                                 &stmt, NULL);
530                 if (ret != SQLITE_OK) {
531                         _LOGE("prepare error: %s", sqlite3_errmsg(db));
532                         return PMINFO_R_ERROR;
533                 }
534                 sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
535                 ret = sqlite3_step(stmt);
536                 sqlite3_finalize(stmt);
537         }
538
539         if (ret != SQLITE_DONE) {
540                 _LOGE("step error: %s", sqlite3_errmsg(db));
541                 return PMINFO_R_ERROR;
542         }
543
544         return PMINFO_R_OK;
545 }
546
547 static int _pkginfo_save_cert_index_info(sqlite3 *db, char *cert_info[])
548 {
549         static const char query[] =
550                 "INSERT OR REPLACE INTO package_cert_index_info "
551                 "(cert_info, cert_id, cert_ref_count) "
552                 "VALUES ( "
553                 " ?, "
554                 " (SELECT cert_id FROM package_cert_index_info "
555                 "  WHERE cert_info=?), "
556                 " COALESCE( "
557                 "  ((SELECT cert_ref_count FROM package_cert_index_info "
558                 "    WHERE cert_info=?) + 1), 1))";
559         int ret;
560         sqlite3_stmt *stmt;
561         int i;
562         int idx;
563
564         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
565         if (ret != SQLITE_OK) {
566                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
567                 return PMINFO_R_ERROR;
568         }
569
570         for (i = 0; i < MAX_CERT_TYPE; i++) {
571                 if (cert_info[i] == NULL)
572                         continue;
573                 idx = 1;
574                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
575                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
576                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
577
578                 ret = sqlite3_step(stmt);
579                 if (ret != SQLITE_DONE) {
580                         _LOGE("step failed: %s", sqlite3_errmsg(db));
581                         sqlite3_finalize(stmt);
582                         return PMINFO_R_ERROR;
583                 }
584
585                 sqlite3_reset(stmt);
586                 sqlite3_clear_bindings(stmt);
587         }
588
589         sqlite3_finalize(stmt);
590
591         return PMINFO_R_OK;
592 }
593
594 API int pkgmgrinfo_save_certinfo(const char *pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid)
595 {
596         int ret;
597         sqlite3 *db;
598         char *dbpath;
599         pkgmgr_instcertinfo_x *info = (pkgmgr_instcertinfo_x *)handle;
600
601         if (pkgid == NULL || handle == NULL) {
602                 _LOGE("invalid parameter");
603                 return PMINFO_R_EINVAL;
604         }
605
606         _check_create_cert_db();
607
608         /* open unified global cert db */
609         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
610         if (dbpath == NULL)
611                 return PMINFO_R_ERROR;
612
613         ret = __open_db(dbpath, &db, SQLITE_OPEN_READWRITE);
614         if (ret != SQLITE_OK) {
615                 _LOGE("failed to open db: %d", ret);
616                 free(dbpath);
617                 return PMINFO_R_ERROR;
618         }
619         free(dbpath);
620
621         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
622         if (ret != SQLITE_OK) {
623                 _LOGE("failed to begin transaction");
624                 sqlite3_close_v2(db);
625                 return PMINFO_R_ERROR;
626         }
627
628         if (_pkginfo_save_cert_index_info(db, info->cert_info)) {
629                 _LOGE("failed to save cert index info, rollback now");
630                 sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
631                 sqlite3_close_v2(db);
632                 return PMINFO_R_ERROR;
633         }
634
635         if (_pkginfo_save_cert_info(db, pkgid, info->cert_info)) {
636                 _LOGE("failed to save cert info, rollback now");
637                 sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
638                 sqlite3_close_v2(db);
639                 return PMINFO_R_ERROR;
640         }
641
642         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
643         if (ret != SQLITE_OK) {
644                 _LOGE("failed to commit transaction, rollback now");
645                 sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
646                 sqlite3_close_v2(db);
647                 return PMINFO_R_ERROR;
648         }
649
650         sqlite3_close_v2(db);
651
652         return PMINFO_R_OK;
653 }
654
655 API int pkgmgrinfo_destroy_certinfo_set_handle(pkgmgrinfo_instcertinfo_h handle)
656 {
657         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
658         int i = 0;
659         pkgmgr_instcertinfo_x *certinfo = NULL;
660         certinfo = (pkgmgr_instcertinfo_x *)handle;
661         if (certinfo->pkgid) {
662                 free(certinfo->pkgid);
663                 certinfo->pkgid = NULL;
664         }
665         for (i = 0; i < MAX_CERT_TYPE; i++) {
666                 if ((certinfo->cert_info)[i]) {
667                         free((certinfo->cert_info)[i]);
668                         (certinfo->cert_info)[i] = NULL;
669                 }
670         }
671         free(certinfo);
672         certinfo = NULL;
673         return PMINFO_R_OK;
674 }
675
676 static int _pkginfo_delete_certinfo(sqlite3 *db, const char *pkgid)
677 {
678         static const char query[] =
679                 "UPDATE package_cert_info "
680                 "SET package_count = package_count - 1 "
681                 "WHERE package=?";
682         int ret;
683         sqlite3_stmt *stmt;
684
685         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
686         if (ret != SQLITE_OK) {
687                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
688                 return PMINFO_R_ERROR;
689         }
690
691         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
692         if (ret != SQLITE_OK) {
693                 _LOGE("bind error: %s", sqlite3_errmsg(db));
694                 sqlite3_finalize(stmt);
695                 return PMINFO_R_ERROR;
696         }
697
698         ret = sqlite3_step(stmt);
699         sqlite3_finalize(stmt);
700         if (ret != SQLITE_DONE) {
701                 _LOGE("step error: %s", sqlite3_errmsg(db));
702                 return PMINFO_R_ERROR;
703         }
704
705         return PMINFO_R_OK;
706 }
707
708 API int pkgmgrinfo_delete_usr_certinfo(const char *pkgid, uid_t uid)
709 {
710         int ret;
711         sqlite3 *db;
712         char *dbpath;
713
714         if (pkgid == NULL) {
715                 _LOGE("invalid parameter");
716                 return PMINFO_R_EINVAL;
717         }
718
719         /* open unified global cert db */
720         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
721         if (dbpath == NULL)
722                 return PMINFO_R_ERROR;
723
724         ret = __open_db(dbpath, &db, SQLITE_OPEN_READWRITE);
725         if (ret != SQLITE_OK) {
726                 _LOGE("failed to open db: %d", ret);
727                 free(dbpath);
728                 return PMINFO_R_ERROR;
729         }
730         free(dbpath);
731
732         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
733         if (ret != SQLITE_OK) {
734                 _LOGE("failed to begin transaction");
735                 sqlite3_close_v2(db);
736                 return PMINFO_R_ERROR;
737         }
738
739         if (_pkginfo_delete_certinfo(db, pkgid)) {
740                 _LOGE("failed to delete certinfo of %s, rollback now", pkgid);
741                 sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
742                 sqlite3_close_v2(db);
743                 return PMINFO_R_ERROR;
744         }
745
746         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
747         if (ret != SQLITE_OK) {
748                 _LOGE("failed to commit transaction, rollback now");
749                 sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
750                 sqlite3_close_v2(db);
751                 return PMINFO_R_ERROR;
752         }
753
754         sqlite3_close_v2(db);
755
756         return PMINFO_R_OK;
757 }
758
759 API int pkgmgrinfo_delete_certinfo(const char *pkgid)
760 {
761         return pkgmgrinfo_delete_usr_certinfo(pkgid, _getuid());
762 }
763