X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b54c578e17e9bcbd74aa30ea75e25e955b9a6205..refs/heads/master:/OSX/libsecurity_codesigning/lib/signer.cpp?ds=inline diff --git a/OSX/libsecurity_codesigning/lib/signer.cpp b/OSX/libsecurity_codesigning/lib/signer.cpp index 89279238..576459c8 100644 --- a/OSX/libsecurity_codesigning/lib/signer.cpp +++ b/OSX/libsecurity_codesigning/lib/signer.cpp @@ -143,12 +143,17 @@ void SecCodeSigner::Signer::prepare(SecCSFlags flags) if (CFRef infoData = rep->component(cdInfoSlot)) infoDict.take(makeCFDictionaryFrom(infoData)); - uint32_t inherit = code->isSigned() ? state.mPreserveMetadata : 0; + uint32_t inherit = 0; + + if (code->isSigned() && (code->codeDirectory(false)->flags & kSecCodeSignatureLinkerSigned) == 0) { + inherit = state.mPreserveMetadata; + } // work out the canonical identifier identifier = state.mIdentifier; - if (identifier.empty() && (inherit & kSecCodeSignerPreserveIdentifier)) + if (identifier.empty() && (inherit & kSecCodeSignerPreserveIdentifier)) { identifier = code->identifier(); + } if (identifier.empty()) { identifier = rep->recommendedIdentifier(*this); if (identifier.find('.') == string::npos) @@ -174,8 +179,6 @@ void SecCodeSigner::Signer::prepare(SecCSFlags flags) entitlements = state.mEntitlementData; if (!entitlements && (inherit & kSecCodeSignerPreserveEntitlements)) entitlements = code->component(cdEntitlementSlot); - - generateEntitlementDER = signingFlags() & kSecCSSignGenerateEntitlementDER; // work out the CodeDirectory flags word bool haveCdFlags = false; @@ -409,12 +412,12 @@ void SecCodeSigner::Signer::buildResources(std::string root, std::string relBase if (!(signingFlags() & kSecCSSignV1)) { CFCopyRef rules2 = cfget(rulesDict, "rules2"); if (!rules2) { - // Clone V1 rules and add default nesting rules at weight 0 (overridden by anything in rules, - // because the default weight, according to ResourceBuilder::addRule(), is 1). + // Clone V1 rules and add default nesting rules at weight 0 (overridden by anything in rules, + // because the default weight, according to ResourceBuilder::addRule(), is 1). // V1 rules typically do not cover these places so we'll prevail, but if they do, we defer to them. - rules2 = cfmake("{+%O" + rules2.take(cfmake("{+%O" "'^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/' = {nested=#T, weight=0}" // exclude dynamic repositories - "}", rules); + "}", rules)); } Dispatch::Group group; @@ -429,11 +432,12 @@ void SecCodeSigner::Signer::buildResources(std::string root, std::string relBase resources.scan(^(FTSENT *ent, uint32_t ruleFlags, const std::string relpath, Rule *rule) { bool isSymlink = (ent->fts_info == FTS_SL); + bool isNested = (ruleFlags & ResourceBuilder::nested); const std::string path(ent->fts_path); const std::string accpath(ent->fts_accpath); this->state.mLimitedAsync->perform(groupRef, ^{ CFRef seal; - if (ruleFlags & ResourceBuilder::nested) { + if (isNested) { seal.take(signNested(path, relpath)); } else if (isSymlink) { char target[PATH_MAX]; @@ -445,6 +449,10 @@ void SecCodeSigner::Signer::buildResources(std::string root, std::string relBase } else { seal.take(resources.hashFile(accpath.c_str(), digestAlgorithms(), signingFlags() & kSecCSSignStrictPreflight)); } + if (seal.get() == NULL) { + secerror("Failed to generate sealed resource: %d, %d, %s", isNested, isSymlink, accpath.c_str()); + MacOSError::throwMe(errSecCSBadResource); + } if (ruleFlags & ResourceBuilder::optional) CFDictionaryAddValue(seal, CFSTR("optional"), kCFBooleanTrue); CFTypeRef hash; @@ -535,7 +543,7 @@ void SecCodeSigner::Signer::signMachO(Universal *fat, const Requirement::Context if (state.mPreserveAFSC) writer->setPreserveAFSC(state.mPreserveAFSC); - auto_ptr editor(state.mDetached + unique_ptr editor(state.mDetached ? static_cast(new BlobEditor(*fat, *this)) : new MachOEditor(writer, *fat, this->digestAlgorithms(), rep->mainExecutablePath())); assert(editor->count() > 0); @@ -553,6 +561,22 @@ void SecCodeSigner::Signer::signMachO(Universal *fat, const Requirement::Context MacOSError::throwMe(errSecCSBadLVArch); } } + + bool generateEntitlementDER = false; + if (signingFlags() & kSecCSSignGenerateEntitlementDER) { + generateEntitlementDER = true; + } else { + uint32_t platform = arch.source->platform(); + switch (platform) { + case PLATFORM_WATCHOS: + case PLATFORM_BRIDGEOS: + generateEntitlementDER = false; + break; + default: + generateEntitlementDER = true; + break; + } + } bool mainBinary = arch.source.get()->type() == MH_EXECUTE; @@ -576,7 +600,7 @@ void SecCodeSigner::Signer::signMachO(Universal *fat, const Requirement::Context arch.source->offset(), arch.source->signingExtent(), mainBinary, rep->execSegBase(&(arch.architecture)), rep->execSegLimit(&(arch.architecture)), unsigned(digestAlgorithms().size()-1), - preEncryptHashMaps[arch.architecture], runtimeVersionToUse); + preEncryptHashMaps[arch.architecture], runtimeVersionToUse, generateEntitlementDER); }); } @@ -655,7 +679,8 @@ void SecCodeSigner::Signer::signArchitectureAgnostic(const Requirement::Context rep->execSegBase(NULL), rep->execSegLimit(NULL), unsigned(digestAlgorithms().size()-1), preEncryptHashMaps[preEncryptMainArch], // Only one map, the default. - (cdFlags & kSecCodeSignatureRuntime) ? state.mRuntimeVersionOverride : 0); + (cdFlags & kSecCodeSignatureRuntime) ? state.mRuntimeVersionOverride : 0, + signingFlags() & kSecCSSignGenerateEntitlementDER); CodeDirectory *cd = builder.build(); if (!state.mDryRun) @@ -703,7 +728,7 @@ void SecCodeSigner::Signer::populate(CodeDirectory::Builder &builder, DiskRep::W bool mainBinary, size_t execSegBase, size_t execSegLimit, unsigned alternateDigestCount, PreEncryptHashMap const &preEncryptHashMap, - uint32_t runtimeVersion) + uint32_t runtimeVersion, bool generateEntitlementDER) { // fill the CodeDirectory builder.executable(rep->mainExecutablePath(), pagesize, offset, length);