bool CCollection::InitCollectionFromFile(const CString& sFilePath, CString sFileName) { DEBUG_ONLY( sFileName.Replace(COLLECTION_FILEEXTENSION, _T("")) ); bool bCollectionLoaded = false; CSafeFile data; if(data.Open(sFilePath, CFile::modeRead | CFile::shareDenyWrite | CFile::typeBinary)) { try { uint32 nVersion = data.ReadUInt32(); if(nVersion == COLLECTION_FILE_VERSION1_INITIAL || nVersion == COLLECTION_FILE_VERSION2_LARGEFILES) { uint32 headerTagCount = data.ReadUInt32(); while(headerTagCount) { CTag tag(&data, true); switch(tag.GetNameID()) { case FT_FILENAME: { if(tag.IsStr()) m_sCollectionName = tag.GetStr(); break; } case FT_COLLECTIONAUTHOR: { if(tag.IsStr()) m_sCollectionAuthorName = tag.GetStr(); break; } case FT_COLLECTIONAUTHORKEY: { if(tag.IsBlob()) { SetCollectionAuthorKey(tag.GetBlob(), tag.GetBlobSize()); } break; } } headerTagCount--; } uint32 fileCount = data.ReadUInt32(); while(fileCount) { CCollectionFile* pCollectionFile = new CCollectionFile(&data); if(pCollectionFile) AddFileToCollection(pCollectionFile, false); fileCount--; } bCollectionLoaded = true; } if (m_pabyCollectionAuthorKey != NULL){ bool bResult = false; if (data.GetLength() > data.GetPosition()){ using namespace CryptoPP; uint32 nPos = (uint32)data.GetPosition(); data.SeekToBegin(); BYTE* pMessage = new BYTE[nPos]; VERIFY( data.Read(pMessage, nPos) == nPos); StringSource ss_Pubkey(m_pabyCollectionAuthorKey, m_nKeySize, true, 0); RSASSA_PKCS1v15_SHA_Verifier pubkey(ss_Pubkey); int nSignLen = (int)(data.GetLength() - data.GetPosition()); BYTE* pSignature = new BYTE[nSignLen ]; VERIFY( data.Read(pSignature, nSignLen) == (UINT)nSignLen); bResult = pubkey.VerifyMessage(pMessage, nPos, pSignature, nSignLen); delete[] pMessage; delete[] pSignature; } if (!bResult){ DebugLogWarning(_T("Collection %s: Verifying of public key failed!"), m_sCollectionName); delete[] m_pabyCollectionAuthorKey; m_pabyCollectionAuthorKey = NULL; m_nKeySize = 0; m_sCollectionAuthorName = _T(""); } else DebugLog(_T("Collection %s: Public key verified"), m_sCollectionName); } else m_sCollectionAuthorName = _T(""); data.Close(); } catch(CFileException* error) { error->Delete(); return false; } catch(...) { ASSERT( false ); data.Close(); return false; } } else return false; if(!bCollectionLoaded) { CStdioFile data; if(data.Open(sFilePath, CFile::modeRead | CFile::shareDenyWrite | CFile::typeText)) { try { CString sLink; while(data.ReadString(sLink)) { //Ignore all lines that start with #. //These lines can be used for future features.. if(sLink.Find(_T("#")) != 0) { try { CCollectionFile* pCollectionFile = new CCollectionFile(); if (pCollectionFile->InitFromLink(sLink)) AddFileToCollection(pCollectionFile, false); else delete pCollectionFile; } catch(...) { ASSERT( false ); data.Close(); return false; } } } data.Close(); m_sCollectionName = sFileName; bCollectionLoaded = true; m_bTextFormat = true; } catch(CFileException* error) { error->Delete(); return false; } catch(...) { ASSERT( false ); data.Close(); return false; } } } return bCollectionLoaded; }