//
// Given a bag of attribute values, automagically come up with a SecCode
// without any other information.
// This is meant to be the "just do what makes sense" generic call, for callers
// who don't want to engage in the fascinating dance of manual guest enumeration.
//
// Note that we expect the logic embedded here to change over time (in backward
// compatible fashion, one hopes), and that it's all right to use heuristics here
// as long as it's done sensibly.
//
// Be warned that the present logic is quite a bit ad-hoc, and will likely not
// handle arbitrary combinations of proxy hosting, dynamic hosting, and dedicated
// hosting all that well.
//
SecCode *SecCode::autoLocateGuest(CFDictionaryRef attributes, SecCSFlags flags)
{
	// special case: with no attributes at all, return the root of trust
	if (CFDictionaryGetCount(attributes) == 0)
		return KernelCode::active()->retain();
	
	// main logic: we need a pid, and we'll take a canonical guest id as an option
	int pid = 0;
	if (!cfscan(attributes, "{%O=%d}", kSecGuestAttributePid, &pid))
		CSError::throwMe(errSecCSUnsupportedGuestAttributes, kSecCFErrorGuestAttributes, attributes);
	if (SecCode *process =
			KernelCode::active()->locateGuest(attributes)) {
		SecPointer<SecCode> code;
		code.take(process);		// locateGuest gave us a retained object
		if (code->staticCode()->flag(kSecCodeSignatureHost)) {
			// might be a code host. Let's find out
			CFRef<CFMutableDictionaryRef> rest = makeCFMutableDictionary(attributes);
			CFDictionaryRemoveValue(rest, kSecGuestAttributePid);
			if (SecCode *guest = code->locateGuest(rest))
				return guest;
		}
		if (!CFDictionaryGetValue(attributes, kSecGuestAttributeCanonical)) {
			// only "soft" attributes, and no hosting is happening. Return the (non-)host itself
			return code.yield();
		}
	}
	MacOSError::throwMe(errSecCSNoSuchCode);
}
示例#2
0
OSStatus SecCodeCheckValidityWithErrors(SecCodeRef codeRef, SecCSFlags flags,
	SecRequirementRef requirementRef, CFErrorRef *errors)
{
	BEGIN_CSAPI

	checkFlags(flags,
		  kSecCSConsiderExpiration
		| kSecCSStrictValidate
		| kSecCSRestrictSidebandData
		| 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
}