From 76a754f55a5456671943ec48660e6ab6d16e4f67 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Sat, 11 Feb 2012 21:57:28 -0800 Subject: [PATCH] Added plSHAChecksum and plSHA1Checksum. --- Sources/Plasma/Apps/CMakeLists.txt | 1 + .../PubUtilLib/plEncryption/plChecksum.cpp | 336 +++++++++++++++--- .../PubUtilLib/plEncryption/plChecksum.h | 121 +++++-- 3 files changed, 396 insertions(+), 62 deletions(-) diff --git a/Sources/Plasma/Apps/CMakeLists.txt b/Sources/Plasma/Apps/CMakeLists.txt index 0f6ebec8..0140ce05 100644 --- a/Sources/Plasma/Apps/CMakeLists.txt +++ b/Sources/Plasma/Apps/CMakeLists.txt @@ -7,3 +7,4 @@ add_subdirectory(plFileEncrypt) add_subdirectory(plLogDecrypt) add_subdirectory(plMD5) add_subdirectory(plPageInfo) +add_subdirectory(plSHA) diff --git a/Sources/Plasma/PubUtilLib/plEncryption/plChecksum.cpp b/Sources/Plasma/PubUtilLib/plEncryption/plChecksum.cpp index 81db5419..b7c79c0e 100644 --- a/Sources/Plasma/PubUtilLib/plEncryption/plChecksum.cpp +++ b/Sources/Plasma/PubUtilLib/plEncryption/plChecksum.cpp @@ -44,6 +44,41 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include + +static uint8_t IHexCharToInt(char c) +{ + switch( c ) + { + // yes, it's ugly, but it'll be fast :) + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + + case 'a': return 10; + case 'b': return 11; + case 'c': return 12; + case 'd': return 13; + case 'e': return 14; + case 'f': return 15; + + case 'A': return 10; + case 'B': return 11; + case 'C': return 12; + case 'D': return 13; + case 'E': return 14; + case 'F': return 15; + } + + return 0xff; +} + plChecksum::plChecksum(unsigned int bufsize, const char* buffer) { unsigned int wndsz = GetWindowSize(),i = 0; @@ -67,6 +102,8 @@ plChecksum::plChecksum(unsigned int bufsize, const char* buffer) fSum+= hsToLE32(last); } +//============================================================================ + plMD5Checksum::plMD5Checksum( uint32_t size, uint8_t *buffer ) { fValid = false; @@ -102,11 +139,11 @@ void plMD5Checksum::Clear() fValid = false; } -void plMD5Checksum::CalcFromFile( const char *fileName ) +void plMD5Checksum::CalcFromFile( const char *fileName ) { hsUNIXStream s; fValid = false; - + if( s.Open(fileName) ) { CalcFromStream(&s); @@ -121,7 +158,7 @@ void plMD5Checksum::CalcFromStream( hsStream* stream ) Start(); uint8_t *buf = new uint8_t[loadLen]; - + while(int read = stream->Read(loadLen, buf)) AddTo( read, buf ); delete[] buf; @@ -130,24 +167,24 @@ void plMD5Checksum::CalcFromStream( hsStream* stream ) stream->SetPosition(sPos); } -void plMD5Checksum::Start( void ) +void plMD5Checksum::Start() { MD5_Init( &fContext ); fValid = false; } -void plMD5Checksum::AddTo( uint32_t size, const uint8_t *buffer ) +void plMD5Checksum::AddTo( uint32_t size, const uint8_t *buffer ) { MD5_Update( &fContext, buffer, size ); } -void plMD5Checksum::Finish( void ) +void plMD5Checksum::Finish() { MD5_Final( fChecksum, &fContext ); fValid = true; } -const char *plMD5Checksum::GetAsHexString( void ) const +const char *plMD5Checksum::GetAsHexString() const { const int kHexStringSize = ( 2 * MD5_DIGEST_LENGTH ) + 1; static char tempString[ kHexStringSize ]; @@ -166,61 +203,280 @@ const char *plMD5Checksum::GetAsHexString( void ) const return tempString; } -uint8_t plMD5Checksum::IHexCharToInt( char c ) const +void plMD5Checksum::SetFromHexString( const char *string ) { - switch( c ) + const char *ptr; + int i; + + + hsAssert( strlen( string ) == 2 * MD5_DIGEST_LENGTH, "Invalid string in MD5Checksum Set()" ); + + for( i = 0, ptr = string; i < sizeof( fChecksum ); i++, ptr += 2 ) + fChecksum[ i ] = ( IHexCharToInt( ptr[ 0 ] ) << 4 ) | IHexCharToInt( ptr[ 1 ] ); + + fValid = true; +} + +void plMD5Checksum::SetValue(uint8_t* checksum) +{ + fValid = true; + memcpy(fChecksum, checksum, sizeof(fChecksum)); +} + +bool plMD5Checksum::operator==( const plMD5Checksum &rhs ) const +{ + return (fValid && rhs.fValid && memcmp(fChecksum, rhs.fChecksum, sizeof(fChecksum)) == 0); +} + +//============================================================================ + +plSHAChecksum::plSHAChecksum( uint32_t size, uint8_t *buffer ) +{ + fValid = false; + Start(); + AddTo(size, buffer); + Finish(); +} + +plSHAChecksum::plSHAChecksum() +{ + Clear(); +} + +plSHAChecksum::plSHAChecksum(const plSHAChecksum& rhs) +{ + memcpy(fChecksum, rhs.fChecksum, sizeof(fChecksum)); + fValid = rhs.fValid; +} + +plSHAChecksum::plSHAChecksum(const char* fileName) +{ + CalcFromFile(fileName); +} + +plSHAChecksum::plSHAChecksum(hsStream* stream) +{ + CalcFromStream(stream); +} + +void plSHAChecksum::Clear() +{ + memset(fChecksum, 0, sizeof(fChecksum)); + fValid = false; +} + +void plSHAChecksum::CalcFromFile(const char* fileName) +{ + hsUNIXStream s; + fValid = false; + + if (s.Open(fileName)) { - // yes, it's ugly, but it'll be fast :) - case '0': return 0; - case '1': return 1; - case '2': return 2; - case '3': return 3; - case '4': return 4; - case '5': return 5; - case '6': return 6; - case '7': return 7; - case '8': return 8; - case '9': return 9; + CalcFromStream(&s); + s.Close(); + } +} - case 'a': return 10; - case 'b': return 11; - case 'c': return 12; - case 'd': return 13; - case 'e': return 14; - case 'f': return 15; +void plSHAChecksum::CalcFromStream(hsStream* stream) +{ + uint32_t sPos = stream->GetPosition(); + unsigned loadLen = 1024 * 1024; + Start(); - case 'A': return 10; - case 'B': return 11; - case 'C': return 12; - case 'D': return 13; - case 'E': return 14; - case 'F': return 15; + uint8_t* buf = new uint8_t[loadLen]; + + while (int read = stream->Read(loadLen, buf)) + { + AddTo( read, buf ); } + delete[] buf; - return 0xff; + Finish(); + stream->SetPosition(sPos); } -void plMD5Checksum::SetFromHexString( const char *string ) +void plSHAChecksum::Start() { - const char *ptr; + SHA_Init(&fContext); + fValid = false; +} + +void plSHAChecksum::AddTo(uint32_t size, const uint8_t* buffer) +{ + SHA_Update(&fContext, buffer, size); +} + +void plSHAChecksum::Finish() +{ + SHA_Final(fChecksum, &fContext); + fValid = true; +} + +const char *plSHAChecksum::GetAsHexString() const +{ + const int kHexStringSize = (2 * SHA_DIGEST_LENGTH) + 1; + static char tempString[kHexStringSize]; + + int i; + char* ptr; + + hsAssert(fValid, "Trying to get string version of invalid checksum"); + + for (i = 0, ptr = tempString; i < sizeof(fChecksum); i++, ptr += 2) + sprintf(ptr, "%02x", fChecksum[i]); + + *ptr = 0; + + return tempString; +} + +void plSHAChecksum::SetFromHexString(const char* string) +{ + const char* ptr; int i; + hsAssert(strlen(string) == (2 * SHA_DIGEST_LENGTH), "Invalid string in SHAChecksum Set()"); - hsAssert( strlen( string ) == 2 * MD5_DIGEST_LENGTH, "Invalid string in MD5Checksum Set()" ); + for (i = 0, ptr = string; i < sizeof(fChecksum); i++, ptr += 2) + fChecksum[i] = (IHexCharToInt(ptr[0]) << 4) | IHexCharToInt(ptr[1]); - for( i = 0, ptr = string; i < sizeof( fChecksum ); i++, ptr += 2 ) - fChecksum[ i ] = ( IHexCharToInt( ptr[ 0 ] ) << 4 ) | IHexCharToInt( ptr[ 1 ] ); + fValid = true; +} +void plSHAChecksum::SetValue(uint8_t* checksum) +{ fValid = true; + memcpy(fChecksum, checksum, sizeof(fChecksum)); } -void plMD5Checksum::SetValue(uint8_t* checksum) +bool plSHAChecksum::operator==(const plSHAChecksum& rhs) const +{ + return (fValid && rhs.fValid && memcmp(fChecksum, rhs.fChecksum, sizeof(fChecksum)) == 0); +} + +//============================================================================ + +plSHA1Checksum::plSHA1Checksum( uint32_t size, uint8_t *buffer ) +{ + fValid = false; + Start(); + AddTo(size, buffer); + Finish(); +} + +plSHA1Checksum::plSHA1Checksum() +{ + Clear(); +} + +plSHA1Checksum::plSHA1Checksum(const plSHA1Checksum& rhs) +{ + memcpy(fChecksum, rhs.fChecksum, sizeof(fChecksum)); + fValid = rhs.fValid; +} + +plSHA1Checksum::plSHA1Checksum(const char* fileName) +{ + CalcFromFile(fileName); +} + +plSHA1Checksum::plSHA1Checksum(hsStream* stream) +{ + CalcFromStream(stream); +} + +void plSHA1Checksum::Clear() +{ + memset(fChecksum, 0, sizeof(fChecksum)); + fValid = false; +} + +void plSHA1Checksum::CalcFromFile(const char* fileName) +{ + hsUNIXStream s; + fValid = false; + + if (s.Open(fileName)) + { + CalcFromStream(&s); + s.Close(); + } +} + +void plSHA1Checksum::CalcFromStream(hsStream* stream) +{ + uint32_t sPos = stream->GetPosition(); + unsigned loadLen = 1024 * 1024; + Start(); + + uint8_t* buf = new uint8_t[loadLen]; + + while (int read = stream->Read(loadLen, buf)) + { + AddTo( read, buf ); + } + delete[] buf; + + Finish(); + stream->SetPosition(sPos); +} + +void plSHA1Checksum::Start() +{ + SHA1_Init(&fContext); + fValid = false; +} + +void plSHA1Checksum::AddTo(uint32_t size, const uint8_t* buffer) +{ + SHA1_Update(&fContext, buffer, size); +} + +void plSHA1Checksum::Finish() +{ + SHA1_Final(fChecksum, &fContext); + fValid = true; +} + +const char *plSHA1Checksum::GetAsHexString() const +{ + const int kHexStringSize = (2 * SHA_DIGEST_LENGTH) + 1; + static char tempString[kHexStringSize]; + + int i; + char* ptr; + + hsAssert(fValid, "Trying to get string version of invalid checksum"); + + for (i = 0, ptr = tempString; i < sizeof(fChecksum); i++, ptr += 2) + sprintf(ptr, "%02x", fChecksum[i]); + + *ptr = 0; + + return tempString; +} + +void plSHA1Checksum::SetFromHexString(const char* string) +{ + const char* ptr; + int i; + + hsAssert(strlen(string) == (2 * SHA_DIGEST_LENGTH), "Invalid string in SHA1Checksum Set()"); + + for (i = 0, ptr = string; i < sizeof(fChecksum); i++, ptr += 2) + fChecksum[i] = (IHexCharToInt(ptr[0]) << 4) | IHexCharToInt(ptr[1]); + + fValid = true; +} + +void plSHA1Checksum::SetValue(uint8_t* checksum) { fValid = true; memcpy(fChecksum, checksum, sizeof(fChecksum)); } -bool plMD5Checksum::operator==( const plMD5Checksum &rhs ) const +bool plSHA1Checksum::operator==(const plSHA1Checksum& rhs) const { return (fValid && rhs.fValid && memcmp(fChecksum, rhs.fChecksum, sizeof(fChecksum)) == 0); } + diff --git a/Sources/Plasma/PubUtilLib/plEncryption/plChecksum.h b/Sources/Plasma/PubUtilLib/plEncryption/plChecksum.h index e4f62990..fed7ce39 100644 --- a/Sources/Plasma/PubUtilLib/plEncryption/plChecksum.h +++ b/Sources/Plasma/PubUtilLib/plEncryption/plChecksum.h @@ -44,6 +44,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "HeadSpin.h" #include +#include class plChecksum { @@ -60,46 +61,122 @@ public: class hsStream; -class plMD5Checksum +class plMD5Checksum { protected: - hsBool fValid; MD5_CTX fContext; - uint8_t fChecksum[ MD5_DIGEST_LENGTH ]; - - uint8_t IHexCharToInt( char c ) const; + uint8_t fChecksum[MD5_DIGEST_LENGTH]; public: - - plMD5Checksum( uint32_t size, uint8_t *buffer ); + plMD5Checksum(uint32_t size, uint8_t *buffer); plMD5Checksum(); - plMD5Checksum( const plMD5Checksum &rhs ); - plMD5Checksum( const char *fileName ); - plMD5Checksum( hsStream* stream ); + plMD5Checksum(const plMD5Checksum &rhs); + plMD5Checksum(const char *fileName); + plMD5Checksum(hsStream* stream); - hsBool IsValid( void ) const { return fValid; } + hsBool IsValid() const { return fValid; } void Clear(); - void CalcFromFile( const char *fileName ); - void CalcFromStream( hsStream* stream ); + void CalcFromFile(const char *fileName); + void CalcFromStream(hsStream* stream); - void Start( void ); - void AddTo( uint32_t size, const uint8_t *buffer ); - void Finish( void ); + void Start(); + void AddTo(uint32_t size, const uint8_t *buffer); + void Finish(); - const uint8_t *GetValue( void ) const { return fChecksum; } - uint32_t GetSize( void ) const { return sizeof( fChecksum ); } + const uint8_t *GetValue() const { return fChecksum; } + uint32_t GetSize() const { return sizeof(fChecksum); } // Backdoor for cached checksums (ie, if you loaded it off disk) void SetValue(uint8_t* checksum); - // Note: GetAsHexString() returns a pointer to a static string; do not rely on the contents of this string between calls! - const char *GetAsHexString( void ) const; + // Note: GetAsHexString() returns a pointer to a static string; + // do not rely on the contents of this string between calls! + const char *GetAsHexString() const; void SetFromHexString( const char *string ); - bool operator==( const plMD5Checksum &rhs ) const; - bool operator!=( const plMD5Checksum &rhs ) const { return !operator==( rhs ); } + bool operator==(const plMD5Checksum &rhs) const; + bool operator!=(const plMD5Checksum &rhs) const { return !operator==(rhs); } +}; + +class plSHAChecksum +{ + protected: + hsBool fValid; + SHA_CTX fContext; + uint8_t fChecksum[SHA_DIGEST_LENGTH]; + + public: + plSHAChecksum(uint32_t size, uint8_t* buffer); + plSHAChecksum(); + plSHAChecksum(const plSHAChecksum& rhs); + plSHAChecksum(const char* fileName); + plSHAChecksum(hsStream* stream); + + hsBool IsValid() const { return fValid; } + void Clear(); + + void CalcFromFile(const char* fileName); + void CalcFromStream(hsStream* stream); + + void Start(); + void AddTo(uint32_t size, const uint8_t* buffer); + void Finish(); + + const uint8_t* GetValue() const { return fChecksum; } + uint32_t GetSize() const { return sizeof(fChecksum); } + + // Backdoor for cached checksums (ie, if you loaded it off disk) + void SetValue(uint8_t* checksum); + + // Note: GetAsHexString() returns a pointer to a static string; + // do not rely on the contents of this string between calls! + const char* GetAsHexString() const; + void SetFromHexString(const char* string); + + bool operator==(const plSHAChecksum& rhs) const; + bool operator!=(const plSHAChecksum& rhs) const { return !operator==(rhs); } +}; + +class plSHA1Checksum +{ + protected: + hsBool fValid; + SHA_CTX fContext; + uint8_t fChecksum[SHA_DIGEST_LENGTH]; + + public: + plSHA1Checksum(uint32_t size, uint8_t* buffer); + plSHA1Checksum(); + plSHA1Checksum(const plSHA1Checksum& rhs); + plSHA1Checksum(const char* fileName); + plSHA1Checksum(hsStream* stream); + + hsBool IsValid() const { return fValid; } + void Clear(); + + void CalcFromFile(const char* fileName); + void CalcFromStream(hsStream* stream); + + void Start(); + void AddTo(uint32_t size, const uint8_t* buffer); + void Finish(); + + const uint8_t* GetValue() const { return fChecksum; } + uint32_t GetSize() const { return sizeof(fChecksum); } + + // Backdoor for cached checksums (ie, if you loaded it off disk) + void SetValue(uint8_t* checksum); + + // Note: GetAsHexString() returns a pointer to a static string; + // do not rely on the contents of this string between calls! + const char* GetAsHexString() const; + void SetFromHexString(const char* string); + + bool operator==(const plSHA1Checksum& rhs) const; + bool operator!=(const plSHA1Checksum& rhs) const { return !operator==(rhs); } }; + #endif // PL_CHECKSUM_H