#ifndef _H_DISKREP
#define _H_DISKREP
#include "cs.h"
#include "codedirectory.h"
#include "cdbuilder.h"
#include "requirement.h"
#include "resources.h"
#include <security_utilities/macho++.h> // for class Architecture
#include <security_utilities/refcount.h>
#include <security_utilities/superblob.h>
#include <CoreFoundation/CFData.h>
namespace Security {
namespace CodeSigning {
class ResourceBuilder;
class SecCodeSigner;
class DiskRep : public RefCount {
public:
class SigningContext;
typedef std::set<OSStatus> ToleratedErrors;
public:
DiskRep();
virtual ~DiskRep();
virtual DiskRep *base();
virtual CFDataRef component(CodeDirectory::SpecialSlot slot) = 0; virtual CFDataRef identification() = 0; virtual std::string mainExecutablePath() = 0; virtual CFURLRef copyCanonicalPath() = 0; virtual std::string resourcesRootPath(); virtual void adjustResources(ResourceBuilder &builder); virtual void prepareForSigning(SigningContext& context); virtual Universal *mainExecutableImage(); virtual size_t signingBase(); virtual size_t signingLimit() = 0;
virtual size_t execSegBase(const Architecture *arch); virtual size_t execSegLimit(const Architecture *arch) = 0;
virtual std::string format() = 0; virtual CFArrayRef modifiedFiles(); virtual UnixPlusPlus::FileDesc &fd() = 0; virtual void flush(); virtual CFDictionaryRef diskRepInformation();
virtual std::string recommendedIdentifier(const SigningContext &ctx) = 0; virtual CFDictionaryRef defaultResourceRules(const SigningContext &ctx); virtual const Requirements *defaultRequirements(const Architecture *arch,
const SigningContext &ctx); virtual size_t pageSize(const SigningContext &ctx);
virtual void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags); virtual CFArrayRef allowedResourceOmissions();
bool mainExecutableIsMachO() { return mainExecutableImage() != NULL; }
CFDataRef signature() { return component(cdSignatureSlot); }
public:
class Writer;
virtual Writer *writer();
public:
struct Context {
Context() : arch(Architecture::none), version(NULL), offset(0), fileOnly(false), inMemory(NULL), size(0) { }
Architecture arch; const char *version; off_t offset; bool fileOnly; const void *inMemory; size_t size; };
static DiskRep *bestGuess(const char *path, const Context *ctx = NULL); static DiskRep *bestFileGuess(const char *path, const Context *ctx = NULL); static DiskRep *bestGuess(const char *path, size_t archOffset);
static DiskRep *bestGuess(const std::string &path, const Context *ctx = NULL)
{ return bestGuess(path.c_str(), ctx); }
static DiskRep *bestGuess(const std::string &path, size_t archOffset) { return bestGuess(path.c_str(), archOffset); }
static DiskRep *bestFileGuess(const std::string &path, const Context *ctx = NULL) { return bestFileGuess(path.c_str(), ctx); }
public:
class SigningContext {
protected:
SigningContext() { }
public:
virtual std::string sdkPath(const std::string &path) const = 0;
virtual bool isAdhoc() const = 0;
virtual SecCSFlags signingFlags() const = 0;
virtual const CodeDirectory::HashAlgorithms &digestAlgorithms() const = 0;
virtual void setDigestAlgorithms(CodeDirectory::HashAlgorithms types) = 0;
void setDigestAlgorithm(CodeDirectory::HashAlgorithm type)
{
CodeDirectory::HashAlgorithms types;
types.insert(type);
setDigestAlgorithms(types);
}
};
protected:
static std::string canonicalIdentifier(const std::string &name);
public:
static const size_t segmentedPageSize = 4096; static const size_t monolithicPageSize = 0; };
class DiskRep::Writer : public RefCount {
public:
Writer(uint32_t attrs = 0);
virtual ~Writer();
virtual void component(CodeDirectory::SpecialSlot slot, CFDataRef data) = 0;
virtual uint32_t attributes() const;
virtual void addDiscretionary(CodeDirectory::Builder &builder);
virtual void remove();
virtual void flush();
bool attribute(uint32_t attr) const { return mAttributes & attr; }
void signature(CFDataRef data) { component(cdSignatureSlot, data); }
void codeDirectory(const CodeDirectory *cd, CodeDirectory::SpecialSlot slot)
{ component(slot, CFTempData(cd->data(), cd->length())); }
private:
Architecture mArch;
uint32_t mAttributes;
};
enum {
writerLastResort = 0x0001, writerNoGlobal = 0x0002, };
class FilterRep : public DiskRep {
public:
FilterRep(DiskRep *orig) : mOriginal(orig) { }
DiskRep *base() { return mOriginal; }
CFDataRef component(CodeDirectory::SpecialSlot slot) = 0;
CFDataRef identification() { return mOriginal->identification(); }
std::string mainExecutablePath() { return mOriginal->mainExecutablePath(); }
CFURLRef copyCanonicalPath() { return mOriginal->copyCanonicalPath(); }
std::string resourcesRootPath() { return mOriginal->resourcesRootPath(); }
void adjustResources(ResourceBuilder &builder) { return mOriginal->adjustResources(builder); }
Universal *mainExecutableImage() { return mOriginal->mainExecutableImage(); }
size_t signingBase() { return mOriginal->signingBase(); }
size_t signingLimit() { return mOriginal->signingLimit(); }
size_t execSegBase(const Architecture *arch) { return mOriginal->execSegBase(arch); }
size_t execSegLimit(const Architecture *arch) { return mOriginal->execSegLimit(arch); }
std::string format() { return mOriginal->format(); }
CFArrayRef modifiedFiles() { return mOriginal->modifiedFiles(); }
UnixPlusPlus::FileDesc &fd() { return mOriginal->fd(); }
void flush() { return mOriginal->flush(); }
std::string recommendedIdentifier(const SigningContext &ctx)
{ return mOriginal->recommendedIdentifier(ctx); }
CFDictionaryRef defaultResourceRules(const SigningContext &ctx)
{ return mOriginal->defaultResourceRules(ctx); }
const Requirements *defaultRequirements(const Architecture *arch, const SigningContext &ctx)
{ return mOriginal->defaultRequirements(arch, ctx); }
size_t pageSize(const SigningContext &ctx) { return mOriginal->pageSize(ctx); }
void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags) { mOriginal->strictValidate(cd, tolerated, flags); }
CFArrayRef allowedResourceOmissions() { return mOriginal->allowedResourceOmissions(); }
private:
RefPointer<DiskRep> mOriginal; };
} }
#endif // !_H_DISKREP