Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

665 lines
13 KiB

  1. // test the published EncryptedString class
  2. #include <windows.h>
  3. #include <time.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. // Make sure we have an ASSERT() function defined for our test.
  7. #ifndef ASSERT
  8. #ifdef NDEBUG
  9. #undef NDEBUG
  10. #endif
  11. #include <assert.h>
  12. #define ASSERT assert
  13. #endif
  14. // Uncomment the #define if you want to trace the test harness.
  15. #ifndef TRACE
  16. //#define TRACE
  17. #endif
  18. class ScopeTracer
  19. {
  20. public:
  21. ScopeTracer(const char* message)
  22. : m_message(NULL)
  23. {
  24. #ifdef TRACE
  25. if (message)
  26. {
  27. m_message = new char[strlen(message) + 1];
  28. strcpy(m_message, message);
  29. }
  30. else
  31. {
  32. m_message = new char[1];
  33. m_message[0] = NULL;
  34. }
  35. PrintIndents();
  36. printf("->%s\n", m_message);
  37. ++g_indentLevel;
  38. #else
  39. // Make the compiler happy.
  40. message = NULL;
  41. #endif
  42. }
  43. ~ScopeTracer(void)
  44. {
  45. #ifdef TRACE
  46. --g_indentLevel;
  47. PrintIndents();
  48. printf("<-%s\n", m_message);
  49. delete [] m_message;
  50. #endif
  51. }
  52. unsigned int GetIndentLevel(void) const
  53. {
  54. return g_indentLevel;
  55. }
  56. private:
  57. void PrintIndents(void)
  58. {
  59. for (unsigned int level = 0;
  60. level < g_indentLevel;
  61. ++level)
  62. {
  63. printf(" ");
  64. }
  65. }
  66. char* m_message;
  67. static unsigned int g_indentLevel;
  68. };
  69. unsigned int ScopeTracer::g_indentLevel = 0;
  70. #include "EncryptedString.hpp"
  71. #include <list>
  72. using namespace std;
  73. HINSTANCE hResourceModuleHandle = 0;
  74. const wchar_t* HELPFILE_NAME = 0;
  75. const wchar_t* RUNTIME_NAME = L"test";
  76. //DWORD DEFAULT_LOGGING_OPTIONS = Burnslib::Log::OUTPUT_TYPICAL;
  77. const size_t MAX_CHARACTER_COUNT = 2047;
  78. void
  79. TestEmptyness(const EncryptedString& empty)
  80. {
  81. ScopeTracer scope("TestEmptyness");
  82. ASSERT(empty.IsEmpty());
  83. ASSERT(empty.GetLength() == 0);
  84. // the cleartext of an empty instance should also be empty
  85. WCHAR* emptyClear = empty.GetClearTextCopy();
  86. ASSERT(emptyClear);
  87. ASSERT(*emptyClear == 0);
  88. empty.DestroyClearTextCopy(emptyClear);
  89. }
  90. void
  91. TestEmptyStrings()
  92. {
  93. ScopeTracer scope("TestEmptyStrings");
  94. EncryptedString empty1;
  95. TestEmptyness(empty1);
  96. // copies of empty strings are themselves empty
  97. EncryptedString empty2(empty1);
  98. // source should still be empty
  99. TestEmptyness(empty1);
  100. TestEmptyness(empty2);
  101. EncryptedString empty3;
  102. TestEmptyness(empty3);
  103. empty3 = empty2;
  104. // source should still be empty
  105. TestEmptyness(empty2);
  106. TestEmptyness(empty3);
  107. empty3 = empty1;
  108. TestEmptyness(empty1);
  109. TestEmptyness(empty2);
  110. TestEmptyness(empty3);
  111. // strings built from empty strings should be empty
  112. EncryptedString empty4;
  113. TestEmptyness(empty4);
  114. empty4.Encrypt(L"");
  115. TestEmptyness(empty4);
  116. // a string made from an empty string is still empty when the source
  117. // is made non-empty
  118. EncryptedString empty5;
  119. EncryptedString empty6(empty5);
  120. TestEmptyness(empty5);
  121. TestEmptyness(empty6);
  122. empty5.Encrypt(L"not empty any more");
  123. ASSERT(!empty5.IsEmpty());
  124. ASSERT(empty5.GetLength() != 0);
  125. TestEmptyness(empty6);
  126. // A cleared string is empty
  127. EncryptedString empty7;
  128. empty7.Encrypt(L"some text");
  129. empty7.Clear();
  130. TestEmptyness(empty7);
  131. // empty strings are equal
  132. ASSERT(empty1 == empty1);
  133. ASSERT(empty1 == empty2);
  134. ASSERT(empty1 == empty3);
  135. ASSERT(empty1 == empty4);
  136. ASSERT(empty1 == empty6);
  137. ASSERT(empty1 == empty7);
  138. ASSERT(empty2 == empty1);
  139. ASSERT(empty2 == empty2);
  140. ASSERT(empty2 == empty3);
  141. ASSERT(empty2 == empty4);
  142. ASSERT(empty2 == empty6);
  143. ASSERT(empty2 == empty7);
  144. ASSERT(empty3 == empty1);
  145. ASSERT(empty3 == empty2);
  146. ASSERT(empty3 == empty3);
  147. ASSERT(empty3 == empty4);
  148. ASSERT(empty3 == empty6);
  149. ASSERT(empty3 == empty7);
  150. ASSERT(empty4 == empty1);
  151. ASSERT(empty4 == empty2);
  152. ASSERT(empty4 == empty3);
  153. ASSERT(empty4 == empty4);
  154. ASSERT(empty4 == empty6);
  155. ASSERT(empty4 == empty7);
  156. ASSERT(empty6 == empty1);
  157. ASSERT(empty6 == empty2);
  158. ASSERT(empty6 == empty3);
  159. ASSERT(empty6 == empty4);
  160. ASSERT(empty6 == empty6);
  161. ASSERT(empty6 == empty7);
  162. ASSERT(empty7 == empty1);
  163. ASSERT(empty7 == empty2);
  164. ASSERT(empty7 == empty3);
  165. ASSERT(empty7 == empty4);
  166. ASSERT(empty7 == empty6);
  167. ASSERT(empty7 == empty7);
  168. }
  169. WCHAR*
  170. MakeRandomString(size_t length)
  171. {
  172. //LOG_FUNCTION2(MakeRandomString, String::format(L"%1!d!", length));
  173. WCHAR* result = new WCHAR[length + 1];
  174. for (size_t i = 0; i < length; ++i)
  175. {
  176. // 32 = space, the lowest printable character
  177. int r1 = rand() % 0xFFEE;
  178. // careful not to use an expression as a parameter to max...
  179. int r2 = max(32, r1);
  180. ASSERT(r2);
  181. ASSERT(r2 >= 32);
  182. ASSERT(r2 < 0xFFEE);
  183. result[i] = (WCHAR) r2;
  184. ASSERT(result[i]);
  185. }
  186. result[length] = 0;
  187. return result;
  188. }
  189. void
  190. TestEncryption(const EncryptedString& s, const WCHAR* sourceClearText)
  191. {
  192. ScopeTracer scope("TestEncryption");
  193. // decrypt s, compare it to sourceClearText
  194. WCHAR* clearText = s.GetClearTextCopy();
  195. // the decryption shouldn't fail (barring out-of-memory);
  196. ASSERT(clearText);
  197. ASSERT(wcscmp(clearText, sourceClearText) == 0);
  198. s.DestroyClearTextCopy(clearText);
  199. }
  200. void
  201. TestEncryptionForStringOfLengthN(size_t length)
  202. {
  203. //LOG_FUNCTION2(TestEncryptionForStringOfLengthN, String::format(L"%1!d!", length));
  204. ASSERT(length <= MAX_CHARACTER_COUNT);
  205. WCHAR* source = MakeRandomString(length);
  206. EncryptedString s;
  207. s.Encrypt(source);
  208. TestEncryption(s, source);
  209. EncryptedString s1(s);
  210. TestEncryption(s1, source);
  211. EncryptedString s2;
  212. s2 = s;
  213. TestEncryption(s2, source);
  214. delete[] source;
  215. }
  216. void
  217. TestEncryptionFidelity()
  218. {
  219. ScopeTracer scope("TestEncryptionFidelity");
  220. // do we get out what we put in?
  221. srand(time(0));
  222. // test increasing lengths of random strings
  223. for (
  224. size_t length = 0;
  225. length <= MAX_CHARACTER_COUNT;
  226. ++length)
  227. {
  228. TestEncryptionForStringOfLengthN(length);
  229. }
  230. // test decreasing lengths of random strings
  231. for (
  232. size_t length = MAX_CHARACTER_COUNT;
  233. length != 0;
  234. --length)
  235. {
  236. TestEncryptionForStringOfLengthN(length);
  237. }
  238. // test strings of random length, with lots of outstanding encrypted
  239. // strings
  240. typedef std::list<EncryptedString*> ESPList;
  241. ESPList strings;
  242. for (
  243. int count = 0;
  244. count < 1000;
  245. ++count)
  246. {
  247. size_t length = rand() % MAX_CHARACTER_COUNT;
  248. WCHAR* source = MakeRandomString(length);
  249. EncryptedString* ps = new EncryptedString;
  250. strings.push_back(ps);
  251. ps->Encrypt(source);
  252. TestEncryption(*ps, source);
  253. // make a copy via copy ctor
  254. EncryptedString* ps1 = new EncryptedString(*ps);
  255. strings.push_back(ps1);
  256. TestEncryption(*ps1, source);
  257. // make a copy via operator =
  258. EncryptedString* ps2 = new EncryptedString;
  259. strings.push_back(ps2);
  260. *ps2 = *ps;
  261. TestEncryption(*ps2, source);
  262. delete[] source;
  263. }
  264. for (
  265. ESPList::iterator i = strings.begin();
  266. i != strings.end();
  267. ++i)
  268. {
  269. (*i)->Clear();
  270. TestEmptyness(**i);
  271. delete *i;
  272. }
  273. }
  274. void
  275. TestClearTextCopying()
  276. {
  277. ScopeTracer scope("TestClearTextCopying");
  278. // make a bunch of copies, make sure the count balances
  279. typedef char foo[2];
  280. // An encrypted string and the source string used to build it.
  281. typedef
  282. std::pair<EncryptedString*, WCHAR*>
  283. EncryptedAndSourcePair;
  284. // A list of results from EncryptedString::GetClearTextCopy
  285. typedef std::list<WCHAR*> ClearTextList;
  286. // A tuple of the encrypted string, its source string, and a list
  287. // of clear-text copies made from the encrypted string
  288. typedef
  289. std::pair<EncryptedAndSourcePair*, ClearTextList*>
  290. MasterAndClearTextCopiesPair;
  291. // A list of the above tuples.
  292. typedef
  293. std::list<MasterAndClearTextCopiesPair*>
  294. MasterAndCopiesList;
  295. MasterAndCopiesList mcList;
  296. for (int count = 0; count < 1000; ++count)
  297. {
  298. // Make a random source string
  299. size_t length = rand() % MAX_CHARACTER_COUNT;
  300. WCHAR* source = MakeRandomString(length);
  301. // Make an encrypted string from it
  302. EncryptedString* ps = new EncryptedString;
  303. ps->Encrypt(source);
  304. // Make a pair of the encrypted string and its source string
  305. EncryptedAndSourcePair* esp = new EncryptedAndSourcePair(ps, source);
  306. // Make a list of clear-text copies of the encrypted string
  307. ClearTextList* ctList = new ClearTextList;
  308. // Make a master and copies pair
  309. MasterAndClearTextCopiesPair* mcPair = new MasterAndClearTextCopiesPair(esp, ctList);
  310. // add the master and copies pair to the master and copies list
  311. mcList.push_back(mcPair);
  312. int copyMax = max(1, rand() % 50);
  313. for (int copyCount = 0; copyCount < copyMax; ++copyCount)
  314. {
  315. // make some copies
  316. ctList->push_back(ps->GetClearTextCopy());
  317. }
  318. }
  319. for (
  320. MasterAndCopiesList::iterator i = mcList.begin();
  321. i != mcList.end();
  322. ++i)
  323. {
  324. EncryptedAndSourcePair* esp = (*i)->first;
  325. ClearTextList* ctList = (*i)->second;
  326. // delete each element of the ClearTextList
  327. for (
  328. ClearTextList::iterator j = ctList->begin();
  329. j != ctList->end();
  330. ++j)
  331. {
  332. // all copies should be identical
  333. ASSERT(wcscmp(esp->second, *j) == 0);
  334. esp->first->DestroyClearTextCopy(*j);
  335. }
  336. // delete the ClearTextList
  337. delete ctList;
  338. // delete the encrypted string
  339. delete esp->first;
  340. // delete the source string;
  341. delete[] esp->second;
  342. // delete the encrypted string/source string pair
  343. delete esp;
  344. // delete the master and copies pair
  345. delete *i;
  346. }
  347. }
  348. void
  349. TestAssignment()
  350. {
  351. ScopeTracer scope("TestAssignment");
  352. }
  353. void
  354. TestEquality(const EncryptedString& s, const EncryptedString& s1, size_t length)
  355. {
  356. ScopeTracer scope("TestEquality");
  357. // a string is equal to itself
  358. ASSERT(s == s);
  359. ASSERT(s1 == s1);
  360. // a string is equal to a copy of itself
  361. ASSERT(s1 == s);
  362. // a copy is equal to its source
  363. ASSERT(s == s1);
  364. // a copy is equal to itself
  365. ASSERT(s1 == s1);
  366. // a copy is the same length as its source
  367. ASSERT(s1.GetLength() == length);
  368. ASSERT(s.GetLength() == length);
  369. // a string is the same length as its copy
  370. ASSERT(s1.GetLength() == s.GetLength());
  371. }
  372. void
  373. TestEqualityForStringOfLengthN(size_t length)
  374. {
  375. //LOG_FUNCTION2(TestEncryptionForStringOfLengthN, String::format(L"%1!d!", length));
  376. ASSERT(length <= MAX_CHARACTER_COUNT);
  377. WCHAR* source = MakeRandomString(length);
  378. EncryptedString s;
  379. s.Encrypt(source);
  380. ASSERT(s.GetLength() == length);
  381. EncryptedString s1(s);
  382. ASSERT(s1.GetLength() == length);
  383. TestEquality(s, s1, length);
  384. EncryptedString s2;
  385. s2 = s;
  386. TestEquality(s, s2, length);
  387. TestEquality(s1, s2, length);
  388. // a copy is not equal to its source when the source is changed
  389. s.Encrypt(L"Something else...");
  390. ASSERT(s != s1);
  391. ASSERT(s != s2);
  392. ASSERT(s2 != s);
  393. ASSERT(s1 != s);
  394. TestEquality(s1, s2, length);
  395. delete[] source;
  396. }
  397. void
  398. DoEqualityTests()
  399. {
  400. ScopeTracer scope("DoEqualityTests");
  401. for (
  402. size_t length = 0;
  403. length <= MAX_CHARACTER_COUNT;
  404. ++length)
  405. {
  406. TestEqualityForStringOfLengthN(length);
  407. }
  408. }
  409. void
  410. TestInequality()
  411. {
  412. ScopeTracer scope("TestInequality");
  413. }
  414. void
  415. TestBoundaries()
  416. {
  417. ScopeTracer scope("TestBoundaries");
  418. }
  419. void
  420. TestLegitimateUse()
  421. {
  422. ScopeTracer scope("TestLegitimateUse");
  423. TestEmptyStrings();
  424. TestClearTextCopying();
  425. TestEncryptionFidelity();
  426. TestAssignment();
  427. DoEqualityTests();
  428. TestInequality();
  429. TestBoundaries();
  430. }
  431. void
  432. TestIlllegitimateUse()
  433. {
  434. ScopeTracer scope("TestIlllegitimateUse");
  435. // make strings that are too long,
  436. // make unbalanced cleartext copyies (call Destroy too many times, not enough times)
  437. }
  438. VOID
  439. _cdecl
  440. main(int, char **)
  441. {
  442. ScopeTracer scope("main");
  443. TestLegitimateUse();
  444. TestIlllegitimateUse();
  445. }