#include "slcrep.h"
namespace Security {
namespace CodeSigning {
using namespace UnixPlusPlus;
DYLDCacheRep::DYLDCacheRep(const char *path)
: SingleDiskRep(path), mCache(path)
{
this->setup();
}
DYLDCacheRep::DYLDCacheRep(const Context *ctx)
: SingleDiskRep(DYLDCache::pathFor(((ctx && ctx->arch) ? ctx->arch : Architecture::local()))),
mCache(this->path())
{
this->setup();
}
void DYLDCacheRep::setup()
{
mSigningData = NULL;
if (mCache.totalSize() >= mCache.mapSize() + sizeof(BlobCore)) {
const EmbeddedSignatureBlob *blob = mCache.at<const EmbeddedSignatureBlob>(mCache.mapSize());
if (mCache.totalSize() >= mCache.mapSize() + blob->length()) mSigningData = blob;
}
CODESIGN_DISKREP_CREATE_SLC(this, (char*)this->mainExecutablePath().c_str());
}
bool DYLDCacheRep::candidate(FileDesc &fd)
{
return DYLDCache::validate(fd);
}
size_t DYLDCacheRep::pageSize(const SigningContext &)
{
return segmentedPageSize;
}
CFDataRef DYLDCacheRep::component(CodeDirectory::SpecialSlot slot)
{
return mSigningData ? mSigningData->component(slot) : NULL;
}
string DYLDCacheRep::format()
{
if (const char *name = mCache.architecture().name()) {
char result[100];
snprintf(result, sizeof(result), "OS X Shared Library Cache (%s @ 0x%llx)",
name, mCache.baseAddress());
return result;
} else
return "OS X Shared Library Cache (unknown type)";
}
DiskRep::Writer *DYLDCacheRep::writer()
{
return new Writer(this);
}
void DYLDCacheRep::Writer::component(CodeDirectory::SpecialSlot slot, CFDataRef data)
{
EmbeddedSignatureBlob::Maker::component(slot, data);
}
void DYLDCacheRep::Writer::flush()
{
delete mSigningData; mSigningData = Maker::make(); fd().seek(rep->mCache.mapSize()); fd().writeAll(*mSigningData);
}
void DYLDCacheRep::Writer::addDiscretionary(CodeDirectory::Builder &builder)
{
unsigned count = rep->mCache.mappingCount();
builder.scatter(count);
for (unsigned n = 0; n < count; n++) {
const DYLDCache::Mapping dmap = rep->mCache.mapping(n);
CodeDirectory::Scatter *scatter = builder.scatter() + n;
scatter->targetOffset = dmap.address();
scatter->base = dmap.offset() / segmentedPageSize;
assert(dmap.offset() % segmentedPageSize == 0);
scatter->count = dmap.size() / segmentedPageSize;
assert(dmap.size() % segmentedPageSize == 0);
}
}
} }