summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJanusz Kozerski <j.kozerski@samsung.com>2015-06-26 11:58:59 +0200
committerJanusz Kozerski <j.kozerski@samsung.com>2015-07-10 11:06:57 +0200
commit1bf0726b3028ddfaae0cdd70e46b416335da39a0 (patch)
tree3c4fff7b35b783a219f763315d4da94ef88137ad /src
parentaa31c0517333688b611ba453b08138960b53244e (diff)
downloadcert-checker-1bf0726b3028ddfaae0cdd70e46b416335da39a0.tar.gz
cert-checker-1bf0726b3028ddfaae0cdd70e46b416335da39a0.tar.bz2
cert-checker-1bf0726b3028ddfaae0cdd70e46b416335da39a0.zip
Refactor DB and app_t structure - preparation for OCSP checking.
New version of DB is needed to keep separately certificates from each signatrue. Because application can be signed by more than one signature we need to keep all certificates from all signatures in separate lists to make building certificates' chains easier. * Add operators (==, !=, <) for app_t structre * Add operators (==, !=) for event_t structure * Add tests for operators * Remove check_id from app_t structure Change-Id: I966dd81420618325d1afa55bcbc656291ccb4238
Diffstat (limited to 'src')
-rw-r--r--src/app.cpp24
-rw-r--r--src/certs.cpp9
-rw-r--r--src/db/sql_query.cpp124
-rw-r--r--src/include/cchecker/app.h18
-rw-r--r--src/include/cchecker/sql_query.h1
5 files changed, 127 insertions, 49 deletions
diff --git a/src/app.cpp b/src/app.cpp
index 58a7883..08b79a5 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -22,16 +22,14 @@
#include <sstream>
#include <string>
-#include <vector>
#include <sys/types.h>
#include <cchecker/app.h>
+#include <cchecker/log.h>
namespace CCHECKER {
app_t::app_t(void):
- check_id(-1), // -1 as invalid check_id - assume that in database
- // all check_ids will be positive
uid((uid_t)-1), // (uid_t)-1 (0xFF) is defined to be invalid uid. According
// to chown manual page, you cannot change file group of owner
// to (uid_t)-1, so we'll use it as initial, invalid value.
@@ -41,19 +39,17 @@ app_t::app_t(void):
app_t::app_t(const std::string &app_id,
const std::string &pkg_id,
uid_t uid,
- const std::vector<std::string> &certificates):
- check_id(-1),
+ const signatures_t &signatures):
app_id(app_id),
pkg_id(pkg_id),
uid(uid),
- certificates(certificates),
+ signatures(signatures),
verified(verified_t::UNKNOWN)
{}
std::ostream & operator<< (std::ostream &out, const app_t &app)
{
- out << "app: " << app.app_id << ", pkg: " << app.pkg_id << ", uid: " << app.uid <<
- ", check_id: " << app.check_id;
+ out << "app: " << app.app_id << ", pkg: " << app.pkg_id << ", uid: " << app.uid;
return out;
}
@@ -64,4 +60,16 @@ std::string app_t::str() const
return ss.str();
}
+std::string app_t::str_certs(void) const
+{
+ std::stringstream ss;
+
+ for (const auto &iter : signatures) {
+ for (const auto iter_cert : iter) {
+ ss << "\"" << iter_cert << "\", ";
+ }
+ }
+ return ss.str();
+}
+
} //CCHECKER
diff --git a/src/certs.cpp b/src/certs.cpp
index 4a69fde..5b69ba0 100644
--- a/src/certs.cpp
+++ b/src/certs.cpp
@@ -119,7 +119,8 @@ void Certs::find_app_signatures (app_t &app, const std::string &app_path, ocsp_u
LogDebug("Number of signature files: " << signature_files.size());
LogDebug("Searching for certificates");
- for (auto iter = signature_files.begin(); iter != signature_files.end(); iter++){
+ for (auto iter = signature_files.begin(); iter != signature_files.end(); iter++) {
+ chain_t chain;
LogDebug("Checking signature");
ValidationCore::SignatureData data(app_path + std::string("/") + (*iter).getFileName(),
(*iter).getFileNumber());
@@ -131,7 +132,7 @@ void Certs::find_app_signatures (app_t &app, const std::string &app_path, ocsp_u
ValidationCore::CertificateList certs = data.getCertList();
for (auto cert_iter = certs.begin(); cert_iter != certs.end(); cert_iter++ ){
std::string app_cert = (*cert_iter)->getBase64();
- app.certificates.push_back(app_cert);
+ chain.push_back(app_cert);
LogDebug("Certificate: " << app_cert << " has been added");
// check OCSP URL
@@ -150,6 +151,10 @@ void Certs::find_app_signatures (app_t &app, const std::string &app_path, ocsp_u
// Needs to catch parser exceptions
LogError("Error occured in ParserSchema: " << exception.DumpToString());
}
+ if (!chain.empty()) {
+ app.signatures.push_back(chain);
+ LogDebug("Certificates chain added to the app");
+ }
}
}
diff --git a/src/db/sql_query.cpp b/src/db/sql_query.cpp
index 0968717..27eb52e 100644
--- a/src/db/sql_query.cpp
+++ b/src/db/sql_query.cpp
@@ -36,6 +36,12 @@ namespace {
// 107 - check_id
// 108 - certificate
// 109 - verified
+ // 110 - chain_id
+
+ // setup
+ const char *DB_CMD_SETUP = "VACUUM; PRAGMA foregin_keys=ON;";
+
+ const char *DB_CMD_GET_LAST_INSERTED_ROW = "SELECT last_insert_rowid();";
// urls
const char *DB_CMD_GET_URL =
@@ -54,17 +60,24 @@ namespace {
const char *DB_CMD_GET_CHECK_ID =
"SELECT check_id FROM to_check WHERE app_id=?104 AND pkg_id=?105 AND uid=?106;";
+ const char *DB_CMD_ADD_CHAIN =
+ "INSERT INTO chains_to_check(check_id) VALUES(?107);";
+
const char *DB_CMD_ADD_CERT =
- "INSERT INTO certs_to_check(check_id, certificate) VALUES(?107, ?108);";
+ "INSERT INTO certs_to_check(chain_id, certificate) VALUES(?110, ?108);";
+
+ const char *DB_CMD_GET_CHAINS =
+ "SELECT chain_id FROM chains_to_check INNER JOIN to_check ON chains_to_check.check_id=to_check.check_id \
+WHERE to_check.app_id=?104 AND to_check.pkg_id=?105 AND to_check.uid=?106;";
const char *DB_CMD_REMOVE_APP =
"DELETE FROM to_check WHERE app_id=?104 AND pkg_id=?105 AND uid=?106;";
const char *DB_CMD_GET_APPS =
- "SELECT * FROM to_check";
+ "SELECT app_id, pkg_id, uid, verified FROM to_check";
const char *DB_CMD_GET_CERTS =
- "SELECT certificate FROM certs_to_check WHERE check_id=?107;";
+ "SELECT certificate FROM certs_to_check WHERE chain_id=?110;";
const char *DB_CMD_SET_APP_AS_VERIFIED =
"UPDATE to_check SET verified=?109 WHERE check_id=?107";
@@ -91,7 +104,7 @@ bool SqlQuery::connect(const std::string& path)
Try {
m_connection = new SqlConnection(path, SqlConnection::Flag::None, SqlConnection::Flag::Option::CRW);
- m_connection->ExecCommand("VACUUM;");
+ m_connection->ExecCommand(DB_CMD_SETUP);
return true;
} Catch(std::bad_alloc) {
LogError("Couldn't allocate SqlConnection");
@@ -185,6 +198,25 @@ bool SqlQuery::get_check_id(const app_t &app, int32_t &check_id)
return false;
}
+bool SqlQuery::add_chain_id(const int32_t check_id, int32_t &chain_id)
+{
+ // Add new chain for an app
+ SqlConnection::DataCommandAutoPtr addChainCommand =
+ m_connection->PrepareDataCommand(DB_CMD_ADD_CHAIN);
+ addChainCommand->BindInt32(107, check_id);
+ addChainCommand->Step();
+
+ // get chain_id
+ SqlConnection::DataCommandAutoPtr getLastInserted =
+ m_connection->PrepareDataCommand(DB_CMD_GET_LAST_INSERTED_ROW);
+ if(getLastInserted->Step()) {
+ chain_id = getLastInserted->GetColumnInt32(0);
+ LogDebug("Found chain_id: " << chain_id << ", for check_id " << check_id);
+ return true;
+ }
+ return false;
+}
+
bool SqlQuery::add_app_to_check_list(const app_t &app)
{
//Check if app exists in DB
@@ -206,23 +238,35 @@ bool SqlQuery::add_app_to_check_list(const app_t &app)
// Get check_id
int32_t check_id;
- if (get_check_id(app, check_id)) {
- // If get check_id succeed we can add certificates to database
- for (const auto &iter : app.certificates) {
- SqlConnection::DataCommandAutoPtr addCertCommand =
- m_connection->PrepareDataCommand(DB_CMD_ADD_CERT);
- addCertCommand->BindInt32(107, check_id);
- addCertCommand->BindString(108, iter.c_str());
- addCertCommand->Step();
- LogDebug("Certificate for app " << app.app_id << "added");
- }
- m_connection->CommitTransaction();
- return true;
- } else { // If get check_id failed return false;
+ if (!get_check_id(app, check_id)) { // If get check_id failed return false;
LogDebug("Failed while addind app "<< app.app_id << " to to_check table.");
m_connection->RollbackTransaction();
return false;
}
+
+ // If get check_id succeed we can add chain to database
+ int32_t chain_id;
+ for (const auto &iter : app.signatures) {
+ // Add chain
+ if (add_chain_id(check_id, chain_id)) {
+ // add certificates from chain
+ for (const auto &iter_cert : iter) {
+ SqlConnection::DataCommandAutoPtr addCertCommand =
+ m_connection->PrepareDataCommand(DB_CMD_ADD_CERT);
+ addCertCommand->BindInt32(110, chain_id);
+ addCertCommand->BindString(108, iter_cert.c_str());
+ addCertCommand->Step();
+ LogDebug("Certificate for app " << app.app_id << "added");
+ }
+ } else {
+ LogDebug("Failed to add certificates chain");
+ m_connection->RollbackTransaction();
+ return false;
+ }
+
+ }
+ m_connection->CommitTransaction();
+ return true;
}
void SqlQuery::remove_app_from_check_list(const app_t &app)
@@ -265,12 +309,11 @@ void SqlQuery::get_apps(std::list<app_t> &apps_buffer)
while (getAppsCommand->Step()) {
app_t app;
- app.check_id = getAppsCommand->GetColumnInt32(0);
- app.app_id = getAppsCommand->GetColumnString(1);
- app.pkg_id = getAppsCommand->GetColumnString(2);
- app.uid = getAppsCommand->GetColumnInt64(3);
- app.verified = static_cast<app_t::verified_t>(getAppsCommand->GetColumnInt32(4));
- app.certificates = {};
+ app.app_id = getAppsCommand->GetColumnString(0);
+ app.pkg_id = getAppsCommand->GetColumnString(1);
+ app.uid = getAppsCommand->GetColumnInt64(2);
+ app.verified = static_cast<app_t::verified_t>(getAppsCommand->GetColumnInt32(3));
+ app.signatures = {};
LogDebug("App read from DB: app_id: " << app.str() << ", verified: " << static_cast<int32_t>(app.verified));
apps_buffer.push_back(app);
}
@@ -278,18 +321,37 @@ void SqlQuery::get_apps(std::list<app_t> &apps_buffer)
void SqlQuery::get_app_list(std::list<app_t> &apps_buffer)
{
+ m_connection->BeginTransaction();
get_apps(apps_buffer);
- // Get certificates for apps
- for (auto &iter : apps_buffer) {
- SqlConnection::DataCommandAutoPtr getCertsCommand =
- m_connection->PrepareDataCommand(DB_CMD_GET_CERTS);
- getCertsCommand->BindInt32(107, iter.check_id);
-
- while (getCertsCommand->Step()) {
- iter.certificates.push_back(getCertsCommand->GetColumnString(0));
+ // Get chain for every application
+ for (auto &iter_app : apps_buffer) {
+ SqlConnection::DataCommandAutoPtr getChainsCommand =
+ m_connection->PrepareDataCommand(DB_CMD_GET_CHAINS);
+ getChainsCommand->BindString(104, iter_app.app_id.c_str());
+ getChainsCommand->BindString(105, iter_app.pkg_id.c_str());
+ getChainsCommand->BindInt32(106, iter_app.uid);
+
+ // Get all certs from chain
+ while (getChainsCommand->Step()) {
+ chain_t chain;
+ int32_t chain_id;
+ chain_id = getChainsCommand->GetColumnInt32(0);
+ LogDebug("Found chain (" << chain_id << ") for " << iter_app.str());
+
+ SqlConnection::DataCommandAutoPtr getCertsCommand =
+ m_connection->PrepareDataCommand(DB_CMD_GET_CERTS);
+ getCertsCommand->BindInt32(110, chain_id);
+
+ // Add found certs to chain
+ while (getCertsCommand->Step()) {
+ chain.push_back(getCertsCommand->GetColumnString(0));
+ LogDebug("Found certificate (" << chain.size() << ") in chain no. " << chain_id);
+ }
+ iter_app.signatures.push_back(chain);
}
}
+ m_connection->CommitTransaction();
}
} // DB
diff --git a/src/include/cchecker/app.h b/src/include/cchecker/app.h
index 3217bdb..46fd9b6 100644
--- a/src/include/cchecker/app.h
+++ b/src/include/cchecker/app.h
@@ -23,7 +23,6 @@
#define CCHECKER_APP_H
#include <string>
-#include <vector>
#include <list>
#include <sys/types.h>
@@ -33,6 +32,9 @@ namespace CCHECKER {
// Currently in signals from pkgmgr only information about pkg_id is included
const char *const TEMP_APP_ID = "temp#app_id";
+typedef std::list<std::string> chain_t;
+typedef std::list<chain_t> signatures_t;
+
struct app_t {
enum class verified_t : int32_t {
NO = 0,
@@ -40,19 +42,19 @@ struct app_t {
UNKNOWN = 2
};
- int32_t check_id;
- std::string app_id;
- std::string pkg_id;
- uid_t uid;
- std::vector<std::string> certificates; //TODO: add typedef
- verified_t verified;
+ std::string app_id;
+ std::string pkg_id;
+ uid_t uid;
+ signatures_t signatures;
+ verified_t verified;
app_t(void);
app_t(const std::string &app_id,
const std::string &pkg_id,
uid_t uid,
- const std::vector<std::string> &certificates);
+ const signatures_t &signatures);
std::string str(void) const;
+ std::string str_certs(void) const;
};
struct url_t {
diff --git a/src/include/cchecker/sql_query.h b/src/include/cchecker/sql_query.h
index 5a22740..e4cc582 100644
--- a/src/include/cchecker/sql_query.h
+++ b/src/include/cchecker/sql_query.h
@@ -69,6 +69,7 @@ class SqlQuery {
void get_apps(std::list<app_t> &apps_buffer);
bool check_if_app_exists(const app_t &app);
bool get_check_id(const app_t &app, int32_t &check_id);
+ bool add_chain_id(const int32_t check_id, int32_t &chain_id);
int verified_enum_to_int(const app_t::verified_t &verified);
app_t::verified_t verified_int_to_enum(const int &verified);
};