1 // 2 // der_vm.h 3 // CoreEntitlements 4 // 5 6 #pragma once 7 8 #include "CoreEntitlements.h" 9 #include <stdint.h> 10 #include <stdbool.h> 11 12 // The kernel doesn't have access to this one 13 #if __has_include (<corecrypto/ccder.h>) 14 #include <corecrypto/ccder.h> 15 #else 16 typedef unsigned long ccder_tag; 17 #endif 18 19 20 /*! 21 * @typedef der_vm_context_t 22 * Represents the current execution state of the DERQL interpreter. 23 * The context can be initialized with der_vm_context_create and subsequently used in invocations of der_vm_execute. 24 * This object is passed by value and the functions that operate on the der_vm_context_t do not modify it but instead return a copy. 25 * As a consequence, the state of the interpreter can be captured at any execution point by holding on to the context. 26 */ 27 typedef struct der_vm_context { 28 CERuntime_t runtime; 29 ccder_tag dictionary_tag; 30 bool sorted; 31 bool valid; 32 struct { 33 const uint8_t *der_start; 34 const uint8_t *der_end; 35 } state; 36 } der_vm_context_t; 37 38 /*! 39 * @function der_vm_context_create 40 * Returns an initialized, valid, der_vm_context_t against which query operations may be performed 41 * @param rt 42 * Active runtime 43 * @param dictionary_tag 44 * Which DER tag should be used when matching dictionaries 45 * @param sorted_keys 46 * Whether the VM can assume that the keys are sorted 47 * @param der 48 * Pointer to the start of a DER object 49 * @param der_end 50 * Pointer to one byte past the end of the DER object 51 * @discussion 52 * The caller must ensure that the memory pointed to by der remains valid as long as the der_vm_context_t is used. 53 * The caller must ensure that the DER object has been validated. 54 */ 55 der_vm_context_t der_vm_context_create(const CERuntime_t rt, ccder_tag dictionary_tag, bool sorted_keys, const uint8_t *der, const uint8_t *der_end); 56 57 /*! 58 * @function der_vm_execute 59 * Returns a new context that is derived by applying the op to the passed in context 60 * 61 * @param context 62 * Context to execute against 63 * 64 * @param op 65 * An operation to be performed against the context 66 * This op should be created by one of the CEMatch* or CESelect* functions 67 * 68 * @discussion 69 * If the VM encounters: 70 * 1. Invalid operation 71 * 2. An operation that fails to execute 72 * 3. Invalid state 73 * The VM will attempt to return an invalid context. 74 * If the VM encounters an operation that it does not understand, the runtime's abort function will be executed. 75 */ 76 der_vm_context_t der_vm_execute(const der_vm_context_t context, CEQueryOperation_t op); 77 78 /*! 79 * @typedef der_vm_iteration_context 80 * Iteration context that gets passed in on every call 81 * 82 * @field original 83 * The original DER VM context (the container over which we are iterating) 84 * 85 * @field active 86 * The actively selected DER VM context (i.e. the value) 87 * 88 * @field parent_type 89 * The type of object being iterated over (dictionary or array) 90 * 91 * @field active_type 92 * The type of the selected object 93 * 94 * @field user_data 95 * The object you passed in the call to der_vm_iterate 96 */ 97 typedef struct { 98 der_vm_context_t original; 99 der_vm_context_t active; 100 CEType_t parent_type; 101 CEType_t active_type; 102 void* user_data; 103 } der_vm_iteration_context; 104 105 /*! 106 * @typedef der_vm_iteration_callback 107 * 108 * @brief Function definition for the callback that der_vm_iterate uses 109 * 110 * @param ctx The information about the iterable is stored here 111 */ 112 typedef bool (*der_vm_iteration_callback)(der_vm_iteration_context ctx); 113 114 /*! 115 * @function der_vm_iterate 116 * @brief Iterates over a DER container, caliing the callback for every element 117 * 118 * @param context The context that points to a container 119 * @param user_data This will be passed in verbatim in the der_vm_iteration_context 120 * @param callback This function is called for every element 121 * 122 * @returns kCENoError if the function exited normally 123 */ 124 CEError_t der_vm_iterate(const der_vm_context_t context, void* user_data, der_vm_iteration_callback callback); 125 126 /*! 127 * @function der_vm_context_is_valid 128 * Returns a boolean indication if a particular context is valid 129 * 130 * @param context 131 * The context in question 132 * 133 * @discussion 134 * It is generally safe to execute any operation against an invalid context 135 * However the resulting context will also be invalid 136 */ 137 bool der_vm_context_is_valid(const der_vm_context_t context); 138 139 /*! 140 * @function der_vm_CEType_from_context 141 * Returns a CEType_t corresponding to the context 142 * 143 * @param context 144 * The context in question 145 * @param tag 146 * Nullable pointer to where to store the decoded DER tag 147 */ 148 CEType_t der_vm_CEType_from_context(const der_vm_context_t context, ccder_tag* tag); 149 150 /*! 151 * @function der_vm_integer_from_context 152 * Returns the number selected by the current context 153 */ 154 int64_t der_vm_integer_from_context(const der_vm_context_t context); 155 156 /*! 157 * @function der_vm_string_from_context 158 * Returns the string selected by the current context 159 */ 160 CEBuffer der_vm_string_from_context(const der_vm_context_t context); 161 162 /*! 163 * @function der_vm_bool_from_context 164 * Returns the bool selected by the current context 165 */ 166 bool der_vm_bool_from_context(const der_vm_context_t context); 167 168 /*! 169 * @function der_vm_buffer_from_context 170 * Returns the content described by the tag in the context 171 */ 172 CEBuffer der_vm_buffer_from_context(const der_vm_context_t context); 173