#ifndef _H_STATICCODE
#define _H_STATICCODE
#include "cs.h"
#include "csutilities.h"
#include "Requirements.h"
#include "requirement.h"
#include "diskrep.h"
#include "codedirectory.h"
#include <Security/SecTrust.h>
#include <CoreFoundation/CFData.h>
#include <security_utilities/dispatch.h>
namespace Security {
namespace CodeSigning {
class SecCode;
class SecStaticCode : public SecCFObject {
NOCOPY(SecStaticCode)
protected:
class ValidationContext {
public:
ValidationContext(SecStaticCode &c) : code(c) { }
virtual ~ValidationContext();
virtual void reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value);
virtual OSStatus osStatus() { return noErr; }
virtual void throwMe() { }
SecStaticCode &code;
};
class CollectingContext : public ValidationContext {
public:
CollectingContext(SecStaticCode &c) : ValidationContext(c), mStatus(errSecSuccess) { }
void reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value);
OSStatus osStatus() { return mStatus; }
operator OSStatus () const { return mStatus; }
void throwMe() __attribute__((noreturn));
private:
CFRef<CFMutableDictionaryRef> mCollection;
OSStatus mStatus;
Mutex mLock;
};
public:
SECCFFUNCTIONS(SecStaticCode, SecStaticCodeRef,
errSecCSInvalidObjectRef, gCFObjects().StaticCode)
static SecStaticCode *requiredStatic(SecStaticCodeRef ref); static SecCode *optionalDynamic(SecStaticCodeRef ref);
SecStaticCode(DiskRep *rep);
virtual ~SecStaticCode() throw();
void initializeFromParent(const SecStaticCode& parent);
bool equal(SecCFObject &other);
CFHashCode hash();
void detachedSignature(CFDataRef sig); void checkForSystemSignature();
const CodeDirectory *codeDirectory(bool check = true) const;
CodeDirectory::HashAlgorithm hashAlgorithm() const { return codeDirectory()->hashType; }
CodeDirectory::HashAlgorithms hashAlgorithms() const { return mHashAlgorithms; }
CFDataRef cdHash();
CFArrayRef cdHashes();
CFDataRef signature();
CFAbsoluteTime signingTime();
CFAbsoluteTime signingTimestamp();
bool isSigned() { return codeDirectory(false) != NULL; }
DiskRep *diskRep() const { return mRep; }
bool isDetached() const { return mRep->base() != mRep; }
std::string mainExecutablePath() { return mRep->mainExecutablePath(); }
CFURLRef copyCanonicalPath() const { return mRep->copyCanonicalPath(); }
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 diskRepInformation();
CFDictionaryRef entitlements();
CFDataRef copyComponent(CodeDirectory::SpecialSlot slot, CFDataRef hash);
CFDictionaryRef resourceDictionary(bool check = true);
CFURLRef resourceBase();
void validateResource(CFDictionaryRef files, std::string path, bool isSymlink, ValidationContext &ctx, SecCSFlags flags, uint32_t version);
void validateSymlinkResource(std::string fullpath, std::string seal, ValidationContext &ctx, SecCSFlags flags);
bool flag(uint32_t tested);
SecCodeCallback monitor() const { return mMonitor; }
void setMonitor(SecCodeCallback monitor) { mMonitor = monitor; }
CFTypeRef reportEvent(CFStringRef stage, CFDictionaryRef info);
void reportProgress(unsigned amount = 1);
void setValidationFlags(SecCSFlags flags) { mValidationFlags = flags; }
void setValidationModifiers(CFDictionaryRef modifiers);
void resetValidity();
bool validated() const { return mValidated; }
bool revocationChecked() const { return mRevocationChecked; }
bool valid() const
{ assert(validated()); return mValidated && (mValidationResult == errSecSuccess); }
bool validatedExecutable() const { return mExecutableValidated; }
bool validatedResources() const { return mResourcesValidated; }
void prepareProgress(unsigned workload);
void cancelValidation();
void validateDirectory();
virtual void validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
void validateNonResourceComponents();
void validateTopDirectory();
unsigned estimateResourceWorkload();
void validateResources(SecCSFlags flags);
void validateExecutable();
void validateNestedCode(CFURLRef path, const ResourceSeal &seal, SecCSFlags flags, bool isFramework);
void validatePlainMemoryResource(string path, CFDataRef fileData, 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); #if !TARGET_OS_OSX
bool trustedSigningCertChain() { return mTrustedSigningCertChain; }
#endif
public:
void staticValidate(SecCSFlags flags, const SecRequirement *req);
void staticValidateCore(SecCSFlags flags, const SecRequirement *req);
protected:
typedef std::map<CodeDirectory::HashAlgorithm, CFCopyRef<CFDataRef> > CodeDirectoryMap;
bool loadCodeDirectories(CodeDirectoryMap& cdMap) const;
protected:
CFDictionaryRef getDictionary(CodeDirectory::SpecialSlot slot, bool check = true); bool verifySignature();
CFArrayRef createVerificationPolicies();
CFArrayRef createTimeStampingAndRevocationPolicies();
bool loadResources(CFDictionaryRef& rules, CFDictionaryRef& files, uint32_t& version);
static void checkOptionalResource(CFTypeRef key, CFTypeRef value, void *context);
bool hasWeakResourceRules(CFDictionaryRef rulesDict, uint32_t version, CFArrayRef allowedOmissions);
void handleOtherArchitectures(void (^handle)(SecStaticCode* other));
private:
void validateOtherVersions(CFURLRef path, SecCSFlags flags, SecRequirementRef req, SecStaticCode *code);
bool checkfix30814861(string path, bool addition);
ResourceBuilder *mCheckfix30814861builder1;
dispatch_once_t mCheckfix30814861builder1_once;
private:
RefPointer<DiskRep> mRep; mutable CodeDirectoryMap mCodeDirectories; mutable CFRef<CFDataRef> mBaseDir; CFRef<CFDataRef> mDetachedSig;
MacOSErrorSet mTolerateErrors; CFRef<CFArrayRef> mAllowOmissions;
bool mValidated; bool mRevocationChecked; OSStatus mValidationResult; bool mValidationExpired;
bool mExecutableValidated; OSStatus mExecutableValidResult;
bool mResourcesValidated; bool mResourcesDeep; OSStatus mResourcesValidResult; ValidationContext *mResourcesValidContext;
SecCSFlags mValidationFlags; unsigned mTotalWork; unsigned mCurrentWork; bool mCancelPending; Dispatch::Queue mProgressQueue;
const SecStaticCode *mOuterScope; ResourceBuilder *mResourceScope;
mutable CFRef<CFDataRef> mDir; mutable CodeDirectory::HashAlgorithms mHashAlgorithms; 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; CFRef<CFArrayRef> mCDHashes;
bool mGotResourceBase; CFRef<CFURLRef> mResourceBase;
SecCodeCallback mMonitor;
LimitedAsync *mLimitedAsync;
CFRef<SecTrustRef> mTrust; CFRef<CFArrayRef> mCertChain;
#if TARGET_OS_OSX
CSSM_TP_APPLE_EVIDENCE_INFO *mEvalDetails;
#else
bool mTrustedSigningCertChain;
#endif
};
} }
#endif // !_H_STATICCODE