X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_transform/lib/SecCustomTransform.h?ds=inline diff --git a/Security/libsecurity_transform/lib/SecCustomTransform.h b/Security/libsecurity_transform/lib/SecCustomTransform.h new file mode 100644 index 00000000..95e807e6 --- /dev/null +++ b/Security/libsecurity_transform/lib/SecCustomTransform.h @@ -0,0 +1,944 @@ +/* + * Copyright (c) 2010-2011,2014 Apple 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@ + */ + +#ifndef _SEC_CUSTOM_TRANSFORM_H__ +#define _SEC_CUSTOM_TRANSFORM_H__ + +#include + +// Blocks are required for custom transforms +#ifdef __BLOCKS__ + +CF_EXTERN_C_BEGIN + +/*! + @header + + Custom transforms are an API that provides the ability to easily create new + transforms. The essential functions of a transform are created in a + collection of blocks. These blocks override the standard behavior of the + base transform; a custom transform with no overrides is a null transform + that merely passes through a data flow. + + A new transform type is created when calling the SecTransformRegister + function which registers the name of the new transform and sets up its + overrides. The SecTransformCreate function creates a new instance of a + registered custom transform. + + A sample custom transform is provided here, along with a basic test program. + This transform creates a Caesar cipher transform, one that simply adds a + value to every byte of the plaintext. + + -----cut here----- +
+@textblock
+//
+//  CaesarXform.c
+//
+//  Copyright (c) 2010-2011,2014 Apple Inc. All Rights Reserved.
+//
+//
+
+#include 
+#include 
+
+// This is the unique name for the custom transform type.
+const CFStringRef kCaesarCipher = CFSTR("com.apple.caesarcipher");
+
+// Name of the "key" attribute.
+const CFStringRef kKeyAttributeName = CFSTR("key");
+
+// Shortcut to return a CFError.
+CFErrorRef invalid_input_error(void)
+{
+    return CFErrorCreate(kCFAllocatorDefault, kSecTransformErrorDomain,
+                         kSecTransformErrorInvalidInput, NULL);
+}
+
+// =========================================================================
+//  Implementation of the Transform instance
+// =========================================================================
+static SecTransformInstanceBlock CaesarImplementation(CFStringRef name,
+                                            SecTransformRef newTransform,
+                                            SecTransformImplementationRef ref)
+{
+   
+    SecTransformInstanceBlock instanceBlock =
+    ^{
+        CFErrorRef result = NULL;
+
+        // Every time a new instance of this custom transform class is
+        // created, this block is called. This behavior means that any
+        // block variables created in this block act like instance
+        // variables for the new custom transform instance.
+        __block int _key = 0;
+
+        result = SecTransformSetAttributeAction(ref,
+                                                kSecTransformActionAttributeNotification,
+                                                kKeyAttributeName,
+                                                ^(SecTransformAttributeRef name, CFTypeRef d)
+            {
+                CFNumberGetValue((CFNumberRef)d, kCFNumberIntType, &_key);
+                return d;
+            });
+
+        if (result)
+            return result;
+
+        // Create an override that will be called to process the input
+        // data into the output data
+        result = SecTransformSetDataAction(ref,
+                                           kSecTransformActionProcessData,
+                                           ^(CFTypeRef d)
+            {
+                if (NULL == d)               // End of stream?
+                    return (CFTypeRef) NULL; // Just return a null.
+
+                char *dataPtr = (char *)CFDataGetBytePtr((CFDataRef)d);
+
+                CFIndex dataLength = CFDataGetLength((CFDataRef)d);
+
+                // Do the processing in memory.  There are better ways to do
+                // this but for showing how custom transforms work this is fine.
+                char *buffer = (char *)malloc(dataLength);
+                if (NULL == buffer)
+                    return (CFTypeRef) invalid_input_error();            // Return a CFErrorRef
+
+                // Do the work of the caesar cipher (Rot(n))
+
+                CFIndex i;
+                for (i = 0; i < dataLength; i++)
+                    buffer[i] = dataPtr[i] + _key;
+
+                return (CFTypeRef)CFDataCreateWithBytesNoCopy(NULL, (UInt8 *)buffer,
+                                                              dataLength, kCFAllocatorMalloc);
+            });
+        return result;
+    };
+
+    return Block_copy(instanceBlock);
+}
+
+SecTransformRef CaesarTransformCreate(CFIndex k, CFErrorRef* error)
+{
+    SecTransformRef caesarCipher;
+    __block Boolean result = 1;
+    static dispatch_once_t registeredOK = 0;
+
+    dispatch_once(®isteredOK,
+                  ^{
+                     result = SecTransformRegister(kCaesarCipher, &CaesarImplementation, error);
+                  });
+
+    if (!result)
+        return NULL;
+
+    caesarCipher = SecTransformCreate(kCaesarCipher, error);
+    if (NULL != caesarCipher)
+    {
+        CFNumberRef keyNumber =  CFNumberCreate(kCFAllocatorDefault,
+                                                kCFNumberIntType, &k);
+        SecTransformSetAttribute(caesarCipher, kKeyAttributeName,
+                                 keyNumber, error);
+        CFRelease(keyNumber);
+    }
+
+    return caesarCipher;
+}
+
+
+// The second function shows how to use custom transform defined in the
+// previous function
+
+// =========================================================================
+//  Use a custom ROT-N (caesar cipher) transform
+// =========================================================================
+CFDataRef TestCaesar(CFDataRef theData, int rotNumber)
+{
+    CFDataRef result = NULL;
+    CFErrorRef error = NULL;
+
+    if (NULL == theData)
+        return result;
+
+    // Create an instance of the custom transform
+    SecTransformRef caesarCipher = CaesarTransformCreate(rotNumber, &error);
+    if (NULL == caesarCipher || NULL != error)
+        return result;
+
+    // Set the data to be transformed as the input to the custom transform
+    SecTransformSetAttribute(caesarCipher,
+                             kSecTransformInputAttributeName, theData, &error);
+
+    if (NULL != error)
+    {
+        CFRelease(caesarCipher);
+        return result;
+    }
+
+    // Execute the transform synchronously
+    result = (CFDataRef)SecTransformExecute(caesarCipher, &error);
+    CFRelease(caesarCipher);
+
+    return result;
+}
+
+#include 
+
+int main (int argc, const char *argv[])
+{
+    CFDataRef testData, testResult;
+    UInt8 bytes[26];
+    int i;
+
+    // Create some test data, a string from A-Z
+
+    for (i = 0; i < sizeof(bytes); i++)
+        bytes[i] = 'A' + i;
+
+    testData = CFDataCreate(kCFAllocatorDefault, bytes, sizeof(bytes));
+    CFRetain(testData);
+    CFShow(testData);
+
+    // Encrypt the test data
+    testResult = TestCaesar(testData, 3);
+
+    CFShow(testResult);
+    CFRelease(testData);
+    CFRelease(testResult);
+    return 0;
+}
+@/textblock
+
+ +*/ + +/**************** Custom Transform attribute metadata ****************/ + +/*! + @enum Custom Transform Attribute Metadata + @discussion + Within a transform, each of its attributes is a collection of + "metadata attributes", of which name and current value are two. The + value is directly visible from outside; the other metadata + attributes direct the behavior of the transform and + its function within its group. Each attribute may be tailored by setting its metadata. + + @const kSecTransformMetaAttributeValue + The actual value of the attribute. The attribute value has a default + value of NULL. + + @const kSecTransformMetaAttributeName + The name of the attribute. Attribute name is read only and may + not be used with the SecTransformSetAttributeBlock block. + + @const kSecTransformMetaAttributeRef + A direct reference to an attribute's value. This reference allows + for direct access to an attribute without having to look up the + attribute by name. If a transform commonly uses an attribute, using + a reference speeds up the use of that attribute. Attribute + references are not visible or valid from outside of the particular + transform instance. + + @const kSecTransformMetaAttributeRequired + Specifies if an attribute must have a non NULL value set or have an + incoming connection before the transform starts to execute. This + metadata has a default value of true for the input attribute, but + false for all other attributes. + + @const kSecTransformMetaAttributeRequiresOutboundConnection + Specifies if an attribute must have an outbound connection. This + metadata has a default value of true for the output attribute but is + false for all other attributes. + + @const kSecTransformMetaAttributeDeferred + Determines if the AttributeSetNotification notification or the + ProcessData blocks are deferred until SecExecuteTransform is called. + This metadata value has a default value of true for the input + attribute but is false for all other attributes. + + @const kSecTransformMetaAttributeStream + Specifies if the attribute should expect a series of values ending + with a NULL to specify the end of the data stream. This metadata has + a default value of true for the input and output attributes, but is + false for all other attributes. + + @const kSecTransformMetaAttributeCanCycle + A Transform group is a directed graph which is typically acyclic. + Some transforms need to work with cycles. For example, a transform + that emits a header and trailer around the data of another transform + must create a cycle. If this metadata set to true, no error is + returned if a cycle is detected for this attribute. + + @const kSecTransformMetaAttributeExternalize + Specifies if this attribute should be written out when creating the + external representation of this transform. This metadata has a + default value of true. + + @const kSecTransformMetaAttributeHasOutboundConnections + This metadata value is true if the attribute has an outbound + connection. This metadata is read only. + + @const kSecTransformMetaAttributeHasInboundConnection + This metadata value is true if the attribute has an inbound + connection. This metadata is read only. +*/ + +enum +{ + kSecTransformMetaAttributeValue, + kSecTransformMetaAttributeName, + kSecTransformMetaAttributeRef, + kSecTransformMetaAttributeRequired, + kSecTransformMetaAttributeRequiresOutboundConnection, + kSecTransformMetaAttributeDeferred, + kSecTransformMetaAttributeStream, + kSecTransformMetaAttributeCanCycle, + kSecTransformMetaAttributeExternalize, + kSecTransformMetaAttributeHasOutboundConnections, + kSecTransformMetaAttributeHasInboundConnection +}; + +typedef CFIndex SecTransformMetaAttributeType; + +/*! + @typedef SecTransformAttributeRef + + @abstract A direct reference to an attribute. Using an attribute + reference speeds up using an attribute's value by removing + the need to look + it up by name. +*/ +typedef CFTypeRef SecTransformAttributeRef; + + +/*! + @typedef SecTransformStringOrAttributeRef + + @abstract This type signifies that either a CFStringRef or + a SecTransformAttributeRef may be used. +*/ +typedef CFTypeRef SecTransformStringOrAttributeRef; + + +/*! + @typedef SecTransformActionBlock + + @abstract A block that overrides the default behavior of a + custom transform. + + @result If this block is used to overide the + kSecTransformActionExternalizeExtraData action then the + block should return a CFDictinaryRef of the custom + items to be exported. For all of other actions the + block should return NULL. If an error occurs for + any action, the block should return a CFErrorRef. + + @discussion A SecTransformTransformActionBlock block is used to + override + the default behavior of a custom transform. This block is + associated with the SecTransformOverrideTransformAction + block. + + The behaviors that can be overridden are: + + kSecTransformActionCanExecute + Determine if the transform has all of the data + needed to run. + + kSecTransformActionStartingExecution + Called just before running ProcessData. + + kSecTransformActionFinalize + Called just before deleting the custom transform. + + kSecTransformActionExternalizeExtraData + Called to allow for writing out custom data + to be exported. + + Example: +
+@textblock
+                    SecTransformImplementationRef ref;
+                    CFErrorRef error = NULL;
+
+                    error = SecTransformSetTransformAction(ref, kSecTransformActionStartingExecution,
+                    ^{
+                        // This is where the work to initialize any data needed
+                        // before running
+                        CFErrorRef result = DoMyInitialization();
+                        return result;
+                    });
+
+                    SecTransformTransformActionBlock actionBlock =
+                    ^{
+                        // This is where the work to clean up any existing data
+                        // before running
+                        CFErrorRef result = DoMyFinalization();
+                        return result;
+                    };
+
+                    error = SecTransformSetTransformAction(ref, kSecTransformActionFinalize,
+                        actionBlock);
+@/textblock
+
+*/ +typedef CFTypeRef (^SecTransformActionBlock)(void); + +/*! + @typedef SecTransformAttributeActionBlock + + @abstract A block used to override the default attribute handling + for when an attribute is set. + + @param attribute The attribute whose default is being overridden or NULL + if this is a generic notification override + + @param value Proposed new value for the attribute. + + @result The new value of the attribute if successful. If an + error occurred then a CFErrorRef is returned. If a transform + needs to have a CFErrorRef as the value of an attribute, + then the CFErrorRef needs to be placed into a container such + as a CFArrayRef, CFDictionaryRef etc. + + @discussion See the example program in this header for more details. + +*/ +typedef CFTypeRef (^SecTransformAttributeActionBlock)( + SecTransformAttributeRef attribute, + CFTypeRef value); + +/*! + @typedef SecTransformDataBlock + + @abstract A block used to override the default data handling + for a transform. + + @param data The data to be processed. When this block is used + to to implement the kSecTransformActionProcessData action, + the data is the input data that is to be processed into the + output data. When this block is used to implement the + kSecTransformActionInternalizeExtraData action, the data is + a CFDictionaryRef that contains the data that needs to be + imported. + + @result When this block is used to implment the + kSecTransformActionProcessData action, the value returned + is to be the data that will be passed to the output + attribute. If an error occured while processing the input + data then the block should return a CFErrorRef. + + When this block is used to implement the + kSecTransformActionInternalizeExtraData action then this block + should return NULL or a CFErrorRef if an error occurred. + + @discussion See the example program for more details. +*/ +typedef CFTypeRef (^SecTransformDataBlock)(CFTypeRef data); + +/*! + @typedef SecTransformInstanceBlock + + @abstract This is the block that is returned from an + implementation of a CreateTransform function. + + @result A CFErrorRef if an error occurred or NULL. + + @discussion The instance block that is returned from the + developers CreateTransform function, defines + the behavior of a custom attribute. Please + see the example at the head of this file. + +*/ +typedef CFErrorRef (^SecTransformInstanceBlock)(void); + +/*! + @typedef SecTransformImplementationRef + + @abstract The SecTransformImplementationRef is a pointer to a block + that implements an instance of a transform. + +*/ +typedef const struct OpaqueSecTransformImplementation* SecTransformImplementationRef; + +/*! + @function SecTransformSetAttributeAction + + @abstract Be notified when a attribute is set. The supplied block is + called when the attribute is set. This can be done for a + specific named attribute or all attributes. + + @param ref A SecTransformImplementationRef that is bound to an instance + of a custom transform. + + @param action The behavior to be set. This can be one of the following + actions: + + kSecTransformActionAttributeNotification - add a block that + is called when an attribute is set. If the name is NULL, + then the supplied block is called for all set attributes + except for ones that have a specific block as a handler. + + For example, if there is a handler for the attribute "foo" + and for all attributes, the "foo" handler is called when the + "foo" attribute is set, but all other attribute sets will + call the NULL handler. + + The kSecTransformActionProcessData action is a special case + of a SecTransformSetAttributeAction action. If this is + called on the input attribute then it will overwrite any + kSecTransformActionProcessData that was set. + + kSecTransformActionAttributeValidation Add a block that is + called to validate the input to an attribute. + + @param attribute + The name of the attribute that will be handled. An attribute + reference may also be given here. A NULL name indicates that + the supplied action is for all attributes. + + @param newAction + A SecTransformAttributeActionBlock which implements the + behavior. + + @result A CFErrorRef if an error occured NULL otherwise. + + @discussion This function may be called multiple times for either a + named attribute or for all attributes when the attribute + parameter is NULL. Each time the API is called it overwrites + what was there previously. + +*/ +CF_EXPORT +CFErrorRef SecTransformSetAttributeAction(SecTransformImplementationRef ref, + CFStringRef action, + SecTransformStringOrAttributeRef attribute, + SecTransformAttributeActionBlock newAction); +/*! + @function SecTransformSetDataAction + + @abstract Change the way a custom transform will do data processing. + When the action parameter is kSecTransformActionProcessData + The newAction block will change the way that input data is + processed to become the output data. When the action + parameter is kSecTransformActionInternalizeExtraData it will + change the way a custom transform reads in data to be + imported into the transform. + + @param ref A SecTransformImplementationRef that is bound to an instance + of a custom transform. + + @param action The action being overridden. This value should be one of the + following: + kSecTransformActionProcessData + Change the way that input data is processed into the + output data. The default behavior is to simply copy + the input data to the output attribute. + + The kSecTransformActionProcessData action is really + a special case of a SecTransformSetAttributeAction + action. If you call this method with + kSecTransformActionProcessData it would overwrite + any kSecTransformActionAttributeNotification action + that was set proviously + + kSecTransformActionInternalizeExtraData + Change the way that custom externalized data is + imported into the transform. The default behavior + is to do nothing. + + @param newAction + A SecTransformDataBlock which implements the behavior. + + If the action parameter is kSecTransformActionProcessData then + this block will be called to process the input data into the + output data. + + if the action parameter is kSecTransformActionInternalizeExtraData then + this block will called to input custom data into the transform. + + @result A CFErrorRef is an error occured NULL otherwise. + + @discussion This API may be called multiple times. Each time the API is called + it overwrites what was there previously. + +*/ +CF_EXPORT +CFErrorRef SecTransformSetDataAction(SecTransformImplementationRef ref, + CFStringRef action, + SecTransformDataBlock newAction); + +/* + @function SecTransformSetTransformAction + + @abstract Change the way that transform deals with transform lifecycle + behaviors. + + @param ref A SecTransformImplementationRef that is bound to an instance + of a custom transform. It provides the neccessary context + for making the call to modify a custom transform. + + @param action Defines what behavior will be changed. The possible values + are: + + kSecTransformActionCanExecute + A CanExecute block is called before the transform + starts to execute. Returning NULL indicates that the + transform has all necessary parameters set up to be + able to execute. If there is a condition that + prevents this transform from executing, return a + CFError. The default behavior is to return NULL. + + kSecTransformActionStartingExecution + A StartingExecution block is called as a transform + starts execution but before any input is delivered. + Transform-specific initialization can be performed + in this block. + + kSecTransformActionFinalize + A Finalize block is called before a transform is + released. Any final cleanup can be performed in this + block. + + kSecTransformActionExternalizeExtraData + An ExternalizeExtraData block is called before a + transform is externalized. If there is any extra + work that the transform needs to do (e.g. copy data + from local variables to attributes) it can be + performed in this block. + + @param newAction + A SecTransformTransformActionBlock which implements the behavior. + + @result A CFErrorRef if an error occured NULL otherwise. + +*/ +CF_EXPORT +CFErrorRef SecTransformSetTransformAction(SecTransformImplementationRef ref, + CFStringRef action, + SecTransformActionBlock newAction); + +/*! + @function SecTranformCustomGetAttribute + + @abstract Allow a custom transform to get an attribute value + + @param ref A SecTransformImplementationRef that is bound to an instance + of a custom transform. + + @param attribute + The name or the attribute handle of the attribute whose + value is to be retrieved. + + @param type The type of data to be retrieved for the attribute. See the + discussion on SecTransformMetaAttributeType for details. + + @result The value of the attribute. + + */ +CF_EXPORT +CFTypeRef SecTranformCustomGetAttribute(SecTransformImplementationRef ref, + SecTransformStringOrAttributeRef attribute, + SecTransformMetaAttributeType type) AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8; + +/*! + @function SecTransformCustomGetAttribute + + @abstract Allow a custom transform to get an attribute value + + @param ref A SecTransformImplementationRef that is bound to an instance + of a custom transform. + + @param attribute + The name or the attribute handle of the attribute whose + value is to be retrieved. + + @param type The type of data to be retrieved for the attribute. See the + discussion on SecTransformMetaAttributeType for details. + + @result The value of the attribute. + + */ +CF_EXPORT +CFTypeRef SecTransformCustomGetAttribute(SecTransformImplementationRef ref, + SecTransformStringOrAttributeRef attribute, + SecTransformMetaAttributeType type) __asm__("_SecTranformCustomGetAttribute"); + +/*! + @function SecTransformCustomSetAttribute + + @abstract Allow a custom transform to set an attribute value + + @param ref A SecTransformImplementationRef that is bound to an instance + of a custom transform. + + @param attribute + The name or the attribute handle of the attribute whose + value is to be set. + + @param type The type of data to be retrieved for the attribute. See the + discussion on SecTransformMetaAttributeType for details. + + @param value The new value for the attribute + + @result A CFErrorRef if an error occured , NULL otherwise. + + @discussion Unlike the SecTransformSetAttribute API this API can set + attribute values while a transform is executing. These + values are limited to the custom transform instance that + is bound to the ref parameter. + +*/ +CF_EXPORT +CFTypeRef SecTransformCustomSetAttribute(SecTransformImplementationRef ref, + SecTransformStringOrAttributeRef attribute, + SecTransformMetaAttributeType type, + CFTypeRef value); +/*! + @function SecTransformPushbackAttribute + + @abstract Allows for putting a single value back for a specific + attribute. This will stop the flow of data into the + specified attribute until any attribute is changed for the + transform instance bound to the ref parameter. + + @param ref A SecTransformImplementationRef that is bound to an instance + of a custom transform. + + @param attribute + The name or the attribute handle of the attribute whose + value is to be pushed back. + + @param value The value being pushed back. + + @result A CFErrorRef if an error occured , NULL otherwise. + +*/ +CF_EXPORT +CFTypeRef SecTransformPushbackAttribute(SecTransformImplementationRef ref, + SecTransformStringOrAttributeRef attribute, + CFTypeRef value); + +/*! + @typedef SecTransformCreateFP + + @abstract A function pointer to a function that will create a + new instance of a custom transform. + + @param name The name of the new custom transform. This name MUST be + unique. + + @param newTransform + The newly created transform Ref. + + @param ref A reference that is bound to an instance of a custom + transform. + + @result A SecTransformInstanceBlock that is used to create a new + instance of a custom transform. + + @discussion The CreateTransform function creates a new transform. The + SecTransformInstanceBlock that is returned from this + function provides the implementation of all of the overrides + necessary to create the custom transform. This returned + SecTransformInstanceBlock is also where the "instance" + variables for the custom transform may be defined. See the + example in the header section of this file for more detail. +*/ + +typedef SecTransformInstanceBlock (*SecTransformCreateFP)(CFStringRef name, + SecTransformRef newTransform, + SecTransformImplementationRef ref); + +/************** custom Transform transform override actions **************/ + +/*! + @constant kSecTransformActionCanExecute + Overrides the standard behavior that checks to see if all of the + required attributes either have been set or are connected to + another transform. When overriding the default behavior the + developer can decided what the necessary data is to have for a + transform to be considered 'ready to run'. Returning NULL means + that the transform is ready to be run. If the transform is NOT + ready to run then the override should return a CFErrorRef + stipulating the error. + */ +CF_EXPORT const CFStringRef kSecTransformActionCanExecute; +/*! + @constant kSecTransformActionStartingExecution + Overrides the standard behavior that occurs just before starting + execution of a custom transform. This is typically overridden + to allow for initialization. This is used with the + SecTransformOverrideTransformAction block. + */ +CF_EXPORT const CFStringRef kSecTransformActionStartingExecution; + +/*! + @constant kSecTransformActionFinalize + Overrides the standard behavior that occurs just before deleting + a custom transform. This is typically overridden to allow for + memory clean up of a custom transform. This is used with the + SecTransformOverrideTransformAction block. + */ +CF_EXPORT const CFStringRef kSecTransformActionFinalize; + +/*! + + @constant kSecTransformActionExternalizeExtraData + Allows for adding to the data that is stored using an override + to the kSecTransformActionExternalizeExtraData block. The output + of this override is a dictionary that contains the custom + externalized data. A common use of this override is to write out + a version number of a custom transform. + */ +CF_EXPORT const CFStringRef kSecTransformActionExternalizeExtraData; + +/*! + @constant kSecTransformActionProcessData + Overrides the standard data processing for an attribute. This is + almost exclusively used for processing the input attribute as + the return value of their block sets the output attribute. This + is used with the SecTransformOverrideAttributeAction block. + */ +CF_EXPORT const CFStringRef kSecTransformActionProcessData; + +/*! + @constant kSecTransformActionInternalizeExtraData + Overrides the standard processing that occurs when externalized + data is used to create a transform. This is closely tied to the + kSecTransformActionExternalizeExtraData override. The 'normal' + attributes are read into the new transform and then this is + called to read in the items that were written out using + kSecTransformActionExternalizeExtraData override. A common use + of this override would be to read in the version number of the + externalized custom transform. + */ +CF_EXPORT const CFStringRef kSecTransformActionInternalizeExtraData; + +/*! + @constant SecTransformActionAttributeNotification + Allows a block to be called when an attribute is set. This + allows for caching the value as a block variable in the instance + block or transmogrifying the data to be set. This action is + where a custom transform would be able to do processing outside + of processing input to output as process data does. One the + data has been processed the action block can call + SecTransformCustomSetAttribute to update and other attribute. + */ +CF_EXPORT const CFStringRef kSecTransformActionAttributeNotification; + +/*! + @constant kSecTransformActionAttributeValidation + Allows a block to be called to validate the new value for an + attribute. The default is no validation and any CFTypeRef can + be used as the new value. The block should return NULL if the + value is ok to set on the attribute or a CFErrorRef otherwise. + +*/ +CF_EXPORT const CFStringRef kSecTransformActionAttributeValidation; + +/*! + @function SecTransformRegister + + @abstract Register a new custom transform so that it may be used to + process data + + @param uniqueName + A unique name for this custom transform. It is recommended + that a reverse DNS name be used for the name of your custom + transform + + @param createTransformFunction + A SecTransformCreateFP function pointer. The function must + return a SecTransformInstanceBlock block that block_copy has + been called on before returning the block. Failure to call + block_copy will cause undefined behavior. + + @param error This pointer is set if an error occurred. This value + may be NULL if you do not want an error returned. + + @result True if the custom transform was registered false otherwise + +*/ +CF_EXPORT +Boolean SecTransformRegister(CFStringRef uniqueName, + SecTransformCreateFP createTransformFunction, + CFErrorRef* error) + __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); + +/*! + @function SecTransformCreate + + @abstract Creates a transform computation object. + + @param name The type of transform to create, must have been registered + by SecTransformRegister, or be a system pre-defined + transform type. + + @param error A pointer to a CFErrorRef. This pointer is set if an error + occurred. This value may be NULL if you do not want an + error returned. + + @result A pointer to a SecTransformRef object. This object must be + released with CFRelease when you are done with it. This + function returns NULL if an error occurred. + */ +CF_EXPORT +SecTransformRef SecTransformCreate(CFStringRef name, CFErrorRef *error) + __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); + +/*! + @Function SecTransformNoData + + @abstract Returns back A CFTypeRef from inside a processData + override that says that while no data is being returned + the transform is still active and awaiting data. + + @result A 'special' value that allows that specifies that the + transform is still active and awaiting data. + + @discussion The standard behavior for the ProcessData override is that + it will receive a CFDataRef and it processes that data and + returns a CFDataRef that contains the processed data. When + there is no more data to process the ProcessData override + block is called one last time with a NULL CFDataRef. The + ProcessData block should/must return the NULL CFDataRef to + complete the processing. This model does not work well for + some transforms. For example a digest transform needs to see + ALL of the data that is being digested before it can send + out the digest value. + + If a ProcessData block has no data to return, it can return + SecTransformNoData(), which informs the transform system + that there is no data to pass on to the next transform. + + +*/ +CF_EXPORT +CFTypeRef SecTransformNoData(void); + +CF_EXTERN_C_END + +#endif // __BLOCKS__ +#endif // _SEC_CUSTOM_TRANSFORM_H__