예제 #1
0
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;
}
예제 #2
0
파일: Encrypt.cpp 프로젝트: ONLYOFFICE/core
        void Reset()
        {
            if (streamEncryption)
                delete streamEncryption;
            if (aesEncryption)
                delete aesEncryption;

			CryptoPP::RandomPool prng;
			CryptoPP::SecByteBlock iv(16);
			CryptoPP::OS_GenerateRandomBlock(false, iv, iv.size());
			prng.IncorporateEntropy(iv, iv.size());

			memcpy(streamInitialization, iv, iv.size());
			
			aesEncryption       = new CryptoPP::AES::Encryption(m_anEncryptionKey, 32);
            streamEncryption    = new CryptoPP::CBC_Mode_ExternalCipher::Encryption( *aesEncryption, streamInitialization);
        }
예제 #3
0
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;
}
예제 #4
0
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);
	}
}
예제 #5
0
파일: Encrypt.cpp 프로젝트: ONLYOFFICE/core
	void CEncrypt::CreateOwnerKey()
	{
        CryptoPP::RandomPool prng;

        CryptoPP::SecByteBlock salt(16);
        CryptoPP::OS_GenerateRandomBlock(false, salt, salt.size());
        prng.IncorporateEntropy(salt, salt.size());

        memcpy(m_anOwnerKey + 32, salt.data(), salt.size());

        CryptoPP::SHA256 hash;

        hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length());
        hash.Update( m_anOwnerKey + 32, 8);
        hash.Update( m_anUserKey, 48);

        CryptoPP::SecByteBlock pHashData(hash.DigestSize());
        hash.Final(pHashData);

        if (MakeFileKey3(impl->m_sOwnerPassword, pHashData.data(), pHashData.size(), m_anUserKey, 48))
        {
            memcpy(m_anOwnerKey, pHashData.data(), pHashData.size());

            hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length());
            hash.Update( m_anOwnerKey + 40, 8);
            hash.Update( m_anUserKey, 48);

            CryptoPP::SecByteBlock pHashKeyData(hash.DigestSize());
            hash.Final(pHashKeyData);

            MakeFileKey3(impl->m_sOwnerPassword, pHashKeyData.data(), pHashKeyData.size(), m_anUserKey, 48);
            unsigned char empty[16] = {};

            CryptoPP::AES::Encryption aesEncryption(pHashKeyData.data(), pHashKeyData.size());
            CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, empty);

            CryptoPP::StreamTransformationFilter stfEncryption(cbcEncryption, new CryptoPP::ArraySink( m_anOwnerEncryptKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING );
            stfEncryption.Put2(impl->m_anEncryptionKey, 32, 1, true);
            stfEncryption.MessageEnd();
        }
	}
예제 #6
0
파일: Encrypt.cpp 프로젝트: ONLYOFFICE/core
	void CEncrypt::CreateEncryptionKey()
	{
        CryptoPP::RandomPool prng;

        CryptoPP::SecByteBlock key(32);
        CryptoPP::OS_GenerateRandomBlock(false, key, key.size());
        prng.IncorporateEntropy(key, key.size());

		memcpy(impl->m_anEncryptionKey, key.data(), key.size());
//-------------------------------------------------------------------

		unsigned long long extended_perms = 0xffffffff00000000LL | m_unPermission;
		for (int i = 0; i < 8; ++i)
		{
			m_anPermEncrypt[i] = static_cast<unsigned char>(extended_perms & 0xff);
			extended_perms >>= 8;
		}
		m_anPermEncrypt[8]	= /*m_bEncryptMetadata ? 'T' : */'F';
		m_anPermEncrypt[9]	= 'a';
		m_anPermEncrypt[10]	= 'd';
		m_anPermEncrypt[11]	= 'b';
        
        CryptoPP::SecByteBlock p(4);
        CryptoPP::OS_GenerateRandomBlock(false, p, p.size());
        prng.IncorporateEntropy(p, p.size());

		memcpy(m_anPermEncrypt + 12, p.data(), p.size());

		unsigned char empty[16] = {};
		
		CryptoPP::AES::Encryption aesEncryption(impl->m_anEncryptionKey, 32);
		
		CryptoPP::CipherModeFinalTemplate_ExternalCipher<CryptoPP::ECB_OneWay> ecbEncryption(aesEncryption, empty ); 

        CryptoPP::StreamTransformationFilter stfEncryption(ecbEncryption, new CryptoPP::ArraySink( m_anPermEncrypt, 16), CryptoPP::StreamTransformationFilter::NO_PADDING );
        stfEncryption.Put2(m_anPermEncrypt, 16, 1, true);
        stfEncryption.MessageEnd();
	}
예제 #7
0
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);
	}
}