]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_codesigning/lib/SecAssessment.cpp
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / libsecurity_codesigning / lib / SecAssessment.cpp
1 /*
2 * Copyright (c) 2011-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 #include "cs.h"
24 #include "SecAssessment.h"
25 #include "policydb.h"
26 #include "policyengine.h"
27 #include "xpcengine.h"
28 #include "csutilities.h"
29 #include "xar++.h"
30 #include <CoreFoundation/CFRuntime.h>
31 #include <CoreFoundation/CFBundlePriv.h>
32 #include <security_utilities/globalizer.h>
33 #include <security_utilities/unix++.h>
34 #include <security_utilities/cfmunge.h>
35 #include <notify.h>
36
37 using namespace CodeSigning;
38
39 //
40 // CF Objects
41 //
42 struct _SecAssessment : private CFRuntimeBase {
43 public:
44 _SecAssessment(CFURLRef p, AuthorityType typ, CFDictionaryRef r) : path(p), type(typ), result(r) { }
45
46 CFCopyRef<CFURLRef> path;
47 AuthorityType type;
48 CFRef<CFDictionaryRef> result;
49
50 public:
51 static _SecAssessment &ref(SecAssessmentRef r)
52 { return *(_SecAssessment *)r; }
53
54 // CF Boiler-plate
55 void *operator new (size_t size)
56 {
57 return (void *)_CFRuntimeCreateInstance(NULL, SecAssessmentGetTypeID(),
58 sizeof(_SecAssessment) - sizeof(CFRuntimeBase), NULL);
59 }
60
61 static void finalize(CFTypeRef obj)
62 { ((_SecAssessment *)obj)->~_SecAssessment(); }
63 };
64
65 typedef _SecAssessment SecAssessment;
66
67
68 static const CFRuntimeClass assessmentClass = {
69 0, // version
70 "SecAssessment", // name
71 NULL, // init
72 NULL, // copy
73 SecAssessment::finalize, // finalize
74 NULL, // equal
75 NULL, // hash
76 NULL, // formatting
77 NULL // debug string
78 };
79
80
81 static dispatch_once_t assessmentOnce;
82 CFTypeID assessmentType = _kCFRuntimeNotATypeID;
83
84 CFTypeID SecAssessmentGetTypeID()
85 {
86 dispatch_once(&assessmentOnce, ^void() {
87 if ((assessmentType = _CFRuntimeRegisterClass(&assessmentClass)) == _kCFRuntimeNotATypeID)
88 abort();
89 });
90 return assessmentType;
91 }
92
93
94 //
95 // Common dictionary constants
96 //
97 CFStringRef kSecAssessmentContextKeyOperation = CFSTR("operation");
98 CFStringRef kSecAssessmentOperationTypeExecute = CFSTR("operation:execute");
99 CFStringRef kSecAssessmentOperationTypeInstall = CFSTR("operation:install");
100 CFStringRef kSecAssessmentOperationTypeOpenDocument = CFSTR("operation:lsopen");
101
102
103 //
104 // Read-only in-process access to the policy database
105 //
106 class ReadPolicy : public PolicyDatabase {
107 public:
108 ReadPolicy() : PolicyDatabase(defaultDatabase) { }
109 };
110 ModuleNexus<ReadPolicy> gDatabase;
111
112
113 //
114 // An on-demand instance of the policy engine
115 //
116 ModuleNexus<PolicyEngine> gEngine;
117
118
119 //
120 // Policy evaluation ("assessment") operations
121 //
122 CFStringRef kSecAssessmentContextKeyUTI = CFSTR("context:uti");
123
124 CFStringRef kSecAssessmentContextKeyFeedback = CFSTR("context:feedback");
125 CFStringRef kSecAssessmentFeedbackProgress = CFSTR("feedback:progress");
126 CFStringRef kSecAssessmentFeedbackInfoCurrent = CFSTR("current");
127 CFStringRef kSecAssessmentFeedbackInfoTotal = CFSTR("total");
128
129 CFStringRef kSecAssessmentContextKeyPrimarySignature = CFSTR("context:primary-signature");
130
131 CFStringRef kSecAssessmentAssessmentVerdict = CFSTR("assessment:verdict");
132 CFStringRef kSecAssessmentAssessmentOriginator = CFSTR("assessment:originator");
133 CFStringRef kSecAssessmentAssessmentAuthority = CFSTR("assessment:authority");
134 CFStringRef kSecAssessmentAssessmentSource = CFSTR("assessment:authority:source");
135 CFStringRef kSecAssessmentAssessmentAuthorityRow = CFSTR("assessment:authority:row");
136 CFStringRef kSecAssessmentAssessmentAuthorityOverride = CFSTR("assessment:authority:override");
137 CFStringRef kSecAssessmentAssessmentAuthorityOriginalVerdict = CFSTR("assessment:authority:verdict");
138 CFStringRef kSecAssessmentAssessmentAuthorityFlags = CFSTR("assessment:authority:flags");
139 CFStringRef kSecAssessmentAssessmentFromCache = CFSTR("assessment:authority:cached");
140 CFStringRef kSecAssessmentAssessmentWeakSignature = CFSTR("assessment:authority:weak");
141 CFStringRef kSecAssessmentAssessmentCodeSigningError = CFSTR("assessment:cserror");
142 CFStringRef kSecAssessmentAssessmentNotarizationDate = CFSTR("assessment:notarization-date");
143
144 CFStringRef kDisabledOverride = CFSTR("security disabled");
145
146 SecAssessmentRef SecAssessmentCreate(CFURLRef path,
147 SecAssessmentFlags flags,
148 CFDictionaryRef context,
149 CFErrorRef *errors)
150 {
151 BEGIN_CSAPI
152
153 if (flags & kSecAssessmentFlagAsynchronous)
154 MacOSError::throwMe(errSecCSUnimplemented);
155
156 AuthorityType type = typeFor(context, kAuthorityExecute);
157 CFRef<CFMutableDictionaryRef> result = makeCFMutableDictionary();
158
159 SYSPOLICY_ASSESS_API(cfString(path).c_str(), int(type), flags);
160
161 try {
162 if (flags & kSecAssessmentFlagDirect) {
163 // ask the engine right here to do its thing
164 SYSPOLICY_ASSESS_LOCAL();
165 gEngine().evaluate(path, type, flags, context, result);
166 } else {
167 // relay the question to our daemon for consideration
168 SYSPOLICY_ASSESS_REMOTE();
169 xpcEngineAssess(path, flags, context, result);
170 }
171 } catch (CommonError &error) {
172 switch (error.osStatus()) {
173 case CSSMERR_TP_CERT_REVOKED:
174 throw;
175 default:
176 if (!overrideAssessment(flags))
177 throw; // let it go as an error
178 break;
179 }
180 // record the error we would have returned
181 cfadd(result, "{%O=#F,'assessment:error'=%d}}", kSecAssessmentAssessmentVerdict, error.osStatus());
182 } catch (...) {
183 // catch stray errors not conforming to the CommonError scheme
184 if (!overrideAssessment(flags))
185 throw; // let it go as an error
186 cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict);
187 }
188
189 return new SecAssessment(path, type, result.yield());
190
191 END_CSAPI_ERRORS1(NULL)
192 }
193
194
195 static void traceResult(CFURLRef target, MessageTrace &trace, std::string &sanitized)
196 {
197 static const char *interestingBundles[] = {
198 "UNBUNDLED",
199 "com.apple.",
200 "com.install4j.",
201 "com.MindVision.",
202 "com.yourcompany.",
203
204 "com.adobe.flashplayer.installmanager",
205 "com.adobe.Installers.Setup",
206 "com.adobe.PDApp.setup",
207 "com.bittorrent.uTorrent",
208 "com.divx.divx6formacinstaller",
209 "com.getdropbox.dropbox",
210 "com.google.Chrome",
211 "com.Google.GoogleEarthPlugin.plugin",
212 "com.Google.GoogleEarthPlus",
213 "com.hp.Installer",
214 "com.macpaw.CleanMyMac",
215 "com.microsoft.SilverlightInstaller",
216 "com.paragon-software.filesystems.NTFS.pkg",
217 "com.RealNetworks.RealPlayer",
218 "com.skype.skype",
219 "it.alfanet.squared5.MPEGStreamclip",
220 "org.mozilla.firefox",
221 "org.videolan.vlc",
222
223 NULL // sentinel
224 };
225
226 string identifier = "UNBUNDLED";
227 string version = "UNKNOWN";
228 if (CFRef<CFBundleRef> bundle = _CFBundleCreateUnique(NULL, target)) {
229 if (CFStringRef ident = CFBundleGetIdentifier(bundle))
230 identifier = cfString(ident);
231 if (CFStringRef vers = CFStringRef(CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString"))))
232 version = cfString(vers);
233 }
234
235 CFRef<CFURLRef> url = CFURLCopyAbsoluteURL(target);
236 sanitized = cfString(url);
237 string::size_type rslash = sanitized.rfind('/');
238 if (rslash != string::npos)
239 sanitized = sanitized.substr(rslash+1);
240 bool keepFilename = false;
241 for (const char **pfx = interestingBundles; *pfx; pfx++) {
242 size_t pfxlen = strlen(*pfx);
243 if (identifier.compare(0, pfxlen, *pfx, pfxlen) == 0)
244 if (pfxlen == identifier.size() || (*pfx)[pfxlen-1] == '.') {
245 keepFilename = true;
246 break;
247 }
248 }
249 if (!keepFilename) {
250 string::size_type dot = sanitized.rfind('.');
251 if (dot != string::npos)
252 sanitized = sanitized.substr(dot);
253 else
254 sanitized = "(none)";
255 }
256
257 trace.add("signature2", "bundle:%s", identifier.c_str());
258 trace.add("signature3", "%s", sanitized.c_str());
259 trace.add("signature5", "%s", version.c_str());
260 }
261
262 static void traceAssessment(SecAssessment &assessment, AuthorityType type, CFDictionaryRef result)
263 {
264 if (CFDictionaryGetValue(result, CFSTR("assessment:remote")))
265 return; // just traced in syspolicyd
266
267 string authority = "UNSPECIFIED";
268 bool overridden = false;
269 bool old_overridden = false;
270 if (CFDictionaryRef authdict = CFDictionaryRef(CFDictionaryGetValue(result, kSecAssessmentAssessmentAuthority))) {
271 if (CFStringRef auth = CFStringRef(CFDictionaryGetValue(authdict, kSecAssessmentAssessmentSource)))
272 authority = cfString(auth);
273 else
274 authority = "no authority";
275 if (CFTypeRef override = CFDictionaryGetValue(authdict, kSecAssessmentAssessmentAuthorityOverride))
276 if (CFEqual(override, kDisabledOverride)) {
277 old_overridden = true;
278 if (CFDictionaryGetValue(authdict, kSecAssessmentAssessmentAuthorityOriginalVerdict) == kCFBooleanFalse)
279 overridden = true;
280 }
281 }
282
283 MessageTrace trace("com.apple.security.assessment.outcome2", NULL);
284 std::string sanitized;
285 traceResult(assessment.path, trace, sanitized);
286 trace.add("signature4", "%d", type);
287
288 if (CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict) == kCFBooleanFalse) {
289 trace.add("signature", "denied:%s", authority.c_str());
290 trace.send("assessment denied for %s", sanitized.c_str());
291 } else if (overridden) { // would have failed except for override
292 trace.add("signature", "defeated:%s", authority.c_str());
293 trace.send("assessment denied for %s but overridden", sanitized.c_str());
294 } else if (old_overridden) { // would have succeeded even without override
295 trace.add("signature", "override:%s", authority.c_str());
296 trace.send("assessment granted for %s and overridden", sanitized.c_str());
297 } else {
298 trace.add("signature", "granted:%s", authority.c_str());
299 trace.send("assessment granted for %s by %s", sanitized.c_str(), authority.c_str());
300 }
301 }
302
303 static void traceUpdate(CFTypeRef target, CFDictionaryRef context, CFDictionaryRef result)
304 {
305 // only trace add operations on URL targets
306 if (target == NULL || CFGetTypeID(target) != CFURLGetTypeID())
307 return;
308 CFStringRef edit = CFStringRef(CFDictionaryGetValue(context, kSecAssessmentContextKeyUpdate));
309 if (!CFEqual(edit, kSecAssessmentUpdateOperationAdd))
310 return;
311 MessageTrace trace("com.apple.security.assessment.update", NULL);
312 std::string sanitized;
313 traceResult(CFURLRef(target), trace, sanitized);
314 trace.send("added rule for %s", sanitized.c_str());
315 }
316
317
318 //
319 // At present, CopyResult simply retrieves the result already formed by Create.
320 // In the future, this will be more lazy.
321 //
322 CFDictionaryRef SecAssessmentCopyResult(SecAssessmentRef assessmentRef,
323 SecAssessmentFlags flags,
324 CFErrorRef *errors)
325 {
326 BEGIN_CSAPI
327
328 SecAssessment &assessment = SecAssessment::ref(assessmentRef);
329 CFCopyRef<CFDictionaryRef> result = assessment.result;
330 if (overrideAssessment(flags)) {
331 // turn rejections into approvals, but note that we did that
332 CFTypeRef verdict = CFDictionaryGetValue(result, kSecAssessmentAssessmentVerdict);
333 if (verdict == kCFBooleanFalse) {
334 CFRef<CFMutableDictionaryRef> adulterated = makeCFMutableDictionary(result.get());
335 CFDictionarySetValue(adulterated, kSecAssessmentAssessmentVerdict, kCFBooleanTrue);
336 if (CFDictionaryRef authority = CFDictionaryRef(CFDictionaryGetValue(adulterated, kSecAssessmentAssessmentAuthority))) {
337 CFRef<CFMutableDictionaryRef> authority2 = makeCFMutableDictionary(authority);
338 CFDictionarySetValue(authority2, kSecAssessmentAssessmentAuthorityOverride, kDisabledOverride);
339 CFDictionarySetValue(authority2, kSecAssessmentAssessmentAuthorityOriginalVerdict, verdict);
340 CFDictionarySetValue(adulterated, kSecAssessmentAssessmentAuthority, authority2);
341 } else {
342 cfadd(adulterated, "{%O={%O=%O}}",
343 kSecAssessmentAssessmentAuthority, kSecAssessmentAssessmentAuthorityOverride, kDisabledOverride);
344 }
345 result = adulterated.get();
346 }
347 }
348 traceAssessment(assessment, assessment.type, result);
349 return result.yield();
350
351 END_CSAPI_ERRORS1(NULL)
352 }
353
354
355 //
356 // Policy editing operations.
357 // These all make permanent changes to the system-wide authority records.
358 //
359 CFStringRef kSecAssessmentContextKeyUpdate = CFSTR("update");
360 CFStringRef kSecAssessmentUpdateOperationAdd = CFSTR("update:add");
361 CFStringRef kSecAssessmentUpdateOperationRemove = CFSTR("update:remove");
362 CFStringRef kSecAssessmentUpdateOperationEnable = CFSTR("update:enable");
363 CFStringRef kSecAssessmentUpdateOperationDisable = CFSTR("update:disable");
364 CFStringRef kSecAssessmentUpdateOperationFind = CFSTR("update:find");
365
366 CFStringRef kSecAssessmentUpdateKeyAuthorization = CFSTR("update:authorization");
367 CFStringRef kSecAssessmentUpdateKeyPriority = CFSTR("update:priority");
368 CFStringRef kSecAssessmentUpdateKeyLabel = CFSTR("update:label");
369 CFStringRef kSecAssessmentUpdateKeyExpires = CFSTR("update:expires");
370 CFStringRef kSecAssessmentUpdateKeyAllow = CFSTR("update:allow");
371 CFStringRef kSecAssessmentUpdateKeyRemarks = CFSTR("update:remarks");
372
373 CFStringRef kSecAssessmentUpdateKeyRow = CFSTR("update:row");
374 CFStringRef kSecAssessmentUpdateKeyCount = CFSTR("update:count");
375 CFStringRef kSecAssessmentUpdateKeyFound = CFSTR("update:found");
376
377 CFStringRef kSecAssessmentRuleKeyID = CFSTR("rule:id");
378 CFStringRef kSecAssessmentRuleKeyPriority = CFSTR("rule:priority");
379 CFStringRef kSecAssessmentRuleKeyAllow = CFSTR("rule:allow");
380 CFStringRef kSecAssessmentRuleKeyLabel = CFSTR("rule:label");
381 CFStringRef kSecAssessmentRuleKeyRemarks = CFSTR("rule:remarks");
382 CFStringRef kSecAssessmentRuleKeyRequirement = CFSTR("rule:requirement");
383 CFStringRef kSecAssessmentRuleKeyType = CFSTR("rule:type");
384 CFStringRef kSecAssessmentRuleKeyExpires = CFSTR("rule:expires");
385 CFStringRef kSecAssessmentRuleKeyDisabled = CFSTR("rule:disabled");
386 CFStringRef kSecAssessmentRuleKeyBookmark = CFSTR("rule:bookmark");
387
388
389 Boolean SecAssessmentUpdate(CFTypeRef target,
390 SecAssessmentFlags flags,
391 CFDictionaryRef context,
392 CFErrorRef *errors)
393 {
394 if (CFDictionaryRef outcome = SecAssessmentCopyUpdate(target, flags, context, errors)) {
395 CFRelease(outcome);
396 return true;
397 } else {
398 return false;
399 }
400 }
401
402 CFDictionaryRef SecAssessmentCopyUpdate(CFTypeRef target,
403 SecAssessmentFlags flags,
404 CFDictionaryRef context,
405 CFErrorRef *errors)
406 {
407 BEGIN_CSAPI
408
409 CFDictionary ctx(context, errSecCSInvalidAttributeValues);
410 CFRef<CFDictionaryRef> result;
411
412 // make context exist and writable
413 CFRef<CFMutableDictionaryRef> mcontext = context ? makeCFMutableDictionary(context) : makeCFMutableDictionary();
414
415 if (CFDictionaryGetValue(mcontext, kSecAssessmentUpdateKeyAuthorization) == NULL) {
416 // no authorization passed in. Make an empty one in this context
417 AuthorizationRef authorization;
418 MacOSError::check(AuthorizationCreate(NULL, NULL, kAuthorizationFlagDefaults, &authorization));
419 AuthorizationExternalForm extform;
420 MacOSError::check(AuthorizationMakeExternalForm(authorization, &extform));
421 CFDictionaryAddValue(mcontext, kSecAssessmentUpdateKeyAuthorization, CFTempData(&extform, sizeof(extform)));
422 if (!(flags & kSecAssessmentFlagDirect))
423 AuthorizationFree(authorization, kAuthorizationFlagDefaults);
424 }
425
426 if (flags & kSecAssessmentFlagDirect) {
427 // ask the engine right here to do its thing
428 result.take(gEngine().update(target, flags, ctx));
429 } else {
430 // relay the question to our daemon for consideration
431 result.take(xpcEngineUpdate(target, flags, ctx));
432 }
433
434 traceUpdate(target, context, result);
435 return result.yield();
436
437 END_CSAPI_ERRORS1(NULL)
438 }
439
440 static Boolean
441 updateAuthority(const char *authority, bool enable, CFErrorRef *errors)
442 {
443 CFStringRef updateValue = enable ? kSecAssessmentUpdateOperationEnable : kSecAssessmentUpdateOperationDisable;
444 CFTemp<CFDictionaryRef> ctx("{%O=%s, %O=%O}", kSecAssessmentUpdateKeyLabel, authority, kSecAssessmentContextKeyUpdate, updateValue);
445 return SecAssessmentUpdate(NULL, kSecCSDefaultFlags, ctx, errors);
446 }
447
448
449 //
450 // The fcntl of System Policies.
451 // For those very special requests.
452 //
453 Boolean SecAssessmentControl(CFStringRef control, void *arguments, CFErrorRef *errors)
454 {
455 BEGIN_CSAPI
456
457 if (CFEqual(control, CFSTR("ui-enable"))) {
458 setAssessment(true);
459 MessageTrace trace("com.apple.security.assessment.state", "enable");
460 trace.send("enable assessment outcomes");
461 return true;
462 } else if (CFEqual(control, CFSTR("ui-disable"))) {
463 setAssessment(false);
464 MessageTrace trace("com.apple.security.assessment.state", "disable");
465 trace.send("disable assessment outcomes");
466 return true;
467 } else if (CFEqual(control, CFSTR("ui-status"))) {
468 CFBooleanRef &result = *(CFBooleanRef*)(arguments);
469 if (overrideAssessment())
470 result = kCFBooleanFalse;
471 else
472 result = kCFBooleanTrue;
473 return true;
474 } else if (CFEqual(control, CFSTR("ui-enable-devid"))) {
475 updateAuthority("Developer ID", true, errors);
476 updateAuthority("Notarized Developer ID", true, errors);
477 MessageTrace trace("com.apple.security.assessment.state", "enable-devid");
478 trace.send("enable Developer ID approval");
479 return true;
480 } else if (CFEqual(control, CFSTR("ui-disable-devid"))) {
481 updateAuthority("Developer ID", false, errors);
482 MessageTrace trace("com.apple.security.assessment.state", "disable-devid");
483 trace.send("disable Developer ID approval");
484 return true;
485 } else if (CFEqual(control, CFSTR("ui-get-devid"))) {
486 xpcEngineCheckDevID((CFBooleanRef*)(arguments));
487 return true;
488 } else if (CFEqual(control, CFSTR("ui-get-devid-local"))) {
489 CFBooleanRef &result = *(CFBooleanRef*)(arguments);
490 if (gEngine().value<int>("SELECT disabled FROM authority WHERE label = 'Developer ID';", true))
491 result = kCFBooleanFalse;
492 else
493 result = kCFBooleanTrue;
494 return true;
495 } else if (CFEqual(control, CFSTR("ui-enable-notarized"))) {
496 updateAuthority("Notarized Developer ID", true, errors);
497 updateAuthority("Unnotarized Developer ID", true, errors);
498 MessageTrace trace("com.apple.security.assessment.state", "enable-notarized");
499 trace.send("enable Notarized Developer ID approval");
500 return true;
501 } else if (CFEqual(control, CFSTR("ui-disable-notarized"))) {
502 updateAuthority("Notarized Developer ID", false, errors);
503 updateAuthority("Unnotarized Developer ID", false, errors);
504 MessageTrace trace("com.apple.security.assessment.state", "disable-notarized");
505 trace.send("disable Notarized Developer ID approval");
506 return true;
507 } else if (CFEqual(control, CFSTR("ui-get-notarized"))) {
508 xpcEngineCheckNotarized((CFBooleanRef*)(arguments));
509 return true;
510 } else if (CFEqual(control, CFSTR("ui-get-notarized-local"))) {
511 CFBooleanRef &result = *(CFBooleanRef*)(arguments);
512 if (gEngine().value<int>("SELECT disabled FROM authority WHERE label = 'Notarized Developer ID';", true))
513 result = kCFBooleanFalse;
514 else
515 result = kCFBooleanTrue;
516 return true;
517 } else if (CFEqual(control, CFSTR("ui-record-reject"))) {
518 // send this through syspolicyd for update validation
519 xpcEngineRecord(CFDictionaryRef(arguments));
520 return true;
521 } else if (CFEqual(control, CFSTR("ui-record-reject-local"))) {
522 // perform the local operation (requires root)
523 gEngine().recordFailure(CFDictionaryRef(arguments));
524 return true;
525 } else if (CFEqual(control, CFSTR("ui-recall-reject"))) {
526 // no special privileges required for this, so read directly
527 CFDictionaryRef &result = *(CFDictionaryRef*)(arguments);
528 CFRef<CFDataRef> infoData = cfLoadFile(lastRejectFile);
529 if (infoData)
530 result = makeCFDictionaryFrom(infoData);
531 else
532 result = NULL;
533 return true;
534 } else if (CFEqual(control, CFSTR("rearm-status"))) {
535 CFTimeInterval &result = *(CFTimeInterval*)(arguments);
536 if (!queryRearmTimer(result))
537 result = 0;
538 return true;
539 } else
540 MacOSError::throwMe(errSecCSInvalidAttributeValues);
541
542 END_CSAPI_ERRORS1(false)
543 }
544
545 Boolean SecAssessmentTicketRegister(CFDataRef ticketData, CFErrorRef *errors)
546 {
547 BEGIN_CSAPI
548
549 xpcEngineTicketRegister(ticketData);
550 return true;
551
552 END_CSAPI_ERRORS1(false)
553 }
554
555 Boolean SecAssessmentRegisterPackageTicket(CFURLRef packageURL, CFErrorRef* errors)
556 {
557 BEGIN_CSAPI
558
559 string path = cfString(packageURL);
560 Xar xar(path.c_str());
561
562 if (!xar) {
563 MacOSError::throwMe(errSecParam);
564 }
565
566 xar.registerStapledNotarization();
567 return true;
568
569 END_CSAPI_ERRORS1(false)
570 }
571
572 Boolean SecAssessmentTicketLookup(CFDataRef hash, SecCSDigestAlgorithm hashType, SecAssessmentTicketFlags flags, double *date, CFErrorRef *errors)
573 {
574 BEGIN_CSAPI
575
576 xpcEngineTicketLookup(hash, hashType, flags, date);
577 return true;
578
579 END_CSAPI_ERRORS1(false)
580 }
581
582 Boolean SecAssessmentLegacyCheck(CFDataRef hash, SecCSDigestAlgorithm hashType, CFStringRef teamID, CFErrorRef *errors)
583 {
584 BEGIN_CSAPI
585
586 xpcEngineLegacyCheck(hash, hashType, teamID);
587 return true;
588
589 END_CSAPI_ERRORS1(false)
590 }
591