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