// ClientCDKey::Init(RawBuffer) // Initializes key from encrypted binary buffer. Does not validate key. bool ClientCDKey::Init(const RawBuffer& theKeyR) { WTRACE("ClientCDKey::Init(RawBuffer)"); WDBG_LH("ClientCDKey::Init(RawBuffer) Buf=" << theKeyR); mValidity = Unknown; mKey.erase(); mStrKey.erase(); // Init BinKey and validate length mBinKey = theKeyR; if (mBinKey.size() != BINARYKEY_LEN) { WDBG_LH("ClientCDKey::Init(RawBuffer) Key length invalid, len=" << mBinKey.size()); mValidity = Invalid; return false; } // Build symmetric key from Product name __int64 aBuf = 0; if (! DecryptKey(aBuf)) { WDBG_LH("ClientCDKey::Init(RawBuffer) Decrypt of bin key failed."); mValidity = Invalid; return false; } WDBG_LM("ClientCDKey::Init(RawBuffer) Extracting fields."); FieldsFromBuffer(aBuf); return true; }
// ClientCDKey::Load // Loads CD-Key from WON standard location in registry. Entry is registry must be // the enrypted binary form. Calls Init(RawBuffer). bool ClientCDKey::Load() { WTRACE("ClientCDKey::Load"); WDBG_LM("ClientCDKey::Load Loading key from registry."); // Open registry key RegKey aRegKey(REG_CDKEY_PATH, HKEY_LOCAL_MACHINE); if (! aRegKey.IsOpen()) { WDBG_LH("ClientCDKey::Load Fail open registry key: " << REG_CDKEY_PATH); mValidity = Invalid; return false; } // Fetch key from registry for value product unsigned char* aBufP = NULL; unsigned long aLen = 0; if (aRegKey.GetValue(mProduct, aBufP, aLen) != RegKey::Ok) { WDBG_LH("ClientCDKey::Load Fail fetch key value for product=" << mProduct); mValidity = Invalid; return false; } // Build buffer and call Init(RawBuffer) RawBuffer aKey(aBufP, aLen); delete aBufP; return Init(aKey); }
// ClientCDKey::Init(string) // Initializes key from human readable string. Does not validate key. bool ClientCDKey::Init(const string& theKeyR) { WTRACE("ClientCDKey::Init(string)"); WDBG_LH("ClientCDKey::Init(string) String=" << theKeyR); mValidity = Unknown; mKey.erase(); mBinKey.erase(); // Init StrKey and remove and dashes mStrKey = theKeyR; RemoveSkipChars(mStrKey); // Validate length if (mStrKey.size() != STRINGKEY_LEN) { WDBG_LH("ClientCDKey::Init(string) Key length invalid, len=" << mStrKey.size()); mValidity = Invalid; return false; } // Process each char in string WDBG_LM("ClientCDKey::Init(string) Parsing string key."); __int64 aBuf = 0; unsigned int anOffset = 0; for (int i=0; i < STRINGKEY_LEN; i++) { bool aTst = true; switch (STRINGKEY_MAP[i]) { case 'C': aTst = ProcessCChar(aBuf, anOffset, mStrKey[i]); break; case 'V': aTst = ProcessVChar(aBuf, anOffset, mStrKey[i]); break; case 'N': aTst = ProcessNChar(aBuf, anOffset, mStrKey[i]); break; #ifdef _DEBUG default: throw WONCommon::WONException(WONCommon::ExSoftwareFail, __LINE__, __FILE__, "ClientCDKey::Init(string) Unknown char is STRINGKEY_MAP!"); break; #endif } if (! aTst) { WDBG_LH("ClientCDKey::Init(string) Parse of string to binary failed."); mValidity = Invalid; return false; } } // Extract fields from buffer WDBG_LM("ClientCDKey::Init(string) Extracting fields."); FieldsFromBuffer(aBuf); mStrKey.erase(); return true; }
// TMessage ctor from WONException BadMsgException::BadMsgException(const BaseMessage& theMsgR, int theLine, const char* theFileP, const char* addTextP) throw() : WONException(WONCommon::ExBadTitanMessage, theLine, theFileP) { WTRACE("BadMsgException::ctor(TMessage)"); // Add header type info or header corrupt message if (theMsgR.GetDataLen() >= theMsgR.GetHeaderLength()) { WDBG_LL("BadMsgException::ctor(TMessage) Add header info."); GetStream() << "MessageClass=" << (int)theMsgR.GetMessageClass() << " MessageType=" << theMsgR.GetMessageType() << " ServiceType=" << theMsgR.GetServiceType(); } else { WDBG_LH("BadMsgException::ctor(TMessage) Corrupt header!"); GetStream() << HDRCORRUPT_MSG; } // Add message length and data length WDBG_LL("BadMsgException::ctor(TMessage) Add length info."); GetStream() << " DataLength=" << theMsgR.GetDataLen(); // Add additional text if defined if (addTextP) GetStream() << " " << addTextP; }
// ClientCDKey::EncryptKey // Encrypts into 8 byte buffer in 16 byte binary. Uses symmetric key built from product // name for encryption. bool ClientCDKey::EncryptKey(const __int64& theBufR) const { WTRACE("ClientCDKey::EncryptKey"); try { // Build symmetric key from product WDBG_LL("ClientCDKey::EncryptKey Creating symmetric key from product=" << mProduct); BFSymmetricKey aSymKey; CreateSymmetricKey(aSymKey); // Decrypt the key WDBG_LL("ClientCDKey::EncryptKey Encrypting CDKey."); BFSymmetricKey::CryptReturn anEncrypt(aSymKey.Encrypt(reinterpret_cast<const unsigned char*>(&theBufR), sizeof(theBufR))); auto_ptr<unsigned char> aDelP(anEncrypt.first); if (anEncrypt.second != BINARYKEY_LEN) { WDBG_LM("ClientCDKey::EncryptKey Encrypt of key has bad length."); return false; } // Fill BinKey with encrypted key mBinKey.assign(anEncrypt.first, anEncrypt.second); } catch (WONCrypt::CryptException& anExR) { WDBG_LH("ClientCDKey::EncryptKey exception encrypting key: " << anExR); return false; } return true; }
// Auth2Certificate::PackData // Packs member data into raw buffer in base class. Returns true on success and // false on failure. Verifies member data and appends member data to buffer. bool Auth2Certificate::PackData() { WTRACE("Auth2Certificate::PackData"); if (! AuthCertificateBase::PackData()) return false; // UserId and be non-zero and at least one community's info must be known. WDBG_LL("Auth2Certificate::PackData Validating..."); if ( mDataList.size() == 0 ) { WDBG_LH("Auth2Certificate::PackData DataList is empty, pack fails."); return false; } unsigned short tmpDataListSize = mDataList.size(); mRawBuf.append(reinterpret_cast<unsigned char*>(&tmpDataListSize), sizeof(tmpDataListSize)); Auth2Certificate::DataListCIter anIter = mDataList.begin(); while( anIter != mDataList.end() ) { if( ! (*anIter)->Serialize( mRawBuf ) ) return false; ++anIter; } return true; }
// Auth1PublicKeyBlock::PackData // Packs member data into raw buffer in base class. Returns true on success and // false on failure. Makes sure keyList is not empty. Appends number of keys // in key list. For each key, appends key length and the key. bool Auth1PublicKeyBlock::PackData() { WTRACE("Auth1PublicKeyBlock::PackData"); if (! AuthPublicKeyBlockBase::PackData()) return false; // KeyList cannot be empty. WDBG_LL("Auth1PublicKeyBlock::PackData Validating..."); if (mKeyList.empty()) { WDBG_LH("Auth1PublicKeyBlock::PackData KeySet is empty, pack fails."); return false; } // Append fixed length data WDBG_LL("Auth1PublicKeyBlock::PackData Packing..."); unsigned short aNumKeys = mKeyList.size(); makeLittleEndian(aNumKeys); mRawBuf.append(reinterpret_cast<unsigned char*>(&aNumKeys), sizeof(aNumKeys)); // Append each key (length and binary data) WDBG_LL("Auth1PublicKeyBlock::PackData Packing keys (" << mKeyList.size() << ')'); PublicKeyList::iterator anItr(mKeyList.begin()); for (; anItr != mKeyList.end(); anItr++) { unsigned short aKeyLen = anItr->GetKeyLen(); unsigned short tmpKeyLen = getLittleEndian(aKeyLen); mRawBuf.append(reinterpret_cast<unsigned char*>(&tmpKeyLen), sizeof(tmpKeyLen)); mRawBuf.append(anItr->GetKey(), aKeyLen); } return true; }
// ClientCDKey::DecryptKey // Decrypt 16 byte binary key into 8 byte buffer. Uses symmetric key built from product // name for decryption. bool ClientCDKey::DecryptKey(__int64& theBufR) { WTRACE("ClientCDKey::DecryptKey"); try { // Build symmetric key from product WDBG_LL("ClientCDKey::DecryptKey Creating symmetric key from product=" << mProduct); BFSymmetricKey aSymKey; CreateSymmetricKey(aSymKey); // Decrypt the key WDBG_LL("ClientCDKey::DecryptKey Decrypting CDKey."); BFSymmetricKey::CryptReturn aDecrypt(aSymKey.Decrypt(mBinKey.data(), mBinKey.size())); auto_ptr<unsigned char> aDelP(aDecrypt.first); if (aDecrypt.second != sizeof(theBufR)) { WDBG_LM("ClientCDKey::DecryptKey Decrypt of key has bad length."); return false; } // Fill buffer with decrypted key memcpy(static_cast<void*>(&theBufR), aDecrypt.first, sizeof(theBufR)); } catch (WONCrypt::CryptException& anExR) { WDBG_LH("ClientCDKey::DecryptKey exception decrypting key: " << anExR); return false; } return true; }
// ClientCDKey::ProcessVChar // Places a V into 8 byte buffer starting at theOffset. Vs use 2 bits. Value of // theOffset is incremented by 2. bool ClientCDKey::ProcessVChar(__int64& theBuf, unsigned int& theOffset, char theChar) { WTRACE("ClientCDKey::ProcessVChar"); WDBG_LL("ClientCDKey::ProcessVChar char=" << theChar << " offset=" << theOffset); bool aRet = true; __int64 aMask = 0; // Determine mask based on char switch (toupper(theChar)) { case 'A': aMask = 0; break; case 'E': aMask = 1; break; case 'U': aMask = 2; break; case 'Y': aMask = 3; break; default: WDBG_LH("ClientCDKey::ProcessVChar Bad input, char=" << theChar); return false; } // Shift mask by offset and or with buffer. Update offset theBuf |= (aMask << theOffset); theOffset += 2; return aRet; }
bool AuthDataBlk::Serialize( WONCommon::RawBuffer &theRawBuf ) const { WTRACE("AuthDataBlk::Serialize"); if (! CertificateDataBlock::Serialize( theRawBuf )) return false; // UserId and be non-zero and at least one community's info must be known. WDBG_LL("AuthDataBlk::Serialize Validating..."); if ((mUserId == 0) || (mAccessList.size() == 0)) { WDBG_LH("AuthDataBlk::Serialize UserId is 0 or AccessList is empty, pack fails."); return false; } // PubKey must be valid if (mPubKey.GetKeyLen() <= 1) { WDBG_LH("Auth2Certificate::PackData PubKey not valid, pack fails."); return false; } // Append fixed length data WDBG_LL("AuthDataBlk::Serialize Packing..."); theRawBuf.append(reinterpret_cast<const unsigned char*>(&mUserId), sizeof(mUserId)); // Append PubKey length and PubKey WDBG_LL("AuthDataBlk::Serialize Packing PublicKey."); unsigned short aKeyLen = mPubKey.GetKeyLen(); theRawBuf.append(reinterpret_cast<unsigned char*>(&aKeyLen), sizeof(aKeyLen)); theRawBuf.append(mPubKey.GetKey(), aKeyLen); // Append user name unsigned short aNameLen = mUserName.size(); theRawBuf.append(reinterpret_cast<unsigned char*>(&aNameLen), sizeof(aNameLen)); theRawBuf.append(reinterpret_cast<const unsigned char*>( mUserName.data() ), (aNameLen*sizeof(wchar_t)) ); // Append community data unsigned char aCommunityCount = mAccessList.size(); theRawBuf.append(reinterpret_cast<unsigned char*>(&aCommunityCount), sizeof(aCommunityCount)); for (AuthCertificateBase::AccessList::const_iterator itr = mAccessList.begin(); itr != mAccessList.end(); ++itr) { theRawBuf.append(reinterpret_cast<const unsigned char*>(&itr->mCommunityId), sizeof(itr->mCommunityId)); theRawBuf.append(reinterpret_cast<const unsigned char*>(&itr->mTrustLevel), sizeof(itr->mTrustLevel)); } return true; }
// Auth1PrivateKeyBlock::PackData // Packs member data into raw buffer in base class. Returns true on success and // false on failure. Makes sure keyList is not empty. Appends number of keys // in key list. For each key, appends key length and the key. bool Auth1PrivateKeyBlock::PackData() { WTRACE("Auth1PrivateKeyBlock::PackData"); if (! AuthPublicKeyBlockBase::PackData()) return false; // KeyList cannot be empty. WDBG_LL("Auth1PrivateKeyBlock::PackData Validating..."); if (mKeyList.empty()) { WDBG_LH("Auth1PrivateKeyBlock::PackData KeySet is empty, pack fails."); return false; } // Append fixed length data WDBG_LL("Auth1PrivateKeyBlock::PackData Packing..."); unsigned short aNumKeys = mKeyList.size(); unsigned short tmpNumKeys = getLittleEndian(aNumKeys); mRawBuf.append(reinterpret_cast<unsigned char*>(&tmpNumKeys), sizeof(tmpNumKeys)); // Append each key (length and binary data) WDBG_LL("Auth1PrivateKeyBlock::PackData Packing keys (" << mKeyList.size() << ')'); PrivateKeyList::iterator anItr(mKeyList.begin()); for (; anItr != mKeyList.end(); anItr++) { unsigned short aKeyLen = (*anItr)->GetKeyLen(); unsigned short tmpKeyLen = getLittleEndian(tmpKeyLen); mRawBuf.append(reinterpret_cast<unsigned char*>(&tmpKeyLen), sizeof(tmpKeyLen)); mRawBuf.append((*anItr)->GetKey(), aKeyLen); // count and record which BlockId's map to this key. PrivateKeyMap::iterator aMapIter(mKeyMap.begin()); unsigned short aBlockIDCount=0; std::list<unsigned short> aBlockIdList; for(; aMapIter != mKeyMap.end(); aMapIter++) { if( aMapIter->second == *anItr ) { aBlockIDCount++; aBlockIdList.push_back( aMapIter->first ); } } unsigned short tmpBlockIDCount = getLittleEndian(aBlockIDCount); // pack BlockId count and BlockIds mRawBuf.append(reinterpret_cast<unsigned char*>(&tmpBlockIDCount), sizeof(tmpBlockIDCount)); while( aBlockIdList.size() ) { unsigned short aBlockId = aBlockIdList.front(); makeLittleEndian(aBlockId); mRawBuf.append(reinterpret_cast<unsigned char*>(& aBlockId), sizeof(unsigned short)); aBlockIdList.pop_front(); } } return true; }
// ClientCDKey::ProcessCChar // Places a C into 8 byte buffer starting at theOffset. Cs use 4 bits. Value of // theOffset is incremented by 4. bool ClientCDKey::ProcessCChar(__int64& theBuf, unsigned int& theOffset, char theChar) { WTRACE("ClientCDKey::ProcessCChar"); WDBG_LL("ClientCDKey::ProcessCChar char=" << theChar << " offset=" << theOffset); bool aRet = true; __int64 aMask = 0; // Determine mask based on char switch (toupper(theChar)) { case 'B': aMask = 0; break; case 'C': aMask = 1; break; case 'D': aMask = 2; break; case 'F': aMask = 3; break; case 'G': aMask = 4; break; case 'J': aMask = 5; break; case 'L': aMask = 6; break; case 'M': aMask = 7; break; case 'N': aMask = 8; break; case 'P': aMask = 9; break; case 'R': aMask = 10; break; case 'S': aMask = 11; break; case 'T': aMask = 12; break; case 'W': aMask = 13; break; case 'X': aMask = 14; break; case 'Z': aMask = 15; break; default: WDBG_LH("ClientCDKey::ProcessCChar Bad input, char=" << theChar); return false; } // Shift mask by offset and or with buffer. Update offset theBuf |= (aMask << theOffset); theOffset += 4; return aRet; }
// Auth1Certificate::PackData // Packs member data into raw buffer in base class. Returns true on success and // false on failure. Verifies member data and appends member data to buffer. bool Auth1Certificate::PackData() { WTRACE("Auth1Certificate::PackData"); if (! AuthCertificateBase::PackData()) return false; // UserId and CommunityId must not be zero. WDBG_LL("Auth1Certificate::PackData Validating..."); if ((GetUserId() == 0) || (GetCommunityId() == 0)) { WDBG_LH("Auth1Certificate::PackData UserId or CommunityId are 0, pack fails."); return false; } // PubKey must be valid if (mPubKey.GetKeyLen() <= 1) { WDBG_LH("Auth1Certificate::PackData PubKey not valid, pack fails."); return false; } // Append fixed length data WDBG_LL("Auth1Certificate::PackData Packing..."); unsigned long tmpUserId = getLittleEndian(mUserId); unsigned long tmpCommunityId = getLittleEndian(GetCommunityId()); unsigned short tmpTrustLevel = getLittleEndian(GetTrustLevel()); mRawBuf.append(reinterpret_cast<unsigned char*>(&tmpUserId), sizeof(tmpUserId)); mRawBuf.append(reinterpret_cast<unsigned char*>(&tmpCommunityId), sizeof(tmpCommunityId)); mRawBuf.append(reinterpret_cast<unsigned char*>(&tmpTrustLevel), sizeof(tmpTrustLevel)); // Append PubKey length and PubKey WDBG_LL("Auth1Certificate::PackData Packing PublicKey."); unsigned short aKeyLen = mPubKey.GetKeyLen(); unsigned short tmpKeyLen = getLittleEndian(aKeyLen); mRawBuf.append(reinterpret_cast<unsigned char*>(&tmpKeyLen), sizeof(tmpKeyLen)); mRawBuf.append(mPubKey.GetKey(), aKeyLen); return true; }
// ClientCDKey::Init(__int64) // Initializes key from 8 byte raw buffer. Does not validate key. bool ClientCDKey::Init(const __int64& theKeyR) { WTRACE("ClientCDKey::Init(__int64)"); WDBG_LH("ClientCDKey::Init(__int64) Key=" << hex << theKeyR << dec); mValidity = Unknown; mKey.erase(); mStrKey.erase(); mBinKey.erase(); WDBG_LM("ClientCDKey::Init(__int64) Extracting fields."); FieldsFromBuffer(theKeyR); return true; }
// ClientCDKey::CleanReg // Cleans registry of CD-Key in WON standard location. bool ClientCDKey::CleanReg() { WTRACE("ClientCDKey::CleanReg"); WDBG_LM("ClientCDKey::CleanReg Clean key from registry."); // Open registry key RegKey aRegKey(REG_CDKEY_PATH, HKEY_LOCAL_MACHINE, true); if (! aRegKey.IsOpen()) { WDBG_LH("ClientCDKey::CleanReg Fail open registry key: " << REG_CDKEY_PATH); return false; } // Delete key from registry return aRegKey.DeleteValue(mProduct.c_str()); }
// ClientCDKey::CleanReg // Cleans registry of CD-Key in WON standard location. bool ClientCDKey::CleanReg() { WTRACE("ClientCDKey::CleanReg"); WDBG_LM("ClientCDKey::CleanReg Clean key from registry."); // Open registry key RegKey aRegKey(REG_CDKEY_PATH, mStoreInHKeyCurUser?HKEY_CURRENT_USER:HKEY_LOCAL_MACHINE, true); // WON 3/21/00 if (! aRegKey.IsOpen()) { WDBG_LH("ClientCDKey::CleanReg Fail open registry key: " << REG_CDKEY_PATH); return false; } // Delete key from registry return aRegKey.DeleteValue(mProduct.c_str()); }
// ClientCDKey::Save // Saves CD-Key to WON standard location in registry. Entry is saved to registry as // the enrypted binary form. Calls AsBinary(). bool ClientCDKey::Save() const { WTRACE("ClientCDKey::Save"); WDBG_LM("ClientCDKey::Save Save encrypted key to registry."); // Open registry key RegKey aRegKey(REG_CDKEY_PATH, HKEY_LOCAL_MACHINE, true); if (! aRegKey.IsOpen()) { WDBG_LH("ClientCDKey::Save Fail open registry key: " << REG_CDKEY_PATH); return false; } // Build encrypted binary form if needed and write to registry AsBinary(); return aRegKey.SetValue(mProduct.c_str(), mBinKey.data(), mBinKey.size()); }
// Auth1Certificate::UnpackData // Unpacks member data from raw buffer in base class. Returns true on success and // false on failure. Verifies raw data length, reads memeber data, sets mDatalen. bool Auth1Certificate::UnpackData() { WTRACE("Auth1Certificate::UnpackData"); if (! AuthCertificateBase::UnpackData()) return false; // Get data pointer (skip header data) WDBG_LL("Auth1Certificate::UnpackData Unpack fixed fields."); const unsigned char* aDataP = mRawBuf.data() + mDataLen; // Read UserId mUserId = *(reinterpret_cast<const unsigned long*>(aDataP)); makeLittleEndian(mUserId); aDataP += sizeof(mUserId); // Read CommunityId unsigned long aCommunityId = *(reinterpret_cast<const unsigned long*>(aDataP)); SetCommunityId(aCommunityId); makeLittleEndian(aCommunityId); aDataP += sizeof(aCommunityId); // Read TrustLeve unsigned short aTrustLevel = *(reinterpret_cast<const unsigned short*>(aDataP)); SetTrustLevel(aTrustLevel); makeLittleEndian(aTrustLevel); aDataP += sizeof(aTrustLevel); // Read length of Pubkey and set mDataLen. Verify there's enough data left // to read PubKey unsigned short aKeyLen = *(reinterpret_cast<const unsigned short*>(aDataP)); makeLittleEndian(aKeyLen); aDataP += sizeof(aKeyLen); mDataLen += CERT_MINLEN + aKeyLen; if (mRawBuf.size() < mDataLen) { WDBG_LH("Auth1Certificate::UnpackData Raw buf len to short for PubKey read (" << mRawBuf.size() << " < " << (CERT_MINLEN + aKeyLen) << ')'); return false; } // Read PubKey WDBG_LL("Auth1Certificate::UnpackData Unpack PubKey and set dataLen."); mPubKey.Create(aKeyLen, aDataP); return true; }