fix to return -1 when cert value is not exists
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_certinfo.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdbool.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7
8 #include <sqlite3.h>
9 #include <glib.h>
10
11 #include <db-util.h>
12
13 #include "pkgmgr-info.h"
14 #include "pkgmgrinfo_debug.h"
15 #include "pkgmgrinfo_private.h"
16 #include "pkgmgr_parser.h"
17
18 typedef struct _pkgmgr_certinfo_x {
19         int for_all_users;
20         char *pkgid;
21         char *cert_value;
22         char *cert_info[MAX_CERT_TYPE]; /*certificate info*/
23         int cert_id[MAX_CERT_TYPE];             /*certificate ID in index table*/
24 } pkgmgr_certinfo_x;
25
26 typedef struct _pkgmgr_instcertinfo_x {
27         char *pkgid;
28         char *cert_info[MAX_CERT_TYPE]; /*certificate data*/
29         int is_new[MAX_CERT_TYPE];              /*whether already exist in table or not*/
30         int ref_count[MAX_CERT_TYPE];           /*reference count of certificate data*/
31         int cert_id[MAX_CERT_TYPE];             /*certificate ID in index table*/
32 } pkgmgr_instcertinfo_x;
33
34 typedef struct _pkgmgr_certindexinfo_x {
35         int cert_id;
36         int cert_ref_count;
37 } pkgmgr_certindexinfo_x;
38
39 typedef struct _pkgmgr_cert_x {
40         char *pkgid;
41         int cert_id;
42 } pkgmgr_cert_x;
43
44 API int pkgmgrinfo_pkginfo_create_certinfo(pkgmgrinfo_certinfo_h *handle)
45 {
46         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
47         pkgmgr_certinfo_x *certinfo = NULL;
48         certinfo = calloc(1, sizeof(pkgmgr_certinfo_x));
49         *handle = NULL;
50         retvm_if(certinfo == NULL, PMINFO_R_ERROR, "Malloc Failed\n");
51         *handle = (void *)certinfo;
52         return PMINFO_R_OK;
53 }
54
55 static int _pkginfo_compare_certinfo(sqlite3 *db, const char *l_pkgid,
56                 const char *r_pkgid,
57                 pkgmgrinfo_cert_compare_result_type_e *result)
58 {
59         static const char query[] =
60                 "SELECT COALESCE(author_signer_cert, -1) FROM package_cert_info "
61                 "WHERE package=?";
62         int ret;
63         sqlite3_stmt *stmt;
64         const char *pkgid[2];
65         int certid[2] = {-1, -1};
66         int i;
67
68         pkgid[0] = l_pkgid;
69         pkgid[1] = r_pkgid;
70
71         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
72         if (ret != SQLITE_OK) {
73                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
74                 return PMINFO_R_ERROR;
75         }
76
77         for (i = 0; i < 2; i++) {
78                 ret = sqlite3_bind_text(stmt, 1, pkgid[i], -1, SQLITE_STATIC);
79                 if (ret != SQLITE_OK) {
80                         _LOGE("bind error: %s", sqlite3_errmsg(db));
81                         sqlite3_finalize(stmt);
82                         return PMINFO_R_ERROR;
83                 }
84
85                 ret = sqlite3_step(stmt);
86                 if (ret == SQLITE_ROW) {
87                         _save_column_int(stmt, 0, &certid[i]);
88                 } else if (ret != SQLITE_DONE) {
89                         _LOGE("step error: %s", sqlite3_errmsg(db));
90                         sqlite3_finalize(stmt);
91                         return PMINFO_R_ERROR;
92                 }
93
94                 sqlite3_reset(stmt);
95                 sqlite3_clear_bindings(stmt);
96         }
97
98         if (certid[0] == -1 && certid[1] == -1)
99                 *result = PMINFO_CERT_COMPARE_BOTH_NO_CERT;
100         else if (certid[0] == -1)
101                 *result = PMINFO_CERT_COMPARE_LHS_NO_CERT;
102         else if (certid[1] == -1)
103                 *result = PMINFO_CERT_COMPARE_RHS_NO_CERT;
104         else if (certid[0] == certid[1])
105                 *result = PMINFO_CERT_COMPARE_MATCH;
106         else
107                 *result = PMINFO_CERT_COMPARE_MISMATCH;
108
109 catch:
110         sqlite3_finalize(stmt);
111
112         return PMINFO_R_OK;
113 }
114
115 API int pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(const char *lhs_package_id,
116                 const char *rhs_package_id, uid_t uid,
117                 pkgmgrinfo_cert_compare_result_type_e *compare_result)
118 {
119         int ret;
120         sqlite3 *db;
121         const char *dbpath;
122
123         if (lhs_package_id == NULL || rhs_package_id == NULL ||
124                         compare_result == NULL) {
125                 _LOGE("invalid parameter");
126                 return PMINFO_R_EINVAL;
127         }
128
129         /* open unified global cert db */
130         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
131         if (dbpath == NULL)
132                 return PMINFO_R_ERROR;
133
134         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
135         if (ret != SQLITE_OK) {
136                 _LOGE("failed to open db: %d", ret);
137                 return PMINFO_R_ERROR;
138         }
139
140         if (_pkginfo_compare_certinfo(db, lhs_package_id, rhs_package_id,
141                                 compare_result)) {
142                 _LOGE("failed to compare certinfo");
143                 sqlite3_close_v2(db);
144                 return PMINFO_R_ERROR;
145         }
146
147         sqlite3_close_v2(db);
148
149         return PMINFO_R_OK;
150 }
151
152 API int pkgmgrinfo_pkginfo_compare_pkg_cert_info(const char *lhs_package_id, const char *rhs_package_id, pkgmgrinfo_cert_compare_result_type_e *compare_result)
153 {
154         return pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(lhs_package_id, rhs_package_id, _getuid(), compare_result);
155 }
156
157 static int _pkginfo_get_pkgid_from_appid(uid_t uid, const char *appid,
158                 char **pkgid)
159 {
160         static const char query[] =
161                 "SELECT package FROM package_app_info WHERE app_id=?";
162         int ret;
163         sqlite3 *db;
164         const char *dbpath;
165         sqlite3_stmt *stmt;
166
167         dbpath = getUserPkgParserDBPathUID(uid);
168         if (dbpath == NULL)
169                 return PMINFO_R_ERROR;
170
171         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
172         if (ret != SQLITE_OK) {
173                 _LOGE("failed to open db: %d", ret);
174                 return PMINFO_R_ERROR;
175         }
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);
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         const char *dbpath;
362
363         /* open unified global cert db */
364         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
365         if (dbpath == NULL)
366                 return PMINFO_R_ERROR;
367
368         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
369         if (ret != SQLITE_OK) {
370                 _LOGE("failed to open db: %d", ret);
371                 return PMINFO_R_ERROR;
372         }
373
374         ret = _pkginfo_get_certid(db, pkgid, info->cert_id);
375         if (ret != PMINFO_R_OK) {
376                 sqlite3_close_v2(db);
377                 return ret;
378         }
379
380         ret = _pkginfo_get_cert(db, info->cert_id, info->cert_info);
381         if (ret != PMINFO_R_OK) {
382                 sqlite3_close_v2(db);
383                 return ret;
384         }
385
386         return PMINFO_R_OK;
387 }
388
389 API int pkgmgrinfo_pkginfo_load_certinfo(const char *pkgid, pkgmgrinfo_certinfo_h handle, uid_t uid)
390 {
391         int ret;
392         pkgmgr_certinfo_x *info = (pkgmgr_certinfo_x *)handle;
393
394         if (pkgid == NULL || handle == NULL) {
395                 _LOGE("invalid parameter");
396                 return PMINFO_R_EINVAL;
397         }
398
399         ret = _pkginfo_get_certinfo(pkgid, info);
400         if (ret != PMINFO_R_OK)
401                 _LOGE("failed to get certinfo of %s ", pkgid);
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_insert[] =
469                 "INSERT 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                 " (SELECT cert_id FROM package_cert_index_info"
475                 "  WHERE cert_info=?),"
476                 " (SELECT cert_id FROM package_cert_index_info"
477                 "  WHERE cert_info=?),"
478                 " (SELECT cert_id FROM package_cert_index_info"
479                 "  WHERE cert_info=?),"
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         static const char query_update[] =
493                 "UPDATE package_cert_info SET "
494                 " author_root_cert= "
495                 "  (SELECT cert_id FROM package_cert_index_info"
496                 "   WHERE cert_info=?),"
497                 " author_im_cert= "
498                 "  (SELECT cert_id FROM package_cert_index_info"
499                 "   WHERE cert_info=?),"
500                 " author_signer_cert= "
501                 "  (SELECT cert_id FROM package_cert_index_info"
502                 "   WHERE cert_info=?),"
503                 " dist_root_cert= "
504                 "  (SELECT cert_id FROM package_cert_index_info"
505                 "   WHERE cert_info=?),"
506                 " dist_im_cert= "
507                 "  (SELECT cert_id FROM package_cert_index_info"
508                 "   WHERE cert_info=?),"
509                 " dist_signer_cert= "
510                 "  (SELECT cert_id FROM package_cert_index_info"
511                 "   WHERE cert_info=?),"
512                 " dist2_root_cert= "
513                 "  (SELECT cert_id FROM package_cert_index_info"
514                 "   WHERE cert_info=?),"
515                 "dist2_im_cert= "
516                 "  (SELECT cert_id FROM package_cert_index_info"
517                 "   WHERE cert_info=?),"
518                 "dist2_signer_cert= "
519                 "  (SELECT cert_id FROM package_cert_index_info"
520                 "   WHERE cert_info=?) "
521                 "WHERE package=?";
522         int ret;
523         sqlite3_stmt *stmt;
524         int i;
525         int idx;
526
527         ret = sqlite3_prepare_v2(db, query_insert, strlen(query_insert),
528                         &stmt, NULL);
529         if (ret != SQLITE_OK) {
530                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
531                 return PMINFO_R_ERROR;
532         }
533
534         idx = 1;
535         sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_STATIC);
536         for (i = 0; i < MAX_CERT_TYPE; i++) {
537                 if (sqlite3_bind_text(stmt, idx++, cert_info[i], -1,
538                                 SQLITE_STATIC)) {
539                         _LOGE("bind error: %s", sqlite3_errmsg(db));
540                         sqlite3_finalize(stmt);
541                         return PMINFO_R_ERROR;
542                 }
543         }
544
545         ret = sqlite3_step(stmt);
546         sqlite3_finalize(stmt);
547         if (ret == SQLITE_CONSTRAINT) {
548                 ret = sqlite3_prepare_v2(db, query_update, strlen(query_update),
549                                 &stmt, NULL);
550                 if (ret != SQLITE_OK) {
551                         _LOGE("prepare error: %s", sqlite3_errmsg(db));
552                         return PMINFO_R_ERROR;
553                 }
554                 idx = 1;
555                 for (i = 0; i < MAX_CERT_TYPE; i++) {
556                         if (sqlite3_bind_text(stmt, idx++, cert_info[i], -1,
557                                         SQLITE_STATIC)) {
558                                 _LOGE("bind error: %s", sqlite3_errmsg(db));
559                                 sqlite3_finalize(stmt);
560                                 return PMINFO_R_ERROR;
561                         }
562                 }
563                 sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_STATIC);
564                 ret = sqlite3_step(stmt);
565                 sqlite3_finalize(stmt);
566         }
567
568         if (ret != SQLITE_DONE) {
569                 _LOGE("step error: %s", sqlite3_errmsg(db));
570                 return PMINFO_R_ERROR;
571         }
572
573         return PMINFO_R_OK;
574 }
575
576 static int _pkginfo_save_cert_index_info(sqlite3 *db, char *cert_info[])
577 {
578         static const char query[] =
579                 "INSERT OR REPLACE INTO package_cert_index_info "
580                 "(cert_info, cert_id, cert_ref_count) "
581                 "VALUES ( "
582                 " ?, "
583                 " (SELECT cert_id FROM package_cert_index_info "
584                 "  WHERE cert_info=?), "
585                 " COALESCE( "
586                 "  ((SELECT cert_ref_count FROM package_cert_index_info "
587                 "    WHERE cert_info=?) + 1), 1))";
588         int ret;
589         sqlite3_stmt *stmt;
590         int i;
591         int idx;
592
593         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
594         if (ret != SQLITE_OK) {
595                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
596                 return PMINFO_R_ERROR;
597         }
598
599         for (i = 0; i < MAX_CERT_TYPE; i++) {
600                 if (cert_info[i] == NULL)
601                         continue;
602                 idx = 1;
603                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
604                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
605                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
606
607                 ret = sqlite3_step(stmt);
608                 if (ret != SQLITE_DONE) {
609                         _LOGE("step failed: %s", sqlite3_errmsg(db));
610                         sqlite3_finalize(stmt);
611                         return PMINFO_R_ERROR;
612                 }
613
614                 sqlite3_reset(stmt);
615                 sqlite3_clear_bindings(stmt);
616         }
617
618         sqlite3_finalize(stmt);
619
620         return PMINFO_R_OK;
621 }
622
623 API int pkgmgrinfo_save_certinfo(const char *pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid)
624 {
625         int ret;
626         sqlite3 *db;
627         const char *dbpath;
628         pkgmgr_instcertinfo_x *info = (pkgmgr_instcertinfo_x *)handle;
629
630         if (pkgid == NULL || handle == NULL) {
631                 _LOGE("invalid parameter");
632                 return PMINFO_R_EINVAL;
633         }
634
635         /* open unified global cert db */
636         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
637         if (dbpath == NULL)
638                 return PMINFO_R_ERROR;
639
640         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READWRITE, NULL);
641         if (ret != SQLITE_OK) {
642                 _LOGE("failed to open db: %d", ret);
643                 return PMINFO_R_ERROR;
644         }
645
646         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
647         if (ret != SQLITE_OK) {
648                 _LOGE("failed to begin transaction");
649                 sqlite3_close_v2(db);
650                 return PMINFO_R_ERROR;
651         }
652
653         _check_create_cert_db(db);
654
655         if (_pkginfo_save_cert_index_info(db, info->cert_info)) {
656                 _LOGE("failed to save cert index info, rollback now");
657                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
658                 sqlite3_close_v2(db);
659                 return PMINFO_R_ERROR;
660         }
661         if (_pkginfo_save_cert_info(db, pkgid, info->cert_info)) {
662                 _LOGE("failed to save cert info, rollback now");
663                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
664                 sqlite3_close_v2(db);
665                 return PMINFO_R_ERROR;
666         }
667
668         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
669         if (ret != SQLITE_OK) {
670                 _LOGE("failed to commit transaction, rollback now");
671                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
672                 sqlite3_close_v2(db);
673                 return PMINFO_R_ERROR;
674         }
675
676         sqlite3_close_v2(db);
677
678         return PMINFO_R_OK;
679 }
680
681 API int pkgmgrinfo_destroy_certinfo_set_handle(pkgmgrinfo_instcertinfo_h handle)
682 {
683         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
684         int i = 0;
685         pkgmgr_instcertinfo_x *certinfo = NULL;
686         certinfo = (pkgmgr_instcertinfo_x *)handle;
687         if (certinfo->pkgid) {
688                 free(certinfo->pkgid);
689                 certinfo->pkgid = NULL;
690         }
691         for (i = 0; i < MAX_CERT_TYPE; i++) {
692                 if ((certinfo->cert_info)[i]) {
693                         free((certinfo->cert_info)[i]);
694                         (certinfo->cert_info)[i] = NULL;
695                 }
696         }
697         free(certinfo);
698         certinfo = NULL;
699         return PMINFO_R_OK;
700 }
701
702 static int _pkginfo_delete_certinfo(sqlite3 *db, const char *pkgid)
703 {
704         static const char query[] =
705                 "DELETE FROM package_cert_info WHERE package=?";
706         int ret;
707         sqlite3_stmt *stmt;
708
709         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
710         if (ret != SQLITE_OK) {
711                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
712                 return PMINFO_R_ERROR;
713         }
714
715         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
716         if (ret != SQLITE_OK) {
717                 _LOGE("bind error: %s", sqlite3_errmsg(db));
718                 sqlite3_finalize(stmt);
719                 return PMINFO_R_ERROR;
720         }
721
722         ret = sqlite3_step(stmt);
723         sqlite3_finalize(stmt);
724         if (ret != SQLITE_DONE) {
725                 _LOGE("step error: %s", sqlite3_errmsg(db));
726                 return PMINFO_R_ERROR;
727         }
728
729         return PMINFO_R_OK;
730 }
731
732 API int pkgmgrinfo_delete_usr_certinfo(const char *pkgid, uid_t uid)
733 {
734         int ret;
735         sqlite3 *db;
736         const char *dbpath;
737
738         if (pkgid == NULL) {
739                 _LOGE("invalid parameter");
740                 return PMINFO_R_EINVAL;
741         }
742
743         /* open unified global cert db */
744         dbpath = getUserPkgCertDBPathUID(GLOBAL_USER);
745         if (dbpath == NULL)
746                 return PMINFO_R_ERROR;
747
748         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READWRITE, NULL);
749         if (ret != SQLITE_OK) {
750                 _LOGE("failed to open db: %d", ret);
751                 return PMINFO_R_ERROR;
752         }
753
754         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
755         if (ret != SQLITE_OK) {
756                 _LOGE("failed to begin transaction");
757                 sqlite3_close_v2(db);
758                 return PMINFO_R_ERROR;
759         }
760
761         if (_pkginfo_delete_certinfo(db, pkgid)) {
762                 _LOGE("failed to delete certinfo of %s, rollback now", pkgid);
763                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
764                 sqlite3_close_v2(db);
765                 return PMINFO_R_ERROR;
766         }
767
768         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
769         if (ret != SQLITE_OK) {
770                 _LOGE("failed to commit transaction, rollback now");
771                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
772                 sqlite3_close_v2(db);
773                 return PMINFO_R_ERROR;
774         }
775
776         sqlite3_close_v2(db);
777
778         return PMINFO_R_OK;
779 }
780
781 API int pkgmgrinfo_delete_certinfo(const char *pkgid)
782 {
783         return pkgmgrinfo_delete_usr_certinfo(pkgid, _getuid());
784 }
785