TrustedApplication.cpp [plain text]
#include <Security/TrustedApplication.h>
#include <Security/ACL.h>
#include <Security/osxsigning.h>
#include <Security/osxsigner.h>
#include <Security/trackingallocator.h>
#include <sys/syslimits.h>
#include <memory>
using namespace KeychainCore;
using namespace CodeSigning;
TrustedApplication::TrustedApplication(const TypedList &subject)
: mSignature(CssmAllocator::standard()),
mData(CssmAllocator::standard())
{
if (subject.type() != CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE)
throw ACL::ParseError();
if (subject[1] != CSSM_ACL_CODE_SIGNATURE_OSX)
throw ACL::ParseError();
mSignature = subject[2].data();
mData = subject[3].data();
}
TrustedApplication::TrustedApplication(const CssmData &signature, const CssmData &data) :
mSignature(CssmAllocator::standard(), signature),
mData(CssmAllocator::standard(), data)
{
}
TrustedApplication::TrustedApplication(const char *path)
: mSignature(CssmAllocator::standard()),
mData(CssmAllocator::standard())
{
OSXSigner signer;
RefPointer<OSXCode> object(OSXCode::at(path));
auto_ptr<OSXSigner::OSXSignature> signature(signer.sign(*object));
mSignature = *signature;
string basePath = object->canonicalPath();
mData = CssmData(const_cast<char *>(basePath.c_str()), basePath.length() + 1);
}
TrustedApplication::TrustedApplication()
: mSignature(CssmAllocator::standard()),
mData(CssmAllocator::standard())
{
OSXSigner signer;
RefPointer<OSXCode> object(OSXCode::main());
auto_ptr<OSXSigner::OSXSignature> signature(signer.sign(*object));
mSignature = *signature;
string path = object->canonicalPath();
mData.copy(path.c_str(), path.length() + 1); }
TrustedApplication::~TrustedApplication() throw()
{
}
const CssmData &
TrustedApplication::signature() const
{
return mSignature;
}
const char *
TrustedApplication::path() const
{
if (mData)
return mData.get().interpretedAs<const char>();
else
return NULL;
}
bool
TrustedApplication::sameSignature(const char *path)
{
CssmAutoData otherSignature(CssmAllocator::standard());
calcSignature(path, otherSignature);
return (mSignature.get() == otherSignature);
}
void
TrustedApplication::calcSignature(const char *path, CssmOwnedData &signature)
{
RefPointer<CodeSigning::OSXCode> objToVerify(CodeSigning::OSXCode::at(path));
CodeSigning::OSXSigner signer;
auto_ptr<CodeSigning::OSXSigner::OSXSignature> osxSignature(signer.sign(*objToVerify));
signature.copy(osxSignature->data(), osxSignature->length());
}
TypedList TrustedApplication::makeSubject(CssmAllocator &allocator)
{
return TypedList(allocator,
CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE,
new(allocator) ListElement(CSSM_ACL_CODE_SIGNATURE_OSX),
new(allocator) ListElement(allocator, mSignature.get()),
new(allocator) ListElement(allocator, mData.get()));
}
PathDatabase::PathDatabase(const char *path)
{
if (FILE *f = fopen(path, "r")) {
mQualifyAll = false;
char path[PATH_MAX+1];
while (fgets(path, sizeof(path), f)) {
path[strlen(path)-1] = '\0'; mPaths.insert(path);
}
fclose(f);
secdebug("equivdb", "read %ld paths from %s", mPaths.size(), path);
} else {
mQualifyAll = true;
secdebug("equivdb", "cannot open %s, will qualify all application paths", path);
}
}
bool PathDatabase::lookup(const string &path)
{
string::size_type lastSlash = path.rfind('/');
string::size_type bundleCore = path.find("/Contents/MacOS/");
if (lastSlash != string::npos && bundleCore != string::npos)
if (bundleCore + 15 == lastSlash)
path = path.substr(0, bundleCore);
return mPaths.find(path) != mPaths.end();
}