|
|
// 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<SymbolID>(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<char*>(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<char *>(bData), size - 1);
m_SymbolTable.Replace(bHandle,ObjInfoRecord); }
unsigned short CObjectInfoFile::TableSize() { return m_SymbolTable.TableSize(); }
unsigned short CObjectInfoFile::FreeSpace() { return m_SymbolTable.FreeSpace(); }
|