Fix logic of pkgmgrinfo_save_cert_info
[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         const 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                 return PMINFO_R_ERROR;
136         }
137
138         if (_pkginfo_compare_certinfo(db, lhs_package_id, rhs_package_id,
139                                 compare_result)) {
140                 _LOGE("failed to compare certinfo");
141                 sqlite3_close_v2(db);
142                 return PMINFO_R_ERROR;
143         }
144
145         sqlite3_close_v2(db);
146
147         return PMINFO_R_OK;
148 }
149
150 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)
151 {
152         return pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(lhs_package_id, rhs_package_id, _getuid(), compare_result);
153 }
154
155 static int _pkginfo_get_pkgid_from_appid(uid_t uid, const char *appid,
156                 char **pkgid)
157 {
158         static const char query[] =
159                 "SELECT package FROM package_app_info WHERE app_id=?";
160         int ret;
161         sqlite3 *db;
162         const char *dbpath;
163         sqlite3_stmt *stmt;
164
165         dbpath = getUserPkgParserDBPathUID(uid);
166         if (dbpath == NULL)
167                 return PMINFO_R_ERROR;
168
169         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
170         if (ret != SQLITE_OK) {
171                 _LOGE("failed to open db: %d", ret);
172                 return PMINFO_R_ERROR;
173         }
174
175         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
176         if (ret != SQLITE_OK) {
177                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
178                 sqlite3_close_v2(db);
179                 return PMINFO_R_ERROR;
180         }
181
182         ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_STATIC);
183         if (ret != SQLITE_OK) {
184                 _LOGE("bind error: %s", sqlite3_errmsg(db));
185                 sqlite3_finalize(stmt);
186                 sqlite3_close_v2(db);
187                 return PMINFO_R_ERROR;
188         }
189
190         ret = sqlite3_step(stmt);
191         if (ret == SQLITE_ROW) {
192                 _save_column_str(stmt, 0, pkgid);
193                 ret = PMINFO_R_OK;
194         } else if (ret == SQLITE_DONE) {
195                 _LOGI("cannot find pkgid of app %s for uid %d", appid, (int)uid);
196                 ret = PMINFO_R_ENOENT;
197         } else {
198                 _LOGE("step error: %s", sqlite3_errmsg(db));
199                 ret = PMINFO_R_ERROR;
200         }
201
202         sqlite3_finalize(stmt);
203         sqlite3_close_v2(db);
204
205         return ret;
206 }
207
208 API int pkgmgrinfo_pkginfo_compare_usr_app_cert_info(const char *lhs_app_id,
209                 const char *rhs_app_id, uid_t uid,
210                 pkgmgrinfo_cert_compare_result_type_e *compare_result)
211 {
212         int ret;
213         char *l_pkgid = NULL;
214         char *r_pkgid = NULL;
215
216         if (lhs_app_id == NULL || rhs_app_id == NULL ||
217                         compare_result == NULL) {
218                 _LOGE("invalid parameter");
219                 return PMINFO_R_EINVAL;
220         }
221
222         ret = _pkginfo_get_pkgid_from_appid(uid, lhs_app_id, &l_pkgid);
223         if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
224                 ret = _pkginfo_get_pkgid_from_appid(GLOBAL_USER, lhs_app_id,
225                                 &l_pkgid);
226
227         if (ret != PMINFO_R_OK)
228                 return ret;
229
230         ret = _pkginfo_get_pkgid_from_appid(uid, rhs_app_id, &r_pkgid);
231         if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
232                 ret = _pkginfo_get_pkgid_from_appid(GLOBAL_USER, rhs_app_id,
233                                 &r_pkgid);
234
235         if (ret != PMINFO_R_OK) {
236                 free(l_pkgid);
237                 return ret;
238         }
239
240         ret = pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(l_pkgid, r_pkgid,
241                         uid, compare_result);
242
243         free(l_pkgid);
244         free(r_pkgid);
245
246         return ret;
247 }
248
249 API int pkgmgrinfo_pkginfo_compare_app_cert_info(const char *lhs_app_id,
250                 const char *rhs_app_id,
251                 pkgmgrinfo_cert_compare_result_type_e *compare_result)
252 {
253         return pkgmgrinfo_pkginfo_compare_usr_app_cert_info(lhs_app_id,
254                         rhs_app_id, _getuid(), compare_result);
255 }
256
257 static int _pkginfo_get_cert(sqlite3 *db, int cert_id[],
258                 char *cert_info[])
259 {
260         static const char query[] =
261                 "SELECT cert_info FROM package_cert_index_info WHERE cert_id=?";
262         int ret;
263         sqlite3_stmt *stmt;
264         int i;
265
266         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
267         if (ret != SQLITE_OK) {
268                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
269                 return PMINFO_R_ERROR;
270         }
271
272         for (i = 0; i < MAX_CERT_TYPE; i++) {
273                 ret = sqlite3_bind_int(stmt, 1, cert_id[i]);
274                 if (ret != SQLITE_OK) {
275                         sqlite3_finalize(stmt);
276                         _LOGE("bind failed: %s", sqlite3_errmsg(db));
277                         return PMINFO_R_ERROR;
278                 }
279
280                 ret = sqlite3_step(stmt);
281                 if (ret == SQLITE_DONE) {
282                         sqlite3_reset(stmt);
283                         sqlite3_clear_bindings(stmt);
284                         continue;
285                 } else if (ret != SQLITE_ROW) {
286                         _LOGE("step failed: %s", sqlite3_errmsg(db));
287                         sqlite3_finalize(stmt);
288                         return PMINFO_R_ERROR;
289                 }
290
291                 _save_column_str(stmt, 0, &cert_info[i]);
292                 sqlite3_reset(stmt);
293                 sqlite3_clear_bindings(stmt);
294         }
295
296         sqlite3_finalize(stmt);
297
298         return PMINFO_R_OK;
299 }
300
301 static int _pkginfo_get_certid(sqlite3 *db, const char *pkgid, int cert_id[])
302 {
303         static const char query[] =
304                 "SELECT author_root_cert, author_im_cert, author_signer_cert, "
305                 "dist_root_cert, dist_im_cert, dist_signer_cert, "
306                 "dist2_root_cert, dist2_im_cert, dist2_signer_cert "
307                 "FROM package_cert_info WHERE package=?";
308         int ret;
309         sqlite3_stmt *stmt;
310         int idx;
311
312         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
313         if (ret != SQLITE_OK) {
314                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
315                 return PMINFO_R_ERROR;
316         }
317
318         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
319         if (ret != SQLITE_OK) {
320                 _LOGE("bind failed: %s", sqlite3_errmsg(db));
321                 sqlite3_finalize(stmt);
322                 return PMINFO_R_ERROR;
323         }
324
325         ret = sqlite3_step(stmt);
326         if (ret == SQLITE_DONE) {
327                 sqlite3_finalize(stmt);
328                 return PMINFO_R_ENOENT;
329         } else if (ret != SQLITE_ROW) {
330                 _LOGE("step failed: %s", sqlite3_errmsg(db));
331                 sqlite3_finalize(stmt);
332                 return PMINFO_R_ERROR;
333         }
334
335         idx = 0;
336         _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_ROOT_CERT]);
337         _save_column_int(stmt, idx++,
338                         &cert_id[PMINFO_AUTHOR_INTERMEDIATE_CERT]);
339         _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_SIGNER_CERT]);
340         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_ROOT_CERT]);
341         _save_column_int(stmt, idx++,
342                         &cert_id[PMINFO_DISTRIBUTOR_INTERMEDIATE_CERT]);
343         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_SIGNER_CERT]);
344         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR2_ROOT_CERT]);
345         _save_column_int(stmt, idx++,
346                         &cert_id[PMINFO_DISTRIBUTOR2_INTERMEDIATE_CERT]);
347         _save_column_int(stmt, idx++,
348                         &cert_id[PMINFO_DISTRIBUTOR2_SIGNER_CERT]);
349
350         sqlite3_finalize(stmt);
351
352         return PMINFO_R_OK;
353 }
354
355 static int _pkginfo_get_certinfo(const char *pkgid, pkgmgr_certinfo_x *info)
356 {
357         int ret;
358         sqlite3 *db;
359         const char *dbpath;
360
361         /* open unified global cert db */
362         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
363         if (dbpath == NULL)
364                 return PMINFO_R_ERROR;
365
366         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
367         if (ret != SQLITE_OK) {
368                 _LOGE("failed to open db: %d", ret);
369                 return PMINFO_R_ERROR;
370         }
371
372         ret = _pkginfo_get_certid(db, pkgid, info->cert_id);
373         if (ret != PMINFO_R_OK) {
374                 sqlite3_close_v2(db);
375                 return ret;
376         }
377
378         ret = _pkginfo_get_cert(db, info->cert_id, info->cert_info);
379         if (ret != PMINFO_R_OK) {
380                 sqlite3_close_v2(db);
381                 return ret;
382         }
383
384         return PMINFO_R_OK;
385 }
386
387 API int pkgmgrinfo_pkginfo_load_certinfo(const char *pkgid, pkgmgrinfo_certinfo_h handle, uid_t uid)
388 {
389         int ret;
390         pkgmgr_certinfo_x *info = (pkgmgr_certinfo_x *)handle;
391
392         if (pkgid == NULL || handle == NULL) {
393                 _LOGE("invalid parameter");
394                 return PMINFO_R_EINVAL;
395         }
396
397         ret = _pkginfo_get_certinfo(pkgid, info);
398         if (ret != PMINFO_R_OK)
399                 _LOGE("failed to get certinfo of %s ", pkgid);
400
401         return ret;
402 }
403
404 API int pkgmgrinfo_pkginfo_get_cert_value(pkgmgrinfo_certinfo_h handle, pkgmgrinfo_cert_type cert_type, const char **cert_value)
405 {
406         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
407         retvm_if(cert_value == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
408         retvm_if(cert_type < PMINFO_AUTHOR_ROOT_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
409         retvm_if(cert_type > PMINFO_DISTRIBUTOR2_SIGNER_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
410         pkgmgr_certinfo_x *certinfo = NULL;
411         certinfo = (pkgmgr_certinfo_x *)handle;
412         if ((certinfo->cert_info)[cert_type])
413                 *cert_value = (certinfo->cert_info)[cert_type];
414         else
415                 *cert_value = NULL;
416         return PMINFO_R_OK;
417 }
418
419 API int pkgmgrinfo_pkginfo_destroy_certinfo(pkgmgrinfo_certinfo_h handle)
420 {
421         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
422         int i = 0;
423         pkgmgr_certinfo_x *certinfo = NULL;
424         certinfo = (pkgmgr_certinfo_x *)handle;
425         if (certinfo->pkgid) {
426                 free(certinfo->pkgid);
427                 certinfo->pkgid = NULL;
428         }
429         for (i = 0; i < MAX_CERT_TYPE; i++) {
430                 if ((certinfo->cert_info)[i]) {
431                         free((certinfo->cert_info)[i]);
432                         (certinfo->cert_info)[i] = NULL;
433                 }
434         }
435         free(certinfo);
436         certinfo = NULL;
437         return PMINFO_R_OK;
438 }
439
440 API int pkgmgrinfo_create_certinfo_set_handle(pkgmgrinfo_instcertinfo_h *handle)
441 {
442         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
443         pkgmgr_instcertinfo_x *certinfo = NULL;
444         *handle = NULL;
445         certinfo = calloc(1, sizeof(pkgmgr_instcertinfo_x));
446         retvm_if(certinfo == NULL, PMINFO_R_ERROR, "Malloc Failed\n");
447         *handle = (void *)certinfo;
448         return PMINFO_R_OK;
449 }
450
451 API int pkgmgrinfo_set_cert_value(pkgmgrinfo_instcertinfo_h handle, pkgmgrinfo_instcert_type cert_type, char *cert_value)
452 {
453         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
454         retvm_if(cert_value == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
455         retvm_if(cert_type < PMINFO_SET_AUTHOR_ROOT_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
456         retvm_if(cert_type > PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
457         pkgmgr_instcertinfo_x *certinfo = NULL;
458         certinfo = (pkgmgr_instcertinfo_x *)handle;
459         (certinfo->cert_info)[cert_type] = strdup(cert_value);
460         return PMINFO_R_OK;
461 }
462
463 static int _pkginfo_save_cert_info(sqlite3 *db, const char *pkgid,
464                 char *cert_info[])
465 {
466         static const char query_insert[] =
467                 "INSERT INTO package_cert_info (package, package_count,"
468                 " author_root_cert, author_im_cert, author_signer_cert,"
469                 " dist_root_cert, dist_im_cert, dist_signer_cert,"
470                 " dist2_root_cert, dist2_im_cert, dist2_signer_cert) "
471                 "VALUES(?, 1,"
472                 " (SELECT cert_id FROM package_cert_index_info"
473                 "  WHERE cert_info=?),"
474                 " (SELECT cert_id FROM package_cert_index_info"
475                 "  WHERE cert_info=?),"
476                 " (SELECT cert_id FROM package_cert_index_info"
477                 "  WHERE cert_info=?),"
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         static const char query_update[] =
491                 "UPDATE package_cert_info "
492                 "SET package_count = package_count + 1 "
493                 "WHERE package=?";
494         int ret;
495         sqlite3_stmt *stmt;
496         int i;
497         int idx;
498
499         ret = sqlite3_prepare_v2(db, query_insert, strlen(query_insert),
500                         &stmt, NULL);
501         if (ret != SQLITE_OK) {
502                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
503                 return PMINFO_R_ERROR;
504         }
505
506         idx = 1;
507         sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_STATIC);
508         for (i = 0; i < MAX_CERT_TYPE; i++) {
509                 if (sqlite3_bind_text(stmt, idx++, cert_info[i], -1,
510                                 SQLITE_STATIC)) {
511                         _LOGE("bind error: %s", sqlite3_errmsg(db));
512                         sqlite3_finalize(stmt);
513                         return PMINFO_R_ERROR;
514                 }
515         }
516
517         ret = sqlite3_step(stmt);
518         sqlite3_finalize(stmt);
519         if (ret == SQLITE_CONSTRAINT) {
520                 ret = sqlite3_prepare_v2(db, query_update, strlen(query_update),
521                                 &stmt, NULL);
522                 if (ret != SQLITE_OK) {
523                         _LOGE("prepare error: %s", sqlite3_errmsg(db));
524                         return PMINFO_R_ERROR;
525                 }
526                 sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
527                 ret = sqlite3_step(stmt);
528                 sqlite3_finalize(stmt);
529         }
530
531         if (ret != SQLITE_DONE) {
532                 _LOGE("step error: %s", sqlite3_errmsg(db));
533                 return PMINFO_R_ERROR;
534         }
535
536         return PMINFO_R_OK;
537 }
538
539 static int _pkginfo_save_cert_index_info(sqlite3 *db, char *cert_info[])
540 {
541         static const char query[] =
542                 "INSERT OR REPLACE INTO package_cert_index_info "
543                 "(cert_info, cert_id, cert_ref_count) "
544                 "VALUES ( "
545                 " ?, "
546                 " (SELECT cert_id FROM package_cert_index_info "
547                 "  WHERE cert_info=?), "
548                 " COALESCE( "
549                 "  ((SELECT cert_ref_count FROM package_cert_index_info "
550                 "    WHERE cert_info=?) + 1), 1))";
551         int ret;
552         sqlite3_stmt *stmt;
553         int i;
554         int idx;
555
556         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
557         if (ret != SQLITE_OK) {
558                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
559                 return PMINFO_R_ERROR;
560         }
561
562         for (i = 0; i < MAX_CERT_TYPE; i++) {
563                 if (cert_info[i] == NULL)
564                         continue;
565                 idx = 1;
566                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
567                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
568                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
569
570                 ret = sqlite3_step(stmt);
571                 if (ret != SQLITE_DONE) {
572                         _LOGE("step failed: %s", sqlite3_errmsg(db));
573                         sqlite3_finalize(stmt);
574                         return PMINFO_R_ERROR;
575                 }
576
577                 sqlite3_reset(stmt);
578                 sqlite3_clear_bindings(stmt);
579         }
580
581         sqlite3_finalize(stmt);
582
583         return PMINFO_R_OK;
584 }
585
586 API int pkgmgrinfo_save_certinfo(const char *pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid)
587 {
588         int ret;
589         sqlite3 *db;
590         const char *dbpath;
591         pkgmgr_instcertinfo_x *info = (pkgmgr_instcertinfo_x *)handle;
592
593         if (pkgid == NULL || handle == NULL) {
594                 _LOGE("invalid parameter");
595                 return PMINFO_R_EINVAL;
596         }
597
598         /* open unified global cert db */
599         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
600         if (dbpath == NULL)
601                 return PMINFO_R_ERROR;
602
603         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READWRITE, NULL);
604         if (ret != SQLITE_OK) {
605                 _LOGE("failed to open db: %d", ret);
606                 return PMINFO_R_ERROR;
607         }
608
609         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
610         if (ret != SQLITE_OK) {
611                 _LOGE("failed to begin transaction");
612                 sqlite3_close_v2(db);
613                 return PMINFO_R_ERROR;
614         }
615
616         _check_create_cert_db(db);
617
618         if (_pkginfo_save_cert_index_info(db, info->cert_info)) {
619                 _LOGE("failed to save cert index info, rollback now");
620                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
621                 sqlite3_close_v2(db);
622                 return PMINFO_R_ERROR;
623         }
624
625         if (_pkginfo_save_cert_info(db, pkgid, info->cert_info)) {
626                 _LOGE("failed to save cert info, rollback now");
627                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
628                 sqlite3_close_v2(db);
629                 return PMINFO_R_ERROR;
630         }
631
632         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
633         if (ret != SQLITE_OK) {
634                 _LOGE("failed to commit transaction, 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         sqlite3_close_v2(db);
641
642         return PMINFO_R_OK;
643 }
644
645 API int pkgmgrinfo_destroy_certinfo_set_handle(pkgmgrinfo_instcertinfo_h handle)
646 {
647         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
648         int i = 0;
649         pkgmgr_instcertinfo_x *certinfo = NULL;
650         certinfo = (pkgmgr_instcertinfo_x *)handle;
651         if (certinfo->pkgid) {
652                 free(certinfo->pkgid);
653                 certinfo->pkgid = NULL;
654         }
655         for (i = 0; i < MAX_CERT_TYPE; i++) {
656                 if ((certinfo->cert_info)[i]) {
657                         free((certinfo->cert_info)[i]);
658                         (certinfo->cert_info)[i] = NULL;
659                 }
660         }
661         free(certinfo);
662         certinfo = NULL;
663         return PMINFO_R_OK;
664 }
665
666 static int _pkginfo_delete_certinfo(sqlite3 *db, const char *pkgid)
667 {
668         static const char query[] =
669                 "UPDATE package_cert_info "
670                 "SET package_count = package_count - 1 "
671                 "WHERE package=?";
672         int ret;
673         sqlite3_stmt *stmt;
674
675         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
676         if (ret != SQLITE_OK) {
677                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
678                 return PMINFO_R_ERROR;
679         }
680
681         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
682         if (ret != SQLITE_OK) {
683                 _LOGE("bind error: %s", sqlite3_errmsg(db));
684                 sqlite3_finalize(stmt);
685                 return PMINFO_R_ERROR;
686         }
687
688         ret = sqlite3_step(stmt);
689         sqlite3_finalize(stmt);
690         if (ret != SQLITE_DONE) {
691                 _LOGE("step error: %s", sqlite3_errmsg(db));
692                 return PMINFO_R_ERROR;
693         }
694
695         return PMINFO_R_OK;
696 }
697
698 API int pkgmgrinfo_delete_usr_certinfo(const char *pkgid, uid_t uid)
699 {
700         int ret;
701         sqlite3 *db;
702         const char *dbpath;
703
704         if (pkgid == NULL) {
705                 _LOGE("invalid parameter");
706                 return PMINFO_R_EINVAL;
707         }
708
709         /* open unified global cert db */
710         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
711         if (dbpath == NULL)
712                 return PMINFO_R_ERROR;
713
714         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READWRITE, NULL);
715         if (ret != SQLITE_OK) {
716                 _LOGE("failed to open db: %d", ret);
717                 return PMINFO_R_ERROR;
718         }
719
720         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
721         if (ret != SQLITE_OK) {
722                 _LOGE("failed to begin transaction");
723                 sqlite3_close_v2(db);
724                 return PMINFO_R_ERROR;
725         }
726
727         if (_pkginfo_delete_certinfo(db, pkgid)) {
728                 _LOGE("failed to delete certinfo of %s, rollback now", pkgid);
729                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
730                 sqlite3_close_v2(db);
731                 return PMINFO_R_ERROR;
732         }
733
734         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
735         if (ret != SQLITE_OK) {
736                 _LOGE("failed to commit transaction, rollback now");
737                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
738                 sqlite3_close_v2(db);
739                 return PMINFO_R_ERROR;
740         }
741
742         sqlite3_close_v2(db);
743
744         return PMINFO_R_OK;
745 }
746
747 API int pkgmgrinfo_delete_certinfo(const char *pkgid)
748 {
749         return pkgmgrinfo_delete_usr_certinfo(pkgid, _getuid());
750 }
751