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