CFDictionaryRef xpcEngineUpdate(CFTypeRef target, uint flags, CFDictionaryRef context) { Message msg("update"); // target can be NULL, a CFURLRef, a SecRequirementRef, or a CFNumberRef if (target) { if (CFGetTypeID(target) == CFNumberGetTypeID()) xpc_dictionary_set_uint64(msg, "rule", cfNumber<int64_t>(CFNumberRef(target))); else if (CFGetTypeID(target) == CFURLGetTypeID()) xpc_dictionary_set_string(msg, "url", cfString(CFURLRef(target)).c_str()); else if (CFGetTypeID(target) == SecRequirementGetTypeID()) { CFRef<CFDataRef> data; MacOSError::check(SecRequirementCopyData(SecRequirementRef(target), kSecCSDefaultFlags, &data.aref())); xpc_dictionary_set_data(msg, "requirement", CFDataGetBytePtr(data), CFDataGetLength(data)); } else MacOSError::throwMe(errSecCSInvalidObjectRef); } xpc_dictionary_set_int64(msg, "flags", flags); CFRef<CFMutableDictionaryRef> ctx = makeCFMutableDictionary(); if (context) CFDictionaryApplyFunction(context, copyCFDictionary, ctx); AuthorizationRef localAuthorization = NULL; if (CFDictionaryGetValue(ctx, kSecAssessmentUpdateKeyAuthorization) == NULL) { // no caller-provided authorization MacOSError::check(AuthorizationCreate(NULL, NULL, kAuthorizationFlagDefaults, &localAuthorization)); AuthorizationExternalForm extForm; MacOSError::check(AuthorizationMakeExternalForm(localAuthorization, &extForm)); CFDictionaryAddValue(ctx, kSecAssessmentUpdateKeyAuthorization, CFTempData(&extForm, sizeof(extForm))); } CFRef<CFDataRef> contextData = makeCFData(CFDictionaryRef(ctx)); xpc_dictionary_set_data(msg, "context", CFDataGetBytePtr(contextData), CFDataGetLength(contextData)); msg.send(); if (localAuthorization) AuthorizationFree(localAuthorization, kAuthorizationFlagDefaults); if (int64_t error = xpc_dictionary_get_int64(msg, "error")) MacOSError::throwMe(error); size_t resultLength; const void *resultData = xpc_dictionary_get_data(msg, "result", &resultLength); return makeCFDictionaryFrom(resultData, resultLength); }
// // Add an auxiliary comment blob. // Note that we only allow one auxiliary blob for each magic number. // void OSXVerifier::add(const BlobCore *blob) { if (blob->is<Requirement>()) { #if defined(NDEBUG) secdebug("codesign", "%p verifier adds requirement", this); #else secdebug("codesign", "%p verifier adds requirement %s", this, Dumper::dump(Requirement::specific(blob), true).c_str()); #endif //NDEBUG MacOSError::check(SecRequirementCreateWithData(CFTempData(*blob), kSecCSDefaultFlags, &mRequirement.aref())); } else { secdebug("codesign", "%p verifier adds blob (0x%x,%zd)", this, blob->magic(), blob->length()); BlobCore * &slot = mAuxiliary[blob->magic()]; if (slot) ::free(slot); slot = blob->clone(); } }
CFDictionaryRef makeCFDictionaryFrom(const void *data, size_t length) { return makeCFDictionaryFrom(CFTempData(data, length).get()); }