1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

updated tonlib

This commit is contained in:
ton 2019-10-04 21:17:47 +04:00
parent dd745485e2
commit 7c595294b6
12 changed files with 125 additions and 14 deletions

View file

@ -39,6 +39,34 @@
// { dup abs <# #s rot sign #> nip } : (.)
// { (.) type } : ._
// { ._ space } : .
{ dup 10 < { 48 } { 55 } cond + } : Digit
{ dup 10 < { 48 } { 87 } cond + } : digit
// x s b -- x' s'
{ -rot swap rot /mod Digit rot swap hold } : B#
{ -rot swap rot /mod digit rot swap hold } : b#
{ 16 B# } : X#
{ 16 b# } : x#
// x s b -- 0 s'
{ -rot { 2 pick B# over 0<= } until rot drop } : B#s
{ -rot { 2 pick b# over 0<= } until rot drop } : b#s
{ 16 B#s } : X#s
{ 16 b#s } : x#s
variable base
{ 10 base ! } : decimal
{ 16 base ! } : hex
{ 8 base ! } : octal
{ 2 base ! } : binary
{ base @ B# } : Base#
{ base @ b# } : base#
{ base @ B#s } : Base#s
{ base @ b#s } : base#s
// x w -- s
{ over abs <# rot 1- ' X# swap times X#s rot sign #> nip } : (0X.)
{ over abs <# rot 1- ' x# swap times x#s rot sign #> nip } : (0x.)
{ (0X.) type } : 0X._
{ 0X._ space } : 0X.
{ (0x.) type } : 0x._
{ 0x._ space } : 0x.
{ bl (-trailing) } : -trailing
{ char 0 (-trailing) } : -trailing0
{ char " word 1 ' $+ } ::_ +"

View file

@ -33,7 +33,7 @@ library TonUtil // TON Blockchain Fift Library
} : parse-smc-addr
// ( wc addr -- ) Show address in <workchain>:<account> form
{ swap ._ .":" x. } : .addr
{ swap ._ .":" 64 0x. } : .addr
// ( wc addr flags -- ) Show address in base64url form
{ smca>$ type } : .Addr
// ( wc addr fname -- ) Save address to file in 36-byte format

View file

@ -85,6 +85,8 @@ logVerbosityLevel verbosity_level:int32 = LogVerbosityLevel;
//@description Contains a list of available TDLib internal log tags @tags List of log tags
logTags tags:vector<string> = LogTags;
data bytes:secureBytes = Data;
---functions---
init options:options = Ok;
@ -103,6 +105,10 @@ importPemKey local_password:secureBytes key_password:secureBytes exported_key:ex
importEncryptedKey local_password:secureBytes key_password:secureBytes exported_encrypted_key:exportedEncryptedKey = Key;
changeLocalPassword input_key:inputKey new_local_password:secureBytes = Key;
encrypt decrypted_data:secureBytes secret:secureBytes = Data;
decrypt encrypted_data:secureBytes secret:secureBytes = Data;
kdf password:secureBytes salt:secureBytes iterations:int32 = Data;
unpackAccountAddress account_address:string = UnpackedAccountAddress;
packAccountAddress account_address:unpackedAccountAddress = AccountAddress;

Binary file not shown.

View file

@ -430,6 +430,34 @@ TEST(Tonlib, ParseAddres) {
ASSERT_EQ("Uf9Tj6fMJP-OqhAdhKXxq36DL-HYSzCc3-9O6UNzqsgPfdyS", addr_str2->account_address_);
}
TEST(Tonlib, EncryptionApi) {
using tonlib_api::make_object;
Client client;
// init
sync_send(client, make_object<tonlib_api::init>(
make_object<tonlib_api::options>(nullptr, make_object<tonlib_api::keyStoreTypeDirectory>("."))))
.ensure();
std::string password = "hello world";
std::string data = "very secret data";
auto key = std::move(
sync_send(client, make_object<tonlib_api::kdf>(td::SecureString(password), td::SecureString("salt"), 100000))
.move_as_ok()
->bytes_);
auto encrypted = std::move(
sync_send(client, make_object<tonlib_api::encrypt>(td::SecureString(data), key.copy())).move_as_ok()->bytes_);
auto decrypted =
std::move(sync_send(client, make_object<tonlib_api::decrypt>(encrypted.copy(), key.copy())).move_as_ok()->bytes_);
ASSERT_EQ(data, decrypted);
auto bad_key = std::move(sync_send(client, make_object<tonlib_api::kdf>(td::SecureString(password + "BAD"),
td::SecureString("salt"), 100000))
.move_as_ok()
->bytes_);
sync_send(client, make_object<tonlib_api::decrypt>(encrypted.copy(), bad_key.copy())).ensure_error();
}
TEST(Tonlib, KeysApi) {
using tonlib_api::make_object;
Client client;

View file

@ -28,6 +28,7 @@
#include "tonlib/TestGiver.h"
#include "tonlib/utils.h"
#include "tonlib/keys/Mnemonic.h"
#include "tonlib/keys/SimpleEncryption.h"
#include "tonlib/TonlibError.h"
@ -444,7 +445,7 @@ tonlib_api::object_ptr<tonlib_api::Object> TonlibClient::static_request(
tonlib_api::object_ptr<tonlib_api::Object> response;
downcast_call(*function, [&response](auto& request) { response = TonlibClient::do_static_request(request); });
VLOG(tonlib_query) << " answer static query " << to_string(function);
VLOG(tonlib_query) << " answer static query " << to_string(response);
return response;
}
@ -466,6 +467,9 @@ bool TonlibClient::is_static_request(td::int32 id) {
case tonlib_api::setLogTagVerbosityLevel::ID:
case tonlib_api::getLogTagVerbosityLevel::ID:
case tonlib_api::addLogMessage::ID:
case tonlib_api::encrypt::ID:
case tonlib_api::decrypt::ID:
case tonlib_api::kdf::ID:
return true;
default:
return false;
@ -1633,4 +1637,28 @@ tonlib_api::object_ptr<tonlib_api::Object> TonlibClient::do_static_request(const
return tonlib_api::make_object<tonlib_api::ok>();
}
tonlib_api::object_ptr<tonlib_api::Object> TonlibClient::do_static_request(const tonlib_api::encrypt& request) {
return tonlib_api::make_object<tonlib_api::data>(
SimpleEncryption::encrypt_data(request.decrypted_data_, request.secret_));
}
tonlib_api::object_ptr<tonlib_api::Object> TonlibClient::do_static_request(const tonlib_api::decrypt& request) {
auto r_data = SimpleEncryption::decrypt_data(request.encrypted_data_, request.secret_);
if (r_data.is_ok()) {
return tonlib_api::make_object<tonlib_api::data>(r_data.move_as_ok());
} else {
return status_to_tonlib_api(r_data.error().move_as_error_prefix(TonlibError::KeyDecrypt()));
}
}
tonlib_api::object_ptr<tonlib_api::Object> TonlibClient::do_static_request(const tonlib_api::kdf& request) {
auto max_iterations = 10000000;
if (request.iterations_ < 0 || request.iterations_ > max_iterations) {
return status_to_tonlib_api(
TonlibError::InvalidField("iterations", PSLICE() << "must be between 0 and " << max_iterations));
}
return tonlib_api::make_object<tonlib_api::data>(
SimpleEncryption::kdf(request.password_, request.salt_, request.iterations_));
}
} // namespace tonlib

View file

@ -117,6 +117,10 @@ class TonlibClient : public td::actor::Actor {
static object_ptr<tonlib_api::Object> do_static_request(const tonlib_api::getLogTags& request);
static object_ptr<tonlib_api::Object> do_static_request(const tonlib_api::addLogMessage& request);
static object_ptr<tonlib_api::Object> do_static_request(const tonlib_api::encrypt& request);
static object_ptr<tonlib_api::Object> do_static_request(const tonlib_api::decrypt& request);
static object_ptr<tonlib_api::Object> do_static_request(const tonlib_api::kdf& request);
template <class T, class P>
td::Status do_request(const T& request, P&& promise) {
return td::Status::Error(400, "Function is unsupported");

View file

@ -42,12 +42,10 @@ EncryptedKey DecryptedKey::encrypt(td::Slice local_password, td::Slice old_secre
} else {
td::Random::secure_bytes(secret.as_mutable_slice());
}
td::SecureString decrypted_secret(32);
hmac_sha256(secret, local_password, decrypted_secret.as_mutable_slice());
td::SecureString decrypted_secret = SimpleEncryption::combine_secrets(secret, local_password);
td::SecureString encryption_secret(64);
pbkdf2_sha512(as_slice(decrypted_secret), "TON local key", EncryptedKey::PBKDF_ITERATIONS,
encryption_secret.as_mutable_slice());
td::SecureString encryption_secret =
SimpleEncryption::kdf(as_slice(decrypted_secret), "TON local key", EncryptedKey::PBKDF_ITERATIONS);
std::vector<td::SecureString> mnemonic_words_copy;
for (auto &w : mnemonic_words) {

View file

@ -28,19 +28,21 @@ td::Result<DecryptedKey> EncryptedKey::decrypt(td::Slice local_password, bool ch
if (secret.size() != 32) {
return td::Status::Error("Failed to decrypt key: invalid secret size");
}
td::SecureString decrypted_secret(32);
td::SecureString decrypted_secret;
if (old) {
decrypted_secret = td::SecureString(32);
td::SecureString local_password_hash(32);
sha256(local_password, local_password_hash.as_mutable_slice());
for (size_t i = 0; i < 32; i++) {
decrypted_secret.as_mutable_slice()[i] = secret.as_slice()[i] ^ local_password_hash.as_slice()[i];
}
} else {
hmac_sha256(secret, local_password, decrypted_secret.as_mutable_slice());
decrypted_secret = SimpleEncryption::combine_secrets(secret, local_password);
}
td::SecureString encryption_secret(64);
pbkdf2_sha512(as_slice(decrypted_secret), "TON local key", PBKDF_ITERATIONS, encryption_secret.as_mutable_slice());
td::SecureString encryption_secret =
SimpleEncryption::kdf(as_slice(decrypted_secret), "TON local key", EncryptedKey::PBKDF_ITERATIONS);
TRY_RESULT(decrypted_data, SimpleEncryption::decrypt_data(as_slice(encrypted_data), as_slice(encryption_secret)));
RawDecryptedKey raw_decrypted_key;

View file

@ -50,6 +50,12 @@ td::SecureString SimpleEncryption::combine_secrets(td::Slice a, td::Slice b) {
return res;
}
td::SecureString SimpleEncryption::kdf(td::Slice secret, td::Slice password, int iterations) {
td::SecureString new_secret(64);
pbkdf2_sha512(secret, password, iterations, new_secret.as_mutable_slice());
return new_secret;
}
td::SecureString SimpleEncryption::encrypt_data_with_prefix(td::Slice data, td::Slice secret) {
CHECK(data.size() % 16 == 0);
auto data_hash = sha256(data);

View file

@ -27,13 +27,14 @@ class SimpleEncryption {
public:
static td::SecureString encrypt_data(td::Slice data, td::Slice secret);
static td::Result<td::SecureString> decrypt_data(td::Slice encrypted_data, td::Slice secret);
static td::SecureString combine_secrets(td::Slice a, td::Slice b);
static td::SecureString kdf(td::Slice secret, td::Slice password, int iterations);
private:
static td::AesCbcState calc_aes_cbc_state_hash(td::Slice hash);
static td::AesCbcState calc_aes_cbc_state_sha512(td::Slice seed);
static td::SecureString gen_random_prefix(td::int64 data_size);
static td::SecureString combine_secrets(td::Slice a, td::Slice b);
static td::SecureString encrypt_data_with_prefix(td::Slice data, td::Slice secret);
};
} // namespace tonlib

View file

@ -58,6 +58,9 @@ class TonlibCli : public td::actor::Actor {
bool is_closing_{false};
td::uint32 ref_cnt_{1};
td::int64 snd_bytes_{0};
td::int64 rcv_bytes_{0};
void start_up() override {
class Cb : public td::TerminalIO::Callback {
public:
@ -258,15 +261,21 @@ class TonlibCli : public td::actor::Actor {
auto addr = parser.read_word();
auto bounceable = parser.read_word();
set_bounceable(addr, to_bool(bounceable, true));
} else if (cmd == "netstats") {
dump_netstats();
}
}
void dump_netstats() {
td::TerminalIO::out() << td::tag("snd", td::format::as_size(snd_bytes_)) << "\n";
td::TerminalIO::out() << td::tag("rcv", td::format::as_size(rcv_bytes_)) << "\n";
}
void on_adnl_result(td::uint64 id, td::Result<td::BufferSlice> res) {
using tonlib_api::make_object;
if (res.is_ok()) {
rcv_bytes_ += res.ok().size();
send_query(make_object<tonlib_api::onLiteServerQueryResult>(id, res.move_as_ok().as_slice().str()),
[](auto r_ok) { LOG_IF(ERROR, r_ok.is_error()) << r_ok.error(); });
LOG(ERROR) << "!!!";
} else {
send_query(make_object<tonlib_api::onLiteServerQueryError>(
id, make_object<tonlib_api::error>(res.error().code(), res.error().message().str())),
@ -279,6 +288,7 @@ class TonlibCli : public td::actor::Actor {
if (result->get_id() == tonlib_api::updateSendLiteServerQuery::ID) {
auto update = tonlib_api::move_object_as<tonlib_api::updateSendLiteServerQuery>(std::move(result));
CHECK(!raw_client_.empty());
snd_bytes_ += update->data_.size();
send_closure(raw_client_, &ton::adnl::AdnlExtClient::send_query, "query", td::BufferSlice(update->data_),
td::Timestamp::in(5),
[actor_id = actor_id(this), id = update->id_](td::Result<td::BufferSlice> res) {
@ -800,7 +810,7 @@ class TonlibCli : public td::actor::Actor {
}
void transfer(Address from, Address to, td::uint64 grams, td::Slice password, td::Slice message,
bool allow_send_to_uninited) {
auto r_sz = td::to_integer_safe<td::size_t>(message);
auto r_sz = td::to_integer_safe<size_t>(message);
auto msg = message.str();
if (r_sz.is_ok()) {
msg = std::string(r_sz.ok(), 'Z');