]> git.saurik.com Git - apple/libsecurity_codesigning.git/blobdiff - lib/csgeneric.cpp
libsecurity_codesigning-55037.15.tar.gz
[apple/libsecurity_codesigning.git] / lib / csgeneric.cpp
index 6840248380a6f41c7ec2c093f9a449e16b6e6c42..c67d9467bddb6c97e42b5a3f8e3b93651d79cb37 100644 (file)
@@ -74,8 +74,7 @@ SecCode *GenericCode::locateGuest(CFDictionaryRef attributes)
                mach_port_t subport;
                CALL(host, findGuest, guestRef(), attrPtr, attrLength,
                        &guestPath, &guestPathLength, &subport);
-               secdebug("genericcode", "%p found guest chain length=%d",
-                       this, guestPathLength);
+               CODESIGN_GUEST_LOCATE_GENERIC(this, guestPath, guestPathLength, subport);
                SecPointer<SecCode> code = this;
                for (unsigned n = 0; n < guestPathLength; n++)
                        code = new GenericCode(code, guestPath[n]);
@@ -86,15 +85,56 @@ SecCode *GenericCode::locateGuest(CFDictionaryRef attributes)
 
 
 //
-// Map a guest to its StaticCode.
+// Identify a guest by returning its StaticCode and running CodeDirectory hash.
 // This uses cshosting RPCs to ask the host (or its proxy).
 //
-SecStaticCode *GenericCode::mapGuestToStatic(SecCode *guest)
+SecStaticCode *GenericCode::identifyGuest(SecCode *guest, CFDataRef *cdhashOut)
+{
+       if (GenericCode *iguest = dynamic_cast<GenericCode *>(guest)) {
+               FilePathOut path;
+               CFRef<CFDataRef> cdhash;
+               CFDictionary attributes(errSecCSHostProtocolInvalidAttribute);
+               identifyGuest(iguest->guestRef(), path, cdhash.aref(), attributes.aref());
+               DiskRep::Context ctx;
+               if (CFNumberRef architecture = attributes.get<CFNumberRef>(kSecGuestAttributeArchitecture)) {
+                       cpu_type_t cpu = cfNumber<cpu_type_t>(architecture);
+                       if (CFNumberRef subarchitecture = attributes.get<CFNumberRef>(kSecGuestAttributeSubarchitecture))
+                               ctx.arch = Architecture(cpu, cfNumber<cpu_subtype_t>(subarchitecture));
+                       else
+                               ctx.arch = Architecture(cpu);
+               }
+               SecPointer<GenericStaticCode> code = new GenericStaticCode(DiskRep::bestGuess(path, &ctx));
+               CODESIGN_GUEST_IDENTIFY_GENERIC(iguest, iguest->guestRef(), code);
+               if (cdhash) {
+                       CODESIGN_GUEST_CDHASH_GENERIC(iguest, (void *)CFDataGetBytePtr(cdhash), CFDataGetLength(cdhash));
+                       *cdhashOut = cdhash.yield();
+               }
+               return code.yield();
+       } else
+               MacOSError::throwMe(errSecCSNotAHost);
+}
+
+// helper to drive the identifyGuest hosting IPC and return results as CF objects
+void GenericCode::identifyGuest(SecGuestRef guest, char *path, CFDataRef &cdhash, CFDictionaryRef &attributes)
 {
        if (Port host = hostingPort()) {
-               char path[MAXPATHLEN];
-               CALL(host, guestPath, safe_cast<GenericCode *>(guest)->guestRef(), path);
-               return (new GenericStaticCode(DiskRep::bestGuess(path)))->retain();
+               HashDataOut hash;
+               uint32_t hashLength;
+               XMLBlobOut attr;
+               uint32_t attrLength;
+               CALL(host, identifyGuest, guest, path, hash, &hashLength, &attr, &attrLength);
+               if (hashLength)
+                       cdhash = makeCFData(hash, hashLength);
+               if (attrLength) {
+                       CFRef<CFDataRef> attrData = makeCFData(attr, attrLength);
+                       attributes = makeCFDictionaryFrom(attrData);
+#if ROSETTA_TEST_HACK
+                       CFMutableDictionaryRef hattr = makeCFMutableDictionary(attributes);
+                       CFDictionaryAddValue(hattr, kSecGuestAttributeArchitecture, CFTempNumber(CPU_TYPE_POWERPC));
+                       CFRelease(attributes);
+                       attributes = hattr;
+#endif
+               }
        } else
                MacOSError::throwMe(errSecCSNotAHost);
 }
@@ -104,7 +144,7 @@ SecStaticCode *GenericCode::mapGuestToStatic(SecCode *guest)
 // Get the Code Signing Status Word for a Code.
 // This uses cshosting RPCs to ask the host (or its proxy).
 //
-uint32_t GenericCode::getGuestStatus(SecCode *guest)
+SecCodeStatus GenericCode::getGuestStatus(SecCode *guest)
 {
        if (Port host = hostingPort()) {
                uint32_t status;
@@ -115,6 +155,28 @@ uint32_t GenericCode::getGuestStatus(SecCode *guest)
 }
 
 
+//
+// Status changes are transmitted through the cshosting RPCs.
+//
+void GenericCode::changeGuestStatus(SecCode *iguest, SecCodeStatusOperation operation, CFDictionaryRef arguments)
+{
+       if (/* GenericCode *guest = */dynamic_cast<GenericCode *>(iguest))
+               switch (operation) {
+               case kSecCodeOperationNull:
+                       break;
+               case kSecCodeOperationInvalidate:
+               case kSecCodeOperationSetHard:
+               case kSecCodeOperationSetKill:
+                       MacOSError::throwMe(errSecCSUnimplemented);
+                       break;
+               default:
+                       MacOSError::throwMe(errSecCSUnimplemented);
+               }
+       else
+               MacOSError::throwMe(errSecCSNoSuchCode);
+}
+
+
 //
 // Return the Hosting Port for this Code.
 // May return MACH_PORT_NULL if the code is not a code host.
@@ -128,8 +190,10 @@ uint32_t GenericCode::getGuestStatus(SecCode *guest)
 Port GenericCode::hostingPort()
 {
        if (!mHostingPort) {
-               if (staticCode()->codeDirectory()->flags & kSecCodeSignatureHost)
+               if (staticCode()->codeDirectory()->flags & kSecCodeSignatureHost) {
                        mHostingPort = getHostingPort();
+                       CODESIGN_GUEST_HOSTINGPORT(this, mHostingPort);
+               }
        }
        return mHostingPort;    
 }