Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions include/libp2p/storage/sqlite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ namespace libp2p::storage {
}

/// Reads extended sqlite3 error code
int getErrorCode();
int getErrorCode() const;

/// Returns human-readable representation of an error
std::string getErrorMessage();
std::string getErrorMessage() const;

/**
* Store prepared statement
Expand All @@ -61,6 +61,7 @@ namespace libp2p::storage {
* @param st_handle - statement identifier
* @param args - command arguments
* @return number of rows affected, -1 in case of error
* @throws std::invalid_argument if statement handle is invalid
*/
template <typename... Args>
inline int execCommand(StatementHandle st_handle, const Args &...args) {
Expand All @@ -69,11 +70,14 @@ namespace libp2p::storage {
bindArgs(st, args...);
st.execute();
return countChanges();
} catch (const std::runtime_error &e) {
} catch (const std::invalid_argument &e) {
// getStatement can receive invalid handle
log_->error(e.what());
log_->error("Invalid statement handle: {}", e.what());
throw; // Re-throw invalid_argument as it's a programming error
} catch (const std::runtime_error &e) {
log_->error("Runtime error during command execution: {}", e.what());
} catch (...) {
log_->error(getErrorMessage());
log_->error("Unknown error during command execution: {}", getErrorMessage());
}
return -1;
}
Expand All @@ -86,6 +90,7 @@ namespace libp2p::storage {
* @param sink - query response consumer
* @param args - query arguments
* @return true when query was successfully executed, otherwise - false
* @throws std::invalid_argument if statement handle is invalid
*/
template <typename Sink, typename... Args>
inline bool execQuery(StatementHandle st_handle,
Expand All @@ -96,11 +101,14 @@ namespace libp2p::storage {
bindArgs(st, args...);
st >> sink;
return true;
} catch (const std::runtime_error &e) {
} catch (const std::invalid_argument &e) {
// getStatement can receive invalid handle
log_->error(e.what());
log_->error("Invalid statement handle: {}", e.what());
throw; // Re-throw invalid_argument as it's a programming error
} catch (const std::runtime_error &e) {
log_->error("Runtime error during query execution: {}", e.what());
} catch (...) {
log_->error(getErrorMessage());
log_->error("Unknown error during query execution: {}", getErrorMessage());
}
return false;
}
Expand All @@ -119,7 +127,13 @@ namespace libp2p::storage {
}

/// Returns the number of rows modified
int countChanges();
int countChanges() const;

/// Returns the database file path
const std::string &getDatabaseFile() const;

/// Returns the number of prepared statements
size_t getStatementCount() const;

::sqlite::database db_;
std::string db_file_;
Expand Down
50 changes: 46 additions & 4 deletions src/crypto/key_validator/key_validator_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,57 @@ namespace libp2p::crypto::validator {

outcome::result<void> KeyValidatorImpl::validateEcdsa(
const PrivateKey &key) const {
// TODO(xDimon): Check if it possible to validate ECDSA key by some way.
// issue: https://github.com/libp2p/cpp-libp2p/issues/103
// Basic ECDSA private key validation
// ECDSA private keys are typically 32 bytes for P-256, 48 bytes for P-384, 66 bytes for P-521
if (key.data.empty()) {
return KeyValidatorError::INVALID_PRIVATE_KEY;
}

// Check for reasonable key sizes (32-66 bytes covers most common curves)
if (key.data.size() < 32 || key.data.size() > 66) {
return KeyValidatorError::WRONG_PRIVATE_KEY_SIZE;
}

// Check that the key is not all zeros (invalid private key)
bool all_zeros = true;
for (const auto& byte : key.data) {
if (byte != 0) {
all_zeros = false;
break;
}
}
if (all_zeros) {
return KeyValidatorError::INVALID_PRIVATE_KEY;
}

return outcome::success();
}

outcome::result<void> KeyValidatorImpl::validateEcdsa(
const PublicKey &key) const {
// TODO(xDimon): Check if it possible to validate ECDSA key by some way.
// issue: https://github.com/libp2p/cpp-libp2p/issues/103
// Basic ECDSA public key validation
if (key.data.empty()) {
return KeyValidatorError::INVALID_PUBLIC_KEY;
}

// ECDSA public keys are typically 64 bytes (uncompressed) or 33/49/67 bytes (compressed)
// for P-256/P-384/P-521 respectively
if (key.data.size() < 33 || key.data.size() > 133) {
return KeyValidatorError::WRONG_PUBLIC_KEY_SIZE;
}

// Check that the key is not all zeros (invalid public key)
bool all_zeros = true;
for (const auto& byte : key.data) {
if (byte != 0) {
all_zeros = false;
break;
}
}
if (all_zeros) {
return KeyValidatorError::INVALID_PUBLIC_KEY;
}

return outcome::success();
}

Expand Down
21 changes: 16 additions & 5 deletions src/storage/sqlite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ namespace libp2p::storage {
}
}

int SQLite::getErrorCode() {
int SQLite::getErrorCode() const {
return sqlite3_extended_errcode(db_.connection().get());
}

std::string SQLite::getErrorMessage() {
int ec{getErrorCode()};
std::string SQLite::getErrorMessage() const {
const int ec{getErrorCode()};
return (0 == ec) ? std::string()
: std::string(sqlite3_errstr(ec)) + ": "
+ sqlite3_errmsg(db_.connection().get());
Expand All @@ -42,12 +42,23 @@ namespace libp2p::storage {
SQLite::database_binder &SQLite::getStatement(
SQLite::StatementHandle handle) {
if (handle >= statements_.size()) {
throw std::runtime_error("SQLite: statement does not exist");
throw std::invalid_argument("SQLite: statement handle " +
std::to_string(handle) +
" does not exist (max: " +
std::to_string(statements_.size() - 1) + ")");
}
return statements_[handle];
}

int SQLite::countChanges() {
int SQLite::countChanges() const {
return sqlite3_changes(db_.connection().get());
}

const std::string &SQLite::getDatabaseFile() const {
return db_file_;
}

size_t SQLite::getStatementCount() const {
return statements_.size();
}
} // namespace libp2p::storage
Loading