#include "reqmaker.h"
namespace Security {
namespace CodeSigning {
Requirement::Maker::Maker(Kind k)
: mSize(1024)
{
mBuffer = (Requirement *)malloc(mSize);
mBuffer->initialize();
mBuffer->kind(k);
mPC = sizeof(Requirement);
}
void Requirement::Maker::require(size_t size)
{
if (mPC + size > mSize) {
mSize *= 2;
if (mPC + size > mSize)
mSize = (Offset)(mPC + size);
if (!(mBuffer = (Requirement *)realloc(mBuffer, mSize)))
UnixError::throwMe(ENOMEM);
}
}
void *Requirement::Maker::alloc(size_t size)
{
size_t usedSize = LowLevelMemoryUtilities::alignUp(size, baseAlignment);
require(usedSize);
void *data = mBuffer->at<void>(mPC);
mPC += usedSize;
const uint32_t zero = 0;
memcpy(mBuffer->at<void>(mPC - usedSize + size), &zero, usedSize - size);
return data;
}
void Requirement::Maker::putData(const void *data, size_t length)
{
put(uint32_t(length));
memcpy(alloc(length), data, length);
}
void Requirement::Maker::anchor()
{
put(opAppleAnchor);
}
void Requirement::Maker::anchorGeneric()
{
put(opAppleGenericAnchor);
}
void Requirement::Maker::anchor(int slot, SHA1::Digest digest)
{
put(opAnchorHash);
put(slot);
putData(digest, SHA1::digestLength);
}
void Requirement::Maker::anchor(int slot, const void *cert, size_t length)
{
SHA1 hasher;
hasher(cert, length);
SHA1::Digest digest;
hasher.finish(digest);
anchor(slot, digest);
}
void Requirement::Maker::trustedAnchor()
{
put(opTrustedCerts);
}
void Requirement::Maker::trustedAnchor(int slot)
{
put(opTrustedCert);
put(slot);
}
void Requirement::Maker::infoKey(const string &key, const string &value)
{
put(opInfoKeyValue);
put(key);
put(value);
}
void Requirement::Maker::ident(const string &identifier)
{
put(opIdent);
put(identifier);
}
void Requirement::Maker::cdhash(SHA1::Digest digest)
{
put(opCDHash);
putData(digest, SHA1::digestLength);
}
void Requirement::Maker::cdhash(CFDataRef digest)
{
put(opCDHash);
putData(CFDataGetBytePtr(digest), CFDataGetLength(digest));
}
void Requirement::Maker::copy(const Requirement *req)
{
assert(req);
if (req->kind() != exprForm) MacOSError::throwMe(errSecCSReqUnsupported);
this->copy(req->at<const void>(sizeof(Requirement)), req->length() - sizeof(Requirement));
}
void *Requirement::Maker::insert(const Label &label, size_t length)
{
require(length);
memmove(mBuffer->at<void>(label.pos + length),
mBuffer->at<void>(label.pos), mPC - label.pos);
mPC += length;
return mBuffer->at<void>(label.pos);
}
Requirement *Requirement::Maker::make()
{
mBuffer->length(mPC);
Requirement *result = mBuffer;
mBuffer = NULL;
return result;
}
} }