299 lines
6.8 KiB
C++
299 lines
6.8 KiB
C++
|
// 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();
|
||
|
}
|