X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/72a12576750f52947eb043106ba5c12c0d07decf..b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195:/libsecurity_codesigning/lib/SecCode.cpp?ds=inline diff --git a/libsecurity_codesigning/lib/SecCode.cpp b/libsecurity_codesigning/lib/SecCode.cpp new file mode 100644 index 00000000..f5b300f6 --- /dev/null +++ b/libsecurity_codesigning/lib/SecCode.cpp @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +// +// SecCode - API frame for SecCode objects. +// +// Note that some SecCode* functions take SecStaticCodeRef arguments in order to +// accept either static or dynamic code references, operating on the respective +// StaticCode. Those functions are in SecStaticCode.cpp, not here, despite their name. +// +#include "cs.h" +#include "Code.h" +#include "cskernel.h" +#include + +using namespace CodeSigning; + + +// +// CFError user info keys +// +const CFStringRef kSecCFErrorArchitecture = CFSTR("SecCSArchitecture"); +const CFStringRef kSecCFErrorPattern = CFSTR("SecCSPattern"); +const CFStringRef kSecCFErrorResourceSeal = CFSTR("SecCSResourceSeal"); +const CFStringRef kSecCFErrorResourceAdded = CFSTR("SecCSResourceAdded"); +const CFStringRef kSecCFErrorResourceAltered = CFSTR("SecCSResourceAltered"); +const CFStringRef kSecCFErrorResourceMissing = CFSTR("SecCSResourceMissing"); +const CFStringRef kSecCFErrorInfoPlist = CFSTR("SecCSInfoPlist"); +const CFStringRef kSecCFErrorGuestAttributes = CFSTR("SecCSGuestAttributes"); +const CFStringRef kSecCFErrorRequirementSyntax = CFSTR("SecRequirementSyntax"); +const CFStringRef kSecCFErrorPath = CFSTR("SecComponentPath"); + + +// +// CF-standard type code functions +// +CFTypeID SecCodeGetTypeID(void) +{ + BEGIN_CSAPI + return gCFObjects().Code.typeID; + END_CSAPI1(_kCFRuntimeNotATypeID) +} + + +// +// Get a reference to the calling code. +// +OSStatus SecCodeCopySelf(SecCSFlags flags, SecCodeRef *selfRef) +{ + BEGIN_CSAPI + + checkFlags(flags); + CFRef attributes = makeCFMutableDictionary(1, + kSecGuestAttributePid, CFTempNumber(getpid()).get()); + CodeSigning::Required(selfRef) = SecCode::autoLocateGuest(attributes, flags)->handle(false); + + END_CSAPI +} + + +// +// Get the dynamic status of a code. +// +OSStatus SecCodeGetStatus(SecCodeRef codeRef, SecCSFlags flags, SecCodeStatus *status) +{ + BEGIN_CSAPI + + checkFlags(flags); + CodeSigning::Required(status) = SecCode::required(codeRef)->status(); + + END_CSAPI +} + + +// +// Change the dynamic status of a code +// +OSStatus SecCodeSetStatus(SecCodeRef codeRef, SecCodeStatusOperation operation, + CFDictionaryRef arguments, SecCSFlags flags) +{ + BEGIN_CSAPI + + checkFlags(flags); + SecCode::required(codeRef)->status(operation, arguments); + + END_CSAPI +} + + +// +// Get the StaticCode for an Code +// +OSStatus SecCodeCopyStaticCode(SecCodeRef codeRef, SecCSFlags flags, SecStaticCodeRef *staticCodeRef) +{ + BEGIN_CSAPI + + checkFlags(flags); + SecPointer staticCode = SecCode::required(codeRef)->staticCode(); + CodeSigning::Required(staticCodeRef) = staticCode ? staticCode->handle() : NULL; + + END_CSAPI +} + + +// +// Get the host for an Code +// +OSStatus SecCodeCopyHost(SecCodeRef guestRef, SecCSFlags flags, SecCodeRef *hostRef) +{ + BEGIN_CSAPI + + checkFlags(flags); + SecPointer host = SecCode::required(guestRef)->host(); + CodeSigning::Required(hostRef) = host ? host->handle() : NULL; + + END_CSAPI +} + + +// +// Find a guest by attribute(s) +// +const CFStringRef kSecGuestAttributeCanonical = CFSTR("canonical"); +const CFStringRef kSecGuestAttributeHash = CFSTR("codedirectory-hash"); +const CFStringRef kSecGuestAttributeMachPort = CFSTR("mach-port"); +const CFStringRef kSecGuestAttributePid = CFSTR("pid"); +const CFStringRef kSecGuestAttributeArchitecture = CFSTR("architecture"); +const CFStringRef kSecGuestAttributeSubarchitecture = CFSTR("subarchitecture"); + +OSStatus SecCodeCopyGuestWithAttributes(SecCodeRef hostRef, + CFDictionaryRef attributes, SecCSFlags flags, SecCodeRef *guestRef) +{ + BEGIN_CSAPI + + checkFlags(flags); + if (hostRef) { + if (SecCode *guest = SecCode::required(hostRef)->locateGuest(attributes)) + CodeSigning::Required(guestRef) = guest->handle(false); + else + return errSecCSNoSuchCode; + } else + CodeSigning::Required(guestRef) = SecCode::autoLocateGuest(attributes, flags)->handle(false); + + END_CSAPI +} + + +// +// Shorthand for getting the SecCodeRef for a UNIX process +// +OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *processRef) +{ + BEGIN_CSAPI + + checkFlags(flags); + if (SecCode *guest = KernelCode::active()->locateGuest(CFTemp("{%O=%d}", kSecGuestAttributePid, pid))) + CodeSigning::Required(processRef) = guest->handle(false); + else + return errSecCSNoSuchCode; + + END_CSAPI +} + + +// +// Check validity of an Code +// +OSStatus SecCodeCheckValidity(SecCodeRef codeRef, SecCSFlags flags, + SecRequirementRef requirementRef) +{ + return SecCodeCheckValidityWithErrors(codeRef, flags, requirementRef, NULL); +} + +OSStatus SecCodeCheckValidityWithErrors(SecCodeRef codeRef, SecCSFlags flags, + SecRequirementRef requirementRef, CFErrorRef *errors) +{ + BEGIN_CSAPI + + checkFlags(flags, + kSecCSConsiderExpiration + | kSecCSEnforceRevocationChecks); + SecPointer code = SecCode::required(codeRef); + code->checkValidity(flags); + if (const SecRequirement *req = SecRequirement::optional(requirementRef)) + code->staticCode()->validateRequirement(req->requirement(), errSecCSReqFailed); + + END_CSAPI_ERRORS +} + + +// +// Collect suitably laundered information about the code signature of a SecStaticCode +// and return it as a CFDictionary. +// +// This API contracts to return a few pieces of information even for unsigned +// code. This means that a SecStaticCodeRef is usable as a basic indentifier +// (i.e. handle) for any code out there. +// +const CFStringRef kSecCodeInfoCertificates = CFSTR("certificates"); +const CFStringRef kSecCodeInfoChangedFiles = CFSTR("changed-files"); +const CFStringRef kSecCodeInfoCMS = CFSTR("cms"); +const CFStringRef kSecCodeInfoDesignatedRequirement = CFSTR("designated-requirement"); +const CFStringRef kSecCodeInfoEntitlements = CFSTR("entitlements"); +const CFStringRef kSecCodeInfoEntitlementsDict = CFSTR("entitlements-dict"); +const CFStringRef kSecCodeInfoFormat = CFSTR("format"); +const CFStringRef kSecCodeInfoDigestAlgorithm = CFSTR("digest-algorithm"); +const CFStringRef kSecCodeInfoIdentifier = CFSTR("identifier"); +const CFStringRef kSecCodeInfoImplicitDesignatedRequirement = CFSTR("implicit-requirement"); +const CFStringRef kSecCodeInfoMainExecutable = CFSTR("main-executable"); +const CFStringRef kSecCodeInfoPList = CFSTR("info-plist"); +const CFStringRef kSecCodeInfoRequirements = CFSTR("requirements"); +const CFStringRef kSecCodeInfoRequirementData = CFSTR("requirement-data"); +const CFStringRef kSecCodeInfoSource = CFSTR("source"); +const CFStringRef kSecCodeInfoStatus = CFSTR("status"); +const CFStringRef kSecCodeInfoTime = CFSTR("signing-time"); +const CFStringRef kSecCodeInfoTimestamp = CFSTR("signing-timestamp"); +const CFStringRef kSecCodeInfoTrust = CFSTR("trust"); +const CFStringRef kSecCodeInfoUnique = CFSTR("unique"); + +const CFStringRef kSecCodeInfoCodeDirectory = CFSTR("CodeDirectory"); +const CFStringRef kSecCodeInfoCodeOffset = CFSTR("CodeOffset"); +const CFStringRef kSecCodeInfoResourceDirectory = CFSTR("ResourceDirectory"); + + +OSStatus SecCodeCopySigningInformation(SecStaticCodeRef codeRef, SecCSFlags flags, + CFDictionaryRef *infoRef) +{ + BEGIN_CSAPI + + checkFlags(flags, + kSecCSInternalInformation + | kSecCSSigningInformation + | kSecCSRequirementInformation + | kSecCSDynamicInformation + | kSecCSContentInformation); + + SecPointer code = SecStaticCode::requiredStatic(codeRef); + CFRef info = code->signingInformation(flags); + + if (flags & kSecCSDynamicInformation) + if (SecPointer dcode = SecStaticCode::optionalDynamic(codeRef)) + info.take(cfmake("{+%O,%O=%u}", info.get(), kSecCodeInfoStatus, dcode->status())); + + CodeSigning::Required(infoRef) = info.yield(); + + END_CSAPI +} +