X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/e3d460c9de4426da6c630c3ae3f46173a99f82d8..b04fe171f0375ecd5d8a24747ca1dff85720a0ca:/OSX/libsecurity_codesigning/lib/StaticCode.cpp diff --git a/OSX/libsecurity_codesigning/lib/StaticCode.cpp b/OSX/libsecurity_codesigning/lib/StaticCode.cpp index 0b993cc7..20c6d40a 100644 --- a/OSX/libsecurity_codesigning/lib/StaticCode.cpp +++ b/OSX/libsecurity_codesigning/lib/StaticCode.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -378,11 +379,23 @@ const CodeDirectory *SecStaticCode::codeDirectory(bool check /* = true */) const { if (!mDir) { // pick our favorite CodeDirectory from the choices we've got - CodeDirectoryMap candidates; - if (loadCodeDirectories(candidates)) { - CodeDirectory::HashAlgorithm type = CodeDirectory::bestHashOf(mHashAlgorithms); - mDir = candidates[type]; // and the winner is... - candidates.swap(mCodeDirectories); + try { + CodeDirectoryMap candidates; + if (loadCodeDirectories(candidates)) { + CodeDirectory::HashAlgorithm type = CodeDirectory::bestHashOf(mHashAlgorithms); + mDir = candidates[type]; // and the winner is... + candidates.swap(mCodeDirectories); + } + } catch (...) { + if (check) + throw; + // We wanted a NON-checked peek and failed to safely decode the existing CodeDirectory. + // Pretend this is unsigned, but make sure we didn't somehow cache an invalid CodeDirectory. + if (mDir) { + assert(false); + Syslog::warning("code signing internal problem: mDir set despite exception exit"); + MacOSError::throwMe(errSecCSInternalError); + } } } if (mDir) @@ -400,6 +413,8 @@ const CodeDirectory *SecStaticCode::codeDirectory(bool check /* = true */) const bool SecStaticCode::loadCodeDirectories(CodeDirectoryMap& cdMap) const { __block CodeDirectoryMap candidates; + __block CodeDirectory::HashAlgorithms hashAlgorithms; + __block CFRef baseDir; auto add = ^bool (CodeDirectory::SpecialSlot slot){ CFRef cdData = diskRep()->component(slot); if (!cdData) @@ -410,10 +425,10 @@ bool SecStaticCode::loadCodeDirectories(CodeDirectoryMap& cdMap) const cd->checkIntegrity(); auto result = candidates.insert(make_pair(cd->hashType, cdData.get())); if (!result.second) - MacOSError::throwMe(errSecCSSignatureFailed); // duplicate hashType, go to heck - mHashAlgorithms.insert(cd->hashType); + MacOSError::throwMe(errSecCSSignatureInvalid); // duplicate hashType, go to heck + hashAlgorithms.insert(cd->hashType); if (slot == cdCodeDirectorySlot) - mBaseDir = cdData; + baseDir = cdData; return true; }; if (!add(cdCodeDirectorySlot)) @@ -423,7 +438,10 @@ bool SecStaticCode::loadCodeDirectories(CodeDirectoryMap& cdMap) const break; if (candidates.empty()) MacOSError::throwMe(errSecCSSignatureFailed); // no viable CodeDirectory in sight + // commit to cached values cdMap.swap(candidates); + mHashAlgorithms.swap(hashAlgorithms); + mBaseDir = baseDir; return true; } @@ -504,8 +522,9 @@ void SecStaticCode::validateDirectory() mValidationResult = err.osStatus(); throw; } catch (...) { - secdebug("staticCode", "%p validation threw non-common exception", this); + secinfo("staticCode", "%p validation threw non-common exception", this); mValidated = true; + Syslog::notice("code signing internal problem: unknown exception thrown by validation"); mValidationResult = errSecCSInternalError; throw; } @@ -613,11 +632,12 @@ bool SecStaticCode::verifySignature() MacOSError::check(CMSDecoderSetDetachedContent(cms, mBaseDir)); MacOSError::check(CMSDecoderFinalizeMessage(cms)); MacOSError::check(CMSDecoderSetSearchKeychain(cms, cfEmptyArray())); - CFRef vf_policies = verificationPolicies(); - CFRef ts_policies = SecPolicyCreateAppleTimeStampingAndRevocationPolicies(vf_policies); - CMSSignerStatus status; - MacOSError::check(CMSDecoderCopySignerStatus(cms, 0, vf_policies, - false, &status, &mTrust.aref(), NULL)); + CFRef vf_policies(verificationPolicies()); + CFRef ts_policies(SecPolicyCreateAppleTimeStampingAndRevocationPolicies(vf_policies)); + + CMSSignerStatus status; + MacOSError::check(CMSDecoderCopySignerStatus(cms, 0, vf_policies, + false, &status, &mTrust.aref(), NULL)); if (status != kCMSSignerValid) { const char *reason; @@ -633,7 +653,7 @@ bool SecStaticCode::verifySignature() reason, (int)status); MacOSError::throwMe(errSecCSSignatureFailed); } - + // retrieve auxiliary data bag and verify against current state CFRef hashBag; switch (OSStatus rc = CMSDecoderCopySignerAppleCodesigningHashAgility(cms, 0, &hashBag.aref())) { @@ -678,13 +698,17 @@ bool SecStaticCode::verifySignature() if (mValidationFlags & kSecCSNoNetworkAccess) { MacOSError::check(SecTrustSetNetworkFetchAllowed(mTrust,false)); // no network? } +#if !SECTRUST_OSX MacOSError::check(SecTrustSetKeychains(mTrust, cfEmptyArray())); // no keychains - +#else + MacOSError::check(SecTrustSetKeychainsAllowed(mTrust, false)); +#endif + CSSM_APPLE_TP_ACTION_DATA actionData = { CSSM_APPLE_TP_ACTION_VERSION, // version of data structure 0 // action flags }; - + if (!(mValidationFlags & kSecCSCheckTrustedAnchors)) { /* no need to evaluate anchor trust when building cert chain */ MacOSError::check(SecTrustSetAnchorCertificates(mTrust, cfEmptyArray())); // no anchors @@ -713,12 +737,13 @@ bool SecStaticCode::verifySignature() CFRef teamIDFromCD = CFStringCreateWithCString(NULL, teamID(), kCFStringEncodingUTF8); if (!teamIDFromCD) { Security::Syslog::error("Could not get team identifier (%s)", teamID()); - MacOSError::throwMe(errSecCSInternalError); + MacOSError::throwMe(errSecCSInvalidTeamIdentifier); } if (CFStringCompare(teamIDFromCert, teamIDFromCD, 0) != kCFCompareEqualTo) { - Security::Syslog::error("Team identifier in the signing certificate (%s) does not match the team identifier (%s) in the code directory", cfString(teamIDFromCert).c_str(), teamID()); - MacOSError::throwMe(errSecCSSignatureInvalid); + Security::Syslog::error("Team identifier in the signing certificate (%s) does not match the team identifier (%s) in the code directory", + cfString(teamIDFromCert).c_str(), teamID()); + MacOSError::throwMe(errSecCSBadTeamIdentifier); } } } @@ -784,6 +809,7 @@ bool SecStaticCode::verifySignature() // This may be a simple SecPolicyRef or a CFArray of policies. // The caller owns the return value. // +#if !SECTRUST_OSX static SecPolicyRef makeCRLPolicy() { CFRef policy; @@ -809,23 +835,35 @@ static SecPolicyRef makeOCSPPolicy() MacOSError::check(SecPolicySetValue(policy, &optData)); return policy.yield(); } +#else +static SecPolicyRef makeRevocationPolicy(CFOptionFlags flags) +{ + CFRef policy(SecPolicyCreateRevocation(flags)); + return policy.yield(); +} +#endif CFArrayRef SecStaticCode::verificationPolicies() { CFRef core; MacOSError::check(SecPolicyCopy(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_CODE_SIGNING, &core.aref())); - if (mValidationFlags & kSecCSNoNetworkAccess) { - // Skips all revocation since they require network connectivity - // therefore annihilates kSecCSEnforceRevocationChecks if present - CFRef no_revoc = SecPolicyCreateRevocation(kSecRevocationNetworkAccessDisabled); - return makeCFArray(2, core.get(), no_revoc.get()); - } + if (mValidationFlags & kSecCSNoNetworkAccess) { + // Skips all revocation since they require network connectivity + // therefore annihilates kSecCSEnforceRevocationChecks if present + CFRef no_revoc = makeRevocationPolicy(kSecRevocationNetworkAccessDisabled); + return makeCFArray(2, core.get(), no_revoc.get()); + } else if (mValidationFlags & kSecCSEnforceRevocationChecks) { - // Add CRL and OCSPPolicies + // Add CRL and OCSP policies +#if !SECTRUST_OSX CFRef crl = makeCRLPolicy(); CFRef ocsp = makeOCSPPolicy(); return makeCFArray(3, core.get(), crl.get(), ocsp.get()); +#else + CFRef revoc = makeRevocationPolicy(kSecRevocationUseAnyAvailableMethod); + return makeCFArray(2, core.get(), revoc.get()); +#endif } else { return makeCFArray(1, core.get()); } @@ -898,9 +936,10 @@ void SecStaticCode::validateExecutable() mExecutableValidResult = err.osStatus(); throw; } catch (...) { - secdebug("staticCode", "%p executable validation threw non-common exception", this); + secinfo("staticCode", "%p executable validation threw non-common exception", this); mExecutableValidated = true; mExecutableValidResult = errSecCSInternalError; + Syslog::notice("code signing internal problem: unknown exception thrown by validation"); throw; } } @@ -942,18 +981,11 @@ void SecStaticCode::validateResources(SecCSFlags flags) } try { - // sanity first - CFDictionaryRef sealedResources = resourceDictionary(); - if (this->resourceBase()) // disk has resources - if (sealedResources) - /* go to work below */; - else - MacOSError::throwMe(errSecCSResourcesNotFound); - else // disk has no resources - if (sealedResources) - MacOSError::throwMe(errSecCSResourcesNotFound); - else - return; // no resources, not sealed - fine (no work) + CFDictionaryRef rules; + CFDictionaryRef files; + uint32_t version; + if (!loadResources(rules, files, version)) + return; // validly no resources; nothing to do (ok) // found resources, and they are sealed DTRACK(CODESIGN_EVAL_STATIC_RESOURCES, this, @@ -962,22 +994,6 @@ void SecStaticCode::validateResources(SecCSFlags flags) // scan through the resources on disk, checking each against the resourceDirectory mResourcesValidContext = new CollectingContext(*this); // collect all failures in here - // use V2 resource seal if available, otherwise fall back to V1 - CFDictionaryRef rules; - CFDictionaryRef files; - uint32_t version; - if (CFDictionaryGetValue(sealedResources, CFSTR("files2"))) { // have V2 signature - rules = cfget(sealedResources, "rules2"); - files = cfget(sealedResources, "files2"); - version = 2; - } else { // only V1 available - rules = cfget(sealedResources, "rules"); - files = cfget(sealedResources, "files"); - version = 1; - } - if (!rules || !files) - MacOSError::throwMe(errSecCSResourcesInvalid); - // check for weak resource rules bool strict = flags & kSecCSStrictValidate; if (strict) { @@ -1014,7 +1030,7 @@ void SecStaticCode::validateResources(SecCSFlags flags) unsigned leftovers = unsigned(CFDictionaryGetCount(resourceMap)); if (leftovers > 0) { - secdebug("staticCode", "%d sealed resource(s) not found in code", int(leftovers)); + secinfo("staticCode", "%d sealed resource(s) not found in code", int(leftovers)); CFDictionaryApplyFunction(resourceMap, SecStaticCode::checkOptionalResource, mResourcesValidContext); } @@ -1029,10 +1045,11 @@ void SecStaticCode::validateResources(SecCSFlags flags) mResourcesValidResult = err.osStatus(); throw; } catch (...) { - secdebug("staticCode", "%p executable validation threw non-common exception", this); + secinfo("staticCode", "%p executable validation threw non-common exception", this); mResourcesValidated = true; mResourcesDeep = flags & kSecCSCheckNestedCode; mResourcesValidResult = errSecCSInternalError; + Syslog::notice("code signing internal problem: unknown exception thrown by validation"); throw; } } @@ -1044,6 +1061,38 @@ void SecStaticCode::validateResources(SecCSFlags flags) } +bool SecStaticCode::loadResources(CFDictionaryRef& rules, CFDictionaryRef& files, uint32_t& version) +{ + // sanity first + CFDictionaryRef sealedResources = resourceDictionary(); + if (this->resourceBase()) { // disk has resources + if (sealedResources) + /* go to work below */; + else + MacOSError::throwMe(errSecCSResourcesNotFound); + } else { // disk has no resources + if (sealedResources) + MacOSError::throwMe(errSecCSResourcesNotFound); + else + return false; // no resources, not sealed - fine (no work) + } + + // use V2 resource seal if available, otherwise fall back to V1 + if (CFDictionaryGetValue(sealedResources, CFSTR("files2"))) { // have V2 signature + rules = cfget(sealedResources, "rules2"); + files = cfget(sealedResources, "files2"); + version = 2; + } else { // only V1 available + rules = cfget(sealedResources, "rules"); + files = cfget(sealedResources, "files"); + version = 1; + } + if (!rules || !files) + MacOSError::throwMe(errSecCSResourcesInvalid); + return true; +} + + void SecStaticCode::checkOptionalResource(CFTypeRef key, CFTypeRef value, void *context) { ValidationContext *ctx = static_cast(context); @@ -1075,8 +1124,10 @@ bool SecStaticCode::hasWeakResourceRules(CFDictionaryRef rulesDict, uint32_t ver { // compute allowed omissions CFRef defaultOmissions = this->diskRep()->allowedResourceOmissions(); - if (!defaultOmissions) + if (!defaultOmissions) { + Syslog::notice("code signing internal problem: diskRep returned no allowedResourceOmissions"); MacOSError::throwMe(errSecCSInternalError); + } CFRef allowed = CFArrayCreateMutableCopy(NULL, 0, defaultOmissions); if (allowedOmissions) CFArrayAppendArray(allowed, allowedOmissions, CFRangeMake(0, CFArrayGetCount(allowedOmissions))); @@ -1109,7 +1160,7 @@ CFDictionaryRef SecStaticCode::infoDictionary() { if (!mInfoDict) { mInfoDict.take(getDictionary(cdInfoSlot, errSecCSInfoPlistFailed)); - secdebug("staticCode", "%p loaded InfoDict %p", this, mInfoDict.get()); + secinfo("staticCode", "%p loaded InfoDict %p", this, mInfoDict.get()); } return mInfoDict; } @@ -1123,7 +1174,7 @@ CFDictionaryRef SecStaticCode::entitlements() const EntitlementBlob *blob = reinterpret_cast(CFDataGetBytePtr(entitlementData)); if (blob->validateBlob()) { mEntitlements.take(blob->entitlements()); - secdebug("staticCode", "%p loaded Entitlements %p", this, mEntitlements.get()); + secinfo("staticCode", "%p loaded Entitlements %p", this, mEntitlements.get()); } // we do not consider a different blob type to be an error. We think it's a new format we don't understand } @@ -1137,13 +1188,31 @@ CFDictionaryRef SecStaticCode::resourceDictionary(bool check /* = true */) return mResourceDict; if (CFRef dict = getDictionary(cdResourceDirSlot, check)) if (cfscan(dict, "{rules=%Dn,files=%Dn}")) { - secdebug("staticCode", "%p loaded ResourceDict %p", + secinfo("staticCode", "%p loaded ResourceDict %p", this, mResourceDict.get()); return mResourceDict = dict; } // bad format return NULL; } + + +CFDataRef SecStaticCode::copyComponent(CodeDirectory::SpecialSlot slot, CFDataRef hash) +{ + const CodeDirectory* cd = this->codeDirectory(); + if (CFCopyRef component = this->component(slot)) { + if (hash) { + const void *slotHash = (*cd)[slot]; + if (cd->hashSize != CFDataGetLength(hash) || 0 != memcmp(slotHash, CFDataGetBytePtr(hash), cd->hashSize)) { + Syslog::notice("copyComponent hash mismatch slot %d length %d", slot, int(CFDataGetLength(hash))); + return NULL; // mismatch + } + } + return component.yield(); + } + return NULL; +} + // @@ -1181,64 +1250,25 @@ CFDictionaryRef SecStaticCode::getDictionary(CodeDirectory::SpecialSlot slot, bo return NULL; } - -// -// Load, validate, and return a sealed resource. -// The resource data (loaded in to memory as a blob) is returned and becomes -// the responsibility of the caller; it is NOT cached by SecStaticCode. // -// A resource that is not sealed will not be returned, and an error will be thrown. -// A missing resource will cause an error unless it's marked optional in the Directory. -// Under no circumstances will a corrupt resource be returned. -// NULL will only be returned for a resource that is neither sealed nor present -// (or that is sealed, absent, and marked optional). -// If the ResourceDictionary itself is not sealed, this function will always fail. // -// There is currently no interface for partial retrieval of the resource data. -// (Since the ResourceDirectory does not currently support segmentation, all the -// data would have to be read anyway, but it could be read into a reusable buffer.) // -CFDataRef SecStaticCode::resource(string path, ValidationContext &ctx) +CFDictionaryRef SecStaticCode::diskRepInformation() { - if (CFDictionaryRef rdict = resourceDictionary()) { - if (CFTypeRef file = cfget(rdict, "files.%s", path.c_str())) { - ResourceSeal seal(file); - if (!resourceBase()) // no resources in DiskRep - MacOSError::throwMe(errSecCSResourcesNotFound); - if (seal.nested()) - MacOSError::throwMe(errSecCSResourcesNotSealed); // (it's nested code) - CFRef fullpath = makeCFURL(path, false, resourceBase()); - if (CFRef data = cfLoadFile(fullpath)) { - MakeHash hasher(this->codeDirectory()); - hasher->update(CFDataGetBytePtr(data), CFDataGetLength(data)); - if (hasher->verify(seal.hash(hashAlgorithm()))) - return data.yield(); // good - else - ctx.reportProblem(errSecCSBadResource, kSecCFErrorResourceAltered, fullpath); // altered - } else { - if (!seal.optional()) - ctx.reportProblem(errSecCSBadResource, kSecCFErrorResourceMissing, fullpath); // was sealed but is now missing - else - return NULL; // validly missing - } - } else - ctx.reportProblem(errSecCSBadResource, kSecCFErrorResourceAdded, CFTempURL(path, false, resourceBase())); - return NULL; - } else - MacOSError::throwMe(errSecCSResourcesNotSealed); + return mRep->diskRepInformation(); } -CFDataRef SecStaticCode::resource(string path) -{ - ValidationContext ctx(*this); - return resource(path, ctx); -} void SecStaticCode::validateResource(CFDictionaryRef files, string path, bool isSymlink, ValidationContext &ctx, SecCSFlags flags, uint32_t version) { if (!resourceBase()) // no resources in DiskRep MacOSError::throwMe(errSecCSResourcesNotFound); CFRef fullpath = makeCFURL(path, false, resourceBase()); + if (version > 1 && ((flags & (kSecCSStrictValidate|kSecCSRestrictSidebandData)) == (kSecCSStrictValidate|kSecCSRestrictSidebandData))) { + AutoFileDesc fd(cfString(fullpath)); + if (fd.hasExtendedAttribute(XATTR_RESOURCEFORK_NAME) || fd.hasExtendedAttribute(XATTR_FINDERINFO_NAME)) + ctx.reportProblem(errSecCSInvalidAssociatedFileData, kSecCFErrorResourceSideband, fullpath); + } if (CFTypeRef file = CFDictionaryGetValue(files, CFTempString(path))) { ResourceSeal seal(file); const ResourceSeal& rseal = seal; @@ -1283,6 +1313,24 @@ void SecStaticCode::validateResource(CFDictionaryRef files, string path, bool is ctx.reportProblem(errSecCSBadResource, kSecCFErrorResourceAdded, CFTempURL(path, false, resourceBase())); } +void SecStaticCode::validatePlainMemoryResource(string path, CFDataRef fileData, SecCSFlags flags) +{ + CFDictionaryRef rules; + CFDictionaryRef files; + uint32_t version; + if (!loadResources(rules, files, version)) + MacOSError::throwMe(errSecCSResourcesNotFound); // no resources sealed; this can't be right + if (CFTypeRef file = CFDictionaryGetValue(files, CFTempString(path))) { + ResourceSeal seal(file); + const Byte *sealHash = seal.hash(hashAlgorithm()); + if (sealHash) { + if (codeDirectory()->verifyMemoryContent(fileData, sealHash)) + return; // success + } + } + MacOSError::throwMe(errSecCSBadResource); +} + void SecStaticCode::validateSymlinkResource(std::string fullpath, std::string seal, ValidationContext &ctx, SecCSFlags flags) { static const char* const allowedDestinations[] = { @@ -1344,7 +1392,7 @@ void SecStaticCode::validateNestedCode(CFURLRef path, const ResourceSeal &seal, // recursively verify this nested code try { if (!(flags & kSecCSCheckNestedCode)) - flags |= kSecCSBasicValidateOnly; + flags |= kSecCSBasicValidateOnly | kSecCSQuickCheck; SecPointer code = new SecStaticCode(DiskRep::bestGuess(cfString(path))); code->initializeFromParent(*this); code->staticValidate(flags & ~kSecCSRestrictToAppLike, SecRequirement::required(req)); @@ -1397,10 +1445,7 @@ void SecStaticCode::validateOtherVersions(CFURLRef path, SecCSFlags flags, SecRe while ((entry = scanner.getNext()) != NULL) { std::ostringstream fullPath; - if (entry->d_type != DT_DIR || - strcmp(entry->d_name, ".") == 0 || - strcmp(entry->d_name, "..") == 0 || - strcmp(entry->d_name, "Current") == 0) + if (entry->d_type != DT_DIR || strcmp(entry->d_name, "Current") == 0) continue; fullPath << versionsPath.str() << entry->d_name; @@ -1532,9 +1577,6 @@ void SecStaticCode::validateRequirements(SecRequirementType type, SecStaticCode /* accept it */; } -/* Public Key Hash for root:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority */ -static const UInt8 retryRootBytes[] = {0x00,0xd8,0x5a,0x4c,0x25,0xc1,0x22,0xe5,0x8b,0x31,0xef,0x6d,0xba,0xf3,0xcc,0x5f,0x29,0xf1,0x0d,0x61}; - // // Validate this StaticCode against an external Requirement // @@ -1544,34 +1586,6 @@ bool SecStaticCode::satisfiesRequirement(const Requirement *req, OSStatus failur assert(req); validateDirectory(); result = req->validates(Requirement::Context(mCertChain, infoDictionary(), entitlements(), codeDirectory()->identifier(), codeDirectory()), failure); - if (result == false) { - /* Fix for rdar://problem/21437632: Work around untrusted root in validation chain */ - CFArrayRef certs = certificates(); - if (!certs || ((int)CFArrayGetCount(certs) < 1)) { - return false; - } - SecCertificateRef root = cert((int)CFArrayGetCount(certs) - 1); - if (!root) { - return false; - } - CFDataRef rootHash = SecCertificateCopyPublicKeySHA1Digest(root); - if (!rootHash) { - return false; - } - - if ((CFDataGetLength(rootHash) == sizeof(retryRootBytes)) && - !memcmp(CFDataGetBytePtr(rootHash), retryRootBytes, sizeof(retryRootBytes))) { - // retry with a rebuilt certificate chain, this time evaluating anchor trust - Security::Syslog::debug("Requirements validation failed: retrying"); - mResourcesValidated = mValidated = false; - setValidationFlags(mValidationFlags | kSecCSCheckTrustedAnchors); - - validateDirectory(); - result = req->validates(Requirement::Context(mCertChain, infoDictionary(), entitlements(), codeDirectory()->identifier(), codeDirectory()), failure); - } - CFRelease(rootHash); - } - return result; } @@ -1712,14 +1726,17 @@ CFDictionaryRef SecStaticCode::signingInformation(SecCSFlags flags) // to reliably transmit through the API wall so that code outside the Security.framework // can use it without having to play nasty tricks to get it. // - if (flags & kSecCSInternalInformation) + if (flags & kSecCSInternalInformation) { try { if (mDir) CFDictionaryAddValue(dict, kSecCodeInfoCodeDirectory, mDir); CFDictionaryAddValue(dict, kSecCodeInfoCodeOffset, CFTempNumber(mRep->signingBase())); if (CFRef rdict = getDictionary(cdResourceDirSlot, false)) // suppress validation CFDictionaryAddValue(dict, kSecCodeInfoResourceDirectory, rdict); + if (CFRef ddict = diskRepInformation()) + CFDictionaryAddValue(dict, kSecCodeInfoDiskRepInfo, ddict); } catch (...) { } + } // @@ -1877,7 +1894,7 @@ void SecStaticCode::handleOtherArchitectures(void (^handle)(SecStaticCode* other for (Universal::Architectures::const_iterator arch = architectures.begin(); arch != architectures.end(); ++arch) { ctx.offset = fat->archOffset(*arch); if (ctx.offset > SIZE_MAX) - MacOSError::throwMe(errSecCSInternalError); + MacOSError::throwMe(errSecCSBadObjectFormat); ctx.size = fat->lengthOfSlice((size_t)ctx.offset); if (ctx.offset != activeOffset) { // inactive architecture; check it SecPointer subcode = new SecStaticCode(DiskRep::bestGuess(this->mainExecutablePath(), &ctx));