From 3aaebd9e50e401f4a84d855a5a95ea07a4b33fa1 Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Thu, 4 Apr 2013 16:17:25 +0000 Subject: [PATCH] Patch by Jerry: * wrote CCryptoStream and supporting unit tests * changed CStreamFilter to accept CMockEventQueue * changed CStreamFilter's dtor to virtual because it is inherited --- src/lib/io/CStreamFilter.cpp | 11 ++- src/lib/io/CStreamFilter.h | 5 +- src/lib/io/IStream.h | 4 +- src/lib/synergy/CCrypto.cpp | 42 -------- src/lib/synergy/CCrypto.h | 24 ----- src/lib/synergy/CCryptoStream.cpp | 58 +++++++++++ src/lib/synergy/CCryptoStream.h | 54 +++++++++++ src/lib/synergy/CMakeLists.txt | 6 +- src/lib/synergy/CPacketStreamFilter.cpp | 2 +- src/test/unittests/CMakeLists.txt | 4 +- .../unittests/synergy/CCryptoStreamTests.cpp | 97 +++++++++++++++++++ src/test/unittests/synergy/CCryptoTests.cpp | 28 ------ tools/CMakeLists.txt | 3 +- 13 files changed, 227 insertions(+), 111 deletions(-) delete mode 100644 src/lib/synergy/CCrypto.cpp delete mode 100644 src/lib/synergy/CCrypto.h create mode 100644 src/lib/synergy/CCryptoStream.cpp create mode 100644 src/lib/synergy/CCryptoStream.h create mode 100644 src/test/unittests/synergy/CCryptoStreamTests.cpp delete mode 100644 src/test/unittests/synergy/CCryptoTests.cpp diff --git a/src/lib/io/CStreamFilter.cpp b/src/lib/io/CStreamFilter.cpp index d800d696..41669570 100644 --- a/src/lib/io/CStreamFilter.cpp +++ b/src/lib/io/CStreamFilter.cpp @@ -24,20 +24,21 @@ // CStreamFilter // -CStreamFilter::CStreamFilter(synergy::IStream* stream, bool adoptStream) : +CStreamFilter::CStreamFilter(IEventQueue& eventQueue, synergy::IStream* stream, bool adoptStream) : + IStream(eventQueue), m_stream(stream), m_adopted(adoptStream) { // replace handlers for m_stream - EVENTQUEUE->removeHandlers(m_stream->getEventTarget()); - EVENTQUEUE->adoptHandler(CEvent::kUnknown, m_stream->getEventTarget(), + m_eventQueue.removeHandlers(m_stream->getEventTarget()); + m_eventQueue.adoptHandler(CEvent::kUnknown, m_stream->getEventTarget(), new TMethodEventJob(this, &CStreamFilter::handleUpstreamEvent)); } CStreamFilter::~CStreamFilter() { - EVENTQUEUE->removeHandler(CEvent::kUnknown, m_stream->getEventTarget()); + m_eventQueue.removeHandler(CEvent::kUnknown, m_stream->getEventTarget()); if (m_adopted) { delete m_stream; } @@ -106,7 +107,7 @@ CStreamFilter::getStream() const void CStreamFilter::filterEvent(const CEvent& event) { - EVENTQUEUE->dispatchEvent(CEvent(event.getType(), + m_eventQueue.dispatchEvent(CEvent(event.getType(), getEventTarget(), event.getData())); } diff --git a/src/lib/io/CStreamFilter.h b/src/lib/io/CStreamFilter.h index 2eb5f9d4..deb71193 100644 --- a/src/lib/io/CStreamFilter.h +++ b/src/lib/io/CStreamFilter.h @@ -20,6 +20,7 @@ #define CSTREAMFILTER_H #include "IStream.h" +#include "IEventQueue.h" //! A stream filter /*! @@ -33,8 +34,8 @@ public: this object takes ownership of the stream and will delete it in the d'tor. */ - CStreamFilter(synergy::IStream* stream, bool adoptStream = true); - ~CStreamFilter(); + CStreamFilter(IEventQueue& eventQueue, synergy::IStream* stream, bool adoptStream = true); + virtual ~CStreamFilter(); // IStream overrides // These all just forward to the underlying stream except getEventTarget. diff --git a/src/lib/io/IStream.h b/src/lib/io/IStream.h index af3aeee5..58e9de4e 100644 --- a/src/lib/io/IStream.h +++ b/src/lib/io/IStream.h @@ -158,9 +158,9 @@ public: //@} -private: - IEventQueue& m_eventQueue; + IEventQueue& m_eventQueue; +private: static CEvent::Type s_inputReadyEvent; static CEvent::Type s_outputFlushedEvent; static CEvent::Type s_outputErrorEvent; diff --git a/src/lib/synergy/CCrypto.cpp b/src/lib/synergy/CCrypto.cpp deleted file mode 100644 index d5fbfcf3..00000000 --- a/src/lib/synergy/CCrypto.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2012 Bolton Software Ltd. - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include "CCrypto.h" - -#include "cryptlib.h" -#include "default.h" -#include "modes.h" -#include "aes.h" -#include "randpool.h" -#include "files.h" -#include "hex.h" -#include "rsa.h" -#include - -using namespace CryptoPP; - -static OFB_Mode::Encryption s_globalRNG; - -void CCrypto::test() -{ - std::string seed = IntToString(time(NULL)); - seed.resize(16); - s_globalRNG.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data()); -} diff --git a/src/lib/synergy/CCrypto.h b/src/lib/synergy/CCrypto.h deleted file mode 100644 index 3b05711a..00000000 --- a/src/lib/synergy/CCrypto.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2012 Bolton Software Ltd. - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -class CCrypto { -public: - void test(); -}; diff --git a/src/lib/synergy/CCryptoStream.cpp b/src/lib/synergy/CCryptoStream.cpp new file mode 100644 index 00000000..a00231a4 --- /dev/null +++ b/src/lib/synergy/CCryptoStream.cpp @@ -0,0 +1,58 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2013 Bolton Software Ltd. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "CCryptoStream.h" + +// TODO: these are just for testing -- make sure they're gone by release! +const byte g_key1[] = "aaaaaaaaaaaaaaa"; +const byte g_key2[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; +const byte g_iv1[] = "aaaaaaaaaaaaaaa"; +const byte g_iv2[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + +using namespace CryptoPP; + +CCryptoStream::CCryptoStream(IEventQueue& eventQueue, synergy::IStream* stream) : + CStreamFilter(eventQueue, stream, false) +{ + m_encryption.SetKeyWithIV(g_key1, sizeof(g_key1), g_iv1); + m_decryption.SetKeyWithIV(g_key1, sizeof(g_key1), g_iv1); +} + +CCryptoStream::~CCryptoStream() +{ +} + +UInt32 +CCryptoStream::read(void* out, UInt32 n) +{ + byte* in = new byte[n]; + int result = getStream()->read(in, n); + m_decryption.ProcessData(static_cast(out), in, n); + delete[] in; + return result; +} + +void +CCryptoStream::write(const void* in, UInt32 n) +{ + byte* out = new byte[n]; + m_encryption.ProcessData(out, static_cast(in), n); + getStream()->write(out, n); + delete[] out; +} diff --git a/src/lib/synergy/CCryptoStream.h b/src/lib/synergy/CCryptoStream.h new file mode 100644 index 00000000..3d32d8db --- /dev/null +++ b/src/lib/synergy/CCryptoStream.h @@ -0,0 +1,54 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2013 Bolton Software Ltd. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "BasicTypes.h" +#include "CStreamFilter.h" +#include "cryptopp562/gcm.h" +#include "cryptopp562/aes.h" + +//! Bidirectional encrypted stream +/*! +Encrypts (on write) and decrypts (on read) to and from an underlying stream. +*/ +class CCryptoStream : public CStreamFilter { +public: + CCryptoStream(IEventQueue& eventQueue, synergy::IStream* stream); + virtual ~CCryptoStream(); + + //! @name manipulators + //@{ + + //! Read from stream + /*! + Read up to \p n bytes into \p buffer to the stream using encryption. + Returns the number of bytes read by the underlying stream. + */ + virtual UInt32 read(void* out, UInt32 n); + + //! Write to stream + /*! + Write \c n bytes from \c buffer to the stream using encryption. + */ + virtual void write(const void* in, UInt32 n); + +private: + // TODO: allow user to change between GCM/CTR/CFB + CryptoPP::GCM::Encryption m_encryption; + CryptoPP::GCM::Decryption m_decryption; +}; diff --git a/src/lib/synergy/CMakeLists.txt b/src/lib/synergy/CMakeLists.txt index a53a295f..1d9df5c6 100644 --- a/src/lib/synergy/CMakeLists.txt +++ b/src/lib/synergy/CMakeLists.txt @@ -50,7 +50,7 @@ set(inc IAppUtil.h CEventGameDevice.h CVncClient.h - CCrypto.h + CCryptoStream.h ) set(src @@ -82,7 +82,7 @@ set(src CEventGameDevice.cpp CVncClient.cpp CGameDevice.cpp - CCrypto.cpp + CCryptoStream.cpp ) if (WIN32) @@ -114,7 +114,7 @@ set(inc ../server ../synergy ../.. - ../../../tools/cryptopp562 + ../../../tools ) if (UNIX) diff --git a/src/lib/synergy/CPacketStreamFilter.cpp b/src/lib/synergy/CPacketStreamFilter.cpp index 60dba733..69437e5d 100644 --- a/src/lib/synergy/CPacketStreamFilter.cpp +++ b/src/lib/synergy/CPacketStreamFilter.cpp @@ -28,7 +28,7 @@ // CPacketStreamFilter::CPacketStreamFilter(synergy::IStream* stream, bool adoptStream) : - CStreamFilter(stream, adoptStream), + CStreamFilter(*EVENTQUEUE, stream, adoptStream), m_size(0), m_inputShutdown(false) { diff --git a/src/test/unittests/CMakeLists.txt b/src/test/unittests/CMakeLists.txt index a726af55..693befd2 100644 --- a/src/test/unittests/CMakeLists.txt +++ b/src/test/unittests/CMakeLists.txt @@ -28,7 +28,7 @@ set(src synergy/CClipboardTests.cpp synergy/CKeyStateTests.cpp client/CServerProxyTests.cpp - synergy/CCryptoTests.cpp + synergy/CCryptoStreamTests.cpp ) set(inc @@ -43,7 +43,7 @@ set(inc ../../lib/synergy ../../../tools/gtest-1.6.0/include ../../../tools/gmock-1.6.0/include -# ../../../tools/cryptopp561 + ../../../tools io synergy ) diff --git a/src/test/unittests/synergy/CCryptoStreamTests.cpp b/src/test/unittests/synergy/CCryptoStreamTests.cpp new file mode 100644 index 00000000..f36ec140 --- /dev/null +++ b/src/test/unittests/synergy/CCryptoStreamTests.cpp @@ -0,0 +1,97 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2013 Bolton Software Ltd. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "CCryptoStream.h" +#include "CMockStream.h" +#include "CMockEventQueue.h" + +using ::testing::_; +using ::testing::Invoke; + +using namespace std; + +void assertWrite(const void* in, UInt32 n); +UInt8 mockRead(void* out, UInt32 n); + +TEST(CCryptoTests, write) +{ + const UInt32 size = 4; + UInt8* buffer = new UInt8[size]; + buffer[0] = 'D'; + buffer[1] = 'K'; + buffer[2] = 'D'; + buffer[3] = 'N'; + + CMockEventQueue eventQueue; + CMockStream innerStream(eventQueue); + + ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(assertWrite)); + EXPECT_CALL(innerStream, write(_, _)).Times(1); + EXPECT_CALL(innerStream, getEventTarget()).Times(3); + EXPECT_CALL(eventQueue, removeHandlers(_)).Times(1); + EXPECT_CALL(eventQueue, adoptHandler(_, _, _)).Times(1); + EXPECT_CALL(eventQueue, removeHandler(_, _)).Times(1); + + CCryptoStream cs(eventQueue, &innerStream); + cs.write(buffer, size); +} + +TEST(CCryptoTests, read) +{ + CMockEventQueue eventQueue; + CMockStream innerStream(eventQueue); + + ON_CALL(innerStream, read(_, _)).WillByDefault(Invoke(mockRead)); + EXPECT_CALL(innerStream, read(_, _)).Times(1); + EXPECT_CALL(innerStream, getEventTarget()).Times(3); + EXPECT_CALL(eventQueue, removeHandlers(_)).Times(1); + EXPECT_CALL(eventQueue, adoptHandler(_, _, _)).Times(1); + EXPECT_CALL(eventQueue, removeHandler(_, _)).Times(1); + + CCryptoStream cs(eventQueue, &innerStream); + + const UInt32 size = 4; + UInt8* buffer = new UInt8[size]; + cs.read(buffer, size); + + EXPECT_EQ('D', buffer[0]); + EXPECT_EQ('K', buffer[1]); + EXPECT_EQ('D', buffer[2]); + EXPECT_EQ('N', buffer[3]); +} + +void +assertWrite(const void* in, UInt32 n) +{ + UInt8* buffer = static_cast(const_cast(in)); + EXPECT_EQ(55, buffer[0]); + EXPECT_EQ(142, buffer[1]); + EXPECT_EQ(189, buffer[2]); + EXPECT_EQ(237, buffer[3]); +} + +UInt8 +mockRead(void* out, UInt32 n) +{ + UInt8* buffer = static_cast(out); + buffer[0] = 55; + buffer[1] = 142; + buffer[2] = 189; + buffer[3] = 237; + return n; +} diff --git a/src/test/unittests/synergy/CCryptoTests.cpp b/src/test/unittests/synergy/CCryptoTests.cpp deleted file mode 100644 index 174f7321..00000000 --- a/src/test/unittests/synergy/CCryptoTests.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2012 Bolton Software Ltd. - * Copyright (C) 2011 Nick Bolton - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include "CCrypto.h" - -using namespace std; - -TEST(CCryptoTests, test) -{ - CCrypto crypto; - crypto.test(); -} diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 6e045dbc..4bea5b14 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,6 +1,5 @@ # synergy -- mouse and keyboard sharing utility -# Copyright (C) 2012 Bolton Software Ltd. -# Copyright (C) 2011 Nick Bolton +# Copyright (C) 2013 Bolton Software Ltd. # # This package is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License