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