// ObjectInfoFile.cpp: implementation of the CObjectInfoFile class. // // (c) Copyright Schlumberger Technology Corp., unpublished work, created // 1999. This computer program includes Confidential, Proprietary // Information and is a Trade Secret of Schlumberger Technology Corp. All // use, disclosure, and/or reproduction is prohibited unless authorized // in writing. All Rights Reserved. ////////////////////////////////////////////////////////////////////// #include "cciCard.h" #include "SymbolTable.h" #include "ObjectInfoFile.h" using std::string; using namespace cci; using namespace iop; CObjectInfoFile::CObjectInfoFile(CSmartCard &rSmartCard, string const &Path, ObjectAccess oa) : m_oa(oa), m_Path(Path), m_SymbolTable(rSmartCard, Path, ObjMasterBlkSize), m_rSmartCard(rSmartCard) { } void CObjectInfoFile::Reset() { BYTE bMasterBlk[ObjMasterBlkSize]; memset(bMasterBlk,0,ObjMasterBlkSize); m_rSmartCard.Select(m_Path.c_str()); m_rSmartCard.WriteBinary(0, ObjMasterBlkSize, bMasterBlk); m_bDefaultContainer = 0; m_bFirstContainer = 0; m_bFirstCertificate = 0; m_bFirstPublicKey = 0; m_bFirstPrivateKey = 0; m_bFirstDataObject = 0; m_SymbolTable.Reset(); } void CObjectInfoFile::UpdateCache() { BYTE bMasterBlk[ObjMasterBlkSize]; m_rSmartCard.Select(m_Path.c_str()); m_rSmartCard.ReadBinary(0, ObjMasterBlkSize, bMasterBlk); m_bDefaultContainer = bMasterBlk[ObjDefaultContainerLoc]; m_bFirstContainer = bMasterBlk[ObjFirstContainerLoc]; m_bFirstCertificate = bMasterBlk[ObjFirstCertificateLoc]; m_bFirstPublicKey = bMasterBlk[ObjFirstPublicKeyLoc]; m_bFirstPrivateKey = bMasterBlk[ObjFirstPrivateKeyLoc]; m_bFirstDataObject = bMasterBlk[ObjFirstDataObjectLoc]; } ObjectAccess CObjectInfoFile::AccessType() const { return m_oa; } void CObjectInfoFile::DefaultContainer(SymbolID bHandle) { m_rSmartCard.Select(m_Path.c_str()); m_rSmartCard.WriteBinary(ObjDefaultContainerLoc, 1, &bHandle); m_bDefaultContainer = bHandle; } SymbolID CObjectInfoFile::AddSymbol(string aString) { return m_SymbolTable.Add(aString); } string CObjectInfoFile::FindSymbol(SymbolID sid) { return m_SymbolTable.Find(sid); } void CObjectInfoFile::RemoveSymbol(SymbolID sid) { m_SymbolTable.Remove(sid); } SymbolID CObjectInfoFile::FirstObject(ObjectType type) const { SymbolID sid; switch(type) { case otContainerObject: sid = m_bFirstContainer; break; case otCertificateObject: sid = m_bFirstCertificate; break; case otPublicKeyObject: sid = m_bFirstPublicKey; break; case otPrivateKeyObject: sid = m_bFirstPrivateKey; break; case otDataObjectObject: sid = m_bFirstDataObject; break; default: throw cci::Exception(ccBadObjectType); break; } return sid; } void CObjectInfoFile::FirstObject(ObjectType type, SymbolID bHandle) { unsigned short sLoc; SymbolID *pbCachedValue; switch(type) { case otContainerObject: sLoc = ObjFirstContainerLoc; pbCachedValue = &m_bFirstContainer; break; case otCertificateObject: sLoc = ObjFirstCertificateLoc; pbCachedValue = &m_bFirstCertificate; break; case otPublicKeyObject: sLoc = ObjFirstPublicKeyLoc; pbCachedValue = &m_bFirstPublicKey; break; case otPrivateKeyObject: sLoc = ObjFirstPrivateKeyLoc; pbCachedValue = &m_bFirstPrivateKey; break; case otDataObjectObject: sLoc = ObjFirstDataObjectLoc; pbCachedValue = &m_bFirstDataObject; break; default: throw cci::Exception(ccBadObjectType); } m_rSmartCard.Select(m_Path.c_str()); m_rSmartCard.WriteBinary(sLoc, 1, &bHandle); *pbCachedValue = bHandle; // Update cache after successful write } SymbolID CObjectInfoFile::NextObject(SymbolID bHandle) { string ObjInfoRecord(m_SymbolTable.Find(bHandle)); if (!ObjInfoRecord.size()) throw cci::Exception(ccFormatError); return static_cast(ObjInfoRecord[0]); } void CObjectInfoFile::NextObject(SymbolID bHandle, SymbolID bHandleNext) { string ObjInfoRecord(m_SymbolTable.Find(bHandle)); if (!ObjInfoRecord.size()) throw cci::Exception(ccFormatError); ObjInfoRecord[0] = bHandleNext; m_SymbolTable.Replace(bHandle,ObjInfoRecord); } SymbolID CObjectInfoFile::AddObject(ObjectType type, unsigned short size) { string strTemp; strTemp.resize(size+1); SymbolID bHandle; bHandle = m_SymbolTable.Add(strTemp, smExclusive); // Add to end of list SymbolID bLast = FirstObject(type); if(!bLast) // No objects in list, add to head of list { FirstObject(type,bHandle); } else { // Search for the last object SymbolID bLastNext = NextObject(bLast); while(bLastNext) { bLast = bLastNext; bLastNext = NextObject(bLast); } NextObject(bLast,bHandle); } return bHandle; } void CObjectInfoFile::RemoveObject(ObjectType type, SymbolID bHandle) { if (FirstObject(type) == bHandle) // Remove from head of list { FirstObject(type,NextObject(bHandle)); } else { // Remove from middle/end of list, search for the previous object SymbolID bPrevNext, bPrevious = FirstObject(type); while(bPrevious) { bPrevNext = NextObject(bPrevious); if (bHandle == bPrevNext) break; bPrevious = bPrevNext; } if (!bPrevious) throw cci::Exception(ccFormatError); // Object not linked // through this list NextObject(bPrevious,NextObject(bHandle)); } m_SymbolTable.Remove(bHandle); } void CObjectInfoFile::ReadObject(SymbolID bHandle, BYTE* bData) { string ObjInfoRecord(m_SymbolTable.Find(bHandle)); string::size_type size = ObjInfoRecord.size(); if (!size) throw cci::Exception(ccFormatError); ObjInfoRecord.copy(reinterpret_cast(bData) , size - 1, 1); // Skip the leading byte. } void CObjectInfoFile::WriteObject(SymbolID bHandle, BYTE* bData) { string ObjInfoRecord(m_SymbolTable.Find(bHandle)); string::size_type size = ObjInfoRecord.size(); if (!size) throw cci::Exception(ccFormatError); ObjInfoRecord.resize(1); ObjInfoRecord += string(reinterpret_cast(bData), size - 1); m_SymbolTable.Replace(bHandle,ObjInfoRecord); } unsigned short CObjectInfoFile::TableSize() { return m_SymbolTable.TableSize(); } unsigned short CObjectInfoFile::FreeSpace() { return m_SymbolTable.FreeSpace(); }