Merge pull request 'refactoring PICrypt, add PIStreamPackerConfig, delete piclientserver_config' (#184) from pisteampackerconfig into master

Reviewed-on: #184
This commit was merged in pull request #184.
This commit is contained in:
2024-11-16 15:44:15 +03:00
15 changed files with 232 additions and 445 deletions

View File

@@ -1,6 +1,6 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
@@ -48,7 +48,6 @@ PIClientServer::Client::~Client() {
void PIClientServer::Client::connect(PINetworkAddress addr) { void PIClientServer::Client::connect(PINetworkAddress addr) {
if (!tcp || !own_tcp) return; if (!tcp || !own_tcp) return;
close(); close();
config.apply(this);
tcp->connect(addr, true); tcp->connect(addr, true);
tcp->startThreadedRead(); tcp->startThreadedRead();
} }

View File

@@ -1,6 +1,6 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by

View File

@@ -1,50 +0,0 @@
/*
PIP - Platform Independent Primitives
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piclientserver_config.h"
#include "piclientserver_client_base.h"
void PIClientServer::Config::setPacketSign(ushort sign) {
packet_sign = sign;
}
void PIClientServer::Config::setPacketSize(int bytes) {
packet_size = bytes;
}
void PIClientServer::Config::enableSymmetricEncryption(const PIByteArray & key) {
crypt_key = key;
}
void PIClientServer::Config::apply(ClientBase * client) {
auto & s(client->stream);
s.setPacketSign(packet_sign);
s.setMaxPacketSize(packet_size);
if (crypt_key.isNotEmpty()) {
s.setCryptEnabled(true);
s.setCryptKey(crypt_key);
} else
s.setCryptEnabled(false);
}

View File

@@ -1,6 +1,6 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
@@ -132,7 +132,7 @@ void PIClientServer::Server::stopServer() {
void PIClientServer::Server::newClient(ServerClient * c) { void PIClientServer::Server::newClient(ServerClient * c) {
clients << c; clients << c;
config.apply(c); c->setConfiguration(configuration());
c->tcp->startThreadedRead(); c->tcp->startThreadedRead();
c->connected(); c->connected();
} }

View File

@@ -20,30 +20,29 @@
#include "picrypt.h" #include "picrypt.h"
#include "pitranslator.h" #include "pitranslator.h"
#ifdef PIP_CRYPT #include <sodium.h>
# include <sodium.h>
#endif
#define PICRYPT_DISABLED_WARNING \
piCout << "[PICrypt]" \
<< "Warning: PICrypt is disabled, to enable install sodium library and rebuild pip"_tr("PICrypt");
const char hash_def_key[] = "_picrypt_\0\0\0\0\0\0\0"; namespace {
const int hash_def_key_size = 9; constexpr char hash_def_key[] = "_picrypt_\0\0\0\0\0\0\0";
constexpr int hash_def_key_size = 9;
} // namespace
PICrypt::PICrypt() { PICrypt::PICrypt() {
#ifdef PIP_CRYPT if (!init()) {
if (!init())
piCout << "[PICrypt]" piCout << "[PICrypt]"
<< "Error while initialize sodium!"_tr("PICrypt"); << "Error while initialize sodium!"_tr("PICrypt");
}
nonce_.resize(crypto_secretbox_NONCEBYTES); nonce_.resize(crypto_secretbox_NONCEBYTES);
key_.resize(crypto_secretbox_KEYBYTES); key_.resize(crypto_secretbox_KEYBYTES);
randombytes_buf(key_.data(), key_.size()); randombytes_buf(key_.data(), key_.size());
randombytes_buf(nonce_.data(), nonce_.size()); randombytes_buf(nonce_.data(), nonce_.size());
#else }
PICRYPT_DISABLED_WARNING
#endif PICrypt::~PICrypt() {
key_.fill(0);
nonce_.fill(0);
} }
@@ -54,156 +53,138 @@ bool PICrypt::setKey(const PIByteArray & _key) {
} }
PIByteArray PICrypt::setKey(const PIString & secret) { bool PICrypt::setKey(const PIString & secret) {;
PIByteArray hash; key_ = hash(secret);
#ifdef PIP_CRYPT return key_.isNotEmpty();
hash.resize(crypto_generichash_BYTES);
PIByteArray s(secret.data(), secret.size());
crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), (const uchar *)hash_def_key, hash_def_key_size);
hash.resize(key_.size());
setKey(hash);
#endif
return hash;
} }
PIByteArray PICrypt::crypt(const PIByteArray & data) { PIByteArray PICrypt::crypt(const PIByteArray & data) {
PIByteArray ret; PIByteArray ret;
#ifdef PIP_CRYPT
ret.resize(data.size() + crypto_secretbox_MACBYTES); ret.resize(data.size() + crypto_secretbox_MACBYTES);
randombytes_buf(nonce_.data(), nonce_.size()); randombytes_buf(nonce_.data(), nonce_.size());
crypto_secretbox_easy(ret.data(), data.data(), data.size(), nonce_.data(), key_.data()); if (crypto_secretbox_easy(ret.data(), data.data(), data.size(), nonce_.data(), key_.data()) != 0) {
ret.append(nonce_); ret.clear();
#endif } else {
ret.append(nonce_);
}
return ret; return ret;
} }
PIByteArray PICrypt::crypt(const PIByteArray & data, PIByteArray key) { PIByteArray PICrypt::crypt(const PIByteArray & data, PIByteArray key) {
PIByteArray ret; if (!init()) {
#ifdef PIP_CRYPT key.fill(0);
return PIByteArray();
}
if (key.size() != crypto_secretbox_KEYBYTES) key.resize(crypto_secretbox_KEYBYTES, ' '); if (key.size() != crypto_secretbox_KEYBYTES) key.resize(crypto_secretbox_KEYBYTES, ' ');
// return PIByteArray();
if (!init()) return ret;
PIByteArray n; PIByteArray n;
ret.resize(data.size() + crypto_secretbox_MACBYTES);
n.resize(crypto_secretbox_NONCEBYTES); n.resize(crypto_secretbox_NONCEBYTES);
PIByteArray ret;
ret.resize(data.size() + crypto_secretbox_MACBYTES);
randombytes_buf(n.data(), n.size()); randombytes_buf(n.data(), n.size());
crypto_secretbox_easy(ret.data(), data.data(), data.size(), n.data(), key.data()); if (crypto_secretbox_easy(ret.data(), data.data(), data.size(), n.data(), key.data()) != 0) {
ret.append(n); ret.clear();
#else } else {
PICRYPT_DISABLED_WARNING ret.append(n);
#endif }
key.fill(0);
return ret; return ret;
} }
PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, bool * ok) { PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, bool * ok) {
PIByteArray ret;
#ifdef PIP_CRYPT
if (crypt_data.size() < nonce_.size() + crypto_secretbox_MACBYTES) { if (crypt_data.size() < nonce_.size() + crypto_secretbox_MACBYTES) {
if (ok) *ok = false; if (ok) *ok = false;
return PIByteArray(); return PIByteArray();
} }
ret.resize(crypt_data.size() - nonce_.size() - crypto_secretbox_MACBYTES); const ullong data_size = crypt_data.size() - nonce_.size();
memcpy(nonce_.data(), crypt_data.data(crypt_data.size() - nonce_.size()), nonce_.size()); PIByteArray ret;
if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - nonce_.size(), nonce_.data(), key_.data()) != 0) { ret.resize(data_size - crypto_secretbox_MACBYTES);
memcpy(nonce_.data(), crypt_data.data(data_size), nonce_.size());
if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), data_size, nonce_.data(), key_.data()) != 0) {
// Bad key
if (ok) *ok = false; if (ok) *ok = false;
// piCout << "[PICrypt]" << "bad key_"; ret.clear();
return PIByteArray(); } else if (ok) {
*ok = true;
} }
#endif
if (ok) *ok = true;
return ret; return ret;
} }
PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bool * ok) { PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bool * ok) {
PIByteArray ret; if (!init()) {
#ifdef PIP_CRYPT key.fill(0);
if (key.size() != crypto_secretbox_KEYBYTES) key.resize(crypto_secretbox_KEYBYTES, ' ');
/*if (ok) *ok = false;
return PIByteArray();
}*/
if (crypt_data.size() < crypto_secretbox_NONCEBYTES + crypto_secretbox_MACBYTES) {
if (ok) *ok = false;
return PIByteArray(); return PIByteArray();
} }
if (!init()) return ret; if (crypt_data.size() < crypto_secretbox_NONCEBYTES + crypto_secretbox_MACBYTES) {
if (ok) *ok = false;
key.fill(0);
return PIByteArray();
}
if (key.size() != crypto_secretbox_KEYBYTES) key.resize(crypto_secretbox_KEYBYTES, ' ');
PIByteArray n; PIByteArray n;
n.resize(crypto_secretbox_NONCEBYTES); n.resize(crypto_secretbox_NONCEBYTES);
ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES); const ullong data_size = crypt_data.size() - n.size();
memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size()); PIByteArray ret;
if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), key.data()) != 0) { ret.resize(data_size - crypto_secretbox_MACBYTES);
memcpy(n.data(), crypt_data.data(data_size), n.size());
if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), data_size, n.data(), key.data()) != 0) {
// Bad key
if (ok) *ok = false; if (ok) *ok = false;
// piCout << "[PICrypt]" << "bad key_"; ret.clear();
return PIByteArray(); } else if (ok) {
} else if (ok)
*ok = true; *ok = true;
#else }
PICRYPT_DISABLED_WARNING key.fill(0);
#endif
return ret; return ret;
} }
PIByteArray PICrypt::hash(const PIString & secret) { PIByteArray PICrypt::hash(PIString secret) {
PIByteArray hash; if (!init()) return {};
#ifdef PIP_CRYPT PIByteArray s = secret.toUTF8();
if (!init()) return hash; PIByteArray h = hash(s);
hash.resize(crypto_generichash_BYTES); memset(const_cast<char *>(secret.data()), 0, s.size());
PIByteArray s(secret.data(), secret.size()); secret.fill('\0');
crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), (const uchar *)hash_def_key, hash_def_key_size); s.fill(0);
#else return h;
PICRYPT_DISABLED_WARNING
#endif
return hash;
} }
PIByteArray PICrypt::hash(const PIByteArray & data) { PIByteArray PICrypt::hash(const PIByteArray & data) {
PIByteArray hash; if (!init()) return {};
#ifdef PIP_CRYPT PIByteArray h;
if (!init()) return hash; h.resize(crypto_generichash_BYTES);
hash.resize(crypto_generichash_BYTES); crypto_generichash(h.data(), h.size(), data.data(), data.size(), (const uchar *)hash_def_key, hash_def_key_size);
crypto_generichash(hash.data(), hash.size(), data.data(), data.size(), (const uchar *)hash_def_key, hash_def_key_size); return h;
#else
PICRYPT_DISABLED_WARNING
#endif
return hash;
} }
PIByteArray PICrypt::hash(const PIByteArray & data, const unsigned char * key, size_t keylen) { PIByteArray PICrypt::hash(const PIByteArray & data, const unsigned char * key, size_t keylen) {
PIByteArray hash; PIByteArray hash;
#ifdef PIP_CRYPT
if (!init()) return hash; if (!init()) return hash;
hash.resize(crypto_generichash_BYTES); hash.resize(crypto_generichash_BYTES);
crypto_generichash(hash.data(), hash.size(), data.data(), data.size(), key, keylen); crypto_generichash(hash.data(), hash.size(), data.data(), data.size(), key, keylen);
#else
PICRYPT_DISABLED_WARNING
#endif
return hash; return hash;
} }
size_t PICrypt::sizeHash() { size_t PICrypt::sizeHash() {
#ifdef PIP_CRYPT
return crypto_generichash_BYTES; return crypto_generichash_BYTES;
#else
PICRYPT_DISABLED_WARNING
#endif
return 0;
} }
ullong PICrypt::shorthash(const PIString & s, PIByteArray key) { ullong PICrypt::shorthash(const PIString & s, PIByteArray key) {
ullong hash = 0; ullong hash = 0;
#ifdef PIP_CRYPT if (!init()) {
key.fill(0);
return hash;
}
if (crypto_shorthash_BYTES != sizeof(hash)) if (crypto_shorthash_BYTES != sizeof(hash))
piCout << "[PICrypt]" piCout << "[PICrypt]"
<< "internal error: bad hash size"_tr("PICrypt"); << "internal error: bad hash size"_tr("PICrypt");
if (!init()) return hash;
if (key.size() != crypto_shorthash_KEYBYTES) { if (key.size() != crypto_shorthash_KEYBYTES) {
piCout << "[PICrypt]" piCout << "[PICrypt]"
<< "invalid key size %1, should be %2, filled with zeros"_tr("PICrypt").arg(key.size()).arg(crypto_shorthash_KEYBYTES); << "invalid key size %1, should be %2, filled with zeros"_tr("PICrypt").arg(key.size()).arg(crypto_shorthash_KEYBYTES);
@@ -211,207 +192,154 @@ ullong PICrypt::shorthash(const PIString & s, PIByteArray key) {
} }
PIByteArray in(s.data(), s.size()); PIByteArray in(s.data(), s.size());
crypto_shorthash((uchar *)&hash, in.data(), in.size(), key.data()); crypto_shorthash((uchar *)&hash, in.data(), in.size(), key.data());
#else key.fill(0);
PICRYPT_DISABLED_WARNING
#endif
return hash; return hash;
} }
PIByteArray PICrypt::generateKey() { PIByteArray PICrypt::generateKey() {
PIByteArray hash; return generateRandomBuff(sizeKey());
#ifdef PIP_CRYPT
if (!init()) return hash;
hash.resize(crypto_secretbox_KEYBYTES);
randombytes_buf(hash.data(), hash.size());
#else
PICRYPT_DISABLED_WARNING
#endif
return hash;
} }
PIByteArray PICrypt::generateRandomBuff(int size) { PIByteArray PICrypt::generateRandomBuff(int size) {
PIByteArray hash; PIByteArray hash;
#ifdef PIP_CRYPT
if (!init() || size <= 0) return hash; if (!init() || size <= 0) return hash;
hash.resize(size); hash.resize(size);
randombytes_buf(hash.data(), hash.size()); randombytes_buf(hash.data(), hash.size());
#else
PICRYPT_DISABLED_WARNING
#endif
return hash; return hash;
} }
size_t PICrypt::sizeKey() { size_t PICrypt::sizeKey() {
#ifdef PIP_CRYPT
return crypto_secretbox_KEYBYTES; return crypto_secretbox_KEYBYTES;
#else
PICRYPT_DISABLED_WARNING
#endif
return 0;
} }
size_t PICrypt::sizeCrypt() { size_t PICrypt::sizeCrypt() {
#ifdef PIP_CRYPT
return crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES; return crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES;
#else
PICRYPT_DISABLED_WARNING
#endif
return 0;
} }
void PICrypt::generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key) { bool PICrypt::generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key) {
#ifdef PIP_CRYPT if (!init()) return false;
if (!init()) return;
public_key.resize(crypto_sign_PUBLICKEYBYTES); public_key.resize(crypto_sign_PUBLICKEYBYTES);
secret_key.resize(crypto_sign_SECRETKEYBYTES); secret_key.resize(crypto_sign_SECRETKEYBYTES);
crypto_sign_keypair(public_key.data(), secret_key.data()); return crypto_sign_keypair(public_key.data(), secret_key.data()) == 0;
#else
PICRYPT_DISABLED_WARNING
#endif
} }
void PICrypt::generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed) { bool PICrypt::generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed) {
#ifdef PIP_CRYPT if (!init() || seed.isEmpty()) return false;
if (!init() || seed.isEmpty()) return;
public_key.resize(crypto_sign_PUBLICKEYBYTES); public_key.resize(crypto_sign_PUBLICKEYBYTES);
secret_key.resize(crypto_sign_SECRETKEYBYTES); secret_key.resize(crypto_sign_SECRETKEYBYTES);
crypto_sign_seed_keypair(public_key.data(), secret_key.data(), hash(seed).data()); return crypto_sign_seed_keypair(public_key.data(), secret_key.data(), hash(seed).data()) == 0;
#else
PICRYPT_DISABLED_WARNING
#endif
} }
PIByteArray PICrypt::extractSignPublicKey(const PIByteArray & secret_key) { PIByteArray PICrypt::extractSignPublicKey(const PIByteArray & secret_key) {
PIByteArray pk; PIByteArray pk;
#ifdef PIP_CRYPT
if (!init() || secret_key.size() != crypto_sign_SECRETKEYBYTES) return pk; if (!init() || secret_key.size() != crypto_sign_SECRETKEYBYTES) return pk;
pk.resize(crypto_sign_PUBLICKEYBYTES); pk.resize(crypto_sign_PUBLICKEYBYTES);
crypto_sign_ed25519_sk_to_pk(pk.data(), secret_key.data()); if (crypto_sign_ed25519_sk_to_pk(pk.data(), secret_key.data()) != 0) {
#else pk.clear();
PICRYPT_DISABLED_WARNING }
#endif
return pk; return pk;
} }
PIByteArray PICrypt::signMessage(const PIByteArray & data, PIByteArray secret_key) { PIByteArray PICrypt::signMessage(const PIByteArray & data, const PIByteArray & secret_key) {
PIByteArray sign; PIByteArray sign;
#ifdef PIP_CRYPT
if (!init()) return sign; if (!init()) return sign;
sign.resize(crypto_sign_BYTES); sign.resize(crypto_sign_BYTES);
crypto_sign_detached(sign.data(), 0, data.data(), data.size(), secret_key.data()); if (crypto_sign_detached(sign.data(), 0, data.data(), data.size(), secret_key.data()) != 0) {
#else sign.clear();
PICRYPT_DISABLED_WARNING }
#endif
return sign; return sign;
} }
bool PICrypt::verifySign(const PIByteArray & data, const PIByteArray & signature, PIByteArray public_key) { bool PICrypt::verifySign(const PIByteArray & data, const PIByteArray & signature, const PIByteArray & public_key) {
#ifdef PIP_CRYPT
if (!init()) return false; if (!init()) return false;
return (crypto_sign_verify_detached(signature.data(), data.data(), data.size(), public_key.data()) == 0); return (crypto_sign_verify_detached(signature.data(), data.data(), data.size(), public_key.data()) == 0);
#else
PICRYPT_DISABLED_WARNING
#endif
return false; return false;
} }
void PICrypt::generateKeypair(PIByteArray & public_key, PIByteArray & secret_key) { bool PICrypt::generateKeypair(PIByteArray & public_key, PIByteArray & secret_key) {
#ifdef PIP_CRYPT if (!init()) return false;
if (!init()) return;
public_key.resize(crypto_box_PUBLICKEYBYTES); public_key.resize(crypto_box_PUBLICKEYBYTES);
secret_key.resize(crypto_box_SECRETKEYBYTES); secret_key.resize(crypto_box_SECRETKEYBYTES);
crypto_box_keypair(public_key.data(), secret_key.data()); return crypto_box_keypair(public_key.data(), secret_key.data()) == 0;
#else
PICRYPT_DISABLED_WARNING
#endif
} }
void PICrypt::generateKeypair(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed) { bool PICrypt::generateKeypair(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed) {
#ifdef PIP_CRYPT if (!init()) return false;
if (!init()) return;
public_key.resize(crypto_box_PUBLICKEYBYTES); public_key.resize(crypto_box_PUBLICKEYBYTES);
secret_key.resize(crypto_box_SECRETKEYBYTES); secret_key.resize(crypto_box_SECRETKEYBYTES);
crypto_box_seed_keypair(public_key.data(), secret_key.data(), hash(seed).data()); return crypto_box_seed_keypair(public_key.data(), secret_key.data(), hash(seed).data()) == 0;
#else
PICRYPT_DISABLED_WARNING
#endif
} }
PIByteArray PICrypt::crypt(const PIByteArray & data, const PIByteArray & public_key, const PIByteArray & secret_key) { PIByteArray PICrypt::crypt(const PIByteArray & data, const PIByteArray & public_key, const PIByteArray & secret_key) {
PIByteArray ret; if (!init()) return PIByteArray();
#ifdef PIP_CRYPT if (public_key.size() != crypto_box_PUBLICKEYBYTES) return PIByteArray();
if (!init()) return ret; if (secret_key.size() != crypto_box_SECRETKEYBYTES) return PIByteArray();
if (public_key.size() != crypto_box_PUBLICKEYBYTES) return ret;
if (secret_key.size() != crypto_box_SECRETKEYBYTES) return ret;
PIByteArray n; PIByteArray n;
ret.resize(data.size() + crypto_box_MACBYTES);
n.resize(crypto_box_NONCEBYTES); n.resize(crypto_box_NONCEBYTES);
PIByteArray ret;
ret.resize(data.size() + crypto_box_MACBYTES);
randombytes_buf(n.data(), n.size()); randombytes_buf(n.data(), n.size());
if (crypto_box_easy(ret.data(), data.data(), data.size(), n.data(), public_key.data(), secret_key.data()) != 0) return PIByteArray(); if (crypto_box_easy(ret.data(), data.data(), data.size(), n.data(), public_key.data(), secret_key.data()) != 0) {
return PIByteArray();
}
ret.append(n); ret.append(n);
#else
PICRYPT_DISABLED_WARNING
#endif
return ret; return ret;
} }
PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, const PIByteArray & public_key, const PIByteArray & secret_key, bool * ok) { PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, const PIByteArray & public_key, const PIByteArray & secret_key, bool * ok) {
PIByteArray ret; if (!init()) {
#ifdef PIP_CRYPT if (ok) *ok = false;
if (!init()) return ret; return PIByteArray();
}
if (public_key.size() != crypto_box_PUBLICKEYBYTES) { if (public_key.size() != crypto_box_PUBLICKEYBYTES) {
if (ok) *ok = false; if (ok) *ok = false;
return ret; return PIByteArray();
} }
if (secret_key.size() != crypto_box_SECRETKEYBYTES) { if (secret_key.size() != crypto_box_SECRETKEYBYTES) {
if (ok) *ok = false; if (ok) *ok = false;
return ret; return PIByteArray();
} }
if (crypt_data.size() < crypto_box_NONCEBYTES + crypto_box_MACBYTES) { if (crypt_data.size() < crypto_box_NONCEBYTES + crypto_box_MACBYTES) {
if (ok) *ok = false; if (ok) *ok = false;
return ret; return PIByteArray();
} }
PIByteArray n; PIByteArray n;
n.resize(crypto_secretbox_NONCEBYTES); n.resize(crypto_secretbox_NONCEBYTES);
ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES); const ullong data_size = crypt_data.size() - n.size();
memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size()); PIByteArray ret;
if (crypto_box_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), public_key.data(), secret_key.data()) != ret.resize(data_size - crypto_secretbox_MACBYTES);
0) { memcpy(n.data(), crypt_data.data(data_size), n.size());
if (crypto_box_open_easy(ret.data(), crypt_data.data(), data_size, n.data(), public_key.data(), secret_key.data()) != 0) {
// Bad key
if (ok) *ok = false; if (ok) *ok = false;
// piCout << "[PICrypt]" << "bad key_"; ret.clear();
return PIByteArray(); } else if (ok) {
} else if (ok)
*ok = true; *ok = true;
#else }
PICRYPT_DISABLED_WARNING
#endif
return ret; return ret;
} }
PIByteArray PICrypt::passwordHash(const PIString & password, const PIByteArray & seed) { PIByteArray PICrypt::passwordHash(PIString password, const PIByteArray & seed) {
#ifdef crypto_pwhash_ALG_ARGON2I13 #ifdef crypto_pwhash_ALG_ARGON2I13
// char out[crypto_pwhash_STRBYTES];
PIByteArray pass = password.toUTF8(); PIByteArray pass = password.toUTF8();
PIByteArray n = hash(seed); PIByteArray n = hash(seed);
PIByteArray ph; PIByteArray ph;
ph.resize(crypto_box_SEEDBYTES); ph.resize(crypto_box_SEEDBYTES);
n.resize(crypto_pwhash_SALTBYTES); n.resize(crypto_pwhash_SALTBYTES);
// randombytes_buf(n.data(), n.size());
// crypto_shorthash(n.data(), seed.data(), seed.size(), PIByteArray(crypto_shorthash_KEYBYTES).data());
int r = crypto_pwhash(ph.data(), int r = crypto_pwhash(ph.data(),
ph.size(), ph.size(),
(const char *)pass.data(), (const char *)pass.data(),
@@ -420,31 +348,24 @@ PIByteArray PICrypt::passwordHash(const PIString & password, const PIByteArray &
crypto_pwhash_argon2i_opslimit_moderate(), crypto_pwhash_argon2i_opslimit_moderate(),
crypto_pwhash_argon2i_memlimit_moderate(), crypto_pwhash_argon2i_memlimit_moderate(),
crypto_pwhash_ALG_ARGON2I13); crypto_pwhash_ALG_ARGON2I13);
// crypto_pwhash_str(out, (const char*)pass.data(), pass.size(), crypto_pwhash_argon2i_opslimit_moderate(),
// crypto_pwhash_argon2i_memlimit_moderate());
pass.fill(0); pass.fill(0);
memset(const_cast<char *>(password.data()), 0, pass.size());
password.fill('\0');
if (r != 0) return PIByteArray(); if (r != 0) return PIByteArray();
return ph; return ph;
// PIByteArray ret;
// ret << ph << n << crypto_pwhash_argon2i_opslimit_moderate() << crypto_pwhash_argon2i_memlimit_moderate();
// return ret;
#else #else
piCout << "[PICrypt] Error, ALG_ARGON2I13 not availible!";
return PIByteArray(); return PIByteArray();
#endif #endif
} }
PIString PICrypt::version() { PIString PICrypt::version() {
#ifdef PIP_CRYPT
return SODIUM_VERSION_STRING; return SODIUM_VERSION_STRING;
#else
return PIString();
#endif
} }
bool PICrypt::init() { bool PICrypt::init() {
#ifdef PIP_CRYPT
static bool inited = false; static bool inited = false;
if (inited) return true; if (inited) return true;
// piCout << "[PICrypt]" << "init ..."; // piCout << "[PICrypt]" << "init ...";
@@ -452,8 +373,4 @@ bool PICrypt::init() {
if (!inited) inited = sodium_init(); if (!inited) inited = sodium_init();
// piCout << "[PICrypt]" << "init" << inited; // piCout << "[PICrypt]" << "init" << inited;
return inited; return inited;
#else
PICRYPT_DISABLED_WARNING
#endif
return false;
} }

View File

@@ -121,3 +121,11 @@ PIByteArray PIEthUtilBase::decryptData(const PIByteArray & data) {
return PIByteArray(); return PIByteArray();
#endif #endif
} }
size_t PIEthUtilBase::cryptSizeAddition() {
#ifdef PIP_CRYPT
return PICrypt::sizeCrypt();
#else
return 0;
#endif
}

View File

@@ -108,7 +108,7 @@ void PIPackedTCP::init() {
// piCout << "Server connected" << client; // piCout << "Server connected" << client;
packer.assignDevice(client); packer.assignDevice(client);
CONNECTL(client, disconnected, [this](bool) { CONNECTL(client, disconnected, [this](bool) {
packer.assignDevice(nullptr); // packer.assignDevice(nullptr); WTF?
packer.clear(); packer.clear();
disconnected(); disconnected();
}); });
@@ -193,7 +193,7 @@ bool PIPackedTCP::closeDevice() {
client->close(); client->close();
client->stopAndWait(); client->stopAndWait();
piDeleteSafety(client); piDeleteSafety(client);
packer.assignDevice(nullptr); // packer.assignDevice(nullptr); WTF?
} }
return eth->close(); return eth->close();
} }

View File

@@ -24,7 +24,6 @@
#include "pistreampacker.h" #include "pistreampacker.h"
#include "piiodevice.h" #include "piiodevice.h"
#include "piliterals_bytes.h"
#include "pitranslator.h" #include "pitranslator.h"
#ifdef __GNUC__ #ifdef __GNUC__
# pragma GCC diagnostic pop # pragma GCC diagnostic pop
@@ -50,28 +49,10 @@
PIStreamPacker::PIStreamPacker(PIIODevice * dev): PIObject() { PIStreamPacker::PIStreamPacker(PIIODevice * dev): PIObject() {
crypt_frag = crypt_size = false; packet_size = -1;
aggressive_optimization = true; if (dev) assignDevice(dev);
packet_size = -1;
size_crypted_size = sizeof(int);
crypt_frag_size = 1_MiB;
max_packet_size = 1400;
packet_sign = 0xAFBE;
assignDevice(dev);
} }
void PIStreamPacker::setCryptSizeEnabled(bool on) {
crypt_size = on;
if (crypt_size) {
PIByteArray ba;
ba << int(0);
size_crypted_size = cryptData(ba).size_s();
} else
size_crypted_size = sizeof(int);
}
void PIStreamPacker::clear() { void PIStreamPacker::clear() {
packet.clear(); packet.clear();
packet_size = -1; packet_size = -1;
@@ -81,22 +62,7 @@ void PIStreamPacker::clear() {
void PIStreamPacker::send(const PIByteArray & data) { void PIStreamPacker::send(const PIByteArray & data) {
if (data.isEmpty()) return; if (data.isEmpty()) return;
PIByteArray cd; PIByteArray cd = cryptData(data);
if (crypt_frag) {
int fcnt = (data.size_s() - 1) / crypt_frag_size + 1, fst = 0;
// piCout << "crypt_frag send" << fcnt << "frags";
PIByteArray frag;
for (int i = 0; i < fcnt; ++i) {
if (i == fcnt - 1)
frag = PIByteArray(data.data(fst), data.size_s() - fst);
else
frag = PIByteArray(data.data(fst), crypt_frag_size);
fst += crypt_frag_size;
cd << cryptData(frag);
}
} else {
cd = cryptData(data);
}
// piCout << "crypt" << data.size() << "->" << cd.size() << key().size(); // piCout << "crypt" << data.size() << "->" << cd.size() << key().size();
PIByteArray hdr, part; PIByteArray hdr, part;
hdr << packet_sign; hdr << packet_sign;
@@ -130,7 +96,7 @@ void PIStreamPacker::received(const PIByteArray & data) {
stream.append(data); stream.append(data);
// piCout << "rec" << data.size(); // piCout << "rec" << data.size();
while (!stream.isEmpty()) { while (!stream.isEmpty()) {
int hdr_size = sizeof(packet_sign) + size_crypted_size; int hdr_size = sizeof(packet_sign) + sizeCryptedSize();
if (packet_size < 0) { if (packet_size < 0) {
if (stream.size_s() < hdr_size) return; if (stream.size_s() < hdr_size) return;
ushort sign(0); ushort sign(0);
@@ -144,8 +110,8 @@ void PIStreamPacker::received(const PIByteArray & data) {
} }
int sz = -1; int sz = -1;
if (crypt_size) { if (crypt_size) {
PIByteArray crsz((uint)size_crypted_size); PIByteArray crsz(sizeCryptedSize());
memcpy(crsz.data(), stream.data(2), size_crypted_size); memcpy(crsz.data(), stream.data(2), crsz.size());
crsz = decryptData(crsz); crsz = decryptData(crsz);
if (crsz.size() < sizeof(sz)) { if (crsz.size() < sizeof(sz)) {
if (aggressive_optimization) if (aggressive_optimization)
@@ -156,7 +122,7 @@ void PIStreamPacker::received(const PIByteArray & data) {
} }
crsz >> sz; crsz >> sz;
} else { } else {
memcpy(&sz, stream.data(2), size_crypted_size); memcpy(&sz, stream.data(2), sizeCryptedSize());
} }
if (sz < 0) { if (sz < 0) {
if (aggressive_optimization) if (aggressive_optimization)
@@ -178,26 +144,7 @@ void PIStreamPacker::received(const PIByteArray & data) {
packet.append(stream.data(), ps); packet.append(stream.data(), ps);
stream.remove(0, ps); stream.remove(0, ps);
if (packet.size_s() == packet_size) { if (packet.size_s() == packet_size) {
PIByteArray cd; PIByteArray cd = decryptData(packet);
if (crypt_frag) {
// piCout << "decrypt frags ..." << packet_size;
while (packet.size_s() >= 4) {
// piCout << "decrypt frags take data ...";
PIByteArray frag;
// piCout << "decrypt frags take data done" << frag.size_s();
packet >> frag;
if (frag.isEmpty()) {
// piCout << "decrypt frags corrupt, break";
cd.clear();
break;
}
cd.append(decryptData(frag));
// piCout << "decrypt frags add" << frag.size_s();
}
// piCout << "decrypt frags done" << cd.size();
} else {
cd = decryptData(packet);
}
// piCout << "decrypt" << packet.size() << "->" << cd.size() << key().size(); // piCout << "decrypt" << packet.size() << "->" << cd.size() << key().size();
if (!cd.isEmpty()) { if (!cd.isEmpty()) {
endPacketReceive(); endPacketReceive();
@@ -213,10 +160,17 @@ void PIStreamPacker::received(const PIByteArray & data) {
void PIStreamPacker::assignDevice(PIIODevice * dev) { void PIStreamPacker::assignDevice(PIIODevice * dev) {
if (!dev) return; if (!dev) {
piCoutObj << "Error! device is NULL";
return;
}
if (!dev->infoFlags()[PIIODevice::Reliable]) { if (!dev->infoFlags()[PIIODevice::Reliable]) {
piCoutObj << "Warning! Not recommended to use with non-reliable device"_tr("PIStreamPacker") << dev; piCoutObj << "Warning! Not recommended to use with non-reliable device"_tr("PIStreamPacker") << dev;
} }
CONNECT2(void, const uchar *, ssize_t, dev, threadedReadEvent, this, received); CONNECT2(void, const uchar *, ssize_t, dev, threadedReadEvent, this, received);
CONNECT1(void, PIByteArray, this, sendRequest, dev, write); CONNECT1(void, PIByteArray, this, sendRequest, dev, write);
} }
uint PIStreamPacker::sizeCryptedSize() {
return sizeof(int) + (crypt_size ? cryptSizeAddition() : 0);
}

View File

@@ -6,7 +6,7 @@
*/ */
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by

View File

@@ -6,7 +6,7 @@
*/ */
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
@@ -25,7 +25,6 @@
#ifndef piclientserver_client_base_H #ifndef piclientserver_client_base_H
#define piclientserver_client_base_H #define piclientserver_client_base_H
#include "piclientserver_config.h"
#include "pidiagnostics.h" #include "pidiagnostics.h"
#include "pip_client_server_export.h" #include "pip_client_server_export.h"
#include "pistreampacker.h" #include "pistreampacker.h"
@@ -36,8 +35,10 @@ namespace PIClientServer {
class Server; class Server;
class ClientInterface {};
// template<bool EnableDiagnostics = false>
class PIP_CLIENT_SERVER_EXPORT ClientBase { class PIP_CLIENT_SERVER_EXPORT ClientBase {
friend class Config;
friend class Server; friend class Server;
NO_COPY_CLASS(ClientBase); NO_COPY_CLASS(ClientBase);
@@ -57,7 +58,9 @@ public:
PIDiagnostics::State diagnostics() const; PIDiagnostics::State diagnostics() const;
int receivePacketProgress() const; int receivePacketProgress() const;
Config & configuration() { return config; } const PIStreamPackerConfig & configuration() const { return stream.configuration(); }
PIStreamPackerConfig & configuration() { return stream.configuration(); }
void setConfiguration(const PIStreamPackerConfig & config) { stream.setConfiguration(config); }
protected: protected:
virtual void readed(PIByteArray data) {} virtual void readed(PIByteArray data) {}
@@ -71,7 +74,6 @@ protected:
bool own_tcp = false; bool own_tcp = false;
std::atomic_bool can_write = {true}; std::atomic_bool can_write = {true};
PIEthernet * tcp = nullptr; PIEthernet * tcp = nullptr;
Config config;
private: private:
void destroy(); void destroy();

View File

@@ -1,60 +0,0 @@
/*! \file piclientserver_config.h
* \ingroup ClientServer
* \~\brief
* \~english
* \~russian
*/
/*
PIP - Platform Independent Primitives
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef piclientserver_config_H
#define piclientserver_config_H
#include "pibytearray.h"
#include "pip_client_server_export.h"
namespace PIClientServer {
class Server;
class Client;
class ClientBase;
class PIP_CLIENT_SERVER_EXPORT Config {
friend class Server;
friend class Client;
public:
void setPacketSign(ushort sign);
void setPacketSize(int bytes);
void enableSymmetricEncryption(const PIByteArray & key);
protected:
void apply(ClientBase * client);
PIByteArray crypt_key;
ushort packet_sign = 0xAFBE;
int packet_size = 1400;
private:
};
} // namespace PIClientServer
#endif

View File

@@ -6,7 +6,7 @@
*/ */
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
@@ -25,10 +25,10 @@
#ifndef piclientserver_server_H #ifndef piclientserver_server_H
#define piclientserver_server_H #define piclientserver_server_H
#include "piclientserver_config.h"
#include "pimutex.h" #include "pimutex.h"
#include "pinetworkaddress.h" #include "pinetworkaddress.h"
#include "pip_client_server_export.h" #include "pip_client_server_export.h"
#include "pistreampacker.h"
#include "pithreadnotifier.h" #include "pithreadnotifier.h"
class PIEthernet; class PIEthernet;
@@ -38,7 +38,7 @@ namespace PIClientServer {
class ServerClient; class ServerClient;
class PIP_CLIENT_SERVER_EXPORT Server { class PIP_CLIENT_SERVER_EXPORT Server: public PIStreamPackerConfig {
friend class ServerClient; friend class ServerClient;
NO_COPY_CLASS(Server); NO_COPY_CLASS(Server);
@@ -59,8 +59,6 @@ public:
void setClientFactory(std::function<ServerClient *()> f) { client_factory = f; } void setClientFactory(std::function<ServerClient *()> f) { client_factory = f; }
Config & configuration() { return config; }
private: private:
void newClient(ServerClient * c); void newClient(ServerClient * c);
void clientDisconnected(ServerClient * c); void clientDisconnected(ServerClient * c);
@@ -70,7 +68,6 @@ private:
PIEthernet * tcp_server = nullptr; PIEthernet * tcp_server = nullptr;
PIThread * clean_thread = nullptr; PIThread * clean_thread = nullptr;
PIThreadNotifier clean_notifier; PIThreadNotifier clean_notifier;
Config config;
PIVector<ServerClient *> clients; PIVector<ServerClient *> clients;
mutable PIMutex clients_mutex; mutable PIMutex clients_mutex;

View File

@@ -5,22 +5,22 @@
* \~russian Шифрование с помощью libsodium * \~russian Шифрование с помощью libsodium
*/ */
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Cryptographic class using lib Sodium Cryptographic class using lib Sodium
Andrey Bychkov work.a.b@yandex.ru Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PICRYPT_H #ifndef PICRYPT_H
@@ -40,6 +40,8 @@ public:
//! \~russian Конструктор, генерирующий случайный ключ //! \~russian Конструктор, генерирующий случайный ключ
PICrypt(); PICrypt();
~PICrypt();
//! \~\brief //! \~\brief
//! \~english Set key to "key", key size must be a \a sizeKey() //! \~english Set key to "key", key size must be a \a sizeKey()
//! \~russian Установить ключ "key", размер ключа должен быть равен \a sizeKey() //! \~russian Установить ключ "key", размер ключа должен быть равен \a sizeKey()
@@ -48,7 +50,7 @@ public:
//! \~\brief //! \~\brief
//! \~english Generate and set key from keyphrase "secret" //! \~english Generate and set key from keyphrase "secret"
//! \~russian Генерировать и установить ключ из ключевой фразы "secret" //! \~russian Генерировать и установить ключ из ключевой фразы "secret"
PIByteArray setKey(const PIString & secret); bool setKey(const PIString & secret);
//! \~\brief //! \~\brief
//! \~english Returns current key //! \~english Returns current key
@@ -78,7 +80,7 @@ public:
//! \~\brief //! \~\brief
//! \~english Generate hash from keyphrase "secret", may be used as a key for encryption //! \~english Generate hash from keyphrase "secret", may be used as a key for encryption
//! \~russian Генерировать хэш из ключевой фразы "secret", может использоваться в качестве ключа для шифрования //! \~russian Генерировать хэш из ключевой фразы "secret", может использоваться в качестве ключа для шифрования
static PIByteArray hash(const PIString & secret); static PIByteArray hash(PIString secret);
//! \~\brief //! \~\brief
//! \~english Generate hash from bytearray //! \~english Generate hash from bytearray
@@ -123,12 +125,12 @@ public:
//! \~\brief //! \~\brief
//! \~english Function randomly generates a secret key and a corresponding public key for digital signature //! \~english Function randomly generates a secret key and a corresponding public key for digital signature
//! \~russian Функция случайным образом генерирует секретный ключ и соответствующий ему открытый ключ для цифровой подписи //! \~russian Функция случайным образом генерирует секретный ключ и соответствующий ему открытый ключ для цифровой подписи
static void generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key); static bool generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key);
//! \~\brief //! \~\brief
//! \~english Function generates a secret key from input data and a corresponding public key for digital signature //! \~english Function generates a secret key from input data and a corresponding public key for digital signature
//! \~russian Функция генерирует секретный ключ из входных данных и соответствующий ему открытый ключ для цифровой подписи //! \~russian Функция генерирует секретный ключ из входных данных и соответствующий ему открытый ключ для цифровой подписи
static void generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed); static bool generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed);
//! \~\brief //! \~\brief
//! \~english Function extract sign public key from sing secret key //! \~english Function extract sign public key from sing secret key
@@ -138,24 +140,24 @@ public:
//! \~\brief //! \~\brief
//! \~english Calculate digital signature for data //! \~english Calculate digital signature for data
//! \~russian Вычислить цифровую подпись для данных //! \~russian Вычислить цифровую подпись для данных
PIByteArray signMessage(const PIByteArray & data, PIByteArray secret_key); PIByteArray signMessage(const PIByteArray & data, const PIByteArray & secret_key);
//! \~\brief //! \~\brief
//! \~english Verify digital signature of signed message //! \~english Verify digital signature of signed message
//! \~russian Проверить цифровую подпись подписанного сообщения //! \~russian Проверить цифровую подпись подписанного сообщения
bool verifySign(const PIByteArray & data, const PIByteArray & signature, PIByteArray public_key); bool verifySign(const PIByteArray & data, const PIByteArray & signature, const PIByteArray & public_key);
//! \~\brief //! \~\brief
//! \~english Function randomly generates a secret key and a corresponding public key for authenticated encryption //! \~english Function randomly generates a secret key and a corresponding public key for authenticated encryption
//! \~russian Функция случайным образом генерирует секретный ключ и соответствующий ему открытый ключ для аутентифицированного //! \~russian Функция случайным образом генерирует секретный ключ и соответствующий ему открытый ключ для аутентифицированного
//! шифрования //! шифрования
static void generateKeypair(PIByteArray & public_key, PIByteArray & secret_key); static bool generateKeypair(PIByteArray & public_key, PIByteArray & secret_key);
//! \~\brief //! \~\brief
//! \~english Function generates a secret key from input data and a corresponding public key for authenticated encryption //! \~english Function generates a secret key from input data and a corresponding public key for authenticated encryption
//! \~russian Функция генерирует секретный ключ из входных данных и соответствующий ему открытый ключ для аутентифицированного //! \~russian Функция генерирует секретный ключ из входных данных и соответствующий ему открытый ключ для аутентифицированного
//! шифрования //! шифрования
static void generateKeypair(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed); static bool generateKeypair(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed);
//! \~\brief //! \~\brief
//! \~english Encrypt given data "data" //! \~english Encrypt given data "data"
@@ -170,7 +172,7 @@ public:
//! \~\brief //! \~\brief
//! \~english Generate password hash from "password" //! \~english Generate password hash from "password"
//! \~russian Генерировать хэш пароля из "password" //! \~russian Генерировать хэш пароля из "password"
static PIByteArray passwordHash(const PIString & password, const PIByteArray & seed); static PIByteArray passwordHash(PIString password, const PIByteArray & seed);
//! \~\brief //! \~\brief
//! \~english Returns libsodium version //! \~english Returns libsodium version

View File

@@ -57,6 +57,9 @@ public:
//! Returns crypt layer key //! Returns crypt layer key
PIByteArray cryptKey() const; PIByteArray cryptKey() const;
//! \brief Returns addition size for crypted data.
static size_t cryptSizeAddition();
protected: protected:
/*! \brief Returns encrypted data if layer enabled, /*! \brief Returns encrypted data if layer enabled,
* otherwise returns unchanged \"data\" */ * otherwise returns unchanged \"data\" */

View File

@@ -33,15 +33,16 @@
class PIIODevice; class PIIODevice;
class PIP_IO_UTILS_EXPORT PIStreamPacker class PIStreamPackerConfig: public PIEthUtilBase {
: public PIObject friend class PIStreamPacker;
, public PIEthUtilBase {
PIOBJECT(PIStreamPacker)
public: public:
//! Contructs packer and try to assign \"dev\" PIStreamPackerConfig() {
PIStreamPacker(PIIODevice * dev = 0); crypt_size = false;
aggressive_optimization = true;
max_packet_size = 1400;
packet_sign = 0xAFBE;
}
//! Set maximum size of single packet //! Set maximum size of single packet
void setMaxPacketSize(int max_size) { max_packet_size = max_size; } void setMaxPacketSize(int max_size) { max_packet_size = max_size; }
@@ -49,17 +50,12 @@ public:
//! Returns maximum size of single packet, default 1400 bytes //! Returns maximum size of single packet, default 1400 bytes
int maxPacketSize() const { return max_packet_size; } int maxPacketSize() const { return max_packet_size; }
//! Set packet sinature //! Set packet sinature
void setPacketSign(ushort sign_) { packet_sign = sign_; } void setPacketSign(ushort sign_) { packet_sign = sign_; }
//! Returns packet sinature, default 0xAFBE //! Returns packet sinature, default 0xAFBE
ushort packetSign() const { return packet_sign; } ushort packetSign() const { return packet_sign; }
//! Returns progress of current packet receive in bytes
int receivePacketProgress() const { return packet.size_s(); }
//! Set receive aggressive optimization. If yes then %PIStreamPacker doesn`t //! Set receive aggressive optimization. If yes then %PIStreamPacker doesn`t
//! check every byte in incoming stream but check only begin of each read() //! check every byte in incoming stream but check only begin of each read()
//! result. Default is \b true. //! result. Default is \b true.
@@ -68,17 +64,37 @@ public:
//! Returns aggressive optimization //! Returns aggressive optimization
bool aggressiveOptimization() const { return aggressive_optimization; } bool aggressiveOptimization() const { return aggressive_optimization; }
bool cryptFragmentationEnabled() const { return crypt_frag; }
void setCryptFragmentationEnabled(bool on) { crypt_frag = on; }
int cryptFragmentationSize() const { return crypt_frag_size; }
void setCryptFragmentationSize(int size_) { crypt_frag_size = size_; }
bool cryptSizeEnabled() const { return crypt_size; } bool cryptSizeEnabled() const { return crypt_size; }
void setCryptSizeEnabled(bool on); void setCryptSizeEnabled(bool on) { crypt_size = on; }
//! Get configuration
const PIStreamPackerConfig & configuration() const { return *this; }
PIStreamPackerConfig & configuration() { return *this; }
//! Apply configuration
void setConfiguration(const PIStreamPackerConfig & config) { *this = config; }
private:
bool crypt_size, aggressive_optimization;
ushort packet_sign;
int max_packet_size;
};
class PIP_IO_UTILS_EXPORT PIStreamPacker
: public PIObject
, public PIStreamPackerConfig {
PIOBJECT(PIStreamPacker)
public:
//! Contructs packer and try to assign \"dev\"
PIStreamPacker(PIIODevice * dev = nullptr);
//! Returns progress of current packet receive in bytes
int receivePacketProgress() const { return packet.size_s(); }
void clear(); void clear();
//! Prepare data for send and raise \a sendRequest() events //! Prepare data for send and raise \a sendRequest() events
void send(const PIByteArray & data); void send(const PIByteArray & data);
@@ -130,11 +146,10 @@ protected:
virtual void packetReceived(PIByteArray data) {} virtual void packetReceived(PIByteArray data) {}
private: private:
uint sizeCryptedSize();
PIByteArray stream, packet; PIByteArray stream, packet;
bool crypt_frag, crypt_size, aggressive_optimization; int packet_size;
int packet_size, crypt_frag_size;
ushort packet_sign;
int max_packet_size, size_crypted_size;
mutable PIMutex prog_s_mutex, prog_r_mutex; mutable PIMutex prog_s_mutex, prog_r_mutex;
}; };