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

// test the published EncryptedString class
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
// Make sure we have an ASSERT() function defined for our test.
#ifndef ASSERT
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#define ASSERT assert
#endif
// Uncomment the #define if you want to trace the test harness.
#ifndef TRACE
//#define TRACE
#endif
class ScopeTracer
{
public:
ScopeTracer(const char* message)
: m_message(NULL)
{
#ifdef TRACE
if (message)
{
m_message = new char[strlen(message) + 1];
strcpy(m_message, message);
}
else
{
m_message = new char[1];
m_message[0] = NULL;
}
PrintIndents();
printf("->%s\n", m_message);
++g_indentLevel;
#else
// Make the compiler happy.
message = NULL;
#endif
}
~ScopeTracer(void)
{
#ifdef TRACE
--g_indentLevel;
PrintIndents();
printf("<-%s\n", m_message);
delete [] m_message;
#endif
}
unsigned int GetIndentLevel(void) const
{
return g_indentLevel;
}
private:
void PrintIndents(void)
{
for (unsigned int level = 0;
level < g_indentLevel;
++level)
{
printf(" ");
}
}
char* m_message;
static unsigned int g_indentLevel;
};
unsigned int ScopeTracer::g_indentLevel = 0;
#include "EncryptedString.hpp"
#include <list>
using namespace std;
HINSTANCE hResourceModuleHandle = 0;
const wchar_t* HELPFILE_NAME = 0;
const wchar_t* RUNTIME_NAME = L"test";
//DWORD DEFAULT_LOGGING_OPTIONS = Burnslib::Log::OUTPUT_TYPICAL;
const size_t MAX_CHARACTER_COUNT = 2047;
void
TestEmptyness(const EncryptedString& empty)
{
ScopeTracer scope("TestEmptyness");
ASSERT(empty.IsEmpty());
ASSERT(empty.GetLength() == 0);
// the cleartext of an empty instance should also be empty
WCHAR* emptyClear = empty.GetClearTextCopy();
ASSERT(emptyClear);
ASSERT(*emptyClear == 0);
empty.DestroyClearTextCopy(emptyClear);
}
void
TestEmptyStrings()
{
ScopeTracer scope("TestEmptyStrings");
EncryptedString empty1;
TestEmptyness(empty1);
// copies of empty strings are themselves empty
EncryptedString empty2(empty1);
// source should still be empty
TestEmptyness(empty1);
TestEmptyness(empty2);
EncryptedString empty3;
TestEmptyness(empty3);
empty3 = empty2;
// source should still be empty
TestEmptyness(empty2);
TestEmptyness(empty3);
empty3 = empty1;
TestEmptyness(empty1);
TestEmptyness(empty2);
TestEmptyness(empty3);
// strings built from empty strings should be empty
EncryptedString empty4;
TestEmptyness(empty4);
empty4.Encrypt(L"");
TestEmptyness(empty4);
// a string made from an empty string is still empty when the source
// is made non-empty
EncryptedString empty5;
EncryptedString empty6(empty5);
TestEmptyness(empty5);
TestEmptyness(empty6);
empty5.Encrypt(L"not empty any more");
ASSERT(!empty5.IsEmpty());
ASSERT(empty5.GetLength() != 0);
TestEmptyness(empty6);
// A cleared string is empty
EncryptedString empty7;
empty7.Encrypt(L"some text");
empty7.Clear();
TestEmptyness(empty7);
// empty strings are equal
ASSERT(empty1 == empty1);
ASSERT(empty1 == empty2);
ASSERT(empty1 == empty3);
ASSERT(empty1 == empty4);
ASSERT(empty1 == empty6);
ASSERT(empty1 == empty7);
ASSERT(empty2 == empty1);
ASSERT(empty2 == empty2);
ASSERT(empty2 == empty3);
ASSERT(empty2 == empty4);
ASSERT(empty2 == empty6);
ASSERT(empty2 == empty7);
ASSERT(empty3 == empty1);
ASSERT(empty3 == empty2);
ASSERT(empty3 == empty3);
ASSERT(empty3 == empty4);
ASSERT(empty3 == empty6);
ASSERT(empty3 == empty7);
ASSERT(empty4 == empty1);
ASSERT(empty4 == empty2);
ASSERT(empty4 == empty3);
ASSERT(empty4 == empty4);
ASSERT(empty4 == empty6);
ASSERT(empty4 == empty7);
ASSERT(empty6 == empty1);
ASSERT(empty6 == empty2);
ASSERT(empty6 == empty3);
ASSERT(empty6 == empty4);
ASSERT(empty6 == empty6);
ASSERT(empty6 == empty7);
ASSERT(empty7 == empty1);
ASSERT(empty7 == empty2);
ASSERT(empty7 == empty3);
ASSERT(empty7 == empty4);
ASSERT(empty7 == empty6);
ASSERT(empty7 == empty7);
}
WCHAR*
MakeRandomString(size_t length)
{
//LOG_FUNCTION2(MakeRandomString, String::format(L"%1!d!", length));
WCHAR* result = new WCHAR[length + 1];
for (size_t i = 0; i < length; ++i)
{
// 32 = space, the lowest printable character
int r1 = rand() % 0xFFEE;
// careful not to use an expression as a parameter to max...
int r2 = max(32, r1);
ASSERT(r2);
ASSERT(r2 >= 32);
ASSERT(r2 < 0xFFEE);
result[i] = (WCHAR) r2;
ASSERT(result[i]);
}
result[length] = 0;
return result;
}
void
TestEncryption(const EncryptedString& s, const WCHAR* sourceClearText)
{
ScopeTracer scope("TestEncryption");
// decrypt s, compare it to sourceClearText
WCHAR* clearText = s.GetClearTextCopy();
// the decryption shouldn't fail (barring out-of-memory);
ASSERT(clearText);
ASSERT(wcscmp(clearText, sourceClearText) == 0);
s.DestroyClearTextCopy(clearText);
}
void
TestEncryptionForStringOfLengthN(size_t length)
{
//LOG_FUNCTION2(TestEncryptionForStringOfLengthN, String::format(L"%1!d!", length));
ASSERT(length <= MAX_CHARACTER_COUNT);
WCHAR* source = MakeRandomString(length);
EncryptedString s;
s.Encrypt(source);
TestEncryption(s, source);
EncryptedString s1(s);
TestEncryption(s1, source);
EncryptedString s2;
s2 = s;
TestEncryption(s2, source);
delete[] source;
}
void
TestEncryptionFidelity()
{
ScopeTracer scope("TestEncryptionFidelity");
// do we get out what we put in?
srand(time(0));
// test increasing lengths of random strings
for (
size_t length = 0;
length <= MAX_CHARACTER_COUNT;
++length)
{
TestEncryptionForStringOfLengthN(length);
}
// test decreasing lengths of random strings
for (
size_t length = MAX_CHARACTER_COUNT;
length != 0;
--length)
{
TestEncryptionForStringOfLengthN(length);
}
// test strings of random length, with lots of outstanding encrypted
// strings
typedef std::list<EncryptedString*> ESPList;
ESPList strings;
for (
int count = 0;
count < 1000;
++count)
{
size_t length = rand() % MAX_CHARACTER_COUNT;
WCHAR* source = MakeRandomString(length);
EncryptedString* ps = new EncryptedString;
strings.push_back(ps);
ps->Encrypt(source);
TestEncryption(*ps, source);
// make a copy via copy ctor
EncryptedString* ps1 = new EncryptedString(*ps);
strings.push_back(ps1);
TestEncryption(*ps1, source);
// make a copy via operator =
EncryptedString* ps2 = new EncryptedString;
strings.push_back(ps2);
*ps2 = *ps;
TestEncryption(*ps2, source);
delete[] source;
}
for (
ESPList::iterator i = strings.begin();
i != strings.end();
++i)
{
(*i)->Clear();
TestEmptyness(**i);
delete *i;
}
}
void
TestClearTextCopying()
{
ScopeTracer scope("TestClearTextCopying");
// make a bunch of copies, make sure the count balances
typedef char foo[2];
// An encrypted string and the source string used to build it.
typedef
std::pair<EncryptedString*, WCHAR*>
EncryptedAndSourcePair;
// A list of results from EncryptedString::GetClearTextCopy
typedef std::list<WCHAR*> ClearTextList;
// A tuple of the encrypted string, its source string, and a list
// of clear-text copies made from the encrypted string
typedef
std::pair<EncryptedAndSourcePair*, ClearTextList*>
MasterAndClearTextCopiesPair;
// A list of the above tuples.
typedef
std::list<MasterAndClearTextCopiesPair*>
MasterAndCopiesList;
MasterAndCopiesList mcList;
for (int count = 0; count < 1000; ++count)
{
// Make a random source string
size_t length = rand() % MAX_CHARACTER_COUNT;
WCHAR* source = MakeRandomString(length);
// Make an encrypted string from it
EncryptedString* ps = new EncryptedString;
ps->Encrypt(source);
// Make a pair of the encrypted string and its source string
EncryptedAndSourcePair* esp = new EncryptedAndSourcePair(ps, source);
// Make a list of clear-text copies of the encrypted string
ClearTextList* ctList = new ClearTextList;
// Make a master and copies pair
MasterAndClearTextCopiesPair* mcPair = new MasterAndClearTextCopiesPair(esp, ctList);
// add the master and copies pair to the master and copies list
mcList.push_back(mcPair);
int copyMax = max(1, rand() % 50);
for (int copyCount = 0; copyCount < copyMax; ++copyCount)
{
// make some copies
ctList->push_back(ps->GetClearTextCopy());
}
}
for (
MasterAndCopiesList::iterator i = mcList.begin();
i != mcList.end();
++i)
{
EncryptedAndSourcePair* esp = (*i)->first;
ClearTextList* ctList = (*i)->second;
// delete each element of the ClearTextList
for (
ClearTextList::iterator j = ctList->begin();
j != ctList->end();
++j)
{
// all copies should be identical
ASSERT(wcscmp(esp->second, *j) == 0);
esp->first->DestroyClearTextCopy(*j);
}
// delete the ClearTextList
delete ctList;
// delete the encrypted string
delete esp->first;
// delete the source string;
delete[] esp->second;
// delete the encrypted string/source string pair
delete esp;
// delete the master and copies pair
delete *i;
}
}
void
TestAssignment()
{
ScopeTracer scope("TestAssignment");
}
void
TestEquality(const EncryptedString& s, const EncryptedString& s1, size_t length)
{
ScopeTracer scope("TestEquality");
// a string is equal to itself
ASSERT(s == s);
ASSERT(s1 == s1);
// a string is equal to a copy of itself
ASSERT(s1 == s);
// a copy is equal to its source
ASSERT(s == s1);
// a copy is equal to itself
ASSERT(s1 == s1);
// a copy is the same length as its source
ASSERT(s1.GetLength() == length);
ASSERT(s.GetLength() == length);
// a string is the same length as its copy
ASSERT(s1.GetLength() == s.GetLength());
}
void
TestEqualityForStringOfLengthN(size_t length)
{
//LOG_FUNCTION2(TestEncryptionForStringOfLengthN, String::format(L"%1!d!", length));
ASSERT(length <= MAX_CHARACTER_COUNT);
WCHAR* source = MakeRandomString(length);
EncryptedString s;
s.Encrypt(source);
ASSERT(s.GetLength() == length);
EncryptedString s1(s);
ASSERT(s1.GetLength() == length);
TestEquality(s, s1, length);
EncryptedString s2;
s2 = s;
TestEquality(s, s2, length);
TestEquality(s1, s2, length);
// a copy is not equal to its source when the source is changed
s.Encrypt(L"Something else...");
ASSERT(s != s1);
ASSERT(s != s2);
ASSERT(s2 != s);
ASSERT(s1 != s);
TestEquality(s1, s2, length);
delete[] source;
}
void
DoEqualityTests()
{
ScopeTracer scope("DoEqualityTests");
for (
size_t length = 0;
length <= MAX_CHARACTER_COUNT;
++length)
{
TestEqualityForStringOfLengthN(length);
}
}
void
TestInequality()
{
ScopeTracer scope("TestInequality");
}
void
TestBoundaries()
{
ScopeTracer scope("TestBoundaries");
}
void
TestLegitimateUse()
{
ScopeTracer scope("TestLegitimateUse");
TestEmptyStrings();
TestClearTextCopying();
TestEncryptionFidelity();
TestAssignment();
DoEqualityTests();
TestInequality();
TestBoundaries();
}
void
TestIlllegitimateUse()
{
ScopeTracer scope("TestIlllegitimateUse");
// make strings that are too long,
// make unbalanced cleartext copyies (call Destroy too many times, not enough times)
}
VOID
_cdecl
main(int, char **)
{
ScopeTracer scope("main");
TestLegitimateUse();
TestIlllegitimateUse();
}