+ xar.registerStapledNotarization();
+ checksum.take(xar.createPackageChecksum());
+ if (checksum) {
+ double notarizationDate = NAN;
+
+ // Force a single online check for the checksum, which is always SHA1.
+ bool is_revoked = checkNotarizationServiceForRevocation(checksum, kSecCodeSignatureHashSHA1, ¬arizationDate);
+ if (is_revoked) {
+ MacOSError::throwMe(errSecCSRevokedNotarization);
+ }
+
+ // Extract a team identifier from the certificates. This isn't validated and could be spoofed,
+ // but since the 'legacy' keyword is only used in addition to the Developer ID requirement,
+ // this is still stafe for now.
+ SecCertificateRef leaf = SecCertificateRef(CFArrayGetValueAtIndex(certs, 0));
+ CFRef<CFArrayRef> orgUnits = SecCertificateCopyOrganizationalUnit(leaf);
+ if (orgUnits.get() && CFArrayGetCount(orgUnits) == 1) {
+ teamID = (CFStringRef)CFArrayGetValueAtIndex(orgUnits, 0);
+ }
+
+ // Create the appropriate requirement context entry to allow notarized requirement check.
+ CFRef<CFNumberRef> algorithm = makeCFNumber((uint32_t)xar.checksumDigestAlgorithm());
+ cfadd(requirementContext, "{%O=%O}", kSecRequirementKeyPackageChecksum, checksum.get());
+ cfadd(requirementContext, "{%O=%O}", kSecRequirementKeyChecksumAlgorithm, algorithm.get());
+ if (teamID.get()) {
+ cfadd(requirementContext, "{%O=%O}", kSecRequirementKeyTeamIdentifier, teamID.get());
+ }
+
+ if (!isnan(notarizationDate)) {
+ CFRef<CFDateRef> date = CFDateCreate(NULL, notarizationDate);
+ if (date) {
+ cfadd(result, "{%O=%O}", kSecAssessmentAssessmentNotarizationDate, date.get());
+ }
+ }
+ }
+