#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(errSecSuccess) { }
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; }
bool isDetached() const { return mRep->base() != mRep; }
std::string mainExecutablePath() { return mRep->mainExecutablePath(); }
CFURLRef canonicalPath() const { return mRep->canonicalPath(); }
std::string identifier() { return codeDirectory()->identifier(); }
const char *teamID() { return codeDirectory()->teamID(); }
std::string format() const { return mRep->format(); }
std::string signatureSource();
virtual CFDataRef component(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
virtual CFDictionaryRef infoDictionary();
CFDictionaryRef entitlements();
CFDictionaryRef resourceDictionary(bool check = true);
CFURLRef resourceBase();
CFDataRef resource(std::string path);
CFDataRef resource(std::string path, ValidationContext &ctx);
void validateResource(CFDictionaryRef files, std::string path, ValidationContext &ctx, SecCSFlags flags, uint32_t version);
bool flag(uint32_t tested);
SecCodeCallback monitor() const { return mMonitor; }
void setMonitor(SecCodeCallback monitor) { mMonitor = monitor; }
CFTypeRef reportEvent(CFStringRef stage, CFDictionaryRef info);
void resetValidity();
bool validated() const { return mValidated; }
bool valid() const
{ assert(validated()); return mValidated && (mValidationResult == errSecSuccess); }
bool validatedExecutable() const { return mExecutableValidated; }
bool validatedResources() const { return mResourcesValidated; }
void validateDirectory();
virtual void validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
void validateNonResourceComponents();
void validateResources(SecCSFlags flags);
void validateExecutable();
void validateNestedCode(CFURLRef path, const ResourceSeal &seal, SecCSFlags flags);
const Requirements *internalRequirements();
const Requirement *internalRequirement(SecRequirementType type);
const Requirement *designatedRequirement();
const Requirement *defaultDesignatedRequirement();
void validateRequirements(SecRequirementType type, SecStaticCode *target,
OSStatus nullError = errSecSuccess); void validateRequirement(const Requirement *req, OSStatus failure); bool satisfiesRequirement(const Requirement *req, OSStatus failure);
SecCertificateRef cert(int ix); CFArrayRef certificates();
CFDictionaryRef signingInformation(SecCSFlags flags);
static bool isAppleDeveloperCert(CFArrayRef certs);
public:
void staticValidate(SecCSFlags flags, const SecRequirement *req);
void staticValidateCore(SecCSFlags flags, const SecRequirement *req);
protected:
CFDictionaryRef getDictionary(CodeDirectory::SpecialSlot slot, bool check = true); bool verifySignature();
CFTypeRef verificationPolicy(SecCSFlags flags);
static void checkOptionalResource(CFTypeRef key, CFTypeRef value, void *context);
void handleOtherArchitectures(void (^handle)(SecStaticCode* other));
private:
RefPointer<DiskRep> mRep; CFRef<CFDataRef> mDetachedSig;
bool mValidated; OSStatus mValidationResult; bool mValidationExpired;
bool mExecutableValidated; OSStatus mExecutableValidResult;
bool mResourcesValidated; bool mResourcesDeep; 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;
SecCodeCallback mMonitor;
CFRef<SecTrustRef> mTrust; CFRef<CFArrayRef> mCertChain;
CSSM_TP_APPLE_EVIDENCE_INFO *mEvalDetails;
};
} }
#endif // !_H_STATICCODE