X-Git-Url: https://git.saurik.com/apple/libsecurity_codesigning.git/blobdiff_plain/2e2533baea112414a307d169c101a9c225fd1d77..935e692843d9c528f9a4c5eee98e00961ca5f4a4:/lib/csgeneric.cpp diff --git a/lib/csgeneric.cpp b/lib/csgeneric.cpp index 6840248..c67d946 100644 --- a/lib/csgeneric.cpp +++ b/lib/csgeneric.cpp @@ -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 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(guest)) { + FilePathOut path; + CFRef cdhash; + CFDictionary attributes(errSecCSHostProtocolInvalidAttribute); + identifyGuest(iguest->guestRef(), path, cdhash.aref(), attributes.aref()); + DiskRep::Context ctx; + if (CFNumberRef architecture = attributes.get(kSecGuestAttributeArchitecture)) { + cpu_type_t cpu = cfNumber(architecture); + if (CFNumberRef subarchitecture = attributes.get(kSecGuestAttributeSubarchitecture)) + ctx.arch = Architecture(cpu, cfNumber(subarchitecture)); + else + ctx.arch = Architecture(cpu); + } + SecPointer 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(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 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(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; }