#include "cs.h"
#include "StaticCode.h"
#include <fcntl.h>
using namespace CodeSigning;
CFTypeID SecStaticCodeGetTypeID(void)
{
BEGIN_CSAPI
return gCFObjects().StaticCode.typeID;
END_CSAPI1(_kCFRuntimeNotATypeID)
}
OSStatus SecStaticCodeCreateWithPath(CFURLRef path, SecCSFlags flags, SecStaticCodeRef *staticCodeRef)
{
BEGIN_CSAPI
checkFlags(flags);
Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str())))->handle();
END_CSAPI
}
OSStatus SecStaticCodeCheckValidity(SecStaticCodeRef staticCodeRef, SecCSFlags flags,
SecRequirementRef requirementRef)
{
return SecStaticCodeCheckValidityWithErrors(staticCodeRef, flags, requirementRef, NULL);
}
OSStatus SecStaticCodeCheckValidityWithErrors(SecStaticCodeRef staticCodeRef, SecCSFlags flags,
SecRequirementRef requirementRef, CFErrorRef *errors)
{
BEGIN_CSAPI
checkFlags(flags,
kSecCSCheckAllArchitectures
| kSecCSDoNotValidateExecutable
| kSecCSDoNotValidateResources
| kSecCSConsiderExpiration);
SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(staticCodeRef);
DTRACK(CODESIGN_EVAL_STATIC, code, (char*)code->mainExecutablePath().c_str());
code->validateDirectory();
if (!(flags & kSecCSDoNotValidateExecutable))
code->validateExecutable();
if (!(flags & kSecCSDoNotValidateResources))
code->validateResources();
if (const SecRequirement *req = SecRequirement::optional(requirementRef))
code->validateRequirements(req->requirement(), errSecCSReqFailed);
END_CSAPI_ERRORS
}
OSStatus SecCodeCopyPath(SecStaticCodeRef staticCodeRef, SecCSFlags flags, CFURLRef *path)
{
BEGIN_CSAPI
checkFlags(flags);
SecPointer<SecStaticCode> staticCode = SecStaticCode::requiredStatic(staticCodeRef);
Required(path) = staticCode->canonicalPath();
END_CSAPI
}
OSStatus SecCodeCopyDesignatedRequirement(SecStaticCodeRef staticCodeRef, SecCSFlags flags,
SecRequirementRef *requirementRef)
{
BEGIN_CSAPI
checkFlags(flags);
const Requirement *req =
SecStaticCode::requiredStatic(staticCodeRef)->designatedRequirement();
Required(requirementRef) = (new SecRequirement(req))->handle();
END_CSAPI
}
OSStatus SecCodeCopyInternalRequirement(SecStaticCodeRef staticCodeRef, SecRequirementType type,
SecCSFlags flags, SecRequirementRef *requirementRef)
{
BEGIN_CSAPI
checkFlags(flags);
const Requirement *req =
SecStaticCode::requiredStatic(staticCodeRef)->internalRequirement(type);
Required(requirementRef) = req ? (new SecRequirement(req))->handle() : NULL;
END_CSAPI
}
OSStatus SecCodeSetDetachedSignature(SecStaticCodeRef codeRef, CFDataRef signature,
SecCSFlags flags)
{
BEGIN_CSAPI
checkFlags(flags);
SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
if (signature)
CFRetain(signature); code->detachedSignature(signature); code->resetValidity();
END_CSAPI
}
OSStatus SecCodeMapMemory(SecStaticCodeRef codeRef, SecCSFlags flags)
{
BEGIN_CSAPI
checkFlags(flags);
SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
if (const CodeDirectory *cd = code->codeDirectory(false)) {
fsignatures args = { code->diskRep()->signingBase(), (void *)cd, cd->length() };
UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDSIGS, &args));
} else
MacOSError::throwMe(errSecCSUnsigned);
END_CSAPI
}