X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/e3d460c9de4426da6c630c3ae3f46173a99f82d8..bf028f67fd3bb2266df81b80fb6f25a77112e308:/OSX/libsecurity_codesigning/lib/SecStaticCode.cpp?ds=inline diff --git a/OSX/libsecurity_codesigning/lib/SecStaticCode.cpp b/OSX/libsecurity_codesigning/lib/SecStaticCode.cpp index 18625c27..b240b4b8 100644 --- a/OSX/libsecurity_codesigning/lib/SecStaticCode.cpp +++ b/OSX/libsecurity_codesigning/lib/SecStaticCode.cpp @@ -52,8 +52,8 @@ OSStatus SecStaticCodeCreateWithPath(CFURLRef path, SecCSFlags flags, SecStaticC { BEGIN_CSAPI - checkFlags(flags); - CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str())))->handle(); + checkFlags(flags, kSecCSForceOnlineNotarizationCheck); + CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str()), flags))->handle(); END_CSAPI } @@ -68,7 +68,7 @@ OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flag { BEGIN_CSAPI - checkFlags(flags); + checkFlags(flags, kSecCSForceOnlineNotarizationCheck); DiskRep::Context ctx; std::string version; // holds memory placed into ctx if (attributes) { @@ -87,7 +87,7 @@ OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flag ctx.version = version.c_str(); } - CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str(), &ctx)))->handle(); + CodeSigning::Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str(), &ctx), flags))->handle(); END_CSAPI } @@ -105,7 +105,6 @@ OSStatus SecStaticCodeCheckValidity(SecStaticCodeRef staticCodeRef, SecCSFlags f OSStatus SecStaticCodeCheckValidityWithErrors(SecStaticCodeRef staticCodeRef, SecCSFlags flags, SecRequirementRef requirementRef, CFErrorRef *errors) { -#if !SECTRUST_OSX BEGIN_CSAPI checkFlags(flags, @@ -114,13 +113,18 @@ OSStatus SecStaticCodeCheckValidityWithErrors(SecStaticCodeRef staticCodeRef, Se | kSecCSDoNotValidateExecutable | kSecCSDoNotValidateResources | kSecCSConsiderExpiration - | kSecCSEnforceRevocationChecks + | kSecCSEnforceRevocationChecks | kSecCSNoNetworkAccess | kSecCSCheckNestedCode | kSecCSStrictValidate + | kSecCSStrictValidateStructure + | kSecCSRestrictSidebandData | kSecCSCheckGatekeeperArchitectures | kSecCSRestrictSymlinks | kSecCSRestrictToAppLike + | kSecCSUseSoftwareSigningCert + | kSecCSValidatePEH + | kSecCSSingleThreaded ); if (errors) @@ -132,57 +136,21 @@ OSStatus SecStaticCodeCheckValidityWithErrors(SecStaticCodeRef staticCodeRef, Se DTRACK(CODESIGN_EVAL_STATIC, code, (char*)code->mainExecutablePath().c_str()); code->staticValidate(flags, req); - END_CSAPI_ERRORS -#else -#warning resolve before enabling SECTRUST_OSX: - OSStatus result = errSecSuccess; - const char *func = "SecStaticCodeCheckValidity"; - CFErrorRef localErrors = NULL; - if (!errors) { errors = &localErrors; } - try { - checkFlags(flags, - kSecCSReportProgress - | kSecCSCheckAllArchitectures - | kSecCSDoNotValidateExecutable - | kSecCSDoNotValidateResources - | kSecCSConsiderExpiration - | kSecCSEnforceRevocationChecks - | kSecCSNoNetworkAccess - | kSecCSCheckNestedCode - | kSecCSStrictValidate - | kSecCSCheckGatekeeperArchitectures - ); - - if (errors) - flags |= kSecCSFullReport; // internal-use flag - - SecPointer code = SecStaticCode::requiredStatic(staticCodeRef); - code->setValidationFlags(flags); - const SecRequirement *req = SecRequirement::optional(requirementRef); - DTRACK(CODESIGN_EVAL_STATIC, code, (char*)code->mainExecutablePath().c_str()); - code->staticValidate(flags, req); - } - catch (...) { - // the actual error being thrown is not being caught by any of the - // type-specific blocks contained in the END_CSAPI_ERRORS macro, - // so we only have the catch-all block here for now. - result = errSecCSInternalError; - } +#if TARGET_OS_IPHONE + // Everything checked out correctly but we need to make sure that when + // we validated the code directory, we trusted the signer. We defer this + // until now because the caller may still trust the signer via a + // provisioning profile so if we prematurely throw an error when validating + // the directory, we potentially skip resource validation even though the + // caller will go on to trust the signature + // Applications that are validated against a provisioning profile do not have their resources checked + if (code->trustedSigningCertChain() == false) { + return CSError::cfError(errors, errSecCSSignatureUntrusted); + } +#endif - if (errors && *errors) { - CFShow(errors); - CFRelease(errors); - *errors = NULL; - } - if (result == errSecCSInternalError) { - #if !NDEBUG - Security::Syslog::error("WARNING: %s ignored error %d", func, (int)result); - #endif - result = errSecSuccess; - } - return result; -#endif + END_CSAPI_ERRORS } @@ -272,10 +240,38 @@ OSStatus SecCodeMapMemory(SecStaticCodeRef codeRef, SecCSFlags flags) checkFlags(flags); SecPointer code = SecStaticCode::requiredStatic(codeRef); if (const CodeDirectory *cd = code->codeDirectory(false)) { - fsignatures args = { code->diskRep()->signingBase(), (void *)cd, cd->length() }; - UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDSIGS, &args)); - } else + if (code->isDetached()) { + // Detached signatures need to attach their code directory from memory. + fsignatures args = { static_cast(code->diskRep()->signingBase()), (void *)cd, cd->length() }; + UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDSIGS, &args)); + } else { + // All other signatures can simply point to the signature in the main executable. + Universal *execImage = code->diskRep()->mainExecutableImage(); + if (execImage == NULL) { + MacOSError::throwMe(errSecCSNoMainExecutable); + } + + auto_ptr arch(execImage->architecture()); + if (arch.get() == NULL) { + MacOSError::throwMe(errSecCSNoMainExecutable); + } + + size_t signatureOffset = arch->signingOffset(); + size_t signatureLength = arch->signingLength(); + if (signatureOffset == 0) { + MacOSError::throwMe(errSecCSUnsigned); + } + + fsignatures args = { + static_cast(code->diskRep()->signingBase()), + (void *)signatureOffset, + signatureLength, + }; + UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDFILESIGS, &args)); + } + } else { MacOSError::throwMe(errSecCSUnsigned); + } END_CSAPI } @@ -323,3 +319,36 @@ OSStatus SecStaticCodeCancelValidation(SecStaticCodeRef codeRef, SecCSFlags flag END_CSAPI } + + +// +// Retrieve a component object for a special slot directly. +// +CFDataRef SecCodeCopyComponent(SecCodeRef codeRef, int slot, CFDataRef hash) +{ + BEGIN_CSAPI + + SecStaticCode* code = SecStaticCode::requiredStatic(codeRef); + return code->copyComponent(slot, hash); + + END_CSAPI1(NULL) +} + + +// +// Validate a single plain file's resource seal against a memory copy. +// This will fail for any other file type (symlink, directory, nested code, etc. etc.) +// +OSStatus SecCodeValidateFileResource(SecStaticCodeRef codeRef, CFStringRef relativePath, CFDataRef fileData, SecCSFlags flags) +{ + BEGIN_CSAPI + + checkFlags(0); + if (fileData == NULL) + MacOSError::throwMe(errSecCSObjectRequired); + SecStaticCode *code = SecStaticCode::requiredStatic(codeRef); + code->validatePlainMemoryResource(cfString(relativePath), fileData, flags); + + END_CSAPI + +}