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 # Sources
# Main lib # 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}") include_directories("${PIP_SRC_MAIN}")
foreach(F ${PIP_FOLDERS}) foreach(F ${PIP_FOLDERS})
include_directories("${PIP_SRC_MAIN}/${F}") include_directories("${PIP_SRC_MAIN}/${F}")
@@ -382,7 +382,7 @@ endif()
find_package(OpenCL QUIET) find_package(OpenCL QUIET)
if(OpenCL_FOUND) if(OpenCL_FOUND)
message(STATUS "Building with OpenCL support") message(STATUS "Building with OpenCL support")
if(APPLE) if(APPLE)
include_directories(${OpenCL_INCLUDE_DIRS}/Headers) include_directories(${OpenCL_INCLUDE_DIRS}/Headers)
else() else()
include_directories(${OpenCL_INCLUDE_DIRS}) include_directories(${OpenCL_INCLUDE_DIRS})
@@ -403,7 +403,7 @@ endif()
# Test program # Test program
add_executable(pip_test "main.cpp") add_executable(pip_test "main.cpp")
target_link_libraries(pip_test pip) target_link_libraries(pip_test pip pip_crypt)
# Install # Install
@@ -479,3 +479,30 @@ foreach(LIB_ ${LIBS_STATUS})
message(WARNING "Library ${LIB_} not found, please install it") message(WARNING "Library ${LIB_} not found, please install it")
endif() endif()
endforeach() 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 "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[]) { int main(int argc, char *argv[]) {
//S s; piCout << "start";
//s.i; PICrypt crypt;
//PICodeParser cp; PIByteArray skey1, pkey1;
//cp.parseFile("cp.h"); 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; 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 PIP - Platform Independent Primitives
Cryptographic class using lib Sodium Cryptographic class using lib Sodium
Copyright (C) 2018 Andrey Bychkov work.a.b@yandex.ru Copyright (C) 2018 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 General Public License as published by it under the terms of the GNU 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 General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU 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/>.
*/ */
#include "picrypt.h" #include "picrypt.h"
@@ -22,6 +22,7 @@
# include <sodium.h> # include <sodium.h>
#endif #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_"; const char hash_def_key[] = "_picrypt_";
@@ -34,7 +35,7 @@ PICrypt::PICrypt() {
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 #else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install libsodium-dev library and build pip_crypt library"; PICRYPT_DISABLED_WARNING
#endif #endif
} }
@@ -72,22 +73,22 @@ PIByteArray PICrypt::crypt(const PIByteArray & data) {
PIByteArray PICrypt::crypt(const PIByteArray & data, PIByteArray key) { PIByteArray PICrypt::crypt(const PIByteArray & data, PIByteArray key) {
PIByteArray retba; PIByteArray ret;
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
if (key.size() != crypto_secretbox_KEYBYTES) if (key.size() != crypto_secretbox_KEYBYTES)
key.resize(crypto_secretbox_KEYBYTES, ' '); key.resize(crypto_secretbox_KEYBYTES, ' ');
//return PIByteArray(); //return PIByteArray();
if (!init()) return retba; if (!init()) return ret;
PIByteArray n; PIByteArray n;
retba.resize(data.size() + crypto_secretbox_MACBYTES); ret.resize(data.size() + crypto_secretbox_MACBYTES);
n.resize(crypto_secretbox_NONCEBYTES); n.resize(crypto_secretbox_NONCEBYTES);
randombytes_buf(n.data(), n.size()); randombytes_buf(n.data(), n.size());
crypto_secretbox_easy(retba.data(), data.data(), data.size(), n.data(), key.data()); crypto_secretbox_easy(ret.data(), data.data(), data.size(), n.data(), key.data());
retba.append(n); ret.append(n);
#else #else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=1"; PICRYPT_DISABLED_WARNING
#endif #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 PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bool *ok) {
PIByteArray retba; PIByteArray ret;
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
if (key.size() != crypto_secretbox_KEYBYTES) if (key.size() != crypto_secretbox_KEYBYTES)
key.resize(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; if (ok) *ok = false;
return PIByteArray(); return PIByteArray();
} }
if (!init()) return retba; if (!init()) return ret;
PIByteArray n; PIByteArray n;
n.resize(crypto_secretbox_NONCEBYTES); 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()); 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; if (ok) *ok = false;
// piCout << "[PICrypt]" << "bad key_"; // piCout << "[PICrypt]" << "bad key_";
return PIByteArray(); return PIByteArray();
} } else if (ok) *ok = true;
#else #else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT="; PICRYPT_DISABLED_WARNING
#endif #endif
if (ok) *ok = true; return ret;
return retba;
} }
@@ -149,7 +149,7 @@ PIByteArray PICrypt::hash(const PIString & secret) {
PIByteArray s(secret.data(), secret.size()); 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); crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), (const uchar*)hash_def_key, sizeof(hash_def_key) - 1);
#else #else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT="; PICRYPT_DISABLED_WARNING
#endif #endif
return hash; return hash;
} }
@@ -167,7 +167,7 @@ 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 #else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT="; PICRYPT_DISABLED_WARNING
#endif #endif
return hash; return hash;
} }
@@ -180,7 +180,20 @@ PIByteArray PICrypt::generateKey() {
hash.resize(crypto_secretbox_KEYBYTES); hash.resize(crypto_secretbox_KEYBYTES);
randombytes_buf(hash.data(), hash.size()); randombytes_buf(hash.data(), hash.size());
#else #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 #endif
return hash; return hash;
} }
@@ -190,7 +203,7 @@ size_t PICrypt::sizeKey() {
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
return crypto_secretbox_KEYBYTES; return crypto_secretbox_KEYBYTES;
#else #else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT="; PICRYPT_DISABLED_WARNING
#endif #endif
return 0; return 0;
} }
@@ -200,12 +213,170 @@ size_t PICrypt::sizeCrypt() {
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
return crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES; return crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES;
#else #else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT="; PICRYPT_DISABLED_WARNING
#endif #endif
return 0; 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() { bool PICrypt::init() {
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
static bool inited = false; static bool inited = false;
@@ -215,7 +386,7 @@ bool PICrypt::init() {
//piCout << "[PICrypt]" << "init" << inited; //piCout << "[PICrypt]" << "init" << inited;
return inited; return inited;
#else #else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT="; PICRYPT_DISABLED_WARNING
#endif #endif
return false; 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 "pievaluator.h"
#include "pifft.h" #include "pifft.h"
#include "picrc.h" #include "picrc.h"
#include "picrypt.h"
#include "pifixedpoint.h" #include "pifixedpoint.h"
#include "piquaternion.h" #include "piquaternion.h"

View File

@@ -1,20 +1,20 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
All includes All includes
Copyright (C) 2018 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru 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 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 it under the terms of the GNU 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 General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU 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 PIP_H #ifndef PIP_H
@@ -28,5 +28,6 @@
#include "pimathmodule.h" #include "pimathmodule.h"
#include "pisystemmodule.h" #include "pisystemmodule.h"
#include "pigeomodule.h" #include "pigeomodule.h"
#include "picryptmodule.h"
#endif // PIP_H #endif // PIP_H