mixed boob
This commit is contained in:
parent
922f801c96
commit
75495fc976
10 changed files with 281 additions and 22 deletions
|
@ -4,7 +4,7 @@ project(server)
|
|||
file(GLOB_RECURSE server_src
|
||||
"src/*.hpp"
|
||||
"src/*.cpp"
|
||||
)
|
||||
)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -static")
|
||||
|
|
|
@ -3,14 +3,18 @@
|
|||
#define B64_IGNORE 0xFE
|
||||
#define B64_PADDING 0xFF
|
||||
|
||||
std::string sosc::cgc::base64_encode(const std::string& data) {
|
||||
std::string sosc::cgc::base64_encode(const std::string& data, bool unix) {
|
||||
return base64_encode(data.c_str(), data.length());
|
||||
}
|
||||
|
||||
std::string sosc::cgc::base64_encode(const void* raw, size_t length) {
|
||||
std::string sosc::cgc::base64_encode
|
||||
(const void* raw, size_t length, bool unix)
|
||||
{
|
||||
uint8_t* data = (uint8_t*)raw;
|
||||
const std::string char_table
|
||||
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
= (unix)
|
||||
? "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
std::string encoded;
|
||||
for(size_t i = 0; i < length; i += 3) {
|
||||
|
@ -27,14 +31,30 @@ std::string sosc::cgc::base64_encode(const void* raw, size_t length) {
|
|||
|
||||
for(int j = 0; j < 4 - padding; ++j)
|
||||
encoded += char_table[(index >> (6 * (3 - j))) & 0x3F];
|
||||
|
||||
for(int j = 0; j < padding; ++j)
|
||||
encoded += '=';
|
||||
|
||||
if(!unix)
|
||||
for(int j = 0; j < padding; ++j)
|
||||
encoded += '=';
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static uint8_t radix64_decode_char(char c) {
|
||||
if(c >= '0' && c <= '9')
|
||||
return c - '0' + 2;
|
||||
else if(c >= 'A' && c <= 'Z')
|
||||
return c - 'A' + 12;
|
||||
else if(c >= 'a' && c <= 'z')
|
||||
return c - 'a' + 38;
|
||||
else if(c == '.')
|
||||
return 0;
|
||||
else if(c == '/')
|
||||
return 1;
|
||||
else
|
||||
return B64_IGNORE;
|
||||
}
|
||||
|
||||
static uint8_t base64_decode_char(char c) {
|
||||
if(c >= 'A' && c <= 'Z')
|
||||
return c - 'A';
|
||||
|
@ -62,12 +82,13 @@ static void base64_decode_append(std::string* decoded, int data) {
|
|||
*decoded += (char)data;
|
||||
}
|
||||
|
||||
std::string sosc::cgc::base64_decode(const std::string& data) {
|
||||
std::string sosc::cgc::base64_decode(const std::string& data, bool unix) {
|
||||
std::string decoded;
|
||||
int index = 0, j = 0;
|
||||
|
||||
for(std::string::size_type i = 0; i < data.length(); ++i) {
|
||||
int sextet = base64_decode_char(data[i]);
|
||||
int sextet = unix ? radix64_decode_char(data[i])
|
||||
: base64_decode_char(data[i]);
|
||||
|
||||
if(sextet == B64_IGNORE || sextet == B64_PADDING) {
|
||||
if(sextet == B64_PADDING && i >= data.length() - 2 && j > 1)
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
namespace sosc {
|
||||
namespace cgc {
|
||||
std::string base64_encode(const std::string& data);
|
||||
std::string base64_encode(const void* raw, size_t length);
|
||||
std::string base64_encode(const std::string& data, bool unix = false);
|
||||
std::string base64_encode(const void* raw, size_t length, bool unix = false);
|
||||
|
||||
std::string base64_decode(const std::string& data);
|
||||
std::string base64_decode(const std::string& data, bool unix = false);
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
|
15
server/src/crypto/bcrypt.cpp
Normal file
15
server/src/crypto/bcrypt.cpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include "bcrypt.hpp"
|
||||
|
||||
std::string sosc::cgc::bcrypt_hash(const std::string& input) {
|
||||
std::string salt = csprng::next_bytes(16),
|
||||
input_t = input.substr(0, 72);
|
||||
|
||||
Blowfish bfish;
|
||||
|
||||
std::stringstream stream;
|
||||
stream << "$2b$" << BCRYPT_COST << "$"
|
||||
<< base64_encode(salt, true)
|
||||
<< "b";
|
||||
|
||||
return stream.str();
|
||||
}
|
18
server/src/crypto/bcrypt.hpp
Normal file
18
server/src/crypto/bcrypt.hpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef SOSC_CRYPTO_BCRYPT_H
|
||||
#define SOSC_CRYPTO_BCRYPT_H
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "base64.hpp"
|
||||
#include "bfish.hpp"
|
||||
#include "../utils/csprng.hpp"
|
||||
|
||||
#define BCRYPT_COST 10
|
||||
|
||||
namespace sosc {
|
||||
namespace cgc {
|
||||
std::string bcrypt_hash(const std::string& input);
|
||||
bool bcrypt_check(std::string input, std::string hash);
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -184,14 +184,48 @@ static const uint32_t init_sbox[4][256] = {
|
|||
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
|
||||
};
|
||||
|
||||
static void swap(uint32_t& a, uint32_t& b) {
|
||||
uint32_t temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
static void pack_bytes
|
||||
(const std::string& data, std::string::size_type i,
|
||||
uint32_t& left, uint32_t& right)
|
||||
{
|
||||
left = right = 0;
|
||||
for(int j = 0; j < 8; ++j) {
|
||||
if(j < 4)
|
||||
left = (left << 8) | (data[(i + j) % data.length()] & 0xFF);
|
||||
else
|
||||
right = (right << 8) | (data[(i + j) % data.length()] & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void unpack_bytes
|
||||
(std::string& data, std::string::size_type i,
|
||||
uint32_t left, uint32_t right)
|
||||
{
|
||||
for(int j = 0; j < 8; ++j) {
|
||||
if(j < 4) {
|
||||
data[i + (3 - j)] = left & 0xFF;
|
||||
left >>= 8;
|
||||
} else {
|
||||
data[i + (7 - j + 4)] = right & 0xFF;
|
||||
right >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sosc::cgc::Blowfish::Blowfish(const std::string& key) {
|
||||
std::memcpy(this->parr, init_parr, sizeof(init_parr));
|
||||
std::memcpy(this->sbox, init_sbox, sizeof(init_sbox));
|
||||
|
||||
this->SetKey(key.c_str(), key.length());
|
||||
}
|
||||
|
||||
void sosc::cgc::Blowfish::SetKey(const char* key, size_t length) {
|
||||
std::memcpy(this->parr, init_parr, sizeof(init_parr));
|
||||
std::memcpy(this->sbox, init_sbox, sizeof(init_sbox));
|
||||
|
||||
for(int i = 0; i < 18; ++i) {
|
||||
uint32_t data = 0;
|
||||
for(int j = 0; j < 4; ++j)
|
||||
|
@ -216,19 +250,99 @@ void sosc::cgc::Blowfish::SetKey(const char* key, size_t length) {
|
|||
}
|
||||
}
|
||||
|
||||
void sosc::cgc::Blowfish::SetEksKey
|
||||
(const std::string& data, const std::string& key)
|
||||
{
|
||||
for(int i = 0; i < 18; ++i) {
|
||||
uint32_t pack = 0;
|
||||
for(int j = 0; j < 4; ++j)
|
||||
pack = (pack << 8) | key[(i * 4 + j) % key.length()];
|
||||
|
||||
this->parr[i] ^= pack;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 18; i += 2) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
std::string sosc::cgc::Blowfish::Encrypt(std::string data) const {
|
||||
size_t pad_length = data.size() % sizeof(uint64_t);
|
||||
int pad_length = data.length() % sizeof(uint64_t);
|
||||
pad_length = sizeof(uint64_t) - pad_length;
|
||||
|
||||
for(size_t i = 0; i < pad_length; ++i)
|
||||
for(int i = 0; i < pad_length; ++i)
|
||||
data.push_back(0);
|
||||
|
||||
for(int i = 0; i < data.size() / sizeof(uint64_t); ++i) {
|
||||
uint32_t* left = &(((uint32_t*)data.data())[i * 2]);
|
||||
uint32_t* right = &(((uint32_t*)data.data())[i * 2 + 1]);
|
||||
for(std::string::size_type i = 0; i < data.size(); i += 8) {
|
||||
uint32_t left, right;
|
||||
|
||||
EncryptBlock(left, right);
|
||||
pack_bytes(data, i, left, right);
|
||||
this->EncryptBlock(&left, &right);
|
||||
unpack_bytes(data, i, left, right);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::string sosc::cgc::Blowfish::Decrypt(std::string data) const {
|
||||
if(data.length() % sizeof(uint64_t) != 0)
|
||||
return "";
|
||||
|
||||
for(std::string::size_type i = 0; i < data.size(); i += 8) {
|
||||
uint32_t left, right;
|
||||
|
||||
pack_bytes(data, i, left, right);
|
||||
this->DecryptBlock(&left, &right);
|
||||
unpack_bytes(data, i, left, right);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for(;; i++)
|
||||
if(data[data.length() - i - 1] != 0)
|
||||
break;
|
||||
|
||||
data.resize(data.length() - i);
|
||||
return data;
|
||||
}
|
||||
|
||||
void sosc::cgc::Blowfish::EncryptBlock
|
||||
(uint32_t* left, uint32_t* right) const
|
||||
{
|
||||
uint32_t left_t = *left,
|
||||
right_t = *right;
|
||||
|
||||
for(int i = 0; i < 16; ++i) {
|
||||
left_t ^= this->parr[i];
|
||||
right_t ^= this->Feistel(left_t);
|
||||
swap(left_t, right_t);
|
||||
}
|
||||
|
||||
swap(left_t, right_t);
|
||||
right_t ^= this->parr[16];
|
||||
left_t ^= this->parr[17];
|
||||
|
||||
*left = left_t;
|
||||
*right = right_t;
|
||||
}
|
||||
|
||||
void sosc::cgc::Blowfish::DecryptBlock
|
||||
(uint32_t* left, uint32_t* right) const
|
||||
{
|
||||
uint32_t left_t = *left,
|
||||
right_t = *right;
|
||||
|
||||
for(int i = 17; i > 1; --i) {
|
||||
left_t ^= this->parr[i];
|
||||
right_t ^= this->Feistel(left_t);
|
||||
swap(left_t, right_t);
|
||||
}
|
||||
|
||||
swap(left_t, right_t);
|
||||
right_t ^= this->parr[1];
|
||||
left_t ^= this->parr[0];
|
||||
|
||||
*left = left_t;
|
||||
*right = right_t;
|
||||
}
|
||||
|
||||
uint32_t sosc::cgc::Blowfish::Feistel(uint32_t input) const {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include "bcrypt.hpp"
|
||||
|
||||
namespace sosc {
|
||||
namespace cgc {
|
||||
|
@ -11,9 +12,11 @@ public:
|
|||
Blowfish(const std::string& key);
|
||||
|
||||
std::string Encrypt(std::string data) const;
|
||||
std::string Decrypt(const std::string& data) const;
|
||||
std::string Decrypt(std::string data) const;
|
||||
private:
|
||||
Blowfish();
|
||||
void SetKey(const char* key, size_t length);
|
||||
void SetEksKey(const std::string& data, const std::string& key);
|
||||
|
||||
void EncryptBlock(uint32_t* left, uint32_t* right) const;
|
||||
void DecryptBlock(uint32_t* left, uint32_t* right) const;
|
||||
|
@ -21,6 +24,8 @@ private:
|
|||
|
||||
uint32_t parr[18];
|
||||
uint32_t sbox[4][256];
|
||||
|
||||
friend std::string sosc::cgc::bcrypt_hash(const std::string&);
|
||||
};
|
||||
}}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "sock/tcpsock.hpp"
|
||||
#include "crypto/sha1.hpp"
|
||||
#include "crypto/base64.hpp"
|
||||
#include "crypto/bfish.hpp"
|
||||
#include "utils/csprng.hpp"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
//auto sock = sosc::TcpClient();
|
||||
|
@ -32,5 +34,12 @@ int main(int argc, char **argv) {
|
|||
|
||||
//std::string a = sosc::cgc::sha1("test", true);
|
||||
|
||||
sosc::cgc::Blowfish fish("");
|
||||
|
||||
std::string test = fish.Encrypt("imagine a test");
|
||||
std::string testd = fish.Decrypt(test);
|
||||
|
||||
uint32_t teest = sosc::csprng::next<uint32_t>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
58
server/src/utils/csprng.cpp
Normal file
58
server/src/utils/csprng.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include "csprng.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
// TODO update win32 code to use csprng in advapi32.lib
|
||||
// NOTE RUNNING ON WINDOWS IS INSECURE DO NOT DOD !!!
|
||||
|
||||
#include <ctime>
|
||||
|
||||
static struct __rng_ctx {
|
||||
std::default_random_engine rng;
|
||||
std::mutex rng_mtx;
|
||||
|
||||
__rng_ctx() : rng(time(NULL)) { }
|
||||
} _rng_ctx;
|
||||
|
||||
std::string sosc::csprng::next_bytes(std::string::size_type count) {
|
||||
_rng_ctx.rng_mtx.lock();
|
||||
|
||||
std::string rand_bytes;
|
||||
for(std::string::size_type i = 0; i < count; ++i)
|
||||
rand_bytes += (char)_rng_ctx.rng();
|
||||
|
||||
_rng_ctx.rng_mtx.unlock();
|
||||
return rand_bytes;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static struct __rng_ctx {
|
||||
std::ifstream urand;
|
||||
std::mutex rng_mtx;
|
||||
|
||||
__rng_ctx() {
|
||||
this->urand.open("/dev/urandom",
|
||||
std::ifstream::in | std::ifstream::binary);
|
||||
|
||||
if(!this->urand.good())
|
||||
throw "Could not establish csprng context.";
|
||||
}
|
||||
|
||||
~__rng_ctx() {
|
||||
this->urand.close();
|
||||
}
|
||||
} _rng_ctx;
|
||||
|
||||
std::string sosc::csprng::next_bytes(std::string::size_type count) {
|
||||
_rng_ctx.rng_mtx.lock();
|
||||
|
||||
char* buffer = new char[count];
|
||||
_rng_ctx.urand.read(buffer, count);
|
||||
std::string rand_bytes(buffer, count);
|
||||
delete[] buffer;
|
||||
|
||||
_rng_ctx.rng_mtx.unlock();
|
||||
return rand_bytes;
|
||||
}
|
||||
|
||||
#endif
|
19
server/src/utils/csprng.hpp
Normal file
19
server/src/utils/csprng.hpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef SOSC_UTIL_CSPRNG_H
|
||||
#define SOSC_UTIL_CSPRNG_H
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <random>
|
||||
|
||||
namespace sosc {
|
||||
namespace csprng {
|
||||
std::string next_bytes(std::string::size_type count);
|
||||
|
||||
template<typename T>
|
||||
T next() {
|
||||
return *((T*)(next_bytes(sizeof(T)).c_str()));
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue