summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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);
};