void O2Profile:: SetRSAKey(const byte *priv, size_t privlen, const byte *pub, size_t publen) { bool valid = false; if (priv && privlen && pub && publen) { if (privlen == RSA_PRIVKEY_SIZE && publen == RSA_PUBKEY_SIZE) { PrivKey.assign(priv, privlen); PubKey.assign(pub, publen); valid = true; } } if (!valid) { CryptoPP::RandomPool randpool; #ifdef _WIN32 /** windows */ GUID guid; CoCreateGuid(&guid); randpool.Put((byte*)&guid, sizeof(GUID)); #else /** unix */ boost::uuids::random_generator gen; boost::uuids::uuid uuid = gen(); randpool.Put((byte*)&uuid, sizeof(boost::uuids::uuid)); #endif byte tmpPriv[RSA_PRIVKEY_SIZE]; CryptoPP::RSAES_OAEP_SHA_Decryptor priv(randpool, RSA_KEYLENGTH); CryptoPP::ArraySink privArray(tmpPriv, RSA_PRIVKEY_SIZE); priv.DEREncode(privArray); privArray.MessageEnd(); PrivKey.assign(tmpPriv, RSA_PRIVKEY_SIZE); byte tmpPub[RSA_PUBKEY_SIZE]; CryptoPP::RSAES_OAEP_SHA_Encryptor pub(priv); CryptoPP::ArraySink pubArray(tmpPub, RSA_PUBKEY_SIZE); pub.DEREncode(pubArray); pubArray.MessageEnd(); PubKey.assign(tmpPub, RSA_PUBKEY_SIZE); } }
void cServer::PrepareKeys(void) { // TODO: Save and load key for persistence across sessions // But generating the key takes only a moment, do we even need that? LOGD("Generating protocol encryption keypair..."); time_t CurTime = time(NULL); CryptoPP::RandomPool rng; rng.Put((const byte *)&CurTime, sizeof(CurTime)); m_PrivateKey.GenerateRandomWithKeySize(rng, 1024); CryptoPP::RSA::PublicKey pk(m_PrivateKey); m_PublicKey = pk; }
void cProtocol132::HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce) { // Decrypt EncNonce using privkey RSAES<PKCS1v15>::Decryptor rsaDecryptor(cRoot::Get()->GetServer()->GetPrivateKey()); time_t CurTime = time(NULL); CryptoPP::RandomPool rng; rng.Put((const byte *)&CurTime, sizeof(CurTime)); byte DecryptedNonce[MAX_ENC_LEN]; DecodingResult res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncNonce.data(), a_EncNonce.size(), DecryptedNonce); if (!res.isValidCoding || (res.messageLength != 4)) { LOGD("Bad nonce length"); m_Client->Kick("Hacked client"); return; } if (ntohl(*((int *)DecryptedNonce)) != (unsigned)(uintptr_t)this) { LOGD("Bad nonce value"); m_Client->Kick("Hacked client"); return; } // Decrypt the symmetric encryption key using privkey: byte DecryptedKey[MAX_ENC_LEN]; res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncKey.data(), a_EncKey.size(), DecryptedKey); if (!res.isValidCoding || (res.messageLength != 16)) { LOGD("Bad key length"); m_Client->Kick("Hacked client"); return; } { // Send encryption key response: cCSLock Lock(m_CSPacket); WriteByte((char)0xfc); WriteShort(0); WriteShort(0); Flush(); } StartEncryption(DecryptedKey); return; }
void O2Profile:: SetRSAKey(const byte *priv, size_t privlen, const byte *pub, size_t publen) { bool valid = false; if (priv && privlen && pub && publen) { if (privlen == RSA_PRIVKEY_SIZE && publen == RSA_PUBKEY_SIZE) { PrivKey.assign(priv, privlen); PubKey.assign(pub, publen); valid = true; } } if (!valid) { GUID guid; CoCreateGuid(&guid); CryptoPP::RandomPool randpool; randpool.Put((byte*)&guid, sizeof(GUID)); byte tmpPriv[RSA_PRIVKEY_SIZE]; CryptoPP::RSAES_OAEP_SHA_Decryptor priv(randpool, RSA_KEYLENGTH); CryptoPP::ArraySink privArray(tmpPriv, RSA_PRIVKEY_SIZE); priv.DEREncode(privArray); privArray.MessageEnd(); PrivKey.assign(tmpPriv, RSA_PRIVKEY_SIZE); byte tmpPub[RSA_PUBKEY_SIZE]; CryptoPP::RSAES_OAEP_SHA_Encryptor pub(priv); CryptoPP::ArraySink pubArray(tmpPub, RSA_PUBKEY_SIZE); pub.DEREncode(pubArray); pubArray.MessageEnd(); PubKey.assign(tmpPub, RSA_PUBKEY_SIZE); } }