TrustedApplication.cpp [plain text]
#include <security_keychain/TrustedApplication.h>
#include <security_keychain/ACL.h>
#include <security_utilities/osxcode.h>
#include <security_utilities/trackingallocator.h>
#include <security_cdsa_utilities/acl_codesigning.h>
#include <sys/syslimits.h>
#include <memory>
using namespace KeychainCore;
TrustedApplication::TrustedApplication(const TypedList &subject)
{
try {
CodeSignatureAclSubject::Maker maker;
mForm = maker.make(subject);
secdebug("trustedapp", "%p created from list form", this);
IFDUMPING("codesign", mForm->AclSubject::dump("STApp created from list"));
} catch (...) {
throw ACL::ParseError();
}
}
TrustedApplication::TrustedApplication(const std::string &path)
{
RefPointer<OSXCode> code(OSXCode::at(path));
mForm = new CodeSignatureAclSubject(OSXVerifier(code));
secdebug("trustedapp", "%p created from path %s", this, path.c_str());
IFDUMPING("codesign", mForm->AclSubject::dump("STApp created from path"));
}
TrustedApplication::TrustedApplication()
{
RefPointer<OSXCode> me(OSXCode::main());
mForm = new CodeSignatureAclSubject(OSXVerifier(me));
secdebug("trustedapp", "%p created from self", this);
IFDUMPING("codesign", mForm->AclSubject::dump("STApp created from self"));
}
TrustedApplication::TrustedApplication(const std::string &path, SecRequirementRef reqRef)
{
CFRef<CFDataRef> reqData;
MacOSError::check(SecRequirementCopyData(reqRef, kSecCSDefaultFlags, &reqData.aref()));
mForm = new CodeSignatureAclSubject(NULL, path);
mForm->add((const BlobCore *)CFDataGetBytePtr(reqData));
secdebug("trustedapp", "%p created from path %s and requirement %p",
this, path.c_str(), reqRef);
IFDUMPING("codesign", mForm->debugDump());
}
TrustedApplication::~TrustedApplication()
{ }
TrustedApplication::TrustedApplication(CFDataRef external)
{
AclSubject::Reader pubReader(CFDataGetBytePtr(external)), privReader;
mForm = CodeSignatureAclSubject::Maker().make(0, pubReader, privReader);
}
CFDataRef TrustedApplication::externalForm() const
{
AclSubject::Writer::Counter pubCounter, privCounter;
mForm->exportBlob(pubCounter, privCounter);
if (privCounter > 0) CssmError::throwMe(CSSMERR_CSSM_INTERNAL_ERROR);
CFRef<CFMutableDataRef> data = CFDataCreateMutable(NULL, pubCounter);
CFDataSetLength(data, pubCounter);
if (CFDataGetLength(data) < CFIndex(pubCounter))
CFError::throwMe();
AclSubject::Writer pubWriter(CFDataGetMutableBytePtr(data)), privWriter;
mForm->exportBlob(pubWriter, privWriter);
return data.yield();
}
void TrustedApplication::data(CFDataRef data)
{
const char *p = (const char *)CFDataGetBytePtr(data);
const std::string path(p, p + CFDataGetLength(data));
RefPointer<OSXCode> code(OSXCode::at(path));
mForm = new CodeSignatureAclSubject(OSXVerifier(code));
}
bool TrustedApplication::verifyToDisk(const char *path)
{
if (SecRequirementRef requirement = mForm->requirement()) {
secdebug("trustedapp", "%p validating requirement against path %s", this, path);
CFRef<SecStaticCodeRef> ondisk;
if (path)
MacOSError::check(SecStaticCodeCreateWithPath(CFTempURL(path),
kSecCSDefaultFlags, &ondisk.aref()));
else
MacOSError::check(SecCodeCopySelf(kSecCSDefaultFlags, (SecCodeRef *)&ondisk.aref()));
return SecStaticCodeCheckValidity(ondisk, kSecCSDefaultFlags, requirement) == errSecSuccess;
} else {
secdebug("trustedapp", "%p validating hash against path %s", this, path);
RefPointer<OSXCode> code = path ? OSXCode::at(path) : OSXCode::main();
SHA1::Digest ondiskDigest;
OSXVerifier::makeLegacyHash(code, ondiskDigest);
return memcmp(ondiskDigest, mForm->legacyHash(), sizeof(ondiskDigest)) == 0;
}
}
CssmList TrustedApplication::makeSubject(Allocator &allocator)
{
return mForm->toList(allocator);
}