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