X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/90dc47c27df1983f6ebc252b0c4b94c8718fe52d..refs/heads/master:/OSX/libsecurity_codesigning/lib/machorep.cpp diff --git a/OSX/libsecurity_codesigning/lib/machorep.cpp b/OSX/libsecurity_codesigning/lib/machorep.cpp index 6986c725..157e6e7a 100644 --- a/OSX/libsecurity_codesigning/lib/machorep.cpp +++ b/OSX/libsecurity_codesigning/lib/machorep.cpp @@ -25,6 +25,7 @@ // machorep - DiskRep mix-in for handling Mach-O main executables // #include "machorep.h" +#include "notarization.h" #include "StaticCode.h" #include "reqmaker.h" #include @@ -53,7 +54,7 @@ MachORep::MachORep(const char *path, const Context *ctx) if (ctx->offset) mExecutable = new Universal(fd(), (size_t)ctx->offset, ctx->size); else if (ctx->arch) { - auto_ptr full(new Universal(fd())); + unique_ptr full(new Universal(fd())); mExecutable = new Universal(fd(), full->archOffset(ctx->arch), full->archLength(ctx->arch)); } else mExecutable = new Universal(fd()); @@ -109,7 +110,7 @@ Universal *MachORep::mainExecutableImage() void MachORep::prepareForSigning(SigningContext &context) { if (context.digestAlgorithms().empty()) { - auto_ptr macho(mainExecutableImage()->architecture()); + unique_ptr macho(mainExecutableImage()->architecture()); uint32_t limit = 0; switch (macho->platform()) { @@ -150,19 +151,22 @@ size_t MachORep::signingBase() size_t MachORep::signingLimit() { - auto_ptr macho(mExecutable->architecture()); + unique_ptr 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(arch ? mExecutable->architecture(*arch) : mExecutable->architecture()); + unique_ptr macho(arch ? mExecutable->architecture(*arch) : mExecutable->architecture()); if (!needsExecSeg(*macho)) { return 0; @@ -187,7 +191,7 @@ size_t MachORep::execSegBase(const Architecture *arch) size_t MachORep::execSegLimit(const Architecture *arch) { - auto_ptr macho(arch ? mExecutable->architecture(*arch) : mExecutable->architecture()); + unique_ptr macho(arch ? mExecutable->architecture(*arch) : mExecutable->architecture()); if (!needsExecSeg(*macho)) { return 0; @@ -218,7 +222,7 @@ size_t MachORep::execSegLimit(const Architecture *arch) // CFDataRef MachORep::identification() { - std::auto_ptr macho(mainExecutableImage()->architecture()); + std::unique_ptr macho(mainExecutableImage()->architecture()); return identificationFor(macho.get()); } @@ -265,6 +269,27 @@ CFDataRef MachORep::component(CodeDirectory::SpecialSlot slot) } } +// +// 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, @@ -275,29 +300,37 @@ CFDataRef MachORep::component(CodeDirectory::SpecialSlot slot) // 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(mainExecutableImage()->architecture()); + unique_ptr 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; } @@ -309,7 +342,7 @@ CFDataRef MachORep::infoPlist() { CFRef info; try { - auto_ptr macho(mainExecutableImage()->architecture()); + unique_ptr macho(mainExecutableImage()->architecture()); if (const section *sect = macho->findSection("__TEXT", "__info_plist")) { if (macho->is64()) { const section_64 *sect64 = reinterpret_cast(sect); @@ -368,7 +401,7 @@ void MachORep::flush() CFDictionaryRef MachORep::diskRepInformation() { - auto_ptr macho (mainExecutableImage()->architecture()); + unique_ptr macho (mainExecutableImage()->architecture()); CFRef info; uint32_t platform = 0; @@ -446,7 +479,7 @@ const Requirements *MachORep::defaultRequirements(const Architecture *arch, cons Requirement *MachORep::libraryRequirements(const Architecture *arch, const SigningContext &ctx) { - auto_ptr macho(mainExecutableImage()->architecture(*arch)); + unique_ptr macho(mainExecutableImage()->architecture(*arch)); Requirement::Maker maker; Requirement::Maker::Chain chain(maker, opOr); @@ -541,6 +574,14 @@ void MachORep::Writer::component(CodeDirectory::SpecialSlot slot, CFDataRef data MacOSError::throwMe(errSecCSInternalError); } +void MachORep::registerStapledTicket() +{ + CFRef data = NULL; + if (mSigningData) { + data.take(mSigningData->component(cdTicketSlot)); + registerStapledTicketInMachO(data); + } +} } // end namespace CodeSigning } // end namespace Security