// machorep - DiskRep mix-in for handling Mach-O main executables
//
#include "machorep.h"
+#include "notarization.h"
#include "StaticCode.h"
#include "reqmaker.h"
#include <security_utilities/logging.h>
if (ctx->offset)
mExecutable = new Universal(fd(), (size_t)ctx->offset, ctx->size);
else if (ctx->arch) {
- auto_ptr<Universal> full(new Universal(fd()));
+ unique_ptr<Universal> full(new Universal(fd()));
mExecutable = new Universal(fd(), full->archOffset(ctx->arch), full->archLength(ctx->arch));
} else
mExecutable = new Universal(fd());
void MachORep::prepareForSigning(SigningContext &context)
{
if (context.digestAlgorithms().empty()) {
- auto_ptr<MachO> macho(mainExecutableImage()->architecture());
+ unique_ptr<MachO> macho(mainExecutableImage()->architecture());
uint32_t limit = 0;
switch (macho->platform()) {
size_t MachORep::signingLimit()
{
- auto_ptr<MachO> macho(mExecutable->architecture());
+ unique_ptr<MachO> macho(mExecutable->architecture());
return macho->signingExtent();
}
bool MachORep::needsExecSeg(const MachO& macho) {
uint32_t platform = macho.platform();
- // Everything embedded gets an exec segment.
- return platform != 0 && platform != PLATFORM_MACOS;
+
+ // Everything gets an exec segment. This is ignored
+ // on non-PPL devices, and explicitly wastes some
+ // space on those devices, but is simpler logic.
+ return platform != 0;
}
size_t MachORep::execSegBase(const Architecture *arch)
{
- auto_ptr<MachO> macho(arch ? mExecutable->architecture(*arch) : mExecutable->architecture());
+ unique_ptr<MachO> macho(arch ? mExecutable->architecture(*arch) : mExecutable->architecture());
if (!needsExecSeg(*macho)) {
return 0;
size_t MachORep::execSegLimit(const Architecture *arch)
{
- auto_ptr<MachO> macho(arch ? mExecutable->architecture(*arch) : mExecutable->architecture());
+ unique_ptr<MachO> macho(arch ? mExecutable->architecture(*arch) : mExecutable->architecture());
if (!needsExecSeg(*macho)) {
return 0;
//
CFDataRef MachORep::identification()
{
- std::auto_ptr<MachO> macho(mainExecutableImage()->architecture());
+ std::unique_ptr<MachO> macho(mainExecutableImage()->architecture());
return identificationFor(macho.get());
}
}
}
+//
+// Retrieve all components, used for signature editing.
+//
+EditableDiskRep::RawComponentMap MachORep::createRawComponents()
+{
+ EditableDiskRep::RawComponentMap blobMap;
+
+ // First call to signingData() caches the result, so this
+ // _should_ not cause performance issues.
+ if (NULL == signingData()) {
+ MacOSError::throwMe(errSecCSUnsigned);
+ }
+ const EmbeddedSignatureBlob &blobs = *signingData();
+
+ for (unsigned int i = 0; i < blobs.count(); ++i) {
+ CodeDirectory::Slot slot = blobs.type(i);
+ const BlobCore *blob = blobs.blob(i);
+ blobMap[slot] = blobs.blobData(slot, blob);
+ }
+ return blobMap;
+}
// Retrieve a component from the embedded signature SuperBlob (if present).
// This reads the entire signing SuperBlob when first called for an executable,
// calls wouldn't be slower in the end.
//
CFDataRef MachORep::embeddedComponent(CodeDirectory::SpecialSlot slot)
+{
+ if (signingData()) {
+ return signingData()->component(slot);
+ }
+
+ // not found
+ return NULL;
+}
+
+
+
+EmbeddedSignatureBlob *MachORep::signingData()
{
if (!mSigningData) { // fetch and cache
- auto_ptr<MachO> macho(mainExecutableImage()->architecture());
+ unique_ptr<MachO> macho(mainExecutableImage()->architecture());
if (macho.get())
if (const linkedit_data_command *cs = macho->findCodeSignature()) {
size_t offset = macho->flip(cs->dataoff);
size_t length = macho->flip(cs->datasize);
if ((mSigningData = EmbeddedSignatureBlob::readBlob(macho->fd(), macho->offset() + offset, length))) {
secinfo("machorep", "%zd signing bytes in %d blob(s) from %s(%s)",
- mSigningData->length(), mSigningData->count(),
- mainExecutablePath().c_str(), macho->architecture().name());
+ mSigningData->length(), mSigningData->count(),
+ mainExecutablePath().c_str(), macho->architecture().name());
} else {
secinfo("machorep", "failed to read signing bytes from %s(%s)",
- mainExecutablePath().c_str(), macho->architecture().name());
+ mainExecutablePath().c_str(), macho->architecture().name());
MacOSError::throwMe(errSecCSSignatureInvalid);
}
}
}
- if (mSigningData)
- return mSigningData->component(slot);
-
- // not found
- return NULL;
+ return mSigningData;
}
{
CFRef<CFDataRef> info;
try {
- auto_ptr<MachO> macho(mainExecutableImage()->architecture());
+ unique_ptr<MachO> macho(mainExecutableImage()->architecture());
if (const section *sect = macho->findSection("__TEXT", "__info_plist")) {
if (macho->is64()) {
const section_64 *sect64 = reinterpret_cast<const section_64 *>(sect);
CFDictionaryRef MachORep::diskRepInformation()
{
- auto_ptr<MachO> macho (mainExecutableImage()->architecture());
+ unique_ptr<MachO> macho (mainExecutableImage()->architecture());
CFRef<CFDictionaryRef> info;
uint32_t platform = 0;
Requirement *MachORep::libraryRequirements(const Architecture *arch, const SigningContext &ctx)
{
- auto_ptr<MachO> macho(mainExecutableImage()->architecture(*arch));
+ unique_ptr<MachO> macho(mainExecutableImage()->architecture(*arch));
Requirement::Maker maker;
Requirement::Maker::Chain chain(maker, opOr);
MacOSError::throwMe(errSecCSInternalError);
}
+void MachORep::registerStapledTicket()
+{
+ CFRef<CFDataRef> data = NULL;
+ if (mSigningData) {
+ data.take(mSigningData->component(cdTicketSlot));
+ registerStapledTicketInMachO(data);
+ }
+}
} // end namespace CodeSigning
} // end namespace Security