#ifndef _H_SIGNERUTILS
#define _H_SIGNERUTILS
#include "CodeSigner.h"
#include "sigblob.h"
#include "cdbuilder.h"
#include <Security/SecCmsBase.h>
#include <security_utilities/utilities.h>
#include <security_utilities/blob.h>
#include <security_utilities/unix++.h>
#include <security_utilities/unixchild.h>
#include <sys/cdefs.h>
#if TARGET_OS_OSX
__BEGIN_DECLS
#include <AppleFSCompression/AppleFSCompression.h>
__END_DECLS
#endif
namespace Security {
namespace CodeSigning {
class InternalRequirements : public Requirements::Maker {
public:
InternalRequirements() : mReqs(NULL) { }
~InternalRequirements() { ::free((void *)mReqs); }
void operator () (const Requirements *given, const Requirements *defaulted, const Requirement::Context &context);
operator const Requirements * () const { return mReqs; }
private:
const Requirements *mReqs;
};
class BlobWriter : public DiskRep::Writer, public EmbeddedSignatureBlob::Maker {
public:
void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
};
class DetachedBlobWriter : public BlobWriter {
public:
DetachedBlobWriter(SecCodeSigner::Signer &s) : signer(s) { }
SecCodeSigner::Signer &signer;
void flush();
};
class ArchEditor : public DiskRep::Writer {
public:
ArchEditor(Universal &fat, CodeDirectory::HashAlgorithms hashTypes, uint32_t attrs);
virtual ~ArchEditor();
public:
struct Arch : public BlobWriter {
Architecture architecture; auto_ptr<MachO> source; std::map<CodeDirectory::HashAlgorithm, RefPointer<CodeDirectory::Builder> > cdBuilders;
InternalRequirements ireqs; size_t blobSize;
Arch(const Architecture &arch, CodeDirectory::HashAlgorithms hashTypes);
void eachDigest(void (^op)(CodeDirectory::Builder& builder))
{
for (auto type = cdBuilders.begin(); type != cdBuilders.end(); ++type)
op(*type->second);
}
};
typedef std::map<Architecture, Arch *> ArchMap;
typedef ArchMap::iterator Iterator;
ArchMap::iterator begin() { return architecture.begin(); }
ArchMap::iterator end() { return architecture.end(); }
unsigned count() const { return (unsigned)architecture.size(); }
virtual void allocate() = 0; virtual void reset(Arch &arch) = 0; virtual void write(Arch &arch, EmbeddedSignatureBlob *blob) = 0; virtual void commit() = 0;
protected:
ArchMap architecture;
};
class BlobEditor : public ArchEditor {
public:
BlobEditor(Universal &fat, SecCodeSigner::Signer &s);
SecCodeSigner::Signer &signer;
void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
void allocate() { }
void reset(Arch &arch) { }
void write(Arch &arch, EmbeddedSignatureBlob *blob);
void commit();
private:
DetachedSignatureBlob::Maker mMaker;
EmbeddedSignatureBlob::Maker mGlobal;
};
class MachOEditor : public ArchEditor, private UnixPlusPlus::Child {
public:
MachOEditor(DiskRep::Writer *w, Universal &code, CodeDirectory::HashAlgorithms hashTypes, std::string srcPath);
~MachOEditor();
const RefPointer<DiskRep::Writer> writer;
const std::string sourcePath;
const std::string tempPath;
void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
void allocate();
void reset(Arch &arch);
void write(Arch &arch, EmbeddedSignatureBlob *blob);
void commit();
private:
CodeDirectory::HashAlgorithms mHashTypes;
void childAction();
void parentAction();
Universal *mNewCode;
UnixPlusPlus::AutoFileDesc mFd;
bool mTempMayExist;
const char *mHelperPath;
bool mHelperOverridden;
};
class PreSigningContext : public Requirement::Context {
public:
PreSigningContext(const SecCodeSigner::Signer &signer);
private:
CFRef<CFArrayRef> mCerts; };
class CodeDirectorySet : public std::map<CodeDirectory::HashAlgorithm, const CodeDirectory *> {
public:
CodeDirectorySet() { mPrimary = NULL; }
~CodeDirectorySet();
void add(const CodeDirectory* cd);
void populate(DiskRep::Writer* writer) const;
const CodeDirectory* primary() const;
CFArrayRef hashList() const;
CFDictionaryRef hashDict() const;
static SECOidTag SECOidTagForAlgorithm(CodeDirectory::HashAlgorithm algorithm);
private:
mutable const CodeDirectory* mPrimary;
};
} }
#endif // !_H_SIGNERUTILS