void AuthContext::AppendHashes(WriteBuffer &theBuf, const RawBuffer &theChallengeSeed) { AutoCrit aCrit(mDataCrit); int aNumHashes = 0; int aNumHashPos = theBuf.length(); theBuf.SkipBytes(1); // put num hashes here AuthLoginCommunityMap::iterator anItr = mCommunityMap.begin(); while(anItr!=mCommunityMap.end()) { AuthLoginCommunityData &aData = anItr->second; if(!aData.mSimpleHash.empty()) { MD5Digest aKeyedHash; aKeyedHash.update(theChallengeSeed); aKeyedHash.update(aData.mKeyedHashData); RawBuffer aKeyedHashBuf = aKeyedHash.digest(); theBuf.AppendByte(1); // hash tag theBuf.AppendWString(anItr->first); // community theBuf.AppendBytes(aData.mSimpleHash.data(),aData.mSimpleHash.length()); theBuf.AppendBytes(aKeyedHashBuf.data(),aKeyedHashBuf.length()); aNumHashes++; } ++anItr; } theBuf.SetByte(aNumHashPos,aNumHashes); }
WONStatus AuthSession::Decrypt(ByteBufferPtr &theMsg) { mLastUseTime = time(NULL); try { if(mAuthType==AUTH_TYPE_NONE || mAuthType==AUTH_TYPE_PERSISTENT_NOCRYPT) return WS_Success; ReadBuffer anIn(theMsg->data(),theMsg->length()); WriteBuffer anOut; unsigned char headerType = anIn.ReadByte(); switch (headerType) { case 2: break; //WONMsg::EncryptedService: case 4: anOut.AppendByte(3); break; //WONMsg::MiniEncryptedService: case 6: anOut.AppendByte(5); break; //WONMsg::SmallEncryptedService: case 8: anOut.AppendByte(7); break; //WONMsg::LargeEncryptedService: case 12: break; //WONMsg::HeaderEncryptedService: default: return WS_Success; } bool sessioned = mAuthType==AUTH_TYPE_SESSION; if(sessioned) { unsigned short aSessionId = anIn.ReadShort(); if(aSessionId!=mId) return WS_AuthSession_DecryptSessionIdMismatch; } ByteBufferPtr aDecrypt = mKey.Decrypt(anIn.data() + anIn.pos(), anIn.length() - anIn.pos()); if(aDecrypt.get()==NULL) return WS_AuthSession_DecryptFailure; if(sessioned) { if(aDecrypt->length()<2) return WS_AuthSession_DecryptBadLen; if(++mInSeq!=ShortFromLittleEndian(*(unsigned short*)aDecrypt->data())) // sequence mismatch return WS_AuthSession_DecryptInvalidSequenceNum; anOut.AppendBytes(aDecrypt->data()+2,aDecrypt->length()-2); } else anOut.AppendBytes(aDecrypt->data(),aDecrypt->length()); theMsg = anOut.ToByteBuffer(); return WS_Success; } catch(ReadBufferException&) { return WS_AuthSession_DecryptUnpackFailure; } }
WONStatus PeerAuthServer::GetComplete(WONStatus theStatus, ByteBufferPtr &theComplete) { mState = STATE_NOT_STARTED; // reset state now WriteBuffer aComplete(mLengthFieldSize); aComplete.AppendLong(203); // Auth peer to peer service aComplete.AppendLong(53); // Complete if(theStatus!=WS_Success) { aComplete.AppendShort(WS_CommServ_InvalidParameters); // failure status aComplete.AppendShort(1); // num errors aComplete.AppendString(WONStatusToString(theStatus)); } else { aComplete.AppendShort(WS_Success); WriteBuffer anEncryptBuf; anEncryptBuf.AppendShort(mSecretA.GetKeyLen()); anEncryptBuf.AppendBytes(mSecretA.GetKey(),mSecretA.GetKeyLen()); ByteBufferPtr anEncrypt = mClientCertificate->GetPubKey().Encrypt(anEncryptBuf.data(),anEncryptBuf.length()); if(anEncrypt.get()==NULL) return WS_PeerAuthServer_FailedToEncryptWithClientPubKey; aComplete.AppendShort(anEncrypt->length()); aComplete.AppendBytes(anEncrypt->data(),anEncrypt->length()); mSession = new AuthSession(mAuthType, 0, mSecretB, mLengthFieldSize); } theComplete = aComplete.ToByteBuffer(); return WS_Success; }
WONStatus PeerAuthServer::GetChallenge1(ByteBufferPtr &theChallenge) { WriteBuffer aChallenge(mLengthFieldSize); aChallenge.AppendLong(203); // Auth peer to peer service aChallenge.AppendLong(51); // Challenge1 mSecretB.Create(8); WriteBuffer aChallengeSecret; aChallengeSecret.AppendShort(mSecretB.GetKeyLen()); aChallengeSecret.AppendBytes(mSecretB.GetKey(),mSecretB.GetKeyLen()); ByteBufferPtr anEncrypt = mClientCertificate->GetPubKey().Encrypt(aChallengeSecret.data(),aChallengeSecret.length()); if(anEncrypt.get()==NULL) return WS_PeerAuthServer_FailedToEncryptWithClientPubKey; aChallenge.AppendShort(anEncrypt->length()); aChallenge.AppendBytes(anEncrypt->data(),anEncrypt->length()); if(mUseAuth2) aChallenge.AppendBuffer(mPeerData->GetCertificate2()->GetRawBuf(),2); else aChallenge.AppendBuffer(mPeerData->GetCertificate()->GetRawBuf(),2); theChallenge = aChallenge.ToByteBuffer(); return WS_Success; }
ByteBufferPtr WIMDecoder::EncodeToBuffer(RawImagePtr theImage) { if(theImage->GetType()!=RawImageType_32) return NULL; RawImage32 *anImage = (RawImage32*)theImage.get(); WriteBuffer aBuf; aBuf.AppendBytes("WIM",3); // file format identifier aBuf.AppendLong(32); // file subtype (32-bit raw) aBuf.AppendByte(anImage->GetDoTransparency()?1:0); // apply transparency bit? aBuf.AppendLong(anImage->GetWidth()); aBuf.AppendLong(anImage->GetHeight()); aBuf.AppendBytes(anImage->GetImageData(), 4*anImage->GetWidth()*anImage->GetHeight()); return aBuf.ToByteBuffer(); }
WONStatus AuthSession::Encrypt(ByteBufferPtr &theMsg) { mLastUseTime = time(NULL); if(mAuthType==AUTH_TYPE_NONE || mAuthType==AUTH_TYPE_PERSISTENT_NOCRYPT) return WS_Success; WriteBuffer aMsg(mLengthFieldSize); aMsg.AppendByte(12); // encrypted message WriteBuffer aSeqBuf; const char *aBuf = theMsg->data() + mLengthFieldSize; unsigned short aLen = theMsg->length() - mLengthFieldSize; if(mAuthType==AUTH_TYPE_SESSION) { aMsg.AppendShort(mId); aSeqBuf.AppendShort(++mOutSeq); aSeqBuf.AppendBytes(aBuf,aLen); aBuf = aSeqBuf.data(); aLen = aSeqBuf.length(); } ByteBufferPtr anEncrypt = mKey.Encrypt(aBuf,aLen); if(anEncrypt.get()==NULL) return WS_AuthSession_EncryptFailure; aMsg.AppendBytes(anEncrypt->data(),anEncrypt->length()); theMsg = aMsg.ToByteBuffer(); return WS_Success; }
void LobbyGame::WriteSummary(WriteBuffer &theMsg) { if(mGameType==LobbyGameType_Internet) theMsg.AppendBytes(mIPAddr.GetSixByte(),6); else theMsg.AppendShort(LobbyMisc::GetLanProductId()); theMsg.AppendBool(mInProgress); if(mGameType!=LobbyGameType_Internet) theMsg.AppendWString(mName); theMsg.AppendByte(mSkillLevel); if(mGameType!=LobbyGameType_Internet) { unsigned char aProtectionFlags = 0; if(!mPassword.empty()) aProtectionFlags |= 0x01; if(mInviteOnly) aProtectionFlags |= 0x02; if(mAskToJoin) aProtectionFlags |= 0x04; theMsg.AppendByte(aProtectionFlags); } theMsg.AppendShort(mNumPlayers); theMsg.AppendShort(mMaxPlayers); WriteSummaryHook(theMsg); }
void AuthContext::AppendLoginSecrets(WriteBuffer &theBuf) { AutoCrit aCrit(mDataCrit); SecretList::iterator anItr = mSecretList.begin(); unsigned long aLenPos = theBuf.length(); unsigned char aNumSecrets = 0; theBuf.SkipBytes(1); while(anItr!=mSecretList.end() && aNumSecrets<256) { theBuf.AppendBytes(anItr->mSecret->data(), anItr->mSecret->length()); aNumSecrets++; ++anItr; } theBuf.SetByte(aLenPos,aNumSecrets); }
ByteBufferPtr ElGamal::Sign(const void* theMessage, int theMessageLen) const { if(!IsPrivate()) return NULL; MD5Digest anMD5; anMD5.update(theMessage, theMessageLen); RawBuffer aDigest = anMD5.digest(); BigInteger M; if(!EncodeDigest(aDigest,M)) return NULL; BigInteger ab[2]; if(!BogusSign(M,ab)) return NULL; WriteBuffer aSignature; int qLen = q.byteLength(); RawBuffer a,b; ab[0].toBinary(a); ab[1].toBinary(b); if(a.length()==qLen) aSignature.AppendBytes(a.data(),a.length()); else if(a.length()>qLen) aSignature.AppendBytes(a.data()+a.length()-qLen,qLen); else { for(int i=a.length(); i<qLen; i++) aSignature.AppendByte(0); aSignature.AppendBytes(a.data(),a.length()); } if(b.length()==qLen) aSignature.AppendBytes(b.data(),b.length()); else if(b.length()>qLen) aSignature.AppendBytes(b.data()+b.length()-qLen,qLen); else { for(int i=b.length(); i<qLen; i++) aSignature.AppendByte(0); aSignature.AppendBytes(b.data(),b.length()); } return aSignature.ToByteBuffer(); }
ByteBufferPtr GetHTTPDocumentOp::GetDocument(HTTPDocOwner theOwner) const { FILE *aFile = NULL; if(!mDocumentPath[theOwner].empty()) // fopen will assert if the path is empty in MS crt debug library aFile = fopen(mDocumentPath[theOwner].c_str(),"r"); if(aFile==NULL) { return new ByteBuffer(""); // return NULL; } const int SIZE = 1024; char aBuf[SIZE]; WriteBuffer anOverallBuf; // Skip the first character in MOTD documents if (mDocType == HTTPDocType_MOTD) { int aChar = fgetc(aFile); if(aChar=='<') // optional HTML ungetc(aChar,aFile); } while(!feof(aFile)) { int aNumRead = fread(aBuf,1,SIZE,aFile); if(aNumRead>0) anOverallBuf.AppendBytes(aBuf,aNumRead); } anOverallBuf.AppendByte(0); fclose(aFile); return anOverallBuf.ToByteBuffer(); }
WONStatus PeerAuthClient::GetChallenge2(ByteBufferPtr &challenge2) { mState = STATE_AWAITING_COMPLETE; WriteBuffer aMsg(mLengthFieldSize); aMsg.AppendLong(203); // Auth1 Peer To Peer aMsg.AppendLong(52); // Auth1 Challenge 2 WriteBuffer anEncryptBuf; anEncryptBuf.AppendShort(mSecretB.GetKeyLen()); anEncryptBuf.AppendBytes(mSecretB.GetKey(), mSecretB.GetKeyLen()); anEncryptBuf.AppendBytes(mSecretA.GetKey(), mSecretA.GetKeyLen()); ByteBufferPtr anEncrypt = mServerCertificate->GetPubKey().Encrypt(anEncryptBuf.data(),anEncryptBuf.length()); if(anEncrypt.get()==NULL) return WS_PeerAuthClient_Challenge2EncryptFailure; aMsg.AppendShort(anEncrypt->length()); aMsg.AppendBytes(anEncrypt->data(),anEncrypt->length()); challenge2 = aMsg.ToByteBuffer(); return WS_Success; }
void InitLogic::ProcessCrossPromotionDoc(const ByteBuffer* theMsg) { WriteBuffer aNewBuffer; aNewBuffer.AppendBytes(theMsg->data(), theMsg->length()); aNewBuffer.AppendByte(0); char* aData = aNewBuffer.data(); char aSeparator[] = " \t\n="; std::string anImageRef(""); mPromotionLink = ""; char* aToken = strtok(aData,aSeparator); while(aToken!=NULL) { if(stricmp(aToken,"link")==0) { aToken = strtok(NULL,"\n"); // the rest of the line if(aToken!=NULL) mPromotionLink = aToken; } else if(stricmp(aToken,"image")==0) { aToken = strtok(NULL,"\n"); // the rest of the line if(aToken!=NULL) anImageRef = aToken; } if(aToken) aToken = strtok(NULL,aSeparator); } if(anImageRef.length()) { HTTPGetOpPtr anImageOp = new HTTPGetOp(anImageRef); anImageOp->SetHTTPCache(HTTPCache::GetGlobalCache()); anImageOp->SetCompletion(new InitLogicCompletion(GetCrossPromotionCompletion,this)); mHTTPSession->AddOp(anImageOp); } }
void AuthContext::AppendCommunityData(WriteBuffer &theBuf) { AutoCrit aCrit(mDataCrit); theBuf.AppendByte(0); // 0 community ids theBuf.AppendByte(mCommunityMap.size()); // num community names AuthLoginCommunityMap::iterator anItr = mCommunityMap.begin(); while(anItr!=mCommunityMap.end()) { theBuf.AppendWString(anItr->first); // community name ++anItr; } int aNumCommnityElementsPos = theBuf.length(); theBuf.SkipBytes(2); int aNumCommunityElements = 0; anItr = mCommunityMap.begin(); while(anItr!=mCommunityMap.end()) // Append CD Keys { AuthLoginCommunityData &aData = anItr->second; if(aData.mCDKey.IsValid()) { ByteBufferPtr aKey = anItr->second.mCDKey.GetRaw(); if(aKey.get()!=NULL) { theBuf.AppendByte(1); // Type = CD Key theBuf.AppendShort(anItr->first.length()*2 + aKey->length() + 2); // length of community + data theBuf.AppendWString(anItr->first); theBuf.AppendBytes(aKey->data(),aKey->length()); aNumCommunityElements++; } } ++anItr; } CDKeyCommunityJoinMap::iterator aKeyJoinItr = mCDKeyCommunityJoinMap.begin(); // Append Community Join By CDKey Info while(aKeyJoinItr!=mCDKeyCommunityJoinMap.end()) { ByteBufferPtr aKey = aKeyJoinItr->second.GetRaw(); if(aKey.get()!=NULL) { theBuf.AppendByte(7); // Type = Join Community with CD Key theBuf.AppendShort(aKeyJoinItr->first.length()*2+2 + 4 + aKey->length()); // community name + commnityseq + key theBuf.AppendWString(aKeyJoinItr->first); theBuf.AppendLong(0); theBuf.AppendBytes(aKey->data(),aKey->length()); aNumCommunityElements++; } ++aKeyJoinItr; } SetCommunityUserDataMap::iterator aUserDataItr = mSetCommunityUserDataMap.begin(); // Append User Data for communities while(aUserDataItr!=mSetCommunityUserDataMap.end()) { const ByteBuffer *aData = aUserDataItr->second; if(aData!=NULL) { theBuf.AppendByte(8); // Type = SetCommunityUserData theBuf.AppendShort(aUserDataItr->first.length()*2+2 + 4 + aData->length()); // community name + commnityseq + key theBuf.AppendWString(aUserDataItr->first); theBuf.AppendLong(0); theBuf.AppendBuffer(aData); aNumCommunityElements++; } ++aUserDataItr; } if(mSecretList.size()>0) // CD Keys -> append login secret { theBuf.AppendByte(6); // Type = LoginSecret unsigned long aPos = theBuf.length(); theBuf.SkipBytes(2); AppendLoginSecrets(theBuf); theBuf.SetShort(aPos,theBuf.length()-aPos-2); aNumCommunityElements++; } NicknameMap::iterator aNickItr = mNicknameMap.begin(); while(aNickItr!=mNicknameMap.end()) { const wstring& aKey = aNickItr->first; const wstring& aVal = aNickItr->second; theBuf.AppendByte(4); // retrieve nickname unsigned long aPos = theBuf.length(); theBuf.SkipBytes(2); theBuf.AppendWString(aKey); theBuf.SetShort(aPos,theBuf.length()-aPos-2); aNumCommunityElements++; if(!aVal.empty()) { theBuf.AppendByte(3); // set nickname unsigned long aPos = theBuf.length(); theBuf.SkipBytes(2); theBuf.AppendWString(aKey); theBuf.AppendWString(aVal); theBuf.SetShort(aPos,theBuf.length()-aPos-2); aNumCommunityElements++; } ++aNickItr; } theBuf.SetShort(aNumCommnityElementsPos,aNumCommunityElements); }
ByteBufferPtr ElGamal::Decrypt(const void *theCipherText, int theCipherTextLen) const { if(!IsPrivate()) return NULL; const unsigned char *in = (const unsigned char*)theCipherText; int inOffset = 0; if(theCipherTextLen-inOffset<4) return NULL; int aNumBlocks = LongFromLittleEndian(*(int*)in); inOffset+=4; if(theCipherTextLen-inOffset < aNumBlocks*modulusLen*2-inOffset) return NULL; RawBuffer aBuf(modulusLen,(unsigned char)0); RawBuffer bBuf(modulusLen,(unsigned char)0); WriteBuffer aDecrypt; BigInteger a;; BigInteger b; BigInteger aPlainText; for(int i=0; i<aNumBlocks; i++) { aBuf.assign(in+inOffset,modulusLen); inOffset+=modulusLen; bBuf.assign(in+inOffset,modulusLen); inOffset+=modulusLen; a.fromBinary(aBuf); b.fromBinary(bBuf); if(!decrypt(a,b,aPlainText)) return NULL; RawBuffer aBigIntArray; aPlainText.toBinary(aBigIntArray); if(aBigIntArray.length()==0) return NULL; int aPlainLen = aBigIntArray[aBigIntArray.length() - 1]; if(aPlainLen>modulusLen - 3) return NULL; if(aBigIntArray.length() - 1 - aPlainLen < 0) { int extra = aPlainLen - (aBigIntArray.length() - 1); for(int j=0; j<extra; j++) aDecrypt.AppendByte(0); aDecrypt.AppendBytes(aBigIntArray.data(),aBigIntArray.length()); } else aDecrypt.AppendBytes(aBigIntArray.data()+aBigIntArray.length()-1-aPlainLen,aPlainLen); } return aDecrypt.ToByteBuffer(); }
ByteBufferPtr ElGamal::Encrypt(const void *thePlainText, int thePlainTextLen) const { if(!IsPublic()) return NULL; const unsigned char *aPlainText = (const unsigned char*)thePlainText; int aBlockLen = modulusLen - 3; int aNumBlock = thePlainTextLen / aBlockLen; if ((thePlainTextLen % aBlockLen) != 0) aNumBlock++; WriteBuffer anEncrypt; anEncrypt.Reserve(4+modulusLen*2*aNumBlock); int anOffset = 0; anEncrypt.AppendLong(aNumBlock); while(anOffset < thePlainTextLen) { int thisBlockLen = aBlockLen; if(thePlainTextLen - anOffset < aBlockLen) thisBlockLen = thePlainTextLen - anOffset; RawBuffer anEncryptBlock(modulusLen-1,(unsigned char)0); for(int k=0,j=modulusLen-2-thisBlockLen; j<modulusLen-2; j++,k++) anEncryptBlock[j] = aPlainText[anOffset+k]; anEncryptBlock[modulusLen - 2] = (unsigned char)thisBlockLen; BigInteger ab[2]; if(!encrypt(BigInteger(anEncryptBlock),ab)) return NULL; RawBuffer aa,bb; ab[0].toBinary(aa); ab[1].toBinary(bb); if(aa.length()==modulusLen) anEncrypt.AppendBytes(aa.data(),aa.length()); else if(aa.length()>modulusLen) anEncrypt.AppendBytes(aa.data()+aa.length()-modulusLen,modulusLen); else { for(int i=aa.length(); i<modulusLen; i++) anEncrypt.AppendByte(0); anEncrypt.AppendBytes(aa.data(),aa.length()); } if(bb.length()==modulusLen) anEncrypt.AppendBytes(bb.data(),bb.length()); else if(bb.length()>modulusLen) anEncrypt.AppendBytes(bb.data()+bb.length()-modulusLen,modulusLen); else { for(int i=bb.length(); i<modulusLen; i++) anEncrypt.AppendByte(0); anEncrypt.AppendBytes(bb.data(),bb.length()); } anOffset+=thisBlockLen; } return anEncrypt.ToByteBuffer(); }