#ifndef _H_STATICCODE
#define _H_STATICCODE
#include "cs.h"
#include "Requirements.h"
#include "requirement.h"
#include "diskrep.h"
#include "codedirectory.h"
#include <Security/SecTrust.h>
#include <CoreFoundation/CFData.h>
namespace Security {
namespace CodeSigning {
class SecCode;
class SecStaticCode : public SecCFObject {
NOCOPY(SecStaticCode)
protected:
class ValidationContext {
public:
virtual ~ValidationContext();
virtual void reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value);
};
class CollectingContext : public ValidationContext {
public:
CollectingContext(SecStaticCode &c) : code(c), mStatus(noErr) { }
void reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value);
OSStatus osStatus() { return mStatus; }
operator OSStatus () const { return mStatus; }
void throwMe() __attribute__((noreturn));
SecStaticCode &code;
private:
CFRef<CFMutableDictionaryRef> mCollection;
OSStatus mStatus;
};
public:
SECCFFUNCTIONS(SecStaticCode, SecStaticCodeRef,
errSecCSInvalidObjectRef, gCFObjects().StaticCode)
static SecStaticCode *requiredStatic(SecStaticCodeRef ref); static SecCode *optionalDynamic(SecStaticCodeRef ref);
SecStaticCode(DiskRep *rep);
virtual ~SecStaticCode() throw();
bool equal(SecCFObject &other);
CFHashCode hash();
void detachedSignature(CFDataRef sig); void checkForSystemSignature();
const CodeDirectory *codeDirectory(bool check = true);
CFDataRef cdHash();
CFDataRef signature();
CFAbsoluteTime signingTime();
CFAbsoluteTime signingTimestamp();
bool isSigned() { return codeDirectory(false) != NULL; }
DiskRep *diskRep() { return mRep; }
std::string mainExecutablePath() { return mRep->mainExecutablePath(); }
CFURLRef canonicalPath() const { return mRep->canonicalPath(); }
std::string identifier() { return codeDirectory()->identifier(); }
std::string format() const { return mRep->format(); }
std::string signatureSource();
CFDataRef component(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
CFDictionaryRef infoDictionary();
CFDictionaryRef entitlements();
CFDictionaryRef resourceDictionary();
CFURLRef resourceBase();
CFDataRef resource(std::string path);
CFDataRef resource(std::string path, ValidationContext &ctx);
void validateResource(std::string path, ValidationContext &ctx);
bool flag(uint32_t tested);
void resetValidity();
bool validated() const { return mValidated; }
bool valid() const
{ assert(validated()); return mValidated && (mValidationResult == noErr); }
bool validatedExecutable() const { return mExecutableValidated; }
bool validatedResources() const { return mResourcesValidated; }
void validateDirectory();
void validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
void validateNonResourceComponents();
void validateResources();
void validateExecutable();
const Requirements *internalRequirements();
const Requirement *internalRequirement(SecRequirementType type);
const Requirement *designatedRequirement();
const Requirement *defaultDesignatedRequirement();
void validateRequirements(SecRequirementType type, SecStaticCode *target,
OSStatus nullError = noErr); void validateRequirement(const Requirement *req, OSStatus failure); bool satisfiesRequirement(const Requirement *req, OSStatus failure);
SecCertificateRef cert(int ix); CFArrayRef certificates();
CFDictionaryRef signingInformation(SecCSFlags flags);
public:
class AllArchitectures;
protected:
CFDictionaryRef getDictionary(CodeDirectory::SpecialSlot slot, OSStatus fail); bool verifySignature();
CFTypeRef verificationPolicy(SecCSFlags flags);
static void checkOptionalResource(CFTypeRef key, CFTypeRef value, void *context);
private:
RefPointer<DiskRep> mRep;
bool mValidated; OSStatus mValidationResult; bool mValidationExpired;
bool mExecutableValidated; OSStatus mExecutableValidResult;
bool mResourcesValidated; OSStatus mResourcesValidResult; CollectingContext *mResourcesValidContext;
CFRef<CFDataRef> mDir; CFRef<CFDataRef> mSignature; CFAbsoluteTime mSigningTime; CFAbsoluteTime mSigningTimestamp; CFRef<CFDataRef> mCache[cdSlotCount];
CFRef<CFDictionaryRef> mInfoDict; CFRef<CFDictionaryRef> mEntitlements; CFRef<CFDictionaryRef> mResourceDict; const Requirement *mDesignatedReq; CFRef<CFDataRef> mCDHash;
bool mGotResourceBase; CFRef<CFURLRef> mResourceBase;
CFRef<SecTrustRef> mTrust; CFRef<CFArrayRef> mCertChain;
CSSM_TP_APPLE_EVIDENCE_INFO *mEvalDetails;
};
class SecStaticCode::AllArchitectures : public SecPointer<SecStaticCode> {
public:
AllArchitectures(SecStaticCode *code);
SecStaticCode *operator () ();
private:
SecPointer<SecStaticCode> mBase;
enum { fatBinary, firstNonFat, atEnd } mState;
Universal::Architectures mArchitectures;
Universal::Architectures::const_iterator mCurrent;
};
} }
#endif // !_H_STATICCODE