Rewrite certinfo apis
[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 static int __cert_cb(void *data, int ncols, char **coltxt, char **colname)
45 {
46         pkgmgr_cert_x *info = (pkgmgr_cert_x *)data;
47         int i = 0;
48
49         for(i = 0; i < ncols; i++)
50         {
51                 if (strcmp(colname[i], "author_signer_cert") == 0) {
52                         if (coltxt[i])
53                                 info->cert_id = atoi(coltxt[i]);
54                         else
55                                 info->cert_id = 0;
56                 } else if (strcmp(colname[i], "package") == 0) {
57                         if (coltxt[i])
58                                 info->pkgid= strdup(coltxt[i]);
59                         else
60                                 info->pkgid = NULL;
61                 } else
62                         continue;
63         }
64         return 0;
65 }
66
67 static int __validate_cb(void *data, int ncols, char **coltxt, char **colname)
68 {
69         int *p = (int*)data;
70         *p = atoi(coltxt[0]);
71         return 0;
72 }
73
74 API int pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(const char *lhs_package_id, const char *rhs_package_id, uid_t uid, pkgmgrinfo_cert_compare_result_type_e *compare_result)
75 {
76         int ret = PMINFO_R_OK;
77         char query[MAX_QUERY_LEN] = {'\0'};
78         char *error_message = NULL;
79         sqlite3_stmt *stmt = NULL;
80         char *lhs_certinfo = NULL;
81         char *rhs_certinfo = NULL;
82         int lcert;
83         int rcert;
84         int exist;
85         int i;
86         int is_global = 0;
87         *compare_result = PMINFO_CERT_COMPARE_ERROR;
88
89         retvm_if(lhs_package_id == NULL, PMINFO_R_EINVAL, "lhs package ID is NULL");
90         retvm_if(rhs_package_id == NULL, PMINFO_R_EINVAL, "rhs package ID is NULL");
91         retvm_if(compare_result == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
92
93         ret = __open_cert_db(uid, true);
94         if (ret != 0) {
95                 ret = PMINFO_R_ERROR;
96                 goto err;
97         }
98         _check_create_cert_db(GET_DB(cert_db));
99         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_cert_info where package='%s')", lhs_package_id);
100         if (SQLITE_OK !=
101             sqlite3_exec(GET_DB(cert_db), query, __validate_cb, (void *)&exist, &error_message)) {
102                 _LOGE("Don't execute query = %s error message = %s\n", query,
103                        error_message);
104                 ret = PMINFO_R_ERROR;
105                 goto err;
106         }
107         lcert = exist;
108
109         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_cert_info where package='%s')", rhs_package_id);
110         if (SQLITE_OK !=
111                 sqlite3_exec(GET_DB(cert_db), query, __validate_cb, (void *)&exist, &error_message)) {
112                 _LOGE("Don't execute query = %s error message = %s\n", query,
113                            error_message);
114                 ret = PMINFO_R_ERROR;
115                 goto err;
116         }
117         rcert = exist;
118
119         if (uid == GLOBAL_USER || uid == ROOT_UID) {
120                 snprintf(query, MAX_QUERY_LEN, "select cert_info from package_cert_index_info where cert_id=(select author_signer_cert from package_cert_info where package=?)");
121                 is_global = 1;
122         } else
123                 snprintf(query, MAX_QUERY_LEN, "select cert_info from package_cert_index_info where cert_id=(select author_signer_cert from package_cert_info where package=?) and for_all_users=(select for_all_users from package_cert_info where package=?)");
124         if (SQLITE_OK != sqlite3_prepare_v2(GET_DB(cert_db), query, strlen(query), &stmt, NULL)) {
125                 _LOGE("sqlite3_prepare_v2 error: %s", sqlite3_errmsg(GET_DB(cert_db)));
126                 ret = PMINFO_R_ERROR;
127                 goto err;
128         }
129
130         for (i = 1; i <= 2 - is_global; i++) {
131                 if (SQLITE_OK != sqlite3_bind_text(stmt, i, lhs_package_id, -1, SQLITE_STATIC)) {
132                         _LOGE("sqlite3_bind_text error: %s", sqlite3_errmsg(GET_DB(cert_db)));
133                         ret = PMINFO_R_ERROR;
134                         goto err;
135                 }
136         }
137         if (SQLITE_ROW != sqlite3_step(stmt) || sqlite3_column_text(stmt, 0) == NULL) {
138                 _LOGE("sqlite3_step error: %s", sqlite3_errmsg(GET_DB(cert_db)));
139                 ret = PMINFO_R_ERROR;
140                 goto err;
141         }
142
143         lhs_certinfo = strdup((const char *)sqlite3_column_text(stmt, 0));
144         sqlite3_reset(stmt);
145         sqlite3_clear_bindings(stmt);
146
147         for (i = 1; i <= 2 - is_global; i++) {
148                 if (SQLITE_OK != sqlite3_bind_text(stmt, i, rhs_package_id, -1, SQLITE_STATIC)) {
149                         _LOGE("sqlite3_bind_text error: %s", sqlite3_errmsg(GET_DB(cert_db)));
150                         ret = PMINFO_R_ERROR;
151                         goto err;
152                 }
153         }
154         if (SQLITE_ROW != sqlite3_step(stmt) || sqlite3_column_text(stmt, 0) == NULL) {
155                 _LOGE("sqlite3_step error: %s", sqlite3_errmsg(GET_DB(cert_db)));
156                 ret = PMINFO_R_ERROR;
157                 goto err;
158         }
159
160         rhs_certinfo = strdup((const char *)sqlite3_column_text(stmt, 0));
161
162         if ((lcert == 0) || (rcert == 0)) {
163                 if ((lcert == 0) && (rcert == 0))
164                         *compare_result = PMINFO_CERT_COMPARE_BOTH_NO_CERT;
165                 else if (lcert == 0)
166                         *compare_result = PMINFO_CERT_COMPARE_LHS_NO_CERT;
167                 else if (rcert == 0)
168                         *compare_result = PMINFO_CERT_COMPARE_RHS_NO_CERT;
169         } else {
170                 if (lhs_certinfo && rhs_certinfo && !strcmp(lhs_certinfo, rhs_certinfo))
171                         *compare_result = PMINFO_CERT_COMPARE_MATCH;
172                 else
173                         *compare_result = PMINFO_CERT_COMPARE_MISMATCH;
174         }
175
176 err:
177         if (stmt)
178                 sqlite3_finalize(stmt);
179         if (lhs_certinfo)
180                 free(lhs_certinfo);
181         if (rhs_certinfo)
182                 free(rhs_certinfo);
183         sqlite3_free(error_message);
184         __close_cert_db();
185
186         return ret;
187 }
188
189 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)
190 {
191         return pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(lhs_package_id, rhs_package_id, GLOBAL_USER, compare_result);
192 }
193
194 API int pkgmgrinfo_pkginfo_compare_app_cert_info(const char *lhs_app_id, const char *rhs_app_id, pkgmgrinfo_cert_compare_result_type_e *compare_result)
195 {
196         int ret = PMINFO_R_OK;
197         char query[MAX_QUERY_LEN] = {'\0'};
198         char *error_message = NULL;
199         pkgmgr_cert_x *info;
200         int exist;
201         char *lpkgid = NULL;
202         char *rpkgid = NULL;
203         const char* user_pkg_parser = getUserPkgParserDBPath();
204
205         retvm_if(lhs_app_id == NULL, PMINFO_R_EINVAL, "lhs app ID is NULL");
206         retvm_if(rhs_app_id == NULL, PMINFO_R_EINVAL, "rhs app ID is NULL");
207         retvm_if(compare_result == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
208
209         info = (pkgmgr_cert_x *)calloc(1, sizeof(pkgmgr_cert_x));
210         retvm_if(info == NULL, PMINFO_R_ERROR, "Out of Memory!!!");
211
212         ret = db_util_open_with_options(user_pkg_parser, &GET_DB(manifest_db),
213                                         SQLITE_OPEN_READONLY, NULL);
214         if (ret != SQLITE_OK) {
215                 _LOGE("connect db [%s] failed!\n", user_pkg_parser);
216                 ret = PMINFO_R_ERROR;
217                 goto err;
218         }
219
220         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_app_info where app_id='%s')", lhs_app_id);
221         if (SQLITE_OK !=
222             sqlite3_exec(GET_DB(manifest_db), query, __validate_cb, (void *)&exist, &error_message)) {
223                 _LOGE("Don't execute query = %s error message = %s\n", query,
224                        error_message);
225                 ret = PMINFO_R_ERROR;
226                 goto err;
227         }
228
229         if (exist == 0) {
230                 lpkgid = NULL;
231         } else {
232                 snprintf(query, MAX_QUERY_LEN, "select package from package_app_info where app_id='%s' ", lhs_app_id);
233                 if (SQLITE_OK !=
234                         sqlite3_exec(GET_DB(manifest_db), query, __cert_cb, (void *)info, &error_message)) {
235                         _LOGE("Don't execute query = %s error message = %s\n", query,
236                                    error_message);
237                         ret = PMINFO_R_ERROR;
238                         goto err;
239                 }
240                 lpkgid = strdup(info->pkgid);
241                 if (lpkgid == NULL) {
242                         _LOGE("Out of Memory\n");
243                         ret = PMINFO_R_ERROR;
244                         goto err;
245                 }
246                 free(info->pkgid);
247                 info->pkgid = NULL;
248         }
249
250         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_app_info where app_id='%s')", rhs_app_id);
251         if (SQLITE_OK !=
252             sqlite3_exec(GET_DB(manifest_db), query, __validate_cb, (void *)&exist, &error_message)) {
253                 _LOGE("Don't execute query = %s error message = %s\n", query,
254                        error_message);
255                 ret = PMINFO_R_ERROR;
256                 goto err;
257         }
258
259         if (exist == 0) {
260                 rpkgid = NULL;
261         } else {
262                 snprintf(query, MAX_QUERY_LEN, "select package from package_app_info where app_id='%s' ", rhs_app_id);
263                 if (SQLITE_OK !=
264                         sqlite3_exec(GET_DB(manifest_db), query, __cert_cb, (void *)info, &error_message)) {
265                         _LOGE("Don't execute query = %s error message = %s\n", query,
266                                    error_message);
267                         ret = PMINFO_R_ERROR;
268                         goto err;
269                 }
270                 rpkgid = strdup(info->pkgid);
271                 if (rpkgid == NULL) {
272                         _LOGE("Out of Memory\n");
273                         ret = PMINFO_R_ERROR;
274                         goto err;
275                 }
276                 free(info->pkgid);
277                 info->pkgid = NULL;
278         }
279         ret = pkgmgrinfo_pkginfo_compare_pkg_cert_info(lpkgid, rpkgid, compare_result);
280  err:
281         if (error_message)
282                 sqlite3_free(error_message);
283         __close_manifest_db();
284         if (info) {
285                 if (info->pkgid) {
286                         free(info->pkgid);
287                         info->pkgid = NULL;
288                 }
289                 free(info);
290                 info = NULL;
291         }
292         if (lpkgid) {
293                 free(lpkgid);
294                 lpkgid = NULL;
295         }
296         if (rpkgid) {
297                 free(rpkgid);
298                 rpkgid = NULL;
299         }
300         return ret;
301 }
302
303 API int pkgmgrinfo_pkginfo_compare_usr_app_cert_info(const char *lhs_app_id, const char *rhs_app_id, uid_t uid, pkgmgrinfo_cert_compare_result_type_e *compare_result)
304 {
305         int ret = PMINFO_R_OK;
306         char query[MAX_QUERY_LEN] = {'\0'};
307         char *error_message = NULL;
308         pkgmgr_cert_x *info;
309         int exist;
310         char *lpkgid = NULL;
311         char *rpkgid = NULL;
312
313         retvm_if(lhs_app_id == NULL, PMINFO_R_EINVAL, "lhs app ID is NULL");
314         retvm_if(rhs_app_id == NULL, PMINFO_R_EINVAL, "rhs app ID is NULL");
315         retvm_if(compare_result == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
316
317         info = (pkgmgr_cert_x *)calloc(1, sizeof(pkgmgr_cert_x));
318         retvm_if(info == NULL, PMINFO_R_ERROR, "Out of Memory!!!");
319
320         ret = __open_manifest_db(uid, true);
321         if (ret != SQLITE_OK) {
322                 _LOGE("connect db [%s] failed!\n", getUserPkgParserDBPathUID(uid));
323                 ret = PMINFO_R_ERROR;
324                 goto err;
325         }
326
327         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_app_info where app_id='%s')", lhs_app_id);
328         if (SQLITE_OK !=
329             sqlite3_exec(GET_DB(manifest_db), query, __validate_cb, (void *)&exist, &error_message)) {
330                 _LOGE("Don't execute query = %s error message = %s\n", query,
331                        error_message);
332                 ret = PMINFO_R_ERROR;
333                 goto err;
334         }
335
336         if (exist == 0) {
337                 lpkgid = NULL;
338         } else {
339                 snprintf(query, MAX_QUERY_LEN, "select package from package_app_info where app_id='%s' ", lhs_app_id);
340                 if (SQLITE_OK !=
341                         sqlite3_exec(GET_DB(manifest_db), query, __cert_cb, (void *)info, &error_message)) {
342                         _LOGE("Don't execute query = %s error message = %s\n", query,
343                                    error_message);
344                         ret = PMINFO_R_ERROR;
345                         goto err;
346                 }
347                 lpkgid = strdup(info->pkgid);
348                 if (lpkgid == NULL) {
349                         _LOGE("Out of Memory\n");
350                         ret = PMINFO_R_ERROR;
351                         goto err;
352                 }
353                 free(info->pkgid);
354                 info->pkgid = NULL;
355         }
356
357         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_app_info where app_id='%s')", rhs_app_id);
358         if (SQLITE_OK !=
359             sqlite3_exec(GET_DB(manifest_db), query, __validate_cb, (void *)&exist, &error_message)) {
360                 _LOGE("Don't execute query = %s error message = %s\n", query,
361                        error_message);
362                 ret = PMINFO_R_ERROR;
363                 goto err;
364         }
365
366         if (exist == 0) {
367                 rpkgid = NULL;
368         } else {
369                 snprintf(query, MAX_QUERY_LEN, "select package from package_app_info where app_id='%s' ", rhs_app_id);
370                 if (SQLITE_OK !=
371                         sqlite3_exec(GET_DB(manifest_db), query, __cert_cb, (void *)info, &error_message)) {
372                         _LOGE("Don't execute query = %s error message = %s\n", query,
373                                    error_message);
374                         ret = PMINFO_R_ERROR;
375                         goto err;
376                 }
377                 rpkgid = strdup(info->pkgid);
378                 if (rpkgid == NULL) {
379                         _LOGE("Out of Memory\n");
380                         ret = PMINFO_R_ERROR;
381                         goto err;
382                 }
383                 free(info->pkgid);
384                 info->pkgid = NULL;
385         }
386         ret = pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(lpkgid, rpkgid, uid, compare_result);
387  err:
388         if (error_message)
389                 sqlite3_free(error_message);
390         __close_manifest_db();
391         if (info) {
392                 if (info->pkgid) {
393                         free(info->pkgid);
394                         info->pkgid = NULL;
395                 }
396                 free(info);
397                 info = NULL;
398         }
399         if (lpkgid) {
400                 free(lpkgid);
401                 lpkgid = NULL;
402         }
403         if (rpkgid) {
404                 free(rpkgid);
405                 rpkgid = NULL;
406         }
407         return ret;
408 }
409
410 API int pkgmgrinfo_pkginfo_create_certinfo(pkgmgrinfo_certinfo_h *handle)
411 {
412         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
413         pkgmgr_certinfo_x *certinfo = NULL;
414         certinfo = calloc(1, sizeof(pkgmgr_certinfo_x));
415         *handle = NULL;
416         retvm_if(certinfo == NULL, PMINFO_R_ERROR, "Malloc Failed\n");
417         *handle = (void *)certinfo;
418         return PMINFO_R_OK;
419 }
420
421 static int _pkginfo_get_cert(sqlite3 *db, int cert_id[],
422                 char *cert_info[])
423 {
424         static const char query[] =
425                 "SELECT cert_info FROM package_cert_index_info WHERE cert_id=?";
426         int ret;
427         sqlite3_stmt *stmt;
428         int i;
429
430         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
431         if (ret != SQLITE_OK) {
432                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
433                 return PMINFO_R_ERROR;
434         }
435
436         for (i = 0; i < MAX_CERT_TYPE; i++) {
437                 ret = sqlite3_bind_int(stmt, 1, cert_id[i]);
438                 if (ret != SQLITE_OK) {
439                         sqlite3_finalize(stmt);
440                         _LOGE("bind failed: %s", sqlite3_errmsg(db));
441                         return PMINFO_R_ERROR;
442                 }
443
444                 ret = sqlite3_step(stmt);
445                 if (ret == SQLITE_DONE) {
446                         sqlite3_reset(stmt);
447                         sqlite3_clear_bindings(stmt);
448                         continue;
449                 } else if (ret != SQLITE_ROW) {
450                         _LOGE("step failed: %s", sqlite3_errmsg(db));
451                         sqlite3_finalize(stmt);
452                         return PMINFO_R_ERROR;
453                 }
454
455                 _save_column_str(stmt, 0, (const char **)&cert_info[i]);
456                 sqlite3_reset(stmt);
457                 sqlite3_clear_bindings(stmt);
458         }
459
460         sqlite3_finalize(stmt);
461
462         return PMINFO_R_OK;
463 }
464
465 static int _pkginfo_get_certid(sqlite3 *db, const char *pkgid, int cert_id[])
466 {
467         static const char query[] =
468                 "SELECT 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                 "FROM package_cert_info WHERE package=?";
472         int ret;
473         sqlite3_stmt *stmt;
474         int idx;
475
476         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
477         if (ret != SQLITE_OK) {
478                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
479                 return PMINFO_R_ERROR;
480         }
481
482         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
483         if (ret != SQLITE_OK) {
484                 _LOGE("bind failed: %s", sqlite3_errmsg(db));
485                 sqlite3_finalize(stmt);
486                 return PMINFO_R_ERROR;
487         }
488
489         ret = sqlite3_step(stmt);
490         if (ret == SQLITE_DONE) {
491                 sqlite3_finalize(stmt);
492                 return PMINFO_R_ENOENT;
493         } else if (ret != SQLITE_ROW) {
494                 _LOGE("step failed: %s", sqlite3_errmsg(db));
495                 sqlite3_finalize(stmt);
496                 return PMINFO_R_ERROR;
497         }
498
499         idx = 0;
500         _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_ROOT_CERT]);
501         _save_column_int(stmt, idx++,
502                         &cert_id[PMINFO_AUTHOR_INTERMEDIATE_CERT]);
503         _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_SIGNER_CERT]);
504         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_ROOT_CERT]);
505         _save_column_int(stmt, idx++,
506                         &cert_id[PMINFO_DISTRIBUTOR_INTERMEDIATE_CERT]);
507         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_SIGNER_CERT]);
508         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR2_ROOT_CERT]);
509         _save_column_int(stmt, idx++,
510                         &cert_id[PMINFO_DISTRIBUTOR2_INTERMEDIATE_CERT]);
511         _save_column_int(stmt, idx++,
512                         &cert_id[PMINFO_DISTRIBUTOR2_SIGNER_CERT]);
513
514         sqlite3_finalize(stmt);
515
516         return PMINFO_R_OK;
517 }
518
519 static int _pkginfo_get_certinfo(const char *pkgid, uid_t uid,
520                 pkgmgr_certinfo_x *info)
521 {
522         int ret;
523         sqlite3 *db;
524         const char *dbpath;
525
526         dbpath = getUserPkgCertDBPathUID(uid);
527         if (dbpath == NULL)
528                 return PMINFO_R_ERROR;
529
530         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
531         if (ret != SQLITE_OK) {
532                 _LOGE("failed to open db: %d", ret);
533                 return PMINFO_R_ERROR;
534         }
535
536         ret = _pkginfo_get_certid(db, pkgid, info->cert_id);
537         if (ret != PMINFO_R_OK) {
538                 sqlite3_close_v2(db);
539                 return ret;
540         }
541
542         ret = _pkginfo_get_cert(db, info->cert_id, info->cert_info);
543         if (ret != PMINFO_R_OK) {
544                 sqlite3_close_v2(db);
545                 return ret;
546         }
547
548         return PMINFO_R_OK;
549 }
550
551 API int pkgmgrinfo_pkginfo_load_certinfo(const char *pkgid, pkgmgrinfo_certinfo_h handle, uid_t uid)
552 {
553         int ret;
554         pkgmgr_certinfo_x *info = (pkgmgr_certinfo_x *)handle;
555
556         if (pkgid == NULL || handle == NULL) {
557                 _LOGE("invalid parameter");
558                 return PMINFO_R_EINVAL;
559         }
560
561         ret = _pkginfo_get_certinfo(pkgid, uid, info);
562         if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
563                 ret = _pkginfo_get_certinfo(pkgid, GLOBAL_USER, info);
564
565         if (ret != PMINFO_R_OK)
566                 _LOGE("failed to get certinfo of %s for user %d", pkgid, uid);
567
568         return ret;
569 }
570
571 API int pkgmgrinfo_pkginfo_get_cert_value(pkgmgrinfo_certinfo_h handle, pkgmgrinfo_cert_type cert_type, const char **cert_value)
572 {
573         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
574         retvm_if(cert_value == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
575         retvm_if(cert_type < PMINFO_AUTHOR_ROOT_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
576         retvm_if(cert_type > PMINFO_DISTRIBUTOR2_SIGNER_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
577         pkgmgr_certinfo_x *certinfo = NULL;
578         certinfo = (pkgmgr_certinfo_x *)handle;
579         if ((certinfo->cert_info)[cert_type])
580                 *cert_value = (certinfo->cert_info)[cert_type];
581         else
582                 *cert_value = NULL;
583         return PMINFO_R_OK;
584 }
585
586 API int pkgmgrinfo_pkginfo_destroy_certinfo(pkgmgrinfo_certinfo_h handle)
587 {
588         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
589         int i = 0;
590         pkgmgr_certinfo_x *certinfo = NULL;
591         certinfo = (pkgmgr_certinfo_x *)handle;
592         if (certinfo->pkgid) {
593                 free(certinfo->pkgid);
594                 certinfo->pkgid = NULL;
595         }
596         for (i = 0; i < MAX_CERT_TYPE; i++) {
597                 if ((certinfo->cert_info)[i]) {
598                         free((certinfo->cert_info)[i]);
599                         (certinfo->cert_info)[i] = NULL;
600                 }
601         }
602         free(certinfo);
603         certinfo = NULL;
604         return PMINFO_R_OK;
605 }
606
607 API int pkgmgrinfo_create_certinfo_set_handle(pkgmgrinfo_instcertinfo_h *handle)
608 {
609         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
610         pkgmgr_instcertinfo_x *certinfo = NULL;
611         *handle = NULL;
612         certinfo = calloc(1, sizeof(pkgmgr_instcertinfo_x));
613         retvm_if(certinfo == NULL, PMINFO_R_ERROR, "Malloc Failed\n");
614         *handle = (void *)certinfo;
615         return PMINFO_R_OK;
616 }
617
618 API int pkgmgrinfo_set_cert_value(pkgmgrinfo_instcertinfo_h handle, pkgmgrinfo_instcert_type cert_type, char *cert_value)
619 {
620         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
621         retvm_if(cert_value == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
622         retvm_if(cert_type < PMINFO_SET_AUTHOR_ROOT_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
623         retvm_if(cert_type > PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
624         pkgmgr_instcertinfo_x *certinfo = NULL;
625         certinfo = (pkgmgr_instcertinfo_x *)handle;
626         (certinfo->cert_info)[cert_type] = strdup(cert_value);
627         return PMINFO_R_OK;
628 }
629
630 static int _pkginfo_save_cert_info(sqlite3 *db, const char *pkgid,
631                 char *cert_info[])
632 {
633         static const char query[] =
634                 "INSERT OR REPLACE INTO package_cert_info (package,"
635                 " author_root_cert, author_im_cert, author_signer_cert,"
636                 " dist_root_cert, dist_im_cert, dist_signer_cert,"
637                 " dist2_root_cert, dist2_im_cert, dist2_signer_cert) "
638                 "VALUES(?, "
639                 " (COALESCE( "
640                 "   (SELECT cert_id FROM package_cert_index_info"
641                 "    WHERE cert_info=?),"
642                 "   (SELECT author_root_cert FROM package_cert_info"
643                 "    WHERE package=?))),"
644                 " (COALESCE( "
645                 "   (SELECT cert_id FROM package_cert_index_info"
646                 "    WHERE cert_info=?),"
647                 "   (SELECT author_im_cert FROM package_cert_info"
648                 "    WHERE package=?))),"
649                 " (COALESCE( "
650                 "   (SELECT cert_id FROM package_cert_index_info"
651                 "    WHERE cert_info=?),"
652                 "   (SELECT author_signer_cert FROM package_cert_info"
653                 "    WHERE package=?))),"
654                 " (COALESCE( "
655                 "   (SELECT cert_id FROM package_cert_index_info"
656                 "    WHERE cert_info=?),"
657                 "   (SELECT dist_root_cert FROM package_cert_info"
658                 "    WHERE package=?))),"
659                 " (COALESCE( "
660                 "   (SELECT cert_id FROM package_cert_index_info"
661                 "    WHERE cert_info=?),"
662                 "   (SELECT dist_im_cert FROM package_cert_info"
663                 "    WHERE package=?))),"
664                 " (COALESCE( "
665                 "   (SELECT cert_id FROM package_cert_index_info"
666                 "    WHERE cert_info=?),"
667                 "   (SELECT dist_signer_cert FROM package_cert_info"
668                 "    WHERE package=?))),"
669                 " (COALESCE( "
670                 "   (SELECT cert_id FROM package_cert_index_info"
671                 "    WHERE cert_info=?),"
672                 "   (SELECT dist2_root_cert FROM package_cert_info"
673                 "    WHERE package=?))),"
674                 " (COALESCE( "
675                 "   (SELECT cert_id FROM package_cert_index_info"
676                 "    WHERE cert_info=?),"
677                 "   (SELECT dist2_im_cert FROM package_cert_info"
678                 "    WHERE package=?))),"
679                 " (COALESCE( "
680                 "   (SELECT cert_id FROM package_cert_index_info"
681                 "    WHERE cert_info=?),"
682                 "   (SELECT dist2_signer_cert FROM package_cert_info"
683                 "    WHERE package=?))))";
684         int ret;
685         sqlite3_stmt *stmt;
686         int i;
687         int idx;
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         idx = 1;
696         sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_STATIC);
697         for (i = 0; i < MAX_CERT_TYPE; i++) {
698                 ret = sqlite3_bind_text(stmt, idx++, cert_info[i], -1,
699                                 SQLITE_STATIC);
700                 if (ret != SQLITE_OK) {
701                         _LOGE("bind error: %s", sqlite3_errmsg(db));
702                         sqlite3_finalize(stmt);
703                         return PMINFO_R_ERROR;
704                 }
705                 ret = sqlite3_bind_text(stmt, idx++, pkgid, -1,
706                                 SQLITE_STATIC);
707                 if (ret != SQLITE_OK) {
708                         _LOGE("bind error: %s", sqlite3_errmsg(db));
709                         sqlite3_finalize(stmt);
710                         return PMINFO_R_ERROR;
711                 }
712         }
713         ret = sqlite3_step(stmt);
714         sqlite3_finalize(stmt);
715         if (ret != SQLITE_DONE) {
716                 _LOGE("step error: %s", sqlite3_errmsg(db));
717                 return PMINFO_R_ERROR;
718         }
719
720         return PMINFO_R_OK;
721 }
722
723 static int _pkginfo_save_cert_index_info(sqlite3 *db, char *cert_info[])
724 {
725         static const char query[] =
726                 "INSERT OR REPLACE INTO package_cert_index_info "
727                 "(cert_info, cert_id, cert_ref_count) "
728                 "VALUES ( "
729                 " ?, "
730                 " (SELECT cert_id FROM package_cert_index_info "
731                 "  WHERE cert_info=?), "
732                 " COALESCE( "
733                 "  ((SELECT cert_ref_count FROM package_cert_index_info "
734                 "    WHERE cert_info=?) + 1), 1))";
735         int ret;
736         sqlite3_stmt *stmt;
737         int i;
738         int idx;
739
740         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
741         if (ret != SQLITE_OK) {
742                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
743                 return PMINFO_R_ERROR;
744         }
745
746         for (i = 0; i < MAX_CERT_TYPE; i++) {
747                 if (cert_info[i] == NULL)
748                         continue;
749                 idx = 1;
750                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
751                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
752                 sqlite3_bind_text(stmt, idx++, cert_info[i], -1, SQLITE_STATIC);
753
754                 ret = sqlite3_step(stmt);
755                 if (ret != SQLITE_DONE) {
756                         _LOGE("step failed: %s", sqlite3_errmsg(db));
757                         sqlite3_finalize(stmt);
758                         return PMINFO_R_ERROR;
759                 }
760
761                 sqlite3_reset(stmt);
762                 sqlite3_clear_bindings(stmt);
763         }
764
765         sqlite3_finalize(stmt);
766
767         return PMINFO_R_OK;
768 }
769
770 API int pkgmgrinfo_save_certinfo(const char *pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid)
771 {
772         int ret;
773         sqlite3 *db;
774         const char *dbpath;
775         pkgmgr_instcertinfo_x *info = (pkgmgr_instcertinfo_x *)handle;
776
777         if (pkgid == NULL || handle == NULL) {
778                 _LOGE("invalid parameter");
779                 return PMINFO_R_EINVAL;
780         }
781
782         dbpath = getUserPkgCertDBPathUID(uid);
783         if (dbpath == NULL)
784                 return PMINFO_R_ERROR;
785
786         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READWRITE, NULL);
787         if (ret != SQLITE_OK) {
788                 _LOGE("failed to open db: %d", ret);
789                 return PMINFO_R_ERROR;
790         }
791
792         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
793         if (ret != SQLITE_OK) {
794                 _LOGE("failed to begin transaction");
795                 sqlite3_close_v2(db);
796                 return PMINFO_R_ERROR;
797         }
798
799         _check_create_cert_db(db);
800
801         if (_pkginfo_save_cert_index_info(db, info->cert_info)) {
802                 _LOGE("failed to save cert index info");
803                 sqlite3_close_v2(db);
804                 return PMINFO_R_ERROR;
805         }
806         if (_pkginfo_save_cert_info(db, pkgid, info->cert_info)) {
807                 _LOGE("failed to save cert info");
808                 sqlite3_close_v2(db);
809                 return PMINFO_R_ERROR;
810         }
811
812         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
813         if (ret != SQLITE_OK) {
814                 _LOGE("failed to commit transaction, rollback now");
815                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
816                 sqlite3_close_v2(db);
817                 return PMINFO_R_ERROR;
818         }
819
820         sqlite3_close_v2(db);
821
822         return PMINFO_R_OK;
823 }
824
825 API int pkgmgrinfo_destroy_certinfo_set_handle(pkgmgrinfo_instcertinfo_h handle)
826 {
827         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
828         int i = 0;
829         pkgmgr_instcertinfo_x *certinfo = NULL;
830         certinfo = (pkgmgr_instcertinfo_x *)handle;
831         if (certinfo->pkgid) {
832                 free(certinfo->pkgid);
833                 certinfo->pkgid = NULL;
834         }
835         for (i = 0; i < MAX_CERT_TYPE; i++) {
836                 if ((certinfo->cert_info)[i]) {
837                         free((certinfo->cert_info)[i]);
838                         (certinfo->cert_info)[i] = NULL;
839                 }
840         }
841         free(certinfo);
842         certinfo = NULL;
843         return PMINFO_R_OK;
844 }
845
846 static int _pkginfo_delete_certinfo(sqlite3 *db, const char *pkgid)
847 {
848         static const char query[] =
849                 "DELETE FROM package_cert_info WHERE package=?";
850         int ret;
851         sqlite3_stmt *stmt;
852
853         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
854         if (ret != SQLITE_OK) {
855                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
856                 return PMINFO_R_ERROR;
857         }
858
859         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
860         if (ret != SQLITE_OK) {
861                 _LOGE("bind error: %s", sqlite3_errmsg(db));
862                 sqlite3_finalize(stmt);
863                 return PMINFO_R_ERROR;
864         }
865
866         ret = sqlite3_step(stmt);
867         sqlite3_finalize(stmt);
868         if (ret != SQLITE_DONE) {
869                 _LOGE("step error: %s", sqlite3_errmsg(db));
870                 return PMINFO_R_ERROR;
871         }
872
873         return PMINFO_R_OK;
874 }
875
876 API int pkgmgrinfo_delete_usr_certinfo(const char *pkgid, uid_t uid)
877 {
878         int ret;
879         sqlite3 *db;
880         const char *dbpath;
881
882         if (pkgid == NULL) {
883                 _LOGE("invalid parameter");
884                 return PMINFO_R_EINVAL;
885         }
886
887         dbpath = getUserPkgCertDBPathUID(uid);
888         if (dbpath == NULL)
889                 return PMINFO_R_ERROR;
890
891         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READWRITE, NULL);
892         if (ret != SQLITE_OK) {
893                 _LOGE("failed to open db: %d", ret);
894                 return PMINFO_R_ERROR;
895         }
896
897         ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
898         if (ret != SQLITE_OK) {
899                 _LOGE("failed to begin transaction");
900                 sqlite3_close_v2(db);
901                 return PMINFO_R_ERROR;
902         }
903
904         if (_pkginfo_delete_certinfo(db, pkgid))
905                 _LOGE("failed to delete certinfo of %s", pkgid);
906
907         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
908         if (ret != SQLITE_OK) {
909                 _LOGE("failed to commit transaction, rollback now");
910                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
911                 sqlite3_close_v2(db);
912                 return PMINFO_R_ERROR;
913         }
914
915         sqlite3_close_v2(db);
916
917         return PMINFO_R_OK;
918 }
919
920 API int pkgmgrinfo_delete_certinfo(const char *pkgid)
921 {
922         return pkgmgrinfo_delete_usr_certinfo(pkgid, GLOBAL_USER);
923 }
924