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); }
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]); }