Fix static analysis issue
[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 "pkgmgr-info.h"
12 #include "pkgmgrinfo_debug.h"
13 #include "pkgmgrinfo_private.h"
14 #include "pkgmgr_parser.h"
15
16 typedef struct _pkgmgr_certinfo_x {
17         int for_all_users;
18         char *pkgid;
19         char *cert_value;
20         char *cert_info[MAX_CERT_TYPE]; /*certificate info*/
21         int cert_id[MAX_CERT_TYPE];             /*certificate ID in index table*/
22 } pkgmgr_certinfo_x;
23
24 typedef struct _pkgmgr_instcertinfo_x {
25         char *pkgid;
26         char *cert_info[MAX_CERT_TYPE]; /*certificate data*/
27         int is_new[MAX_CERT_TYPE];              /*whether already exist in table or not*/
28         int ref_count[MAX_CERT_TYPE];           /*reference count of certificate data*/
29         int cert_id[MAX_CERT_TYPE];             /*certificate ID in index table*/
30 } pkgmgr_instcertinfo_x;
31
32 typedef struct _pkgmgr_certindexinfo_x {
33         int cert_id;
34         int cert_ref_count;
35 } pkgmgr_certindexinfo_x;
36
37 typedef struct _pkgmgr_cert_x {
38         char *pkgid;
39         int cert_id;
40 } pkgmgr_cert_x;
41
42 API int pkgmgrinfo_pkginfo_create_certinfo(pkgmgrinfo_certinfo_h *handle)
43 {
44         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
45         pkgmgr_certinfo_x *certinfo = NULL;
46         certinfo = calloc(1, sizeof(pkgmgr_certinfo_x));
47         *handle = NULL;
48         retvm_if(certinfo == NULL, PMINFO_R_ERROR, "Malloc Failed\n");
49         *handle = (void *)certinfo;
50         return PMINFO_R_OK;
51 }
52
53 static int _pkginfo_compare_certinfo(sqlite3 *db, const char *l_pkgid,
54                 const char *r_pkgid,
55                 pkgmgrinfo_cert_compare_result_type_e *result)
56 {
57         static const char query[] =
58                 "SELECT COALESCE(author_signer_cert, -1) FROM package_cert_info "
59                 "WHERE package=?";
60         int ret;
61         sqlite3_stmt *stmt;
62         const char *pkgid[2];
63         int certid[2] = {-1, -1};
64         int i;
65
66         pkgid[0] = l_pkgid;
67         pkgid[1] = r_pkgid;
68
69         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
70         if (ret != SQLITE_OK) {
71                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
72                 return PMINFO_R_ERROR;
73         }
74
75         for (i = 0; i < 2; i++) {
76                 ret = sqlite3_bind_text(stmt, 1, pkgid[i], -1, SQLITE_STATIC);
77                 if (ret != SQLITE_OK) {
78                         _LOGE("bind error: %s", sqlite3_errmsg(db));
79                         sqlite3_finalize(stmt);
80                         return PMINFO_R_ERROR;
81                 }
82
83                 ret = sqlite3_step(stmt);
84                 if (ret == SQLITE_ROW) {
85                         _save_column_int(stmt, 0, &certid[i]);
86                 } else if (ret != SQLITE_DONE) {
87                         _LOGE("step error: %s", sqlite3_errmsg(db));
88                         sqlite3_finalize(stmt);
89                         return PMINFO_R_ERROR;
90                 }
91
92                 sqlite3_reset(stmt);
93                 sqlite3_clear_bindings(stmt);
94         }
95
96         if (certid[0] == -1 && certid[1] == -1)
97                 *result = PMINFO_CERT_COMPARE_BOTH_NO_CERT;
98         else if (certid[0] == -1)
99                 *result = PMINFO_CERT_COMPARE_LHS_NO_CERT;
100         else if (certid[1] == -1)
101                 *result = PMINFO_CERT_COMPARE_RHS_NO_CERT;
102         else if (certid[0] == certid[1])
103                 *result = PMINFO_CERT_COMPARE_MATCH;
104         else
105                 *result = PMINFO_CERT_COMPARE_MISMATCH;
106
107         sqlite3_finalize(stmt);
108         return PMINFO_R_OK;
109 }
110
111 API int pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(const char *lhs_package_id,
112                 const char *rhs_package_id, uid_t uid,
113                 pkgmgrinfo_cert_compare_result_type_e *compare_result)
114 {
115         int ret;
116         sqlite3 *db;
117         char *dbpath;
118
119         if (lhs_package_id == NULL || rhs_package_id == NULL ||
120                         compare_result == NULL) {
121                 _LOGE("invalid parameter");
122                 return PMINFO_R_EINVAL;
123         }
124
125         /* open unified global cert db */
126         dbpath = getUserPkgCertDBPath();
127         if (dbpath == NULL)
128                 return PMINFO_R_ERROR;
129
130         ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
131         if (ret != SQLITE_OK) {
132                 _LOGE("failed to open db: %d", ret);
133                 free(dbpath);
134                 return PMINFO_R_ERROR;
135         }
136         free(dbpath);
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         char *dbpath;
163         sqlite3_stmt *stmt;
164
165         dbpath = getUserPkgParserDBPathUID(uid);
166         if (dbpath == NULL)
167                 return PMINFO_R_ERROR;
168
169         ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
170         if (ret != SQLITE_OK) {
171                 _LOGE("failed to open db: %d", ret);
172                 free(dbpath);
173                 return PMINFO_R_ERROR;
174         }
175         free(dbpath);
176
177         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
178         if (ret != SQLITE_OK) {
179                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
180                 sqlite3_close_v2(db);
181                 return PMINFO_R_ERROR;
182         }
183
184         ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_STATIC);
185         if (ret != SQLITE_OK) {
186                 _LOGE("bind error: %s", sqlite3_errmsg(db));
187                 sqlite3_finalize(stmt);
188                 sqlite3_close_v2(db);
189                 return PMINFO_R_ERROR;
190         }
191
192         ret = sqlite3_step(stmt);
193         if (ret == SQLITE_ROW) {
194                 _save_column_str(stmt, 0, pkgid);
195                 ret = PMINFO_R_OK;
196         } else if (ret == SQLITE_DONE) {
197                 _LOGI("cannot find pkgid of app %s for uid %d", appid, (int)uid);
198                 ret = PMINFO_R_ENOENT;
199         } else {
200                 _LOGE("step error: %s", sqlite3_errmsg(db));
201                 ret = PMINFO_R_ERROR;
202         }
203
204         sqlite3_finalize(stmt);
205         sqlite3_close_v2(db);
206
207         return ret;
208 }
209
210 API int pkgmgrinfo_pkginfo_compare_usr_app_cert_info(const char *lhs_app_id,
211                 const char *rhs_app_id, uid_t uid,
212                 pkgmgrinfo_cert_compare_result_type_e *compare_result)
213 {
214         int ret;
215         char *l_pkgid = NULL;
216         char *r_pkgid = NULL;
217
218         if (lhs_app_id == NULL || rhs_app_id == NULL ||
219                         compare_result == NULL) {
220                 _LOGE("invalid parameter");
221                 return PMINFO_R_EINVAL;
222         }
223
224         ret = _pkginfo_get_pkgid_from_appid(uid, lhs_app_id, &l_pkgid);
225         if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
226                 ret = _pkginfo_get_pkgid_from_appid(GLOBAL_USER, lhs_app_id,
227                                 &l_pkgid);
228
229         if (ret != PMINFO_R_OK)
230                 return ret;
231
232         ret = _pkginfo_get_pkgid_from_appid(uid, rhs_app_id, &r_pkgid);
233         if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
234                 ret = _pkginfo_get_pkgid_from_appid(GLOBAL_USER, rhs_app_id,
235                                 &r_pkgid);
236
237         if (ret != PMINFO_R_OK) {
238                 free(l_pkgid);
239                 return ret;
240         }
241
242         ret = pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(l_pkgid, r_pkgid,
243                         uid, compare_result);
244
245         free(l_pkgid);
246         free(r_pkgid);
247
248         return ret;
249 }
250
251 API int pkgmgrinfo_pkginfo_compare_app_cert_info(const char *lhs_app_id,
252                 const char *rhs_app_id,
253                 pkgmgrinfo_cert_compare_result_type_e *compare_result)
254 {
255         return pkgmgrinfo_pkginfo_compare_usr_app_cert_info(lhs_app_id,
256                         rhs_app_id, _getuid(), compare_result);
257 }
258
259 static int _pkginfo_get_cert(sqlite3 *db, int cert_id[],
260                 char *cert_info[])
261 {
262         static const char query[] =
263                 "SELECT cert_info FROM package_cert_index_info WHERE cert_id=?";
264         int ret;
265         sqlite3_stmt *stmt;
266         int i;
267
268         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
269         if (ret != SQLITE_OK) {
270                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
271                 return PMINFO_R_ERROR;
272         }
273
274         for (i = 0; i < MAX_CERT_TYPE; i++) {
275                 ret = sqlite3_bind_int(stmt, 1, cert_id[i]);
276                 if (ret != SQLITE_OK) {
277                         sqlite3_finalize(stmt);
278                         _LOGE("bind failed: %s", sqlite3_errmsg(db));
279                         return PMINFO_R_ERROR;
280                 }
281
282                 ret = sqlite3_step(stmt);
283                 if (ret == SQLITE_DONE) {
284                         sqlite3_reset(stmt);
285                         sqlite3_clear_bindings(stmt);
286                         continue;
287                 } else if (ret != SQLITE_ROW) {
288                         _LOGE("step failed: %s", sqlite3_errmsg(db));
289                         sqlite3_finalize(stmt);
290                         return PMINFO_R_ERROR;
291                 }
292
293                 _save_column_str(stmt, 0, &cert_info[i]);
294                 sqlite3_reset(stmt);
295                 sqlite3_clear_bindings(stmt);
296         }
297
298         sqlite3_finalize(stmt);
299
300         return PMINFO_R_OK;
301 }
302
303 static int _pkginfo_get_certid(sqlite3 *db, const char *pkgid, int cert_id[])
304 {
305         static const char query[] =
306                 "SELECT author_root_cert, author_im_cert, author_signer_cert, "
307                 "dist_root_cert, dist_im_cert, dist_signer_cert, "
308                 "dist2_root_cert, dist2_im_cert, dist2_signer_cert "
309                 "FROM package_cert_info WHERE package=?";
310         int ret;
311         sqlite3_stmt *stmt;
312         int idx;
313
314         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
315         if (ret != SQLITE_OK) {
316                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
317                 return PMINFO_R_ERROR;
318         }
319
320         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
321         if (ret != SQLITE_OK) {
322                 _LOGE("bind failed: %s", sqlite3_errmsg(db));
323                 sqlite3_finalize(stmt);
324                 return PMINFO_R_ERROR;
325         }
326
327         ret = sqlite3_step(stmt);
328         if (ret == SQLITE_DONE) {
329                 sqlite3_finalize(stmt);
330                 return PMINFO_R_ENOENT;
331         } else if (ret != SQLITE_ROW) {
332                 _LOGE("step failed: %s", sqlite3_errmsg(db));
333                 sqlite3_finalize(stmt);
334                 return PMINFO_R_ERROR;
335         }
336
337         idx = 0;
338         _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_ROOT_CERT]);
339         _save_column_int(stmt, idx++,
340                         &cert_id[PMINFO_AUTHOR_INTERMEDIATE_CERT]);
341         _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_SIGNER_CERT]);
342         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_ROOT_CERT]);
343         _save_column_int(stmt, idx++,
344                         &cert_id[PMINFO_DISTRIBUTOR_INTERMEDIATE_CERT]);
345         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_SIGNER_CERT]);
346         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR2_ROOT_CERT]);
347         _save_column_int(stmt, idx++,
348                         &cert_id[PMINFO_DISTRIBUTOR2_INTERMEDIATE_CERT]);
349         _save_column_int(stmt, idx++,
350                         &cert_id[PMINFO_DISTRIBUTOR2_SIGNER_CERT]);
351
352         sqlite3_finalize(stmt);
353
354         return PMINFO_R_OK;
355 }
356
357 static int _pkginfo_get_certinfo(const char *pkgid, pkgmgr_certinfo_x *info)
358 {
359         int ret;
360         sqlite3 *db;
361         char *dbpath;
362
363         /* open unified global cert db */
364         dbpath = getUserPkgCertDBPath();
365         if (dbpath == NULL)
366                 return PMINFO_R_ERROR;
367
368         ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
369         if (ret != SQLITE_OK) {
370                 _LOGE("failed to open db: %d", ret);
371                 free(dbpath);
372                 return PMINFO_R_ERROR;
373         }
374         free(dbpath);
375
376         ret = _pkginfo_get_certid(db, pkgid, info->cert_id);
377         if (ret != PMINFO_R_OK) {
378                 sqlite3_close_v2(db);
379                 return ret;
380         }
381
382         ret = _pkginfo_get_cert(db, info->cert_id, info->cert_info);
383         if (ret != PMINFO_R_OK) {
384                 sqlite3_close_v2(db);
385                 return ret;
386         }
387
388         sqlite3_close_v2(db);
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         if (certinfo->cert_info[cert_type])
466                 free(certinfo->cert_info[cert_type]);
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                 ret = sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
587                 if (ret != SQLITE_OK) {
588                         _LOGE("bind failed: %s", sqlite3_errmsg(db));
589                         sqlite3_finalize(stmt);
590                         return PMINFO_R_ERROR;
591                 }
592                 ret = sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
593                 if (ret != SQLITE_OK) {
594                         _LOGE("bind failed: %s", sqlite3_errmsg(db));
595                         sqlite3_finalize(stmt);
596                         return PMINFO_R_ERROR;
597                 }
598                 ret = sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
599                 if (ret != SQLITE_OK) {
600                         _LOGE("bind failed: %s", sqlite3_errmsg(db));
601                         sqlite3_finalize(stmt);
602                         return PMINFO_R_ERROR;
603                 }
604
605                 ret = sqlite3_step(stmt);
606                 if (ret != SQLITE_DONE) {
607                         _LOGE("step failed: %s", sqlite3_errmsg(db));
608                         sqlite3_finalize(stmt);
609                         return PMINFO_R_ERROR;
610                 }
611
612                 sqlite3_reset(stmt);
613                 sqlite3_clear_bindings(stmt);
614         }
615
616         sqlite3_finalize(stmt);
617
618         return PMINFO_R_OK;
619 }
620
621 API int pkgmgrinfo_save_certinfo(const char *pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid)
622 {
623         int ret;
624         sqlite3 *db;
625         char *dbpath;
626         pkgmgr_instcertinfo_x *info = (pkgmgr_instcertinfo_x *)handle;
627
628         if (pkgid == NULL || handle == NULL) {
629                 _LOGE("invalid parameter");
630                 return PMINFO_R_EINVAL;
631         }
632
633         _check_create_cert_db();
634
635         /* open unified global cert db */
636         dbpath = getUserPkgCertDBPath();
637         if (dbpath == NULL)
638                 return PMINFO_R_ERROR;
639
640         ret = __open_db(dbpath, &db, SQLITE_OPEN_READWRITE);
641         if (ret != SQLITE_OK) {
642                 _LOGE("failed to open db: %d", ret);
643                 free(dbpath);
644                 return PMINFO_R_ERROR;
645         }
646         free(dbpath);
647
648         ret = sqlite3_exec(db, "BEGIN DEFERRED", NULL, NULL, NULL);
649         if (ret != SQLITE_OK) {
650                 _LOGE("failed to begin transaction");
651                 sqlite3_close_v2(db);
652                 return PMINFO_R_ERROR;
653         }
654
655         if (_pkginfo_save_cert_index_info(db, info->cert_info)) {
656                 _LOGE("failed to save cert index info, rollback now");
657                 ret = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
658                 if (ret != SQLITE_OK)
659                         LOGE("Rollback is failed. error(%s)", sqlite3_errmsg(db));
660                 sqlite3_close_v2(db);
661                 return PMINFO_R_ERROR;
662         }
663
664         if (_pkginfo_save_cert_info(db, pkgid, info->cert_info)) {
665                 _LOGE("failed to save cert info, rollback now");
666                 ret = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
667                 if (ret != SQLITE_OK)
668                         LOGE("Rollback is failed. error(%s)", sqlite3_errmsg(db));
669                 sqlite3_close_v2(db);
670                 return PMINFO_R_ERROR;
671         }
672
673         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
674         if (ret != SQLITE_OK) {
675                 _LOGE("failed to commit transaction, rollback now");
676                 ret = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
677                 if (ret != SQLITE_OK)
678                         LOGE("Rollback is failed. error(%s)", sqlite3_errmsg(db));
679                 sqlite3_close_v2(db);
680                 return PMINFO_R_ERROR;
681         }
682
683         sqlite3_close_v2(db);
684
685         return PMINFO_R_OK;
686 }
687
688 API int pkgmgrinfo_destroy_certinfo_set_handle(pkgmgrinfo_instcertinfo_h handle)
689 {
690         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
691         int i = 0;
692         pkgmgr_instcertinfo_x *certinfo = NULL;
693         certinfo = (pkgmgr_instcertinfo_x *)handle;
694         if (certinfo->pkgid) {
695                 free(certinfo->pkgid);
696                 certinfo->pkgid = NULL;
697         }
698         for (i = 0; i < MAX_CERT_TYPE; i++) {
699                 if ((certinfo->cert_info)[i]) {
700                         free((certinfo->cert_info)[i]);
701                         (certinfo->cert_info)[i] = NULL;
702                 }
703         }
704         free(certinfo);
705         certinfo = NULL;
706         return PMINFO_R_OK;
707 }
708
709 static int _pkginfo_delete_certinfo(sqlite3 *db, const char *pkgid)
710 {
711         static const char query[] =
712                 "UPDATE package_cert_info "
713                 "SET package_count = package_count - 1 "
714                 "WHERE package=?";
715         int ret;
716         sqlite3_stmt *stmt;
717
718         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
719         if (ret != SQLITE_OK) {
720                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
721                 return PMINFO_R_ERROR;
722         }
723
724         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
725         if (ret != SQLITE_OK) {
726                 _LOGE("bind error: %s", sqlite3_errmsg(db));
727                 sqlite3_finalize(stmt);
728                 return PMINFO_R_ERROR;
729         }
730
731         ret = sqlite3_step(stmt);
732         sqlite3_finalize(stmt);
733         if (ret != SQLITE_DONE) {
734                 _LOGE("step error: %s", sqlite3_errmsg(db));
735                 return PMINFO_R_ERROR;
736         }
737
738         return PMINFO_R_OK;
739 }
740
741 API int pkgmgrinfo_delete_usr_certinfo(const char *pkgid, uid_t uid)
742 {
743         int ret;
744         sqlite3 *db;
745         char *dbpath;
746
747         if (pkgid == NULL) {
748                 _LOGE("invalid parameter");
749                 return PMINFO_R_EINVAL;
750         }
751
752         /* open unified global cert db */
753         dbpath = getUserPkgCertDBPath();
754         if (dbpath == NULL)
755                 return PMINFO_R_ERROR;
756
757         ret = __open_db(dbpath, &db, SQLITE_OPEN_READWRITE);
758         if (ret != SQLITE_OK) {
759                 _LOGE("failed to open db: %d", ret);
760                 free(dbpath);
761                 return PMINFO_R_ERROR;
762         }
763         free(dbpath);
764
765         ret = sqlite3_exec(db, "BEGIN DEFERRED", NULL, NULL, NULL);
766         if (ret != SQLITE_OK) {
767                 _LOGE("failed to begin transaction");
768                 sqlite3_close_v2(db);
769                 return PMINFO_R_ERROR;
770         }
771
772         if (_pkginfo_delete_certinfo(db, pkgid)) {
773                 _LOGE("failed to delete certinfo of %s, rollback now", pkgid);
774                 ret = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
775                 if (ret != SQLITE_OK)
776                         LOGE("Rollback is failed. error(%s)", sqlite3_errmsg(db));
777                 sqlite3_close_v2(db);
778                 return PMINFO_R_ERROR;
779         }
780
781         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
782         if (ret != SQLITE_OK) {
783                 _LOGE("failed to commit transaction, rollback now");
784                 ret = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
785                 if (ret != SQLITE_OK)
786                         LOGE("Rollback is failed. error(%s)", sqlite3_errmsg(db));
787                 sqlite3_close_v2(db);
788                 return PMINFO_R_ERROR;
789         }
790
791         sqlite3_close_v2(db);
792
793         return PMINFO_R_OK;
794 }
795
796 API int pkgmgrinfo_delete_certinfo(const char *pkgid)
797 {
798         return pkgmgrinfo_delete_usr_certinfo(pkgid, _getuid());
799 }
800