git-svn-id: svn://db.shs.com.ru/pip@607 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2018-04-26 18:20:03 +00:00
parent ef4030ebb9
commit cfa7be623c
11 changed files with 815 additions and 131 deletions

View File

@@ -98,7 +98,7 @@ get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME)
# Sources
# Main lib
set(PIP_FOLDERS "." "core" "containers" "thread" "system" "io" "console" "math" "code" "geo" "resources" "opencl")
set(PIP_FOLDERS "." "core" "containers" "thread" "system" "io" "console" "math" "code" "geo" "resources" "opencl" "crypt")
include_directories("${PIP_SRC_MAIN}")
foreach(F ${PIP_FOLDERS})
include_directories("${PIP_SRC_MAIN}/${F}")
@@ -382,7 +382,7 @@ endif()
find_package(OpenCL QUIET)
if(OpenCL_FOUND)
message(STATUS "Building with OpenCL support")
if(APPLE)
if(APPLE)
include_directories(${OpenCL_INCLUDE_DIRS}/Headers)
else()
include_directories(${OpenCL_INCLUDE_DIRS})
@@ -403,7 +403,7 @@ endif()
# Test program
add_executable(pip_test "main.cpp")
target_link_libraries(pip_test pip)
target_link_libraries(pip_test pip pip_crypt)
# Install
@@ -479,3 +479,30 @@ foreach(LIB_ ${LIBS_STATUS})
message(WARNING "Library ${LIB_} not found, please install it")
endif()
endforeach()
#
# Build Documentation
#
find_package(Doxygen QUIET)
if(Doxygen_FOUND)
message(STATUS "Building with documentation via Doxygen")
#set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in)
set(DOXYFILE ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile)
#configure_file(${DOXYFILE_IN} ${DOXYFILE} @ONLY)
add_custom_target(DOC
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM)
add_custom_command(TARGET DOC
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/source/doc/Documentation.html ${CMAKE_SOURCE_DIR}/doc
)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/doc)
endif()

Binary file not shown.

View File

@@ -1,10 +1,98 @@
#include "pip.h"
#include "piauth.h"
class Obj : public PIObject {
PIOBJECT(Obj)
public:
Obj() : PIObject() {}
EVENT_HANDLER2(void, authorizeServer, PIByteArray, info, bool *, ok) {
piCout << "[authorizeServer]" << PIString(info);
//*ok = true;
}
EVENT_HANDLER2(void, passwordCheck, PIByteArray, phash, bool *, ok) {
piCout << "[passwordCheck]" << phash.toHex();
PIByteArray ph = PICrypt::passwordHash("secret", PIByteArray::fromHex("AABBCCDD"));
piCout << "[passwordCheck]" << ph.toHex();
if (phash == ph) *ok = true;
}
EVENT_HANDLER1(void, userEnterPassword, PIString *, password) {
*password = "secret";
piCout << "[userEnterPassword]" << *password;
}
};
int main(int argc, char *argv[]) {
//S s;
//s.i;
//PICodeParser cp;
//cp.parseFile("cp.h");
piCout << "start";
PICrypt crypt;
PIByteArray skey1, pkey1;
crypt.generateKeypair(pkey1, skey1);
PIByteArray skey2, pkey2;
crypt.generateKeypair(pkey2, skey2);
PIByteArray sign = PIAuth::generateSign(PICrypt::generateKey());
piCout << "sign" << sign.toHex();
piCout << "key1 " << pkey1.toHex() << skey1.toHex();
piCout << "key2 " << pkey2.toHex() << skey2.toHex();
PIString msg = "what the f*ck?";
PIByteArray ba = msg.toUTF8();
piCout << "source" << ba.toHex() << msg;
PIByteArray cba = crypt.crypt(ba, pkey2, skey1);
PIByteArray psign = crypt.extractSignPublicKey(sign);
PIByteArray scba = crypt.signMessage(cba, sign);
piCout << "crypted" << cba.toHex();
piCout << "signed" << scba.toHex() << psign.toHex();
PIByteArray dba = crypt.decrypt(cba, pkey1, skey2);
piCout << "decrypted" << dba.toHex() << PIString(dba);
piCout << "verify" << crypt.verifySign(cba, scba, psign);
cba = crypt.crypt(ba, pkey1, skey2);
piCout << "crypted" << cba.toHex();
//cba[7] = 0;
dba = crypt.decrypt(cba, pkey2, skey1);
piCout << "decrypted" << dba.toHex() << PIString(dba);
piCout << "=======================================";
PIAuth server(PIAuth::generateSign(pkey1));
msg = "This is Server with PIAuth";
server.setInfoData(msg.toUTF8());
PIAuth client(PIAuth::generateSign(pkey2));
client.setAuthorizedPublicKeys(PIVector<PIByteArray>() << server.getSignPublicKey());
Obj o;
CONNECTU(&client, authorize, &o, authorizeServer);
CONNECTU(&client, passwordRequest, &o, userEnterPassword);
CONNECTU(&server, passwordCheck, &o, passwordCheck);
client.startClient();
ba = server.startServer();
int st = PIAuth::AuthProbe;
piCout << "server" << st << ba.toHex() << ba.size();
// ba[40] = 2;
// {
// int s;
// ba >> s;
// PIByteArray rinfo;
// PIByteArray rsign;
// PIByteArray rsign_pk;
// PIByteArray box_pk;
// PIByteArray noise;
// ba >> rinfo >> rsign_pk >> box_pk >> noise >> rsign;
// ba.clear();
// PIByteArray sign2 = PIAuth::generateSign(PICrypt::generateRandomBuff(100));
// msg = "Server";
// ba << s << msg.toUTF8() << crypt.extractSignPublicKey(sign2) << box_pk << noise;
// rsign = crypt.signMessage(ba, sign2);
// ba << rsign;
// }
st = client.receive(ba);
piCout << "client" << st << ba.toHex() << ba.size();
st = server.receive(ba);
piCout << "server" << st << ba.toHex() << ba.size();
st = client.receive(ba);
piCout << "client" << st << ba.toHex() << ba.size();
st = server.receive(ba);
piCout << "server" << st << ba.toHex() << ba.size();
return 0;
}

257
src_crypt/piauth.cpp Normal file
View File

@@ -0,0 +1,257 @@
/*
PIP - Platform Independent Primitives
PIP Authentication API
Copyright (C) 2018 Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piauth.h"
PIAuth::PIAuth(const PIByteArray & sign) : PIObject() {
setName("Client");
role = Client;
state = NotConnected;
sign_sk = sign;
sign_pk = crypt.extractSignPublicKey(sign);
}
void PIAuth::stop() {
role = Client;
state = NotConnected;
auth_sign.clear();
box_sk.clear();
box_pk.clear();
my_pk.clear();
}
void PIAuth::startClient() {
role = Client;
state = AuthProbe;
}
PIByteArray PIAuth::startServer() {
setName("Server");
role = Server;
state = AuthProbe;
PIByteArray ba;
crypt.generateKeypair(my_pk, box_sk);
PIByteArray noise = crypt.generateRandomBuff(randomi()%256+128);
ba << (int)state << info << sign_pk << my_pk << noise;
PIByteArray sign = crypt.signMessage(ba, sign_sk);
ba << sign;
return ba;
}
PIAuth::State PIAuth::receive(PIByteArray & ba) {
if (ba.size() < sizeof(int)) return disconnect(ba, "invalid data size");
State rstate;
int s;
ba >> s;
rstate = (State)s;
// if (state != rstate) return disconect(ba);
//client side
if (role == Client) {
if (state == AuthProbe && rstate == AuthProbe) {
if (ba.size() < sizeof(int)*5) return disconnect(ba, "invalid data size");
PIByteArray rinfo;
PIByteArray rsign;
PIByteArray rsign_pk;
PIByteArray noise;
ba >> rinfo >> rsign_pk >> box_pk >> noise >> rsign;
if (rsign_pk.isEmpty() || box_pk.isEmpty() || rsign.isEmpty()) return disconnect(ba, "invalid key size");
PIByteArray tba;
tba << (int)rstate << rinfo << rsign_pk << box_pk << noise;
if (!crypt.verifySign(tba, rsign, rsign_pk)) return disconnect(ba, "Incorrect sign");
bool auth = false;
if (isAuthorizedKey(rsign_pk)) {
auth = true;
} else {
authorize(rinfo, &auth);
if (auth) auth_pkeys << rsign_pk;
}
if (!auth) return disconnect(ba, "Unauthorised");
ba.clear();
auth_sign = rsign_pk;
crypt.generateKeypair(my_pk, box_sk);
tba.clear();
tba << sign_pk << my_pk << box_pk;
PIByteArray sign = crypt.signMessage(tba, sign_sk);
tba << sign;
tba = crypt.crypt(tba, box_pk, box_sk);
state = AuthReply;
noise = crypt.generateRandomBuff(randomi()%256);
ba << (int)state << tba << my_pk << noise;
sign = crypt.signMessage(ba, sign_sk);
ba << sign;
return state;
}
if (state == AuthReply && rstate == PassRequest) {
PIByteArray ctba, tba;
PIByteArray noise;
PIByteArray rsign, rsign_pk;
ba >> ctba >> rsign;
bool ok = false;
tba = crypt.decrypt(ctba, box_pk, box_sk, &ok);
if (tba.isEmpty() || !ok) return disconnect(ba, "Message corrupted");
ba.clear();
ba << (int)rstate << ctba;
if (!crypt.verifySign(ba, rsign, auth_sign)) return disconnect(ba, "Incorrect sign");
ctba.clear();
tba >> rsign_pk >> noise >> ctba;
if (rsign_pk != auth_sign || ctba != my_pk) return disconnect(ba, "Invalid public key");
PIString ps;
PIByteArray ph;
passwordRequest(&ps);
if (ps.isEmpty()) return disconnect(ba, "Canceled by user");
ph = crypt.passwordHash(ps, PIByteArray::fromHex("AABBCCDD"));
ps.fill(0);
tba.clear();
tba << ph << auth_sign << sign_pk;
tba = crypt.crypt(tba, box_pk, box_sk);
ba.clear();
state = PassRequest;
ba << (int)state << tba;
rsign = crypt.signMessage(ba, sign_sk);
ba << rsign;
return state;
}
if (state == AuthReply && rstate == KeyExchange) {
}
}
// server side
if (role == Server) {
if (state == AuthProbe && rstate == AuthReply) {
if (ba.size() < sizeof(int)*4) return disconnect(ba, "invalid data size");
PIByteArray ctba, tba;
PIByteArray noise;
PIByteArray rsign1, rsign2;
PIByteArray rsign_pk;
PIByteArray pk, mpk;
ba >> ctba >> pk >> noise >> rsign1;
bool ok = false;
tba = crypt.decrypt(ctba, pk, box_sk, &ok);
if (tba.isEmpty() || !ok) return disconnect(ba, "Message corrupted");
if (tba.size() < sizeof(int)*3) return disconnect(tba, "invalid data size");
tba >> rsign_pk >> box_pk >> mpk >> rsign2;
if (pk != box_pk || mpk != my_pk) return disconnect(ba, "Invalid public key");
ba.clear();
ba << (int)rstate << ctba << box_pk << noise;
if (!crypt.verifySign(ba, rsign1, rsign_pk)) return disconnect(ba, "Incorrect sign");
ba.clear();
ba << rsign_pk << box_pk << my_pk;
if (!crypt.verifySign(ba, rsign2, rsign_pk)) return disconnect(ba, "Incorrect sign");
auth_sign = rsign_pk;
if (isAuthorizedKey(rsign_pk)) {
state = KeyExchange;
ba = createSKMessage();
return state;
} else {
ba.clear();
tba.clear();
state = PassRequest;
noise = crypt.generateRandomBuff(randomi()%256);
tba << sign_pk << noise << box_pk;
tba = crypt.crypt(tba, box_pk, box_sk);
ba << (int)state << tba;
rsign1 = crypt.signMessage(ba, sign_sk);
ba << rsign1;
return state;
}
}
if (state == PassRequest && rstate == PassRequest) {
PIByteArray tba, ctba;
PIByteArray rsign_pk, rsign, mpk;
ba >> ctba >> rsign;
bool ok = false;
tba = crypt.decrypt(ctba, box_pk, box_sk, &ok);
if (tba.isEmpty() || !ok) return disconnect(ba, "Message corrupted");
ba.clear();
ba << (int)rstate << ctba;
if (!crypt.verifySign(ba, rsign, auth_sign)) return disconnect(ba, "Incorrect sign");
ctba.clear();
tba >> ctba >> mpk >> rsign_pk;
if (rsign_pk != auth_sign || mpk != sign_pk) return disconnect(ba, "Invalid public key");
bool auth = false;
passwordCheck(ctba, &auth);
if (!auth) {
piSleep(1);
return disconnect(ba, "Invalid password");
}
state = KeyExchange;
ba = createSKMessage();
return state;
}
}
return disconnect(ba, "invalid state " + PIString::fromNumber((int)state));
}
PIByteArray PIAuth::getSecretKey() {
if (state == Connected) return secret_key;
return PIByteArray();
}
PIByteArray PIAuth::generateSign(const PIByteArray & seed) {
PIByteArray pk, sk;
PICrypt::generateSignKeys(pk, sk, seed);
return sk;
}
PIAuth::State PIAuth::disconnect(PIByteArray & ba, const PIString & error) {
if (!error.isEmpty()) piCoutObj << error;
auth_sign.clear();
box_sk.clear();
box_pk.clear();
my_pk.clear();
secret_key.clear();
ba.clear();
state = NotConnected;
disconnected();
return state;
}
bool PIAuth::isAuthorizedKey(const PIByteArray & pkey) {
for (int i=0; i<auth_pkeys.size_s(); ++i) {
if (pkey == auth_pkeys[i]) return true;
}
return false;
}
PIByteArray PIAuth::createSKMessage() {
secret_key = crypt.generateKey();
PIByteArray tba;
PIByteArray noise = crypt.generateRandomBuff(randomi()%256);
tba << secret_key << noise << box_pk;
tba = crypt.crypt(tba, box_pk, box_sk);
PIByteArray ret;
ret << (int)state << tba;
PIByteArray sign = crypt.signMessage(ret, sign_sk);
ret << sign;
return ret;
}

View File

@@ -1,20 +1,20 @@
/*
PIP - Platform Independent Primitives
Cryptographic class using lib Sodium
PIP - Platform Independent Primitives
Cryptographic class using lib Sodium
Copyright (C) 2018 Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 free software: you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.
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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "picrypt.h"
@@ -22,6 +22,7 @@
# include <sodium.h>
#endif
#define PICRYPT_DISABLED_WARNING piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and rebuild pip";
const char hash_def_key[] = "_picrypt_";
@@ -34,7 +35,7 @@ PICrypt::PICrypt() {
randombytes_buf(key_.data(), key_.size());
randombytes_buf(nonce_.data(), nonce_.size());
#else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install libsodium-dev library and build pip_crypt library";
PICRYPT_DISABLED_WARNING
#endif
}
@@ -72,22 +73,22 @@ PIByteArray PICrypt::crypt(const PIByteArray & data) {
PIByteArray PICrypt::crypt(const PIByteArray & data, PIByteArray key) {
PIByteArray retba;
PIByteArray ret;
#ifdef PIP_CRYPT
if (key.size() != crypto_secretbox_KEYBYTES)
key.resize(crypto_secretbox_KEYBYTES, ' ');
//return PIByteArray();
if (!init()) return retba;
if (!init()) return ret;
PIByteArray n;
retba.resize(data.size() + crypto_secretbox_MACBYTES);
ret.resize(data.size() + crypto_secretbox_MACBYTES);
n.resize(crypto_secretbox_NONCEBYTES);
randombytes_buf(n.data(), n.size());
crypto_secretbox_easy(retba.data(), data.data(), data.size(), n.data(), key.data());
retba.append(n);
crypto_secretbox_easy(ret.data(), data.data(), data.size(), n.data(), key.data());
ret.append(n);
#else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=1";
PICRYPT_DISABLED_WARNING
#endif
return retba;
return ret;
}
@@ -112,7 +113,7 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, bool *ok) {
PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bool *ok) {
PIByteArray retba;
PIByteArray ret;
#ifdef PIP_CRYPT
if (key.size() != crypto_secretbox_KEYBYTES)
key.resize(crypto_secretbox_KEYBYTES, ' ');
@@ -123,21 +124,20 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bo
if (ok) *ok = false;
return PIByteArray();
}
if (!init()) return retba;
if (!init()) return ret;
PIByteArray n;
n.resize(crypto_secretbox_NONCEBYTES);
retba.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES);
ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES);
memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size());
if (crypto_secretbox_open_easy(retba.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), key.data()) != 0) {
if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), key.data()) != 0) {
if (ok) *ok = false;
// piCout << "[PICrypt]" << "bad key_";
return PIByteArray();
}
} else if (ok) *ok = true;
#else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=";
PICRYPT_DISABLED_WARNING
#endif
if (ok) *ok = true;
return retba;
return ret;
}
@@ -149,7 +149,7 @@ PIByteArray PICrypt::hash(const PIString & secret) {
PIByteArray s(secret.data(), secret.size());
crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), (const uchar*)hash_def_key, sizeof(hash_def_key) - 1);
#else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=";
PICRYPT_DISABLED_WARNING
#endif
return hash;
}
@@ -167,7 +167,7 @@ ullong PICrypt::shorthash(const PIString& s, PIByteArray key) {
PIByteArray in(s.data(), s.size());
crypto_shorthash((uchar *)&hash, in.data(), in.size(), key.data());
#else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=";
PICRYPT_DISABLED_WARNING
#endif
return hash;
}
@@ -180,7 +180,20 @@ PIByteArray PICrypt::generateKey() {
hash.resize(crypto_secretbox_KEYBYTES);
randombytes_buf(hash.data(), hash.size());
#else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=";
PICRYPT_DISABLED_WARNING
#endif
return hash;
}
PIByteArray PICrypt::generateRandomBuff(int size) {
PIByteArray hash;
#ifdef PIP_CRYPT
if (!init() || size <= 0) return hash;
hash.resize(size);
randombytes_buf(hash.data(), hash.size());
#else
PICRYPT_DISABLED_WARNING
#endif
return hash;
}
@@ -190,7 +203,7 @@ size_t PICrypt::sizeKey() {
#ifdef PIP_CRYPT
return crypto_secretbox_KEYBYTES;
#else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=";
PICRYPT_DISABLED_WARNING
#endif
return 0;
}
@@ -200,12 +213,170 @@ size_t PICrypt::sizeCrypt() {
#ifdef PIP_CRYPT
return crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES;
#else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=";
PICRYPT_DISABLED_WARNING
#endif
return 0;
}
void PICrypt::generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key) {
#ifdef PIP_CRYPT
if (!init()) return;
public_key.resize(crypto_sign_PUBLICKEYBYTES);
secret_key.resize(crypto_sign_SECRETKEYBYTES);
crypto_sign_keypair(public_key.data(), secret_key.data());
#else
PICRYPT_DISABLED_WARNING
#endif
}
void PICrypt::generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed) {
#ifdef PIP_CRYPT
if (!init() || seed.isEmpty()) return;
public_key.resize(crypto_sign_PUBLICKEYBYTES);
secret_key.resize(crypto_sign_SECRETKEYBYTES);
crypto_sign_seed_keypair(public_key.data(), secret_key.data(), hash(seed).data());
#else
PICRYPT_DISABLED_WARNING
#endif
}
PIByteArray PICrypt::extractSignPublicKey(const PIByteArray & secret_key) {
PIByteArray pk;
#ifdef PIP_CRYPT
if (!init() || secret_key.size() != crypto_sign_SECRETKEYBYTES) return pk;
pk.resize(crypto_sign_PUBLICKEYBYTES);
crypto_sign_ed25519_sk_to_pk(pk.data(), secret_key.data());
#else
PICRYPT_DISABLED_WARNING
#endif
return pk;
}
PIByteArray PICrypt::signMessage(const PIByteArray & data, PIByteArray secret_key) {
PIByteArray sign;
#ifdef PIP_CRYPT
if (!init()) return sign;
sign.resize(crypto_sign_BYTES);
crypto_sign_detached(sign.data(), 0, data.data(), data.size(), secret_key.data());
#else
PICRYPT_DISABLED_WARNING
#endif
return sign;
}
bool PICrypt::verifySign(const PIByteArray & data, const PIByteArray & signature, PIByteArray public_key) {
#ifdef PIP_CRYPT
if (!init()) return false;
return (crypto_sign_verify_detached(signature.data(), data.data(), data.size(), public_key.data()) == 0);
#else
PICRYPT_DISABLED_WARNING
return false;
#endif
}
void PICrypt::generateKeypair(PIByteArray & public_key, PIByteArray & secret_key) {
#ifdef PIP_CRYPT
if (!init()) return;
public_key.resize(crypto_box_PUBLICKEYBYTES);
secret_key.resize(crypto_box_SECRETKEYBYTES);
crypto_box_keypair(public_key.data(), secret_key.data());
#else
PICRYPT_DISABLED_WARNING
#endif
}
void PICrypt::generateKeypair(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed) {
#ifdef PIP_CRYPT
if (!init()) return;
public_key.resize(crypto_box_PUBLICKEYBYTES);
secret_key.resize(crypto_box_SECRETKEYBYTES);
crypto_box_seed_keypair(public_key.data(), secret_key.data(), hash(seed).data());
#else
PICRYPT_DISABLED_WARNING
#endif
}
PIByteArray PICrypt::crypt(const PIByteArray & data, const PIByteArray & public_key, const PIByteArray & secret_key) {
PIByteArray ret;
#ifdef PIP_CRYPT
if (!init()) return ret;
if (public_key.size() != crypto_box_PUBLICKEYBYTES)
return ret;
if (secret_key.size() != crypto_box_SECRETKEYBYTES)
return ret;
PIByteArray n;
ret.resize(data.size() + crypto_box_MACBYTES);
n.resize(crypto_box_NONCEBYTES);
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();
ret.append(n);
#else
PICRYPT_DISABLED_WARNING
#endif
return ret;
}
PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, const PIByteArray & public_key, const PIByteArray & secret_key, bool * ok) {
PIByteArray ret;
#ifdef PIP_CRYPT
if (!init()) return ret;
if (public_key.size() != crypto_box_PUBLICKEYBYTES) {
if (ok) *ok = false;
return ret;
}
if (secret_key.size() != crypto_box_SECRETKEYBYTES) {
if (ok) *ok = false;
return ret;
}
if (crypt_data.size() < crypto_box_NONCEBYTES + crypto_box_MACBYTES) {
if (ok) *ok = false;
return ret;
}
PIByteArray n;
n.resize(crypto_secretbox_NONCEBYTES);
ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES);
memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size());
if (crypto_box_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), public_key.data(), secret_key.data()) != 0) {
if (ok) *ok = false;
// piCout << "[PICrypt]" << "bad key_";
return PIByteArray();
} else if (ok) *ok = true;
#else
PICRYPT_DISABLED_WARNING
#endif
return ret;
}
PIByteArray PICrypt::passwordHash(const PIString & password, const PIByteArray & seed) {
// char out[crypto_pwhash_STRBYTES];
PIByteArray pass = password.toUTF8();
PIByteArray n;
PIByteArray ph;
ph.resize(crypto_box_SEEDBYTES);
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(), ph.size(), (const char*)pass.data(), pass.size(), n.data(), crypto_pwhash_argon2i_opslimit_moderate(), crypto_pwhash_argon2i_memlimit_moderate(), 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);
if (r != 0) return PIByteArray();
PIByteArray ret;
ret << ph << n << crypto_pwhash_argon2i_opslimit_moderate() << crypto_pwhash_argon2i_memlimit_moderate();
return ret;
}
bool PICrypt::init() {
#ifdef PIP_CRYPT
static bool inited = false;
@@ -215,7 +386,7 @@ bool PICrypt::init() {
//piCout << "[PICrypt]" << "init" << inited;
return inited;
#else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=";
PICRYPT_DISABLED_WARNING
#endif
return false;
}

81
src_main/crypt/piauth.h Normal file
View File

@@ -0,0 +1,81 @@
/*! \file piauth.h
* \brief PIP Authentication API
*/
/*
PIP - Platform Independent Primitives
PIP Authentication API
Copyright (C) 2018 Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIAUTH_H
#define PIAUTH_H
#include "piobject.h"
#include "picrypt.h"
class PIP_EXPORT PIAuth : public PIObject
{
PIOBJECT(PIAuth)
public:
enum Role {Client, Server};
enum State {NotConnected, AuthProbe, PassRequest, AuthReply, KeyExchange, Connected};
PIAuth(const PIByteArray & sign);
void setInfoData(const PIByteArray & info_) {info = info_;}
void setAuthorizedPublicKeys(const PIVector<PIByteArray> & pkeys) {auth_pkeys = pkeys;}
PIVector<PIByteArray> getAuthorizedPublicKeys() {return auth_pkeys;}
PIByteArray getSignPublicKey() {return sign_pk;}
void stop();
void startClient();
PIByteArray startServer();
State receive(PIByteArray & ba);
PIByteArray getSecretKey();
static PIByteArray generateSign(const PIByteArray & seed);
EVENT(disconnected)
EVENT(connected)
EVENT2(authorize, PIByteArray, data, bool *, ok)
EVENT1(passwordRequest, PIString *, pass)
EVENT2(passwordCheck, PIByteArray, phash, bool *, ok)
//EVENT_HANDLER1(void, received, PIByteArray, data);
private:
State disconnect(PIByteArray & ba, const PIString & error = PIString());
bool isAuthorizedKey(const PIByteArray & pkey);
PIByteArray createSKMessage();
Role role;
State state;
PIByteArray info;
PICrypt crypt;
PIByteArray sign_sk, sign_pk;
PIByteArray auth_sign;
PIByteArray box_sk, box_pk;
PIByteArray my_pk;
PIByteArray secret_key;
PIVector<PIByteArray> auth_pkeys;
};
#endif // PIAUTH_H

110
src_main/crypt/picrypt.h Normal file
View File

@@ -0,0 +1,110 @@
/*! \file picrypt.h
* \brief Cryptographic class using lib Sodium
*/
/*
PIP - Platform Independent Primitives
Cryptographic class using lib Sodium
Copyright (C) 2018 Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICRYPT_H
#define PICRYPT_H
#include "pistring.h"
class PIP_EXPORT PICrypt {
public:
//! Construct and generate random key
PICrypt();
//! Set key to "key", key size must be a \a sizeKey()
bool setKey(const PIByteArray & key);
//! Generate and set key from keyphrase "secret"
PIByteArray setKey(const PIString & secret);
//! Returns current key
PIByteArray key() {return key_;}
//! Encrypt given data "data", result size will be increased by \a sizeCrypt()
PIByteArray crypt(const PIByteArray & data);
//! Decrypt given data "crypt_data"
PIByteArray decrypt(const PIByteArray & crypt_data, bool * ok = 0);
//! Encrypt given data "data" with key "key", result size will be increased by \a sizeCrypt()
static PIByteArray crypt(const PIByteArray & data, PIByteArray key);
//! Decrypt given data "crypt_data" with key "key"
static PIByteArray decrypt(const PIByteArray & crypt_data, PIByteArray key, bool * ok = 0);
//! Generate hash from keyphrase "secret", may be used as a key for encryption
static PIByteArray hash(const PIString & secret);
//! Generate short hash from string "s", may be used for hash table
static ullong shorthash(const PIString & s, PIByteArray key = PIByteArray());
//! Generate random key
static PIByteArray generateKey();
//! Generate random buffer
static PIByteArray generateRandomBuff(int size);
//! Returns key size
static size_t sizeKey();
//! Returns size which be added to data size in encryption process
static size_t sizeCrypt();
//! Function randomly generates a secret key and a corresponding public key for digital signature
static void generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key);
//! Function generates a secret key from input data and a corresponding public key for digital signature
static void generateSignKeys(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed);
//! Function extract sign public key from sing secret key
static PIByteArray extractSignPublicKey(const PIByteArray & secret_key);
//! Calculate digital signature for data
PIByteArray signMessage(const PIByteArray & data, PIByteArray secret_key);
//! Verify digital signature of signed message
bool verifySign(const PIByteArray & data, const PIByteArray & signature, PIByteArray public_key);
//! Function randomly generates a secret key and a corresponding public key for authenticated encryption
static void generateKeypair(PIByteArray & public_key, PIByteArray & secret_key);
//! Function generates a secret key from input data and a corresponding public key for authenticated encryption
static void generateKeypair(PIByteArray & public_key, PIByteArray & secret_key, const PIByteArray & seed);
//! Encrypt given data "data"
PIByteArray crypt(const PIByteArray &data, const PIByteArray & public_key, const PIByteArray & secret_key);
//! Decrypt given data "crypt_data"
PIByteArray decrypt(const PIByteArray & crypt_data, const PIByteArray & public_key, const PIByteArray & secret_key, bool * ok = 0);
//! Generate password hash from "password"
static PIByteArray passwordHash(const PIString & password, const PIByteArray & seed);
private:
static bool init();
PIByteArray nonce_, key_;
};
#endif // PICRYPT_H

View File

@@ -0,0 +1,26 @@
/*
PIP - Platform Independent Primitives
Module includes
Copyright (C) 2018 Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIMATHMODULE_H
#define PIMATHMODULE_H
#include "picrypt.h"
#include "piauth.h"
#endif // PIMATHMODULE_H

View File

@@ -1,76 +0,0 @@
/*! \file picrypt.h
* \brief Cryptographic class using lib Sodium
*/
/*
PIP - Platform Independent Primitives
Cryptographic class using lib Sodium
Copyright (C) 2018 Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICRYPT_H
#define PICRYPT_H
#include "pistring.h"
class PIP_EXPORT PICrypt {
public:
//! Construct and generate random key
PICrypt();
//! Set key to "key", key size must be a \a sizeKey()
bool setKey(const PIByteArray & key);
//! Generate and set key from keyphrase "secret"
PIByteArray setKey(const PIString & secret);
//! Returns current key
PIByteArray key() {return key_;}
//! Encrypt given data "data", result size will be increased by \a sizeCrypt()
PIByteArray crypt(const PIByteArray & data);
//! Decrypt given data "crypt_data"
PIByteArray decrypt(const PIByteArray & crypt_data, bool * ok = 0);
//! Encrypt given data "data" with key "key", result size will be increased by \a sizeCrypt()
static PIByteArray crypt(const PIByteArray & data, PIByteArray key);
//! Decrypt given data "crypt_data" with key "key"
static PIByteArray decrypt(const PIByteArray & crypt_data, PIByteArray key, bool * ok = 0);
//! Generate hash from keyphrase "secret", may be used as a key for encryption
static PIByteArray hash(const PIString & secret);
//! Generate short hash from string "s", may be used for hash table
static ullong shorthash(const PIString & s, PIByteArray key = PIByteArray());
//! Generate random key
static PIByteArray generateKey();
//! Returns key size
static size_t sizeKey();
//! Returns size which be added to data size in encryption process
static size_t sizeCrypt();
private:
static bool init();
PIByteArray nonce_, key_;
};
#endif // PICRYPT_H

View File

@@ -25,7 +25,6 @@
#include "pievaluator.h"
#include "pifft.h"
#include "picrc.h"
#include "picrypt.h"
#include "pifixedpoint.h"
#include "piquaternion.h"

View File

@@ -1,20 +1,20 @@
/*
PIP - Platform Independent Primitives
All includes
Copyright (C) 2018 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
PIP - Platform Independent Primitives
All includes
Copyright (C) 2018 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 free software: you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.
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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIP_H
@@ -28,5 +28,6 @@
#include "pimathmodule.h"
#include "pisystemmodule.h"
#include "pigeomodule.h"
#include "picryptmodule.h"
#endif // PIP_H