]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_codesigning/lib/SecCode.cpp
Security-55163.44.tar.gz
[apple/security.git] / libsecurity_codesigning / lib / SecCode.cpp
diff --git a/libsecurity_codesigning/lib/SecCode.cpp b/libsecurity_codesigning/lib/SecCode.cpp
new file mode 100644 (file)
index 0000000..f5b300f
--- /dev/null
@@ -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 <security_utilities/cfmunge.h>
+
+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<CFMutableDictionaryRef> 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<SecStaticCode> 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<SecCode> 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<CFDictionaryRef>("{%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<SecCode> 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<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
+       CFRef<CFDictionaryRef> info = code->signingInformation(flags);
+       
+       if (flags & kSecCSDynamicInformation)
+               if (SecPointer<SecCode> dcode = SecStaticCode::optionalDynamic(codeRef))
+                       info.take(cfmake<CFDictionaryRef>("{+%O,%O=%u}", info.get(), kSecCodeInfoStatus, dcode->status()));
+       
+       CodeSigning::Required(infoRef) = info.yield();
+       
+       END_CSAPI
+}
+