1//
2// Entitlements.h
3// CoreEntitlements
4//
5//
6
7#ifndef CORE_ENTITLEMENTS_ENTITLEMENTS_H
8#define CORE_ENTITLEMENTS_ENTITLEMENTS_H
9
10#ifndef _CE_INDIRECT
11#error "Please include <CoreEntitlements/CoreEntitlements.h> instead of this file"
12#endif
13
14#include <CoreEntitlements/Result.h>
15#include <CoreEntitlements/Runtime.h>
16
17__ptrcheck_abi_assume_single();
18
19/*!
20 * @enum CEVersion_t
21 * Represents the various versions supported by CoreEntitlements
22 */
23OS_ENUM(CEVersion, int64_t,
24 kCEVersionInvalid = 0,
25 kCEVersionZero = 1,
26 kCEVersionOne = 2);
27
28/*!
29 * @struct CEValidationResult
30 * Contains the result of the call to CEValidate
31 */
32typedef struct {
33 CEVersion_t version;
34 const uint8_t *__ended_by(blob_end) blob;
35 const uint8_t * blob_end;
36} CEValidationResult;
37
38typedef struct {
39 bool allow_data_elements;
40} CEValidationOptions;
41
42/*!
43 * @function CEValidate
44 * Validates if the provided blob conforms to one of the entitlement specification understood by CoreEntitlements
45 * @param rt
46 * Active runtime
47 * @param result
48 * The validation result will be stored here
49 * @param blob
50 * Pointer to the start of the entitlements object
51 * @param blob_end
52 * Pointer to one byte past the end of the entitlements object
53 * @discussion
54 * This function will return kCENoError if the entitlements are valid
55 */
56CEError_t CEValidate(const CERuntime_t rt, CEValidationResult* result, const uint8_t *__ended_by(blob_end) blob, const uint8_t* blob_end) __result_use_check;
57/*!
58 * @function CEValidateWithOptions
59 * Validates if the provided blob conforms to one of the entitlement specification understood by CoreEntitlements
60 * @param rt
61 * Active runtime
62 * @param options
63 * Options that modify how validation behaves
64 * @param result
65 * The validation result will be stored here
66 * @param blob
67 * Pointer to the start of the entitlements object
68 * @param blob_end
69 * Pointer to one byte past the end of the entitlements object
70 * @discussion
71 * This function will return kCENoError if the entitlements are valid
72 */
73CEError_t CEValidateWithOptions(const CERuntime_t rt, CEValidationOptions* options, CEValidationResult* result, const uint8_t *__ended_by(blob_end) blob, const uint8_t* blob_end) __result_use_check;
74
75/*!
76 * @function CEAcquireManagedContext
77 * Creates and returns a managed query context for the validated blob against which you can perform queries
78 * @param rt
79 * Active runtime (must support allocation and deallocation)
80 * @param validationResult
81 * The validation result returned by CEValidate
82 * @param ctx
83 * Pointer to where the context is to be returned
84 * @note
85 * The returned managed context must be subsequently released with CEAcquireManagedContext
86 */
87CEError_t CEAcquireManagedContext(const CERuntime_t rt, CEValidationResult validationResult, CEQueryContext_t* ctx) __result_use_check;
88
89/*!
90 @discussion
91 Releases the managed context
92 */
93CEError_t CEReleaseManagedContext(CEQueryContext_t* ctx);
94
95/*!
96 * @enum CEQueryOpOpcode_t
97 * These are all the supported operations by the CoreEntitlements VM
98 */
99OS_ENUM(CEQueryOpOpcode, int64_t,
100 kCEOpNoop = 0,
101 kCEOpSelectKey = 1,
102 kCEOpSelectIndex = 2,
103 kCEOpMatchString = 3,
104 kCEOpMatchStringPrefix = 4,
105 kCEOpMatchBool = 5,
106 kCEOpStringValueAllowed = 6,
107 kCEOpMatchInteger = 7,
108 kCEOpStringPrefixValueAllowed = 8,
109 kCEOpSelectKeyWithPrefix = 9,
110 kCEOpIntegerValueAllowed = 10,
111 kCEOpMatchType = 11,
112 kCEOpMatchData = 12,
113 kCEOpMatchDataValueAllowed = 13,
114 kCEOpMaxOperation = 14, /* Sentinel value */
115 kCEOpDynamic = 0x1LL << 62);
116
117
118
119/*!
120 * @typedef CEQueryOperation_t
121 * Represents an operation within the DERQL interpreter
122 * The opcode specified _which_ operation to perform, while the parameters specify how to perform it.
123 * Operations are passed by value and may be safely reused.
124 */
125typedef struct CEQueryOperation {
126 CEQueryOpOpcode_t opcode;
127 union {
128 CEBuffer dynamicParameter;
129 CEStaticBuffer stringParameter;
130 int64_t numericParameter;
131 } parameters;
132} CEQueryOperation_t;
133
134typedef CEQueryOperation_t CEQuery_t[];
135
136extern const CEQueryOperation_t* CESelectKeyOperation;
137extern const CEQueryOperation_t* CESelectValueOperation;
138
139/*!
140 * @typedef CEPrepareOptions_t
141 * Containts the options you may pass in to CEPrepareQuery.
142 */
143typedef struct CEPrepareOptions {
144 /*
145 If materialize is true dynamic ops are turned into static ones
146 */
147 bool materialize;
148 /*
149 Controls if CEPrepareQuery should fail on keys in dynamic operations that are too long
150 */
151 bool failOnOversizedParameters;
152} CEPrepareOptions_t;
153
154/*!
155 * @function CEContextQuery
156 * Performs a query on the passed in CEQueryContext_t
157 *
158 * @param ctx
159 * The context on which to perform the query
160 *
161 * @param query
162 * The sequence of operations to execute
163 *
164 * @param queryLength
165 * The number of operations in the query
166 *
167 * @returns
168 * This function will return kCENoError if the query is satisfiable, otherwise kCEQueryCannotBeSatisfied.
169 *
170 * @note
171 * As stated previously, the query only succeeds if it is satisfiable by the context, meaning that the operations executed in the passed in order
172 * leave the VM in the valid state. An invalid state may arise from a variety of situations, like trying to select a value for a key that doesn't exist,
173 * or a failing string matching operations.
174 */
175CEError_t CEContextQuery(CEQueryContext_t ctx, const CEQueryOperation_t *__counted_by(queryLength) query, size_t queryLength) __result_use_check;
176
177/*!
178 * @function CEPrepareQuery
179 * Prepares the query for execution by materializing dynamic operations if needed
180 *
181 * @params options
182 * Options to control how the query should be prepared
183 *
184 * @param query
185 * The sequence of operations to prepare
186 *
187 * @param queryLength
188 * The number of operations in the query
189 */
190CEError_t CEPrepareQuery(CEPrepareOptions_t options, CEQueryOperation_t *__counted_by(queryLength) query, size_t queryLength);
191
192/*!
193 * @function CEContextIsSubset
194 * Checks if the subset <-> superset relation holds between two context.
195 * The logic relations used to establish that relation correspond to the normal profile-validation rules.
196 *
197 * @param subset
198 * The context that is meant to a subset
199 *
200 * @param superset
201 * The context that is meant to be a superset
202 *
203 * @returns
204 * This function will return kCENoError if the relation holds, otherwise kCEQueryCannotBeSatisfied.
205 */
206CEError_t CEContextIsSubset(CEQueryContext_t subset, CEQueryContext_t superset);
207
208#include <CoreEntitlements/QueryHelpers.h>
209
210#endif
211