Add datacontrol trusted communication 99/124099/13
authorJiwoong Im <jiwoong.im@samsung.com>
Mon, 10 Apr 2017 06:29:19 +0000 (15:29 +0900)
committerJiwoong Im <jiwoong.im@samsung.com>
Wed, 19 Apr 2017 02:01:05 +0000 (19:01 -0700)
- Provider app can set whether datacontrol is trusted communication or not
  with trusted attribute in manifest file.
  If provider app sets trusted communication, only consumer apps signed
  with the same certificate can request to the provider.

- Related patches
  [pkgmgr-info] https://review.tizen.org/gerrit/#/c/124100/
  [tpk-manifest-handler] https://review.tizen.org/gerrit/#/c/124101/
  [app-installer] https://review.tizen.org/gerrit/#/c/124102/

Change-Id: Ieb38a23684632b1e1f20093059eb94011ef5e83f
Signed-off-by: Jiwoong Im <jiwoong.im@samsung.com>
include/data_control_internal.h
src/data-control-internal.h
src/data-control-provider.c
src/data_control_internal.c
src/data_control_map.c
src/data_control_noti.c
src/data_control_sql.c

index 32f998e..a6be427 100644 (file)
@@ -29,8 +29,16 @@ typedef enum {
        PRIVILEGE_CONSUMER
 } privilege_type;
 
+typedef enum {
+       CERT_UNCHECKED,
+       CERT_MATCH,
+       CERT_MISMATCH
+} cert_status_type;
+
 int convert_to_tizen_error(datacontrol_error_e error);
 int datacontrol_check_privilege(privilege_type check_type);
+int datacontrol_check_cert(const char *provider_id, bool is_map,
+               const char *consumer_appid);
 
 #ifdef __cplusplus
 }
index 56aa5be..35eb7d2 100755 (executable)
@@ -21,6 +21,7 @@
 #include <gio/gio.h>
 #include <bundle.h>
 #include "data_control_types.h"
+#include "data_control_internal.h"
 
 #ifndef _APPFW_DATA_CONTROL_INTERNAL_H_
 #define _APPFW_DATA_CONTROL_INTERNAL_H_
index 4b0705a..e9b05c8 100755 (executable)
@@ -1130,14 +1130,18 @@ static int __set_consumer_app_list(
        return ret;
 }
 
-int __provider_process(bundle *b, int fd)
+int __provider_process(bundle *b, int fd, const char *consumer_appid)
 {
+       int ret;
        int len = 0;
        const char **arg_list = NULL;
        const char **column_list = NULL;
        datacontrol_h provider = NULL;
        int provider_req_id = 0;
        int *key = NULL;
+       bool is_map;
+       char *provider_id;
+       char *caller_appid;
        bundle *value = NULL;
 
        const char *request_type = bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
@@ -1149,11 +1153,13 @@ int __provider_process(bundle *b, int fd)
        /* Get the request type */
        datacontrol_request_type type = atoi(request_type);
        if (type >= DATACONTROL_TYPE_SQL_SELECT && type <= DATACONTROL_TYPE_SQL_BULK_INSERT)    {
+               is_map = false;
                if (provider_sql_cb == NULL) {
                        LOGE("SQL callback is not registered.");
                        return DATACONTROL_ERROR_INVALID_PARAMETER;
                }
        } else if (type >= DATACONTROL_TYPE_MAP_GET && type <= DATACONTROL_TYPE_MAP_BULK_ADD) {
+               is_map = true;
                if (provider_map_cb == NULL) {
                        LOGE("Map callback is not registered.");
                        return DATACONTROL_ERROR_INVALID_PARAMETER;
@@ -1163,6 +1169,26 @@ int __provider_process(bundle *b, int fd)
                return DATACONTROL_ERROR_INVALID_PARAMETER;
        }
 
+       caller_appid = (char *)bundle_get_val(b, AUL_K_CALLER_APPID);
+       if (caller_appid && strncmp(caller_appid,
+                               consumer_appid, strlen(consumer_appid)) != 0) {
+               LOGE("The passed appid(%s) is different from the registered appid(%s).",
+                               caller_appid, consumer_appid);
+               return DATACONTROL_ERROR_NONE;
+       }
+
+       provider_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
+       ret = datacontrol_check_cert(provider_id, is_map, consumer_appid);
+       if (ret != DATA_CONTROL_ERROR_NONE) {
+               if (ret == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+                       LOGE("The consumer (%s) is not signed with the same certificate",
+                                       consumer_appid);
+                       return DATACONTROL_ERROR_NONE;
+               } else {
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+       }
+
        arg_list = bundle_get_str_array(b, OSP_K_ARG, &len);
 
        provider = malloc(sizeof(struct datacontrol_s));
@@ -1172,7 +1198,7 @@ int __provider_process(bundle *b, int fd)
        }
 
        /* Set the provider ID */
-       provider->provider_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
+       provider->provider_id = provider_id;
 
        /* Set the data ID */
        provider->data_id = (char *)arg_list[PACKET_INDEX_DATAID];
@@ -1361,6 +1387,7 @@ gboolean __provider_recv_message(GIOChannel *channel,
 {
        char *buf = NULL;
        int data_len;
+       char *consumer_appid = (char *)data;
        guint nb;
 
        gint fd = g_io_channel_unix_get_fd(channel);
@@ -1409,7 +1436,7 @@ gboolean __provider_recv_message(GIOChannel *channel,
                        }
 
                        kb = bundle_decode_raw((bundle_raw *)buf, data_len);
-                       if (__provider_process(kb, fd) != DATACONTROL_ERROR_NONE) {
+                       if (__provider_process(kb, fd, consumer_appid) != DATACONTROL_ERROR_NONE) {
                                bundle_free(kb);
                                goto error;
                        }
@@ -1421,8 +1448,8 @@ gboolean __provider_recv_message(GIOChannel *channel,
 
        return retval;
 error:
-       if (((char *)data) != NULL)
-               g_hash_table_remove(__socket_pair_hash, (char *)data);
+       if (consumer_appid != NULL)
+               g_hash_table_remove(__socket_pair_hash, consumer_appid);
        if (buf)
                free(buf);
 
@@ -2161,6 +2188,24 @@ out:
        return result;
 }
 
+static int __check_consumer_cert(const char *provider_id,
+               const char *consumer_appid,
+               datacontrol_data_change_type_e type)
+{
+       bool is_map;
+
+       if (consumer_appid == NULL)
+               return DATACONTROL_ERROR_IO_ERROR;
+
+       if (type >= DATACONTROL_DATA_CHANGE_SQL_UPDATE &&
+                       type <= DATACONTROL_DATA_CHANGE_SQL_DELETE)
+               is_map = false;
+       else
+               is_map = true;
+
+       return datacontrol_check_cert(provider_id, is_map, consumer_appid);
+}
+
 int datacontrol_provider_send_data_change_noti(
                datacontrol_h provider,
                datacontrol_data_change_type_e type,
@@ -2174,6 +2219,10 @@ int datacontrol_provider_send_data_change_noti(
        consumer_iter = g_list_first(__noti_consumer_app_list);
        for (; consumer_iter != NULL; consumer_iter = consumer_iter->next) {
                consumer_info = (datacontrol_consumer_info *)consumer_iter->data;
+               if (__check_consumer_cert(provider->provider_id,
+                                       consumer_info->appid,
+                                       type) != DATACONTROL_ERROR_NONE)
+                       continue;
                result = __send_signal_to_consumer(
                                provider,
                                consumer_info->unique_id,
index 7ec7f23..2ab1b32 100755 (executable)
@@ -23,6 +23,8 @@
 #include <fcntl.h>
 #include <cynara-client.h>
 #include <stdio.h>
+#include <pkgmgr-info.h>
+#include <aul.h>
 
 #include "data_control_internal.h"
 
 #define _LOGE(fmt, arg...) LOGE(fmt, ##arg)
 #define _LOGD(fmt, arg...) LOGD(fmt, ##arg)
 
+#define CHECKED_CACHE_SIZE 10
+
+struct datacontrol_cert_info {
+       cert_status_type sql;
+       cert_status_type map;
+       time_t time;
+};
+
+static GHashTable *__checked_provider_hash;
+static GHashTable *__checked_consumer_hash;
 
 int datacontrol_check_privilege(privilege_type check_type)
 {
-
        cynara *p_cynara = NULL;
 
        int fd = 0;
@@ -106,6 +117,142 @@ out:
        return ret;
 }
 
+static char *__get_victim(GHashTable *hash)
+{
+       GHashTableIter iter;
+       gpointer key;
+       gpointer value;
+       time_t time = 0;
+       char *victim_key = NULL;
+
+       g_hash_table_iter_init(&iter, hash);
+
+       while (g_hash_table_iter_next(&iter, &key, &value)) {
+               struct datacontrol_cert_info *info = (struct datacontrol_cert_info *)value;
+               if (time == 0 || time > info->time) {
+                       time = info->time;
+                       victim_key = key;
+               }
+       }
+
+       return victim_key;
+}
+
+static void _insert_hash(GHashTable *hash, const char *key,
+               bool is_map, cert_status_type status)
+{
+       struct datacontrol_cert_info *cert_info;
+       char *victim_key;
+
+       if (g_hash_table_size(hash) > CHECKED_CACHE_SIZE) {
+               victim_key = __get_victim(hash);
+               if (victim_key)
+                       g_hash_table_remove(hash, victim_key);
+       }
+
+       cert_info = (struct datacontrol_cert_info *)calloc(1,
+                       sizeof(struct datacontrol_cert_info));
+
+       if (is_map)
+               cert_info->map = status;
+       else
+               cert_info->sql = status;
+
+       time(&cert_info->time);
+
+       g_hash_table_insert(hash, strdup(key), cert_info);
+}
+
+int datacontrol_check_cert(const char *provider_id, bool is_map,
+               const char *consumer_appid)
+{
+       int ret;
+       bool is_trusted;
+       bool is_update = false;
+       char *provider_appid;
+       char appid[255];
+       GHashTable *hash_table;
+       struct datacontrol_cert_info *cert_info;
+       cert_status_type *status;
+       pkgmgrinfo_cert_compare_result_type_e res;
+
+       if (consumer_appid == NULL) {
+               if (__checked_provider_hash == NULL)
+                       __checked_provider_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
+               hash_table = __checked_provider_hash;
+       } else {
+               if (__checked_consumer_hash == NULL)
+                       __checked_consumer_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
+               hash_table = __checked_consumer_hash;
+       }
+
+       cert_info = g_hash_table_lookup(hash_table, provider_id);
+
+       if (cert_info) {
+               status = is_map ? &cert_info->map : &cert_info->sql;
+
+               if (*status == CERT_MATCH)
+                       return DATA_CONTROL_ERROR_NONE;
+               else if (*status == CERT_MISMATCH)
+                       return DATA_CONTROL_ERROR_PERMISSION_DENIED;
+
+               is_update = true;
+       }
+
+       ret = pkgmgrinfo_appinfo_usr_get_datacontrol_trusted_info(provider_id,
+                       is_map ? "Map" : "Sql", getuid(), &provider_appid, &is_trusted);
+       if (ret != PMINFO_R_OK) {
+               LOGE("unable to get data control information: %d", ret);
+               return DATA_CONTROL_ERROR_IO_ERROR;
+       }
+
+       if (!is_trusted) {
+               if (is_update)
+                       *status = CERT_MATCH;
+               else
+                       _insert_hash(hash_table, provider_id, is_map, CERT_MATCH);
+               free(provider_appid);
+               return DATA_CONTROL_ERROR_NONE;
+       }
+
+       if (!consumer_appid) {
+               ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
+               if (ret != AUL_R_OK) {
+                       LOGE("Failed to get appid: %d", ret);
+                       free(provider_appid);
+                       return DATA_CONTROL_ERROR_IO_ERROR;
+               }
+               consumer_appid = appid;
+       }
+
+       ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(provider_appid,
+                       consumer_appid, getuid(), &res);
+       if (ret < 0) {
+               LOGE("certificate check [%d] failed!", ret);
+               free(provider_appid);
+               return DATA_CONTROL_ERROR_IO_ERROR;
+       }
+       if (res != PMINFO_CERT_COMPARE_MATCH) {
+               LOGE("certificate mismatch. provider : %s consumer %s",
+                               provider_appid, consumer_appid);
+               if (is_update)
+                       *status = CERT_MISMATCH;
+               else
+                       _insert_hash(hash_table, provider_id, is_map, CERT_MISMATCH);
+               free(provider_appid);
+               return DATA_CONTROL_ERROR_PERMISSION_DENIED;
+       }
+
+       if (is_update)
+               *status = CERT_MATCH;
+       else
+               _insert_hash(hash_table, provider_id, is_map, CERT_MATCH);
+
+       free(provider_appid);
+
+       return DATA_CONTROL_ERROR_NONE;
+}
+
 int convert_to_tizen_error(datacontrol_error_e error)
 {
        switch (error) {
@@ -124,4 +271,4 @@ int convert_to_tizen_error(datacontrol_error_e error)
        default:
                return error;
        }
-}
\ No newline at end of file
+}
index 1df54da..033701e 100755 (executable)
@@ -240,7 +240,19 @@ EXPORT_API int data_control_map_unregister_add_bulk_data_response_cb(data_contro
 
 EXPORT_API int data_control_map_get(data_control_h provider, const char *key, int *request_id)
 {
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       int retval;
+
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL || key == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
+
+       retval = datacontrol_check_cert(provider->provider_id, true, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
@@ -249,7 +261,19 @@ EXPORT_API int data_control_map_get(data_control_h provider, const char *key, in
 
 EXPORT_API int data_control_map_get_with_page(data_control_h provider, const char *key, int *request_id, int page_number, int count_per_page)
 {
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       int retval;
+
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL || key == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
+
+       retval = datacontrol_check_cert(provider->provider_id, true, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
@@ -258,7 +282,20 @@ EXPORT_API int data_control_map_get_with_page(data_control_h provider, const cha
 
 EXPORT_API int data_control_map_set(data_control_h provider, const char *key, const char *old_value, const char *new_value, int *request_id)
 {
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       int retval;
+
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL || key == NULL ||
+                       old_value == NULL || new_value == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
+
+       retval = datacontrol_check_cert(provider->provider_id, true, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
@@ -267,7 +304,19 @@ EXPORT_API int data_control_map_set(data_control_h provider, const char *key, co
 
 EXPORT_API int data_control_map_add(data_control_h provider, const char *key, const char *value, int *request_id)
 {
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       int retval;
+
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL || key == NULL || value == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
+
+       retval = datacontrol_check_cert(provider->provider_id, true, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
@@ -276,7 +325,19 @@ EXPORT_API int data_control_map_add(data_control_h provider, const char *key, co
 
 EXPORT_API int data_control_map_remove(data_control_h provider, const char *key, const char *value, int *request_id)
 {
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       int retval;
+
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL || key == NULL || value == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
+
+       retval = datacontrol_check_cert(provider->provider_id, true, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
@@ -285,7 +346,19 @@ EXPORT_API int data_control_map_remove(data_control_h provider, const char *key,
 
 EXPORT_API int data_control_map_add_bulk_data(data_control_h provider, data_control_bulk_data_h bulk_data_h, int *request_id)
 {
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       int retval;
+
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
+
+       retval = datacontrol_check_cert(provider->provider_id, true, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
index 853eab3..f90c87b 100644 (file)
@@ -9,6 +9,11 @@
 #include "data_control_noti.h"
 #include "data-control-noti.h"
 
+struct data_control_s {
+       char *provider_id;
+       char *data_id;
+};
+
 EXPORT_API int data_control_add_data_change_cb(
                data_control_h provider,
                data_control_data_change_cb callback,
@@ -17,13 +22,24 @@ EXPORT_API int data_control_add_data_change_cb(
                void *result_cb_user_data,
                int *callback_id)
 {
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       int retval;
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
        if (callback == NULL || provider == NULL || callback_id == NULL)
                return DATA_CONTROL_ERROR_INVALID_PARAMETER;
 
+       retval = datacontrol_check_cert(provider->provider_id, true, NULL);
+       if (retval == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+               retval = datacontrol_check_cert(provider->provider_id, false, NULL);
+               if (retval != DATA_CONTROL_ERROR_NONE)
+                       return retval;
+       } else if (retval != DATA_CONTROL_ERROR_NONE) {
+               return retval;
+       }
+
        return datacontrol_add_data_change_cb(
                        (datacontrol_h)provider,
                        callback,
@@ -35,12 +51,23 @@ EXPORT_API int data_control_add_data_change_cb(
 
 EXPORT_API int data_control_remove_data_change_cb(data_control_h provider, int callback_id)
 {
+       int retval;
+
        if (callback_id < 1 || provider == NULL)
                return DATA_CONTROL_ERROR_INVALID_PARAMETER;
 
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
+       retval = datacontrol_check_cert(provider->provider_id, true, NULL);
+       if (retval == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+               retval = datacontrol_check_cert(provider->provider_id, false, NULL);
+               if (retval != DATA_CONTROL_ERROR_NONE)
+                       return retval;
+       } else if (retval != DATA_CONTROL_ERROR_NONE) {
+               return retval;
+       }
+
        return datacontrol_remove_data_change_cb((datacontrol_h)provider, callback_id);
 }
index 9f14745..624b0db 100755 (executable)
@@ -240,8 +240,19 @@ EXPORT_API int data_control_sql_unregister_insert_bulk_data_response_cb(data_con
 
 EXPORT_API int data_control_sql_insert_bulk_data(data_control_h provider, data_control_bulk_data_h bulk_data_h, int *request_id)
 {
+       int retval;
 
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
+
+       retval = datacontrol_check_cert(provider->provider_id, false, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
@@ -250,8 +261,19 @@ EXPORT_API int data_control_sql_insert_bulk_data(data_control_h provider, data_c
 
 EXPORT_API int data_control_sql_insert(data_control_h provider, const bundle *insert_data, int *request_id)
 {
+       int retval;
+
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL || insert_data == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
 
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       retval = datacontrol_check_cert(provider->provider_id, false, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
@@ -260,7 +282,19 @@ EXPORT_API int data_control_sql_insert(data_control_h provider, const bundle *in
 
 EXPORT_API int data_control_sql_delete(data_control_h provider, const char *where, int *request_id)
 {
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       int retval;
+
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
+
+       retval = datacontrol_check_cert(provider->provider_id, false, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
@@ -269,7 +303,19 @@ EXPORT_API int data_control_sql_delete(data_control_h provider, const char *wher
 
 EXPORT_API int data_control_sql_select(data_control_h provider, char **column_list, int column_count, const char *where, const char *order, int *request_id)
 {
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       int retval;
+
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL || column_list == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
+
+       retval = datacontrol_check_cert(provider->provider_id, false, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
@@ -278,7 +324,19 @@ EXPORT_API int data_control_sql_select(data_control_h provider, char **column_li
 
 EXPORT_API int data_control_sql_select_with_page(data_control_h provider, char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page, int *request_id)
 {
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       int retval;
+
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL || column_list == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
+
+       retval = datacontrol_check_cert(provider->provider_id, false, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;
 
@@ -288,7 +346,20 @@ EXPORT_API int data_control_sql_select_with_page(data_control_h provider, char *
 
 EXPORT_API int data_control_sql_update(data_control_h provider, const bundle *update_data, const char *where, int *request_id)
 {
-       int retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       int retval;
+
+       if (provider == NULL || provider->provider_id == NULL ||
+                       provider->data_id == NULL ||
+                       update_data == NULL || where == NULL) {
+               _LOGE("Invalid parameter");
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+       if (retval != DATA_CONTROL_ERROR_NONE)
+               return retval;
+
+       retval = datacontrol_check_cert(provider->provider_id, false, NULL);
        if (retval != DATA_CONTROL_ERROR_NONE)
                return retval;