void
CClientProxy1_4::cryptoIv()
{
	CCryptoStream* cryptoStream = dynamic_cast<CCryptoStream*>(getStream());
	if (cryptoStream == NULL) {
		return;
	}

	byte iv[CRYPTO_IV_SIZE];
	cryptoStream->newIv(iv);
	CString data(reinterpret_cast<const char*>(iv), CRYPTO_IV_SIZE);

	LOG((CLOG_DEBUG2 "send crypto iv change to \"%s\"", getName().c_str()));
	CProtocolUtil::writef(getStream(), kMsgDCryptoIv, &data);
	
	// change IV only after we've sent the current IV, otherwise
	// the client won't be able to decrypt the new IV.
	cryptoStream->setEncryptIv(iv);
}
Beispiel #2
0
TEST(CClientProxyTests, cryptoIvWrite)
{
	g_cryptoIvWrite_writeBufferIndex = 0;
	g_cryptoIvWrite_readBufferIndex = 0;

	NiceMock<CMockEventQueue> eventQueue;
	NiceMock<CMockStream> innerStream;
	NiceMock<CMockServer> server;
	CCryptoOptions options("ctr", "mock");
	IStreamEvents streamEvents;
	streamEvents.setEvents(&eventQueue);

	CCryptoStream* serverStream = new CCryptoStream(&eventQueue, &innerStream, options, false);
	CCryptoStream* clientStream = new CCryptoStream(&eventQueue, &innerStream, options, false);

	byte iv[CRYPTO_IV_SIZE];
	serverStream->newIv(iv);
	serverStream->setEncryptIv(iv);
	clientStream->setDecryptIv(iv);
	
	ON_CALL(eventQueue, forIStream()).WillByDefault(ReturnRef(streamEvents));
	ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(cryptoIv_mockWrite));
	ON_CALL(innerStream, read(_, _)).WillByDefault(Invoke(cryptoIv_mockRead));

	CClientProxy1_4 clientProxy("stub", serverStream, &server, &eventQueue);
	
	UInt8 buffer[100];
	clientStream->read(buffer, 4);

	g_cryptoIvWrite_writeBufferIndex = 0;
	g_cryptoIvWrite_readBufferIndex = 0;

	// DCIV, then DKDN.
	clientProxy.keyDown(1, 2, 3);
	clientStream->read(buffer, 24);
	EXPECT_EQ('D', buffer[0]);
	EXPECT_EQ('C', buffer[1]);
	EXPECT_EQ('I', buffer[2]);
	EXPECT_EQ('V', buffer[3]);
	clientStream->setDecryptIv(&buffer[8]);
	clientStream->read(buffer, 10);
	EXPECT_EQ('D', buffer[0]);
	EXPECT_EQ('K', buffer[1]);
	EXPECT_EQ('D', buffer[2]);
	EXPECT_EQ('N', buffer[3]);
	
	g_cryptoIvWrite_writeBufferIndex = 0;
	g_cryptoIvWrite_readBufferIndex = 0;

	// DCIV, then DKUP.
	clientProxy.keyUp(1, 2, 3);
	clientStream->read(buffer, 24);
	EXPECT_EQ('D', buffer[0]);
	EXPECT_EQ('C', buffer[1]);
	EXPECT_EQ('I', buffer[2]);
	EXPECT_EQ('V', buffer[3]);
	clientStream->setDecryptIv(&buffer[8]);
	clientStream->read(buffer, 10);
	EXPECT_EQ('D', buffer[0]);
	EXPECT_EQ('K', buffer[1]);
	EXPECT_EQ('U', buffer[2]);
	EXPECT_EQ('P', buffer[3]);
	
	g_cryptoIvWrite_writeBufferIndex = 0;
	g_cryptoIvWrite_readBufferIndex = 0;
	
	// DCIV, then DKRP.
	clientProxy.keyRepeat(1, 2, 4, 4);
	clientStream->read(buffer, 24);
	EXPECT_EQ('D', buffer[0]);
	EXPECT_EQ('C', buffer[1]);
	EXPECT_EQ('I', buffer[2]);
	EXPECT_EQ('V', buffer[3]);
	clientStream->setDecryptIv(&buffer[8]);
	clientStream->read(buffer, 12);
	EXPECT_EQ('D', buffer[0]);
	EXPECT_EQ('K', buffer[1]);
	EXPECT_EQ('R', buffer[2]);
	EXPECT_EQ('P', buffer[3]);
}