X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_codesigning/lib/SecRequirement.cpp diff --git a/libsecurity_codesigning/lib/SecRequirement.cpp b/libsecurity_codesigning/lib/SecRequirement.cpp deleted file mode 100644 index 7414cec9..00000000 --- a/libsecurity_codesigning/lib/SecRequirement.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -// -// SecRequirement - API frame for SecRequirement objects -// -#include "cs.h" -#include "Requirements.h" -#include "reqparser.h" -#include "reqmaker.h" -#include "reqdumper.h" -#include -#include - -using namespace CodeSigning; - - -// -// CF-standard type code function -// -CFTypeID SecRequirementGetTypeID(void) -{ - BEGIN_CSAPI - return gCFObjects().Requirement.typeID; - END_CSAPI1(_kCFRuntimeNotATypeID) -} - - -// -// Create a Requirement from data -// -OSStatus SecRequirementCreateWithData(CFDataRef data, SecCSFlags flags, - SecRequirementRef *requirementRef) -{ - BEGIN_CSAPI - - checkFlags(flags); - CodeSigning::Required(requirementRef) = (new SecRequirement(CFDataGetBytePtr(data), CFDataGetLength(data)))->handle(); - - END_CSAPI -} - - -// -// Create a Requirement from data in a file -// -OSStatus SecRequirementCreateWithResource(CFURLRef resource, SecCSFlags flags, - SecRequirementRef *requirementRef) -{ - BEGIN_CSAPI - - checkFlags(flags); - CFRef data = cfLoadFile(resource); - CodeSigning::Required(requirementRef) = - (new SecRequirement(CFDataGetBytePtr(data), CFDataGetLength(data)))->handle(); - - END_CSAPI -} - - -// -// Create a Requirement from source text (compiling it) -// -OSStatus SecRequirementCreateWithString(CFStringRef text, SecCSFlags flags, - SecRequirementRef *requirementRef) -{ - return SecRequirementCreateWithStringAndErrors(text, flags, NULL, requirementRef); -} - -OSStatus SecRequirementCreateWithStringAndErrors(CFStringRef text, SecCSFlags flags, - CFErrorRef *errors, SecRequirementRef *requirementRef) -{ - BEGIN_CSAPI - - checkFlags(flags); - CodeSigning::Required(requirementRef) = (new SecRequirement(parseRequirement(cfString(text)), true))->handle(); - - END_CSAPI_ERRORS -} - - -// -// Create a Requirement group. -// This is the canonical point where "application group" is defined. -// -OSStatus SecRequirementCreateGroup(CFStringRef groupName, SecCertificateRef anchorRef, - SecCSFlags flags, SecRequirementRef *requirementRef) -{ - BEGIN_CSAPI - - checkFlags(flags); - Requirement::Maker maker; - maker.put(opAnd); // both of... - maker.infoKey("Application-Group", cfString(groupName)); - if (anchorRef) { - CSSM_DATA certData; - MacOSError::check(SecCertificateGetData(anchorRef, &certData)); - maker.anchor(0, certData.Data, certData.Length); - } else { - maker.anchor(); // canonical Apple anchor - } - CodeSigning::Required(requirementRef) = (new SecRequirement(maker.make(), true))->handle(); - - END_CSAPI -} - - -// -// Extract the stable binary from from a SecRequirementRef -// -OSStatus SecRequirementCopyData(SecRequirementRef requirementRef, SecCSFlags flags, - CFDataRef *data) -{ - BEGIN_CSAPI - - const Requirement *req = SecRequirement::required(requirementRef)->requirement(); - checkFlags(flags); - CodeSigning::Required(data); - *data = makeCFData(*req); - - END_CSAPI -} - - -// -// Generate source form for a SecRequirement (decompile/disassemble) -// -OSStatus SecRequirementCopyString(SecRequirementRef requirementRef, SecCSFlags flags, - CFStringRef *text) -{ - BEGIN_CSAPI - - const Requirement *req = SecRequirement::required(requirementRef)->requirement(); - checkFlags(flags); - CodeSigning::Required(text); - *text = makeCFString(Dumper::dump(req)); - - END_CSAPI -} - - -// -CFStringRef kSecRequirementKeyInfoPlist = CFSTR("requirement:eval:info"); -CFStringRef kSecRequirementKeyEntitlements = CFSTR("requirement:eval:entitlements"); -CFStringRef kSecRequirementKeyIdentifier = CFSTR("requirement:eval:identifier"); - -OSStatus SecRequirementEvaluate(SecRequirementRef requirementRef, - CFArrayRef certificateChain, CFDictionaryRef context, - SecCSFlags flags) -{ - BEGIN_CSAPI - - const Requirement *req = SecRequirement::required(requirementRef)->requirement(); - checkFlags(flags); - CodeSigning::Required(certificateChain); - - Requirement::Context ctx(certificateChain, // mandatory - context ? CFDictionaryRef(CFDictionaryGetValue(context, kSecRequirementKeyInfoPlist)) : NULL, - context ? CFDictionaryRef(CFDictionaryGetValue(context, kSecRequirementKeyEntitlements)) : NULL, - (context && CFDictionaryGetValue(context, kSecRequirementKeyIdentifier)) ? - cfString(CFStringRef(CFDictionaryGetValue(context, kSecRequirementKeyIdentifier))) : "", - NULL // can't specify a CodeDirectory here - ); - req->validate(ctx); - - END_CSAPI -} - - -// -// Assemble a requirement set (as a CFData) from a dictionary of requirement objects. -// An empty set is allowed. -// -OSStatus SecRequirementsCreateFromRequirements(CFDictionaryRef requirements, SecCSFlags flags, - CFDataRef *requirementSet) -{ - BEGIN_CSAPI - - checkFlags(flags); - if (requirements == NULL) - return errSecCSObjectRequired; - CFIndex count = CFDictionaryGetCount(requirements); - CFNumberRef keys[count]; - SecRequirementRef reqs[count]; - CFDictionaryGetKeysAndValues(requirements, (const void **)keys, (const void **)reqs); - Requirements::Maker maker; - for (CFIndex n = 0; n < count; n++) { - const Requirement *req = SecRequirement::required(reqs[n])->requirement(); - maker.add(cfNumber(keys[n]), req->clone()); - } - Requirements *reqset = maker.make(); // malloc'ed - CodeSigning::Required(requirementSet) = makeCFDataMalloc(*reqset); // takes ownership of reqs - - END_CSAPI -} - - -// -// Break a requirement set (given as a CFData) into its constituent requirements -// and return it as a CFDictionary. -// -OSStatus SecRequirementsCopyRequirements(CFDataRef requirementSet, SecCSFlags flags, - CFDictionaryRef *requirements) -{ - BEGIN_CSAPI - - checkFlags(flags); - if (requirementSet == NULL) - return errSecCSObjectRequired; - const Requirements *reqs = (const Requirements *)CFDataGetBytePtr(requirementSet); - if (!reqs->validateBlob()) - MacOSError::throwMe(errSecCSReqInvalid); - CFRef dict = makeCFMutableDictionary(); - unsigned count = reqs->count(); - for (unsigned n = 0; n < count; n++) { - CFRef req = (new SecRequirement(reqs->blob(n)))->handle(); - CFDictionaryAddValue(dict, CFTempNumber(reqs->type(n)), req); - } - CodeSigning::Required(requirements) = dict.yield(); - - END_CSAPI -} - - -// -// Generically parse a string as some kind of requirement-related source form. -// If properly recognized, return the result as a CF object: -// SecRequirementRef for a single requirement -// CFDataRef for a requirement set -// -OSStatus SecRequirementsCreateWithString(CFStringRef text, SecCSFlags flags, - CFTypeRef *result, CFErrorRef *errors) -{ - BEGIN_CSAPI - - checkFlags(flags, kSecCSParseRequirement | kSecCSParseRequirementSet); - if (text == NULL || result == NULL) - return errSecCSObjectRequired; - std::string s = cfString(text); - switch (flags & (kSecCSParseRequirement | kSecCSParseRequirementSet)) { - case kSecCSParseRequirement: // single only - *result = (new SecRequirement(parseRequirement(s), true))->handle(); - break; - case kSecCSParseRequirementSet: // single only - { - const Requirements *reqs = parseRequirements(s); - *result = makeCFDataMalloc(*reqs); - break; - } - case 0: - case kSecCSParseRequirement | kSecCSParseRequirementSet: - { - const BlobCore *any = parseGeneric(s); - if (any->is()) - *result = (new SecRequirement(Requirement::specific(any), true))->handle(); - else - *result = makeCFDataMalloc(*any); - break; - } - } - - END_CSAPI_ERRORS -} - - -// -// Convert a SecRequirementRef or a CFDataRef containing a requirement set to text. -// Requirement sets will be formatted as multiple lines (one per requirement). They can be empty. -// A single requirement will return a single line that is NOT newline-terminated. -// -OSStatus SecRequirementsCopyString(CFTypeRef input, SecCSFlags flags, CFStringRef *text) -{ - BEGIN_CSAPI - - checkFlags(flags); - if (input == NULL) - return errSecCSObjectRequired; - if (CFGetTypeID(input) == SecRequirementGetTypeID()) { - return SecRequirementCopyString(SecRequirementRef(input), flags, text); - } else if (CFGetTypeID(input) == CFDataGetTypeID()) { - const Requirements *reqs = (const Requirements *)CFDataGetBytePtr(CFDataRef(input)); - if (!reqs->validateBlob(CFDataGetLength(CFDataRef(input)))) - return errSecCSReqInvalid; - CodeSigning::Required(text) = makeCFString(Dumper::dump(reqs, false)); - } else - return errSecCSInvalidObjectRef; - - END_CSAPI -}