3 #include "longstring.h"
5 #include "stg/bfstream.h"
6 #include "stg/os_int.h"
18 TRACKER() : m_lastSize(0), m_callCount(0), m_lastBlock(NULL) {}
19 ~TRACKER() { delete[] m_lastBlock; }
20 bool Call(const void * block, size_t size)
25 m_lastBlock = new char[size];
26 memcpy(m_lastBlock, block, size);
27 m_result.append(m_lastBlock, size);
35 size_t LastSize() const { return m_lastSize; }
36 size_t CallCount() const { return m_callCount; }
37 const void * LastBlock() const { return m_lastBlock; }
39 const std::string& Result() const { return m_result; }
49 bool DecryptCallback(const void * block, size_t size, void * data);
54 Decryptor(const std::string & key)
55 : m_stream(key, DecryptCallback, this)
58 bool Call(const void * block, size_t size)
60 m_stream.Put(block, size);
64 bool Put(const void * block, size_t size)
66 const char * data = static_cast<const char *>(block);
67 size = strnlen(data, size);
68 m_result.append(data, size);
74 m_stream.Put(NULL, 0);
77 const std::string & Result() const { return m_result; }
80 STG::DECRYPT_STREAM m_stream;
84 bool EncryptCallback(const void * block, size_t size, void * data)
86 Decryptor & decryptor = *static_cast<Decryptor *>(data);
87 return decryptor.Call(block, size);
90 bool DecryptCallback(const void * block, size_t size, void * data)
92 Decryptor & decryptor = *static_cast<Decryptor *>(data);
93 return decryptor.Put(block, size);
96 bool Callback(const void * block, size_t size, void * data)
98 TRACKER & tracker = *static_cast<TRACKER *>(data);
99 return tracker.Call(block, size);
106 struct bfstream_data {
109 typedef test_group<bfstream_data> tg;
110 tg bfstream_test_group("BFStream tests group");
112 typedef tg::object testobject;
116 void testobject::test<1>()
118 set_test_name("Check bfstream mechanics");
121 STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
122 ensure_equals("CallCount() == 0 after construction", tracker.CallCount(), 0);
124 uint32_t block[2] = {0x12345678, 0x87654321};
125 stream.Put(&block[0], sizeof(block[0]));
126 ensure_equals("CallCount() == 0 after first put", tracker.CallCount(), 0);
127 stream.Put(&block[1], sizeof(block[1]));
128 ensure_equals("CallCount() == 1 after second put", tracker.CallCount(), 1);
130 uint32_t block2[4] = {0x12345678, 0x87654321, 0x12345678, 0x87654321};
131 stream.Put(&block2[0], sizeof(block2[0]) * 3);
132 ensure_equals("CallCount() == 2 after third put", tracker.CallCount(), 2);
133 stream.Put(&block2[3], sizeof(block2[3]));
134 ensure_equals("CallCount() == 3 after fourth put", tracker.CallCount(), 3);
139 void testobject::test<2>()
141 set_test_name("Check bfstream encryption");
144 STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
146 uint32_t block[2] = {0x12345678, 0x87654321};
147 stream.Put(&block[0], sizeof(block[0]));
148 ensure_equals("LastSize() == 0 after first put", tracker.LastSize(), 0);
149 ensure_equals("LastBlock() == NULL after first put", tracker.LastBlock(), static_cast<const void *>(NULL));
150 stream.Put(&block[1], sizeof(block[1]));
151 ensure_equals("LastSize() == 8 after second put", tracker.LastSize(), 8);
152 const uint32_t * ptr = static_cast<const uint32_t *>(tracker.LastBlock());
153 ensure_equals("ptr[0] == 0xd3988cd after second put", ptr[0], 0xd3988cd);
154 ensure_equals("ptr[1] == 0x7996c6d6 after second put", ptr[1], 0x7996c6d6);
156 uint32_t block2[4] = {0x12345678, 0x87654321, 0x12345678, 0x87654321};
157 stream.Put(&block2[0], sizeof(block2[0]) * 3);
158 ensure_equals("LastSize() == 8 after third put", tracker.LastSize(), 8);
159 ptr = static_cast<const uint32_t *>(tracker.LastBlock());
160 ensure_equals("ptr[0] == 0xd3988cd after third put", ptr[0], 0xd3988cd);
161 ensure_equals("ptr[1] == 0x7996c6d6 after third put", ptr[1], 0x7996c6d6);
163 stream.Put(&block2[3], sizeof(block2[3]));
164 ensure_equals("LastSize() == 8 after fourth put", tracker.LastSize(), 8);
165 ptr = static_cast<const uint32_t *>(tracker.LastBlock());
166 ensure_equals("ptr[0] == 0xd3988cd after fourth put", ptr[0], 0xd3988cd);
167 ensure_equals("ptr[1] == 0x7996c6d6 after fourth put", ptr[1], 0x7996c6d6);
172 void testobject::test<3>()
174 set_test_name("Check bfstream long string processing");
177 STG::ENCRYPT_STREAM estream("pr7Hhen", Callback, &tracker);
178 std::string source = "This is a test long string for checking stream encryption/decryption. \"abcdefghijklmnopqrstuvwxyz 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ\"";
179 char buffer[source.length() + 9];
180 memset(buffer, 0, sizeof(buffer));
182 estream.Put(source.c_str(), source.length() + 1, true);
183 ensure("Encryption long string LastSize()", tracker.LastSize() >= source.length() + 1);
184 ensure("Encryption long string LastBlock() != NULL", tracker.LastBlock() != NULL);
185 memcpy(buffer, tracker.LastBlock(), std::min(tracker.LastSize(), sizeof(buffer)));
187 STG::DECRYPT_STREAM dstream("pr7Hhen", Callback, &tracker);
188 dstream.Put(buffer, sizeof(buffer), true);
189 ensure("Decryption long string LastSize() decryption", tracker.LastSize() >= sizeof(buffer));
190 ensure("Decryption long string LastBlock() != NULL", tracker.LastBlock() != NULL);
191 memcpy(buffer, tracker.LastBlock(), std::min(tracker.LastSize(), sizeof(buffer)));
193 ensure_equals("Decrypt(Encrypt(source)) == source", std::string(buffer), source);
198 void testobject::test<4>()
200 set_test_name("Check bfstream very long string processing");
202 Decryptor decryptor("pr7Hhen");
203 STG::ENCRYPT_STREAM estream("pr7Hhen", EncryptCallback, &decryptor);
204 //char buffer[source.length() + 9];
205 //memset(buffer, 0, sizeof(buffer));
207 estream.Put(longString.c_str(), longString.length() + 1, true);
208 //ensure("Encryption long string LastSize()", tracker.LastSize() >= source.length() + 1);
209 //ensure("Encryption long string LastBlock() != NULL", tracker.LastBlock() != NULL);
210 //memcpy(buffer, tracker.LastBlock(), std::min(tracker.LastSize(), sizeof(buffer)));
212 //dstream.Put(buffer, sizeof(buffer), true);
213 //ensure("Decryption long string LastSize() decryption", tracker.LastSize() >= sizeof(buffer));
214 //ensure("Decryption long string LastBlock() != NULL", tracker.LastBlock() != NULL);
215 //memcpy(buffer, tracker.LastBlock(), std::min(tracker.LastSize(), sizeof(buffer)));
217 ensure_equals("Decrypt(Encrypt(source)) == source", decryptor.Result(), longString);
222 void testobject::test<5>()
224 set_test_name("Check bfstream mechanics");
227 STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
228 ensure_equals("CallCount() == 0 after construction", tracker.CallCount(), 0);
230 uint32_t block[2] = {0x12345678, 0x87654321};
231 stream.Put(&block[0], sizeof(block[0]));
232 ensure_equals("CallCount() == 0 after first put", tracker.CallCount(), 0);
233 stream.Put(&block[1], sizeof(block[1]));
234 ensure_equals("CallCount() == 1 after second put", tracker.CallCount(), 1);
235 stream.Put(&block[0], 0, true); // Check last callback
236 ensure_equals("CallCount() == 2 after third (null) put", tracker.CallCount(), 2);