]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_transform/lib/SecCustomTransform.h
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_transform / lib / SecCustomTransform.h
diff --git a/Security/libsecurity_transform/lib/SecCustomTransform.h b/Security/libsecurity_transform/lib/SecCustomTransform.h
new file mode 100644 (file)
index 0000000..95e807e
--- /dev/null
@@ -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 <Security/SecTransform.h>
+
+// 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-----
+<pre>
+@textblock
+//
+//  CaesarXform.c
+//
+//  Copyright (c) 2010-2011,2014 Apple Inc. All Rights Reserved.
+//
+//
+
+#include <Security/SecCustomTransform.h>
+#include <Security/SecTransform.h>
+
+// 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(&registeredOK,
+                  ^{
+                     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 <CoreFoundation/CoreFoundation.h>
+
+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
+</pre>
+       
+*/
+
+/****************      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:
+<pre>
+@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
+</pre>
+*/
+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__