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