Fix static analyzer issues
[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         ret = sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_STATIC);
516         if (ret != SQLITE_OK) {
517                 _LOGE("bind failed: %s", sqlite3_errmsg(db));
518                 sqlite3_finalize(stmt);
519                 return PMINFO_R_ERROR;
520         }
521
522         for (i = 0; i < MAX_CERT_TYPE; i++) {
523                 if (sqlite3_bind_text(stmt, idx++, cert_info[i], -1,
524                                 SQLITE_STATIC)) {
525                         _LOGE("bind error: %s", sqlite3_errmsg(db));
526                         sqlite3_finalize(stmt);
527                         return PMINFO_R_ERROR;
528                 }
529         }
530
531         ret = sqlite3_step(stmt);
532         sqlite3_finalize(stmt);
533         if (ret == SQLITE_CONSTRAINT) {
534                 ret = sqlite3_prepare_v2(db, query_update, strlen(query_update),
535                                 &stmt, NULL);
536                 if (ret != SQLITE_OK) {
537                         _LOGE("prepare error: %s", sqlite3_errmsg(db));
538                         return PMINFO_R_ERROR;
539                 }
540
541                 if (sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC)) {
542                         _LOGE("bind error: %s", sqlite3_errmsg(db));
543                         sqlite3_finalize(stmt);
544                         return PMINFO_R_ERROR;
545                 }
546
547                 ret = sqlite3_step(stmt);
548                 sqlite3_finalize(stmt);
549         }
550
551         if (ret != SQLITE_DONE) {
552                 _LOGE("step error: %s", sqlite3_errmsg(db));
553                 return PMINFO_R_ERROR;
554         }
555
556         return PMINFO_R_OK;
557 }
558
559 static int _pkginfo_save_cert_index_info(sqlite3 *db, char *cert_info[])
560 {
561         static const char query[] =
562                 "INSERT OR REPLACE INTO package_cert_index_info "
563                 "(cert_info, cert_id, cert_ref_count) "
564                 "VALUES ( "
565                 " ?, "
566                 " (SELECT cert_id FROM package_cert_index_info "
567                 "  WHERE cert_info=?), "
568                 " COALESCE( "
569                 "  ((SELECT cert_ref_count FROM package_cert_index_info "
570                 "    WHERE cert_info=?) + 1), 1))";
571         int ret;
572         sqlite3_stmt *stmt;
573         int i;
574         int idx;
575
576         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
577         if (ret != SQLITE_OK) {
578                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
579                 return PMINFO_R_ERROR;
580         }
581
582         for (i = 0; i < MAX_CERT_TYPE; i++) {
583                 if (cert_info[i] == NULL)
584                         continue;
585                 idx = 1;
586                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
587                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
588                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
589
590                 ret = sqlite3_step(stmt);
591                 if (ret != SQLITE_DONE) {
592                         _LOGE("step failed: %s", sqlite3_errmsg(db));
593                         sqlite3_finalize(stmt);
594                         return PMINFO_R_ERROR;
595                 }
596
597                 sqlite3_reset(stmt);
598                 sqlite3_clear_bindings(stmt);
599         }
600
601         sqlite3_finalize(stmt);
602
603         return PMINFO_R_OK;
604 }
605
606 API int pkgmgrinfo_save_certinfo(const char *pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid)
607 {
608         int ret;
609         sqlite3 *db;
610         char *dbpath;
611         pkgmgr_instcertinfo_x *info = (pkgmgr_instcertinfo_x *)handle;
612
613         if (pkgid == NULL || handle == NULL) {
614                 _LOGE("invalid parameter");
615                 return PMINFO_R_EINVAL;
616         }
617
618         _check_create_cert_db();
619
620         /* open unified global cert db */
621         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
622         if (dbpath == NULL)
623                 return PMINFO_R_ERROR;
624
625         ret = __open_db(dbpath, &db, SQLITE_OPEN_READWRITE);
626         if (ret != SQLITE_OK) {
627                 _LOGE("failed to open db: %d", ret);
628                 free(dbpath);
629                 return PMINFO_R_ERROR;
630         }
631         free(dbpath);
632
633         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
634         if (ret != SQLITE_OK) {
635                 _LOGE("failed to begin transaction");
636                 sqlite3_close_v2(db);
637                 return PMINFO_R_ERROR;
638         }
639
640         if (_pkginfo_save_cert_index_info(db, info->cert_info)) {
641                 _LOGE("failed to save cert index info, rollback now");
642                 sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
643                 sqlite3_close_v2(db);
644                 return PMINFO_R_ERROR;
645         }
646
647         if (_pkginfo_save_cert_info(db, pkgid, info->cert_info)) {
648                 _LOGE("failed to save cert info, rollback now");
649                 sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
650                 sqlite3_close_v2(db);
651                 return PMINFO_R_ERROR;
652         }
653
654         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
655         if (ret != SQLITE_OK) {
656                 _LOGE("failed to commit transaction, rollback now");
657                 sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
658                 sqlite3_close_v2(db);
659                 return PMINFO_R_ERROR;
660         }
661
662         sqlite3_close_v2(db);
663
664         return PMINFO_R_OK;
665 }
666
667 API int pkgmgrinfo_destroy_certinfo_set_handle(pkgmgrinfo_instcertinfo_h handle)
668 {
669         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
670         int i = 0;
671         pkgmgr_instcertinfo_x *certinfo = NULL;
672         certinfo = (pkgmgr_instcertinfo_x *)handle;
673         if (certinfo->pkgid) {
674                 free(certinfo->pkgid);
675                 certinfo->pkgid = NULL;
676         }
677         for (i = 0; i < MAX_CERT_TYPE; i++) {
678                 if ((certinfo->cert_info)[i]) {
679                         free((certinfo->cert_info)[i]);
680                         (certinfo->cert_info)[i] = NULL;
681                 }
682         }
683         free(certinfo);
684         certinfo = NULL;
685         return PMINFO_R_OK;
686 }
687
688 static int _pkginfo_delete_certinfo(sqlite3 *db, const char *pkgid)
689 {
690         static const char query[] =
691                 "UPDATE package_cert_info "
692                 "SET package_count = package_count - 1 "
693                 "WHERE package=?";
694         int ret;
695         sqlite3_stmt *stmt;
696
697         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
698         if (ret != SQLITE_OK) {
699                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
700                 return PMINFO_R_ERROR;
701         }
702
703         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
704         if (ret != SQLITE_OK) {
705                 _LOGE("bind error: %s", sqlite3_errmsg(db));
706                 sqlite3_finalize(stmt);
707                 return PMINFO_R_ERROR;
708         }
709
710         ret = sqlite3_step(stmt);
711         sqlite3_finalize(stmt);
712         if (ret != SQLITE_DONE) {
713                 _LOGE("step error: %s", sqlite3_errmsg(db));
714                 return PMINFO_R_ERROR;
715         }
716
717         return PMINFO_R_OK;
718 }
719
720 API int pkgmgrinfo_delete_usr_certinfo(const char *pkgid, uid_t uid)
721 {
722         int ret;
723         sqlite3 *db;
724         char *dbpath;
725
726         if (pkgid == NULL) {
727                 _LOGE("invalid parameter");
728                 return PMINFO_R_EINVAL;
729         }
730
731         /* open unified global cert db */
732         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
733         if (dbpath == NULL)
734                 return PMINFO_R_ERROR;
735
736         ret = __open_db(dbpath, &db, SQLITE_OPEN_READWRITE);
737         if (ret != SQLITE_OK) {
738                 _LOGE("failed to open db: %d", ret);
739                 free(dbpath);
740                 return PMINFO_R_ERROR;
741         }
742         free(dbpath);
743
744         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
745         if (ret != SQLITE_OK) {
746                 _LOGE("failed to begin transaction");
747                 sqlite3_close_v2(db);
748                 return PMINFO_R_ERROR;
749         }
750
751         if (_pkginfo_delete_certinfo(db, pkgid)) {
752                 _LOGE("failed to delete certinfo of %s, rollback now", pkgid);
753                 sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
754                 sqlite3_close_v2(db);
755                 return PMINFO_R_ERROR;
756         }
757
758         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
759         if (ret != SQLITE_OK) {
760                 _LOGE("failed to commit transaction, rollback now");
761                 sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
762                 sqlite3_close_v2(db);
763                 return PMINFO_R_ERROR;
764         }
765
766         sqlite3_close_v2(db);
767
768         return PMINFO_R_OK;
769 }
770
771 API int pkgmgrinfo_delete_certinfo(const char *pkgid)
772 {
773         return pkgmgrinfo_delete_usr_certinfo(pkgid, _getuid());
774 }
775