]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_transform/lib/SecCustomTransform.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / Security / libsecurity_transform / lib / SecCustomTransform.cpp
diff --git a/Security/libsecurity_transform/lib/SecCustomTransform.cpp b/Security/libsecurity_transform/lib/SecCustomTransform.cpp
deleted file mode 100644 (file)
index e8a243e..0000000
+++ /dev/null
@@ -1,1142 +0,0 @@
-/*
- * Copyright (c) 2010-2012,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@
- */
-
-
-#include "SecCustomTransform.h"
-#include "SecTransformValidator.h"
-
-#include "TransformFactory.h"
-#include <CoreFoundation/CoreFoundation.h>
-#include <Block.h>
-#include <syslog.h>
-#include "Utilities.h"
-#include "misc.h"
-
-static const CFStringRef kSecCustom = CFSTR("CustomTransform");
-const CFStringRef kSecTransformPreviousErrorKey = CFSTR("PreviousError");
-const CFStringRef kSecTransformAbortOriginatorKey = CFSTR("Originating Transform");
-const CFStringRef kSecTransformActionCanExecute = CFSTR("CanExecute");
-const CFStringRef kSecCustomTransformWhatIsRequired = CFSTR("WhatIsRequired");
-const CFStringRef kSecCustomTransformAttributesToExternalize = CFSTR("AttributesToExternalize");
-const CFStringRef kSecTransformActionStartingExecution = CFSTR("ExecuteStarting");
-const CFStringRef kSecTransformActionProcessData = CFSTR("TransformProcessData");
-const CFStringRef kSecTransformActionAttributeNotification = CFSTR("GenericAttributeSetNotification");
-const CFStringRef kSecTransformActionFinalize = CFSTR("Finalize");
-const CFStringRef kSecTransformActionExternalizeExtraData = CFSTR("ExternalizeExtraData");
-const CFStringRef kSecTransformActionInternalizeExtraData = CFSTR("InternalizeExtraData");
-const CFStringRef kSecTransformActionAttributeValidation = CFSTR("AttributeValidation");
-
-/*!
-       @function               SecTransformOverrideTransformAction
-       
-       @abstract               Used to override the default behavior of a custom transform. 
-       
-       @param action   This should be either kSecTransformActionCanExecute, 
-                                       kSecTransformActionStartingExecution, or 
-                                       kSecTransformActionFinalize which signifies the behavior
-                                       that is being overridden.                                                                       
-                                       
-       @param newAction        
-                                       A SecTransformAttributeActionBlock block that implements the 
-                                       override behavior.  Please see the 
-                                       SecTransformActionBlock discussion for more 
-                                       information.
-                               
-       @result                 A CFErrorRef if an error occurred, NULL otherwise.
-                                       
-       @discussion             An action may be overridden more then once, the most
-                                       recent override will be used.Please see the example in 
-                                       the documentation for the SecTransformActionBlock 
-                                       block.
-                                       
-*/
-typedef CFTypeRef (^SecTransformOverrideTransformAction)(CFStringRef action, 
-                                                               SecTransformActionBlock newAction);
-                                                               
-/*!
-       @function               SecTransformOverrideDataAction
-       
-       @abstract               Changes the default attribute handling for a 
-                                       specified attribute.
-                                       
-       @param action   This should be either kSecTransformActionProcessData, 
-                                       kSecTransformActionExternalizeExtraData which signifies  
-                                       what behavior is being overridden.
-                                                                                                                       
-       @param newAction         
-                                       A SecTransformDataBlock block that implements the 
-                                       override behavior. Please see the 
-                                       SecTransformDataBlock discussion for more 
-                                       information.
-
-       @result                 A CFErrorRef if an error occurred. NULL otherwise.
-                                       
-       @discussion             An action may be overridden more then once, the most
-                                   recent override will be used. Please see the example 
-                                       in the documentation for the SecTransformAttributeActionBlock 
-                                       block.
-                               
-*/
-typedef CFTypeRef (^SecTransformOverrideDataAction)(CFStringRef action, 
-                                                               SecTransformDataBlock newAction);
-                                                               
-/*!
-       @function               SecTransformOverrideAttributeAction
-       
-       @abstract               Changes the default attribute handling for a 
-                                       specified attribute.
-                                       
-       @param action   This should be either SecTransformSetAttributeAction, 
-                                       kSecTransformActionAttributeValidation which signifies  
-                                       what behavior is being overridden.
-       
-       @param attribute        
-                                       The attribute whose attribute default attribute handling is 
-                                       being overridden.  Passing NULL will override all attributes
-                                       that have not been specifically overridden.
-                                                                               
-       @param newAction         
-                                       A SecTransformAttributeActionBlock block 
-                                       that implements the  override behavior. 
-                                       
-                                       If the action parameter is SecTransformSetAttributeAction
-                                       then this block is called whenever a set is called on the
-                                       attribute that this block was registered for or in the case
-                                       of a NULL attribute name any attribute that has not been specifically
-                                       overridden.  The block may transmogrify the data as needed.  It may
-                                       also send the data to any other attribue by calling 
-                                       SecTransformCustomSetAttribute.  The value returned from the block 
-                                       will be the new value for the attribute.
-                                       
-                                       If the action parameter is kSecTransformActionAttributeValidation then
-                                       this block is called to validate the new value for the
-                                       attribute that this block was registered for or in the case
-                                       of a NULL attribute name any attribute that has not been specifically
-                                       overridden.  The block should test if the new value is acceptable
-                                       and return NULL if it is valid a CFErrorRef otherwise.
-                                       
-       @result                 A CFErrorRef if an error occurred. NULL otherwise.
-                                       
-       @discussion             An action may be overridden more then once, the most
-                                   recent override will be used. Please see the example 
-                                       in the documentation for the 
-                                       SecTransformAttributeActionBlock block.
-                               
-*/
-typedef CFTypeRef (^SecTransformOverrideAttributeAction)( 
-                                                               CFStringRef action,
-                                                               SecTransformStringOrAttributeRef attribute, 
-                                                               SecTransformAttributeActionBlock newAction);
-
-                                                               
-/*!
-       @function               SecTransformGetAttributeBlock
-       
-       @abstract               Retrieves the value of the attribute metadata of the 
-                                       type specified.
-                                       
-       @param attribute        
-                                       The attribute from which to retrieve the metadata from.
-                                       
-       @param type             The type of the metadata to be fetched.
-                                               
-       @result                 The value of the metadata that was retrieved or a CFErrorRef
-                                       if an error occurred
-       
-       @result                 The value of the metadata that was retrieved.
-       
-
-*/
-typedef CFTypeRef (^SecTransformGetAttributeBlock)(
-                                                                               SecTransformStringOrAttributeRef attribute, 
-                                                                               SecTransformMetaAttributeType type);
-                                                                               
-/*!
-       @function               SecTransformSetAttributeBlock
-       
-       @abstract               This sets the value of the metadata of an attribute.  
-               
-       @param attribute        
-                                       The attribute whose value is sent
-                                       
-       @param type             The metadata type that specifies what metadata value
-                                       is set.
-                                       
-       @param value    The value of the metadata to be sent.
-                                               
-       @result                 A CFErrorRef is an error occurred, NULL otherwise.
-       
-       @discussion             The attribute parameter specifies which attribute will 
-                                       have its data set. The type parameter specifies which of 
-                                       the metadata items is set. The value parameter is the 
-                                       new metadata value.
-                                                       
-*/
-typedef CFErrorRef (^SecTransformSetAttributeBlock)(
-       SecTransformStringOrAttributeRef attribute, 
-       SecTransformMetaAttributeType type, 
-       CFTypeRef value);
-       
-
-/*!
-       @function               SecTransformPushBackAttributeBlock
-
-       @abstract               Allows for putting a single value back for a 
-                                       specific attribute.  This will stop the flow of
-                                       data into the specified attribute until an
-                                       attribute is changed.
-
-       @param attribute        
-                                       The attribute that has its data pushed back.
-
-       @param value    The value being pushed back.
-
-
-       @result                 A CFErrorRef is an error occurred, NULL otherwise.
-                                       Note: pushing back a second value will abort the
-                                       transform, not return an error from this call.
-
-       @discussion             A particular custom transform may need multple
-                                       values to be set before it can do the processing
-                                       that the custom transform is designed to do. For
-                                       example, it may need a key and a salt value.  The
-                                       salt value maybe supplied by another transform while
-                                       the key transform may have been set explicitly.  When
-                                       data is presented to this custom transform the salt
-                                       value may not have been sent from the upstream transform.
-                                       The custom transform can then push back the input data
-                                       which causes the transform to stall.  When any 
-                                       attribute on the custom transform is changed, such as 
-                                       the upstream transform delivers the salt value, then 
-                                       the data that was pushed back is re-delivered
-
-*/
-typedef CFErrorRef (^SecTransformPushBackAttributeBlock)(
-                                                                               SecTransformStringOrAttributeRef attribute, 
-                                                                               CFTypeRef value);
-
-/*!
-       @const kSecTransformCreateBlockParametersVersion
-                       The current version number of the SecTransformCreateBlockParameters
-                       struct
-       
-*/
-enum 
-{
-       kSecTransformCreateBlockParametersVersion = 1
-};
-
-extern "C" {
-       Boolean SecExternalSourceSetValue(SecTransformRef xst, CFTypeRef value, CFErrorRef *error);
-}
-
-/*!
-       @struct OpaqueSecTransformImplementation
-       
-       @field version
-                       The version number of this structure
-                       
-       @field overrideTransform
-                       A SecTransformOverrideTransformAction block.  See
-                       the headerdoc for this block for additional information.
-                       
-       @field overrideAttribute
-                       A SecTransformOverrideAttributeAction block. See
-                       the headerdoc for this block for additional information.
-
-       @field get
-                       A SecTransformGetAttributeBlock block. See
-                       the headerdoc for this block for additional information.
-                       
-       @field send
-               A SecTransformSetAttributeBlock block.  See
-               the headerdoc for this block for additional information.
-               
-       @field pushback
-               A SecTransformPushBackAttributeBlock block. See
-               the headerdoc for this block for additional information.
-*/
-struct OpaqueSecTransformImplementation
-{
-       CFIndex version;        // Set to kSecTransformCreateBlockParametersVersion
-       
-       // The following two blocks allow for overriding 'standard' 
-       // transform behavior
-       SecTransformOverrideTransformAction overrideTransform;
-       SecTransformOverrideDataAction overrideData;
-       SecTransformOverrideAttributeAction overrideAttribute;
-       
-       // The following methods allow for dealing with the transform mechanism
-       // They are called synchronously
-       SecTransformGetAttributeBlock get;
-       SecTransformSetAttributeBlock send;
-       SecTransformPushBackAttributeBlock pushback;
-};
-
-                                                                               
-class CustomTransformFactory : public TransformFactory 
-{
-protected:
-       SecTransformCreateFP  createFuncPtr;
-public:
-       CustomTransformFactory(CFStringRef name, SecTransformCreateFP createFP, CFErrorRef *error);
-    virtual ~CustomTransformFactory() {};
-       virtual CFTypeRef Make();
-};
-
-
-static SecTransformActionBlock default_can_run = ^{ return (CFTypeRef)NULL; };
-static SecTransformActionBlock default_execute_starting = default_can_run;
-static SecTransformActionBlock default_finalize = default_execute_starting;
-static SecTransformActionBlock default_externalize_data = default_finalize;
-
-static SecTransformDataBlock default_process_data = ^(CFTypeRef value) { return value; };
-//static SecTransformDataBlock default_validate = ^(CFTypeRef value) { return (CFTypeRef)NULL; };
-static SecTransformAttributeActionBlock default_generic_attribute_set_notification = 
-       ^(SecTransformAttributeRef ah, CFTypeRef value) { return value; };
-
-static SecTransformAttributeActionBlock default_generic_attribute_validation = 
-^(SecTransformAttributeRef ah, CFTypeRef value) 
-{
-        return (CFTypeRef)NULL;
-};
-
-static SecTransformDataBlock default_internalize_data = 
-                       ^(CFTypeRef value) 
-{ 
-       return (CFTypeRef)NULL; 
-};
-
-class CustomTransform : public Transform 
-{
-protected:
-       SecTransformCreateFP                                    createFuncPtr;
-       SecTransformInstanceBlock                       instanceBlock;    
-                       
-       SecTransformActionBlock                         can_run;
-       SecTransformActionBlock                         execute_starting;
-       SecTransformActionBlock                         finalize;
-       SecTransformAttributeActionBlock        generic_attribute_set_notification;
-       SecTransformAttributeActionBlock        generic_attribute_validation;
-       SecTransformDataBlock                           process_data;
-       SecTransformActionBlock                         externalize_data;
-       SecTransformDataBlock                           internalize_data;
-               
-       SecTransformRef tr;     
-       
-       SecTransformAttributeRef                        input_ah;
-       SecTransformAttributeRef                        output_ah;
-       
-       OpaqueSecTransformImplementation parameters;
-       
-       void SetCanExecute(SecTransformActionBlock CanExecuteBlock)
-       {
-               Block_release(can_run);
-               if (CanExecuteBlock)
-               {
-                       can_run = Block_copy(CanExecuteBlock);
-                       
-               }
-               else
-               {
-                       can_run  = Block_copy(default_can_run);
-               }
-       }
-       
-       void SetExecuteStarting(SecTransformActionBlock executeStartingBlock)
-       {
-               Block_release(execute_starting);
-               if (executeStartingBlock)
-               {
-                       execute_starting = Block_copy(executeStartingBlock);
-                       
-               }
-               else
-               {
-                       execute_starting = Block_copy(default_execute_starting);
-               }
-       }
-       
-       void SetFinalize(SecTransformActionBlock finalizeBlock)
-       {
-               Block_release(finalize);
-               if (finalizeBlock)
-               {
-                       finalize = Block_copy(finalizeBlock);
-                       
-               }
-               else
-               {
-                       finalize = Block_copy(default_finalize);
-               }
-       }
-       
-       void SetExternalizeExtraData(SecTransformActionBlock externalizeBlock)
-       {
-               Block_release(externalizeBlock);
-               if (externalizeBlock)
-               {
-                       externalize_data = Block_copy(externalizeBlock);
-                       
-               }
-               else
-               {
-                       externalize_data = Block_copy(default_externalize_data);
-               }
-       }
-       
-       void SetProcessData(SecTransformDataBlock processDataBlock)
-       {
-               Block_release(process_data);
-               if (processDataBlock)
-               {
-                       process_data = Block_copy(processDataBlock);
-                       
-               }
-               else
-               {
-                       process_data = Block_copy(default_process_data);
-               }
-       }
-       
-       void SetInternalizeExtraData(SecTransformDataBlock InternalizeExtraDataBlock)
-       {
-               Block_release(internalize_data);
-               if (InternalizeExtraDataBlock)
-               {
-                       internalize_data = Block_copy(InternalizeExtraDataBlock);
-                       
-               }
-               else
-               {
-                       internalize_data = Block_copy(default_internalize_data);
-               }
-       }
-       
-       
-               
-       void SetNotficationBlock(SecTransformStringOrAttributeRef attribute, 
-                                                       SecTransformAttributeActionBlock notificationBlock)
-       {
-               SecTransformAttributeActionBlock blockToSet = 
-                       Block_copy((notificationBlock) ? notificationBlock : 
-                                  default_generic_attribute_set_notification);
-               
-               if (attribute)
-               {
-                       transform_attribute *ta = getTA(attribute, true);
-                       
-                       if (ta->attribute_changed_block) 
-                       {
-                               Block_release(ta->attribute_changed_block);
-                       }
-                       
-                       ta->attribute_changed_block = blockToSet;
-               }
-               else            
-               {       
-                       
-                       if (generic_attribute_set_notification) 
-                       {
-                               Block_release(generic_attribute_set_notification);
-                       }
-                       
-                       generic_attribute_set_notification = blockToSet;                        
-               }
-       }
-
-       void SetVerifyBlock(SecTransformStringOrAttributeRef attribute, 
-                                                       SecTransformAttributeActionBlock verifyBlock)
-       {
-               SecTransformAttributeActionBlock blockToSet = 
-                       Block_copy((verifyBlock) ? verifyBlock : 
-                                  generic_attribute_validation);
-               
-               if (attribute)
-               {
-                       transform_attribute *ta = getTA(attribute, true);
-                       
-                       if (ta->attribute_validate_block) 
-                       {
-                               Block_release(ta->attribute_validate_block);
-                       }
-                       
-                       ta->attribute_validate_block = blockToSet;
-               }
-               else            
-               {       
-                       if (generic_attribute_validation) 
-                       {
-                               Block_release(generic_attribute_validation);
-                       }
-                       
-                       generic_attribute_validation = blockToSet;                      
-               }
-       }
-               
-               
-
-public:
-       CustomTransform(CFStringRef name, SecTransformCreateFP createFP);
-       virtual ~CustomTransform();
-       
-       void Create();
-       
-       CFTypeRef rebind_data_action(CFStringRef action, 
-               SecTransformDataBlock new_action);
-               
-       CFTypeRef rebind_transform_action(CFStringRef action, SecTransformActionBlock new_action);
-       
-       CFTypeRef rebind_attribute_action(CFStringRef action,
-                                                       SecTransformStringOrAttributeRef attribute, 
-                                                       SecTransformAttributeActionBlock new_action);
-       
-       SecTransformRef get_ref() { return tr; }
-       
-       virtual void AttributeChanged(CFStringRef name, CFTypeRef value);
-       virtual void AttributeChanged(SecTransformAttributeRef ah, CFTypeRef value);
-       virtual CFErrorRef TransformStartingExecution();
-       virtual CFDictionaryRef GetCustomExternalData();
-       virtual void SetCustomExternalData(CFDictionaryRef customData);
-       
-       friend Boolean SecExternalSourceSetValue(SecTransformRef xst, CFTypeRef value, CFErrorRef *error);
-};
-
-
-
-#pragma mark CustomTransformFactory
-
-CustomTransformFactory::CustomTransformFactory(CFStringRef uniqueName, SecTransformCreateFP createFP, CFErrorRef* error) : 
-       TransformFactory(uniqueName, false, kSecCustom), 
-       createFuncPtr(createFP) 
-{
-       TransformFactory *existing = FindTransformFactoryByType(uniqueName);
-       if (existing) 
-       {
-               if (error) 
-               {
-                       *error = CreateSecTransformErrorRef(kSecTransformErrorNameAlreadyRegistered, 
-                               "Custom transform type %s already exists.", uniqueName);
-               }
-        return;
-       }
-       
-    
-    if (CFStringGetCharacterAtIndex(uniqueName, 0) == '_')
-    {
-        if (error)
-        {
-            *error = CreateSecTransformErrorRef(kSecTransformInvalidArgument, 
-                                                "Invalid transform type name %s -- type names must not start with an _", uniqueName);
-        }
-        return;
-    }
-    
-    static CFCharacterSetRef invalidTypeCharactors = NULL;
-    static dispatch_once_t setupInvalidTypeCharactors;
-    dispatch_once(&setupInvalidTypeCharactors, ^{
-        invalidTypeCharactors = CFCharacterSetCreateWithCharactersInString(NULL, CFSTR("/:"));
-    });
-    CFRange has_bad;
-    if (CFStringFindCharacterFromSet(uniqueName, invalidTypeCharactors, CFRangeMake(0, CFStringGetLength(uniqueName)), 0, &has_bad)) {
-        if (error)
-        {
-            *error = CreateSecTransformErrorRef(kSecTransformInvalidArgument, 
-                                            "Invalid character '%c' in transform type name %s", CFStringGetCharacterAtIndex(uniqueName, has_bad.location), uniqueName);
-        }
-        return;
-    }
-    RegisterTransform(this, kSecCustom);
-}
-
-CFTypeRef CustomTransformFactory::Make() 
-{
-       CustomTransform *ct = new CustomTransform(this->GetTypename(), createFuncPtr);
-       ct->Create();
-       return ct->get_ref();
-}
-
-#pragma mark MISC
-
-extern "C" {
-       SecTransformAttributeActionBlock SecTransformCreateValidatorForCFtype(CFTypeID expected_type, Boolean null_allowed) {
-               SecTransformAttributeActionBlock validate = NULL;
-               CFErrorRef (^make_error_message)(SecTransformAttributeRef attr, CFTypeRef value, CFTypeID expected_type, Boolean null_allowed) = 
-               ^(SecTransformAttributeRef attr, CFTypeRef value, CFTypeID expected_type, Boolean null_allowed) {
-                       CFStringRef expected_type_name = CFCopyTypeIDDescription(expected_type);
-                       CFErrorRef error = NULL;
-                       if (value) {
-                               CFStringRef value_type_name = CFCopyTypeIDDescription(CFGetTypeID(value));
-                               error = CreateSecTransformErrorRef(kSecTransformErrorInvalidType, "%@ received value of type %@ (%@), expected%@ a %@%@",
-                                                                                                                         attr, value_type_name, value,
-                                                                                                                         null_allowed ? CFSTR(" either") : CFSTR(""),
-                                                                                                                         expected_type_name,
-                                                                                                                         null_allowed ? CFSTR(" or a NULL") : CFSTR(""));
-                               CFRelease(value_type_name);
-                       } else {
-                               error = CreateSecTransformErrorRef(kSecTransformErrorInvalidType, "%@ received NULL value, expected a %@",
-                                                                                                  attr, expected_type_name);
-                       }
-                       CFRelease(expected_type_name);
-                       
-                       return error;
-               };
-               
-               
-               if (null_allowed) {
-                       validate = ^(SecTransformAttributeRef attr, CFTypeRef value) {
-                               if (value == NULL || CFGetTypeID(value) == expected_type) {
-                                       return (CFTypeRef)NULL;
-                               }
-                               return (CFTypeRef)make_error_message(attr, value, expected_type, null_allowed);
-                       };
-               } else {
-                       validate = ^(SecTransformAttributeRef attr, CFTypeRef value) {
-                               if (value != NULL && CFGetTypeID(value) == expected_type) {
-                                       return (CFTypeRef)NULL;
-                               }
-                               return (CFTypeRef)make_error_message(attr, value, expected_type, null_allowed);
-                       };
-               }
-               
-               return Block_copy(validate);
-       }
-}
-
-Boolean SecTransformRegister(CFStringRef uniqueName, SecTransformCreateFP createFP, CFErrorRef *caller_error) 
-{
-       CFErrorRef error = NULL;
-       
-       CustomTransformFactory *tf = new CustomTransformFactory(uniqueName, createFP, &error);
-       if (error) 
-       {
-               delete tf;
-               if (caller_error) 
-               {
-                       *caller_error = error;
-               }
-               return FALSE;
-       } 
-       else 
-       {
-               return TRUE;
-       }
-}
-
-SecTransformRef SecTransformCreate(CFStringRef name, CFErrorRef *error) 
-{
-       SecTransformRef tr = TransformFactory::MakeTransformWithType(name, error);
-       return tr;
-}
-
-extern "C" {
-       Boolean SecExternalSourceSetValue(SecTransformRef xst, CFTypeRef value, CFErrorRef *error)
-       {
-               CustomTransform *ct = (CustomTransform *)CoreFoundationHolder::ObjectFromCFType(xst);
-               extern CFStringRef external_source_name;
-               if (CFEqual(ct->mTypeName, external_source_name)) {
-                       ct->SetAttribute(ct->input_ah, value);
-                       return true;
-               } else {
-                       if (error) {
-                               *error = CreateSecTransformErrorRef(kSecTransformErrorInvalidType, "SecExternalSourceSetValue called for %@, you need to pass in an ExternalSource transform not a %@", ct->GetName(), ct->mTypeName);
-                       }
-                       return false;
-               }
-       }
-}
-
-/* ==========================================================================
-       class:                  NoDataClass
-       description:    A Special CFType that signifies that no data is being 
-                                       returned
-   ==========================================================================*/
-#pragma mark NoDataClass
-
-class NoDataClass : public CoreFoundationObject
-{
-protected:
-       NoDataClass();
-
-public:
-       virtual ~NoDataClass();
-       std::string FormattingDescription(CFDictionaryRef options);
-       std::string DebugDescription();
-       static CFTypeRef Make();
-};
-
-CFTypeRef NoDataClass::Make() {
-       NoDataClass* obj = new NoDataClass();
-       return CoreFoundationHolder::MakeHolder(gInternalProtectedCFObjectName, obj);
-}
-
-
-NoDataClass::NoDataClass() : CoreFoundationObject(gInternalProtectedCFObjectName) {
-}
-
-NoDataClass::~NoDataClass()
-{
-}
-
-std::string NoDataClass::DebugDescription() 
-{
-       return CoreFoundationObject::DebugDescription() + " | SecTransformNoData";
-}
-
-std::string NoDataClass::FormattingDescription(CFDictionaryRef options) 
-{
-       return CoreFoundationObject::FormattingDescription(options) + " | SecTransformNoData";
-}
-
-CFTypeRef SecTransformNoData() 
-{
-       static dispatch_once_t inited;
-       static CFTypeRef no_data;
-       
-       dispatch_once(&inited, 
-       ^{
-               no_data = NoDataClass::Make();
-       });
-       
-       return no_data;
-}
-
-/* ==========================================================================
-       class Implementation    CustomTransform 
-   ==========================================================================*/
-
-#pragma mark CustomTransform
-
-void CustomTransform::AttributeChanged(CFStringRef name, CFTypeRef value) {
-#ifndef NDEBUG
-       // We really shouldn't get here, and this is the debug build so we can blow up on the spot so it is easy to look at the stack trace
-       abort();
-#else
-       // We really shouldn't get here, but this is a production build and recovery is easy to code (but costly to execute)
-       AttributeChanged(getAH(name, false), value);
-#endif
-}
-
-void CustomTransform::AttributeChanged(SecTransformAttributeRef ah, CFTypeRef value) 
-{
-       transform_attribute *ta = ah2ta(ah);
-       SecTransformAttributeActionBlock attribute_set_notification = NULL;
-
-       SecTransformAttributeActionBlock attribute_validate = NULL;
-
-       attribute_validate = (SecTransformAttributeActionBlock)ta->attribute_validate_block;
-       if (!attribute_validate) {
-                       attribute_validate = generic_attribute_validation;
-       }
-       CFTypeRef vr = attribute_validate(ah, value);
-       if (vr) {
-                       if (CFGetTypeID(vr) == CFErrorGetTypeID()) {
-                                       SendAttribute(AbortAH, vr);
-                                       CFRelease(vr);
-                       } else {
-                                       CFErrorRef e = CreateSecTransformErrorRef(kSecTransformErrorInvalidType, "Invalid return type from a validate action, expected a CFErrorRef got a %@ (%@)", CFCopyTypeIDDescription(CFGetTypeID(vr)), vr);
-                                       SendAttribute(AbortAH, e);
-                                       CFRelease(vr);
-                                       // XXX: this causes a core dump -- I think AbortAH doesn't take it's own reference!!   CFRelease(e);
-                       }
-                       return;
-       }
-
-       attribute_set_notification = (SecTransformAttributeActionBlock)ta->attribute_changed_block;
-
-       if ((!attribute_set_notification) && ah == input_ah) 
-       {
-               CFTypeID vtype = value ? CFGetTypeID(value) : CFDataGetTypeID();
-               if (vtype == CFDataGetTypeID()) 
-               {
-                       CFTypeRef output = process_data(value);
-                       if (output == NULL || output != SecTransformNoData()) 
-                       {
-                               SendAttribute(output_ah, output);
-
-                // if output == value, we are being asked to just
-                // forward the existing value.  No need to release.
-                // If they are different, we are being asked to
-                // send a new value which must be released.
-
-                if (output != value && output != NULL)
-                {
-                    CFRelease(output);
-                }
-                       }
-               } 
-               else if (vtype == CFErrorGetTypeID() && !ah2ta(ah)->direct_error_handling) 
-               {
-                       SendAttribute(output_ah, value);
-               } else 
-               {
-                       attribute_set_notification = attribute_set_notification ? attribute_set_notification : generic_attribute_set_notification;
-                       CFTypeRef new_value = attribute_set_notification(ah, value);
-                       if (new_value != value) 
-                       {
-                               SendAttribute(ah, new_value);
-                       }
-               }
-       } 
-       else 
-       {
-               CFTypeID vtype = value ? CFGetTypeID(value) : CFDataGetTypeID();
-               if (vtype != CFErrorGetTypeID() || ah2ta(ah)->direct_error_handling) 
-               {
-                       attribute_set_notification = attribute_set_notification ? attribute_set_notification : generic_attribute_set_notification;
-                       CFTypeRef new_value = attribute_set_notification(ah, value);
-                       if (new_value != value) 
-                       {
-                               SendAttribute(ah, new_value);
-                       }
-               } 
-               else 
-               {
-                       SendAttribute(output_ah, value);
-               }
-       }
-}
-
-CFTypeRef CustomTransform::rebind_data_action(CFStringRef action, 
-                       SecTransformDataBlock new_action) 
-{
-       CFTypeRef result = NULL;
-       if (kCFCompareEqualTo == CFStringCompare(kSecTransformActionProcessData, action, 0)) 
-       {
-               SetProcessData(new_action);
-       }
-       else if (kCFCompareEqualTo == CFStringCompare(kSecTransformActionInternalizeExtraData, action, 0))
-       {
-               SetInternalizeExtraData(new_action);
-       }
-       else 
-       {
-               result = (CFTypeRef)CreateSecTransformErrorRef(kSecTransformInvalidOverride, "Unkown override type");
-
-        // XXX: can we get a stackdump here too?
-        CFStringRef msg = CFStringCreateWithFormat(NULL, NULL,
-                                                   CFSTR("rebind_data_action (action %@, new_action %p, transform %s)"),
-                                                   action, (void*)new_action, DebugDescription().c_str());
-        char *utf8_message = utf8(msg);
-        syslog(LOG_ERR, "%s", utf8_message);
-        free(utf8_message);
-        CFRelease(msg);
-       }
-       return result;
-}
-
-CFTypeRef CustomTransform::rebind_transform_action(CFStringRef action, SecTransformActionBlock new_action) 
-{
-       CFErrorRef result = NULL;
-       
-       if (kCFCompareEqualTo == CFStringCompare(action, kSecTransformActionCanExecute, 0)) 
-       {
-               SetCanExecute(new_action);
-       }
-       else if (kCFCompareEqualTo == CFStringCompare(action, kSecTransformActionStartingExecution, 0)) 
-       {
-               SetExecuteStarting(new_action);
-       }
-       else if (kCFCompareEqualTo == CFStringCompare(action, kSecTransformActionFinalize, 0))
-       {
-               SetFinalize(new_action);
-       }
-       else if (kCFCompareEqualTo == CFStringCompare(action, kSecTransformActionExternalizeExtraData, 0))
-       {
-               SetExternalizeExtraData(new_action);
-       }
-       else
-       {
-               result = CreateSecTransformErrorRef(kSecTransformInvalidOverride, "Unkown override type");
-
-               char *action_utf8 = utf8(action);
-               syslog(LOG_ERR, "rebind_transform_action (action %s, all-attributes, block %p, transform %s)\n", action_utf8, (void*)new_action, DebugDescription().c_str());
-               free(action_utf8);
-       }
-               
-       return result;
-}
-
-CFTypeRef CustomTransform::rebind_attribute_action(
-                       CFStringRef action,
-                       SecTransformStringOrAttributeRef attribute, 
-                       SecTransformAttributeActionBlock new_action) 
-{
-       CFErrorRef result = NULL;
-       
-       if (kCFCompareEqualTo == CFStringCompare(action, kSecTransformActionAttributeNotification, 0)) 
-       {
-               SetNotficationBlock(attribute, new_action);
-       }
-       else if (kCFCompareEqualTo == CFStringCompare(action, kSecTransformActionAttributeValidation, 0))
-       {
-               SetVerifyBlock(attribute, new_action);
-       }
-       else
-       {
-               result = CreateSecTransformErrorRef(kSecTransformInvalidOverride, "Unkown override type");
-               char *action_utf8 = utf8(action);
-               syslog(LOG_ERR, "rebind_attribute_action (action %s, all-attributes, block %p, transform %s)\n", action_utf8, (void*)new_action, DebugDescription().c_str());
-               free(action_utf8);
-       }
-       
-       return result;  
-}
-
-CustomTransform::CustomTransform(CFStringRef cfname, SecTransformCreateFP createFP) : 
-       Transform(cfname), 
-       createFuncPtr(createFP), 
-       instanceBlock(NULL),
-       can_run(Block_copy(default_can_run)), 
-       execute_starting(Block_copy(default_execute_starting)), 
-       finalize(Block_copy(default_finalize)), 
-       generic_attribute_set_notification(Block_copy(default_generic_attribute_set_notification)),
-       generic_attribute_validation(Block_copy(default_generic_attribute_validation)),
-       process_data(Block_copy(default_process_data)),
-       externalize_data(Block_copy(default_externalize_data)),
-       internalize_data(Block_copy(default_internalize_data))
-{
-       mAlwaysSelfNotify = true;
-       
-       input_ah = getAH(kSecTransformInputAttributeName, true);
-       output_ah = getAH(kSecTransformOutputAttributeName, true);
-       
-       parameters.version = kSecTransformCreateBlockParametersVersion;
-       parameters.send = Block_copy(^(SecTransformStringOrAttributeRef attribute, SecTransformMetaAttributeType type, CFTypeRef value) 
-       { 
-               return SendMetaAttribute(attribute, type, value); 
-       });
-       
-       parameters.pushback = Block_copy(^(SecTransformStringOrAttributeRef attribute, CFTypeRef value) 
-       { 
-               return Pushback(getAH(attribute), value); 
-       });
-       
-       parameters.get = Block_copy(^(SecTransformStringOrAttributeRef attribute, SecTransformMetaAttributeType type) 
-       { 
-               return GetMetaAttribute(attribute, type); 
-       });
-       
-       parameters.overrideTransform = Block_copy(^(CFStringRef action, SecTransformActionBlock new_action) 
-       { 
-               return rebind_transform_action(action, new_action); 
-       });
-       
-       parameters.overrideData = Block_copy(^(CFStringRef action, 
-                                                               SecTransformDataBlock new_action)
-       {
-               return rebind_data_action(action, new_action); 
-       });
-       
-       /*
-        CFTypeRef (^SecTransformOverrideAttributeAction)( 
-        CFStringRef action,
-        SecTransformStringOrAttributeRef attribute, 
-        SecTransformAttributeActionBlock newAction);
-       */
-       parameters.overrideAttribute = 
-               Block_copy(^(CFStringRef action, SecTransformStringOrAttributeRef attribute, SecTransformAttributeActionBlock new_action) 
-       { 
-               return rebind_attribute_action(action, attribute, new_action); 
-       });
-       
-       char *tname = const_cast<char*>(CFStringGetCStringPtr(cfname, kCFStringEncodingUTF8));
-       if (!tname) {
-               CFIndex sz = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfname), kCFStringEncodingUTF8);
-               tname = static_cast<typeof(tname)>(alloca(sz));
-               CFStringGetCString(cfname, tname, sz, kCFStringEncodingUTF8);
-       }       
-       tr = CoreFoundationHolder::MakeHolder(kSecCustom, (CoreFoundationObject*)this);
-       
-       instanceBlock = (*createFuncPtr)(cfname, tr, &parameters);
-}
-
-void CustomTransform::Create()
-{
-       (void)instanceBlock();
-}
-
-
-CustomTransform::~CustomTransform() {
-       finalize();
-       
-       if (instanceBlock)
-       {
-               Block_release(instanceBlock);
-       }
-       
-       Block_release(can_run);
-       Block_release(execute_starting);
-       Block_release(finalize);
-       Block_release(generic_attribute_set_notification);
-       Block_release(process_data);
-       Block_release(externalize_data);
-       Block_release(internalize_data);
-
-       Block_release(parameters.send);
-       Block_release(parameters.pushback);
-       Block_release(parameters.get);
-       Block_release(parameters.overrideTransform);
-       Block_release(parameters.overrideData);
-       Block_release(parameters.overrideAttribute);
-       
-       // strictly speaking this isn't needed, but it can help track down some "use after free" bugs
-       tr = NULL;
-       createFuncPtr = NULL;
-       process_data = NULL;
-}
-
-CFErrorRef CustomTransform::TransformStartingExecution() 
-{
-       CFTypeRef result = execute_starting();
-       return (CFErrorRef)result;
-}
-
-
-CFDictionaryRef CustomTransform::GetCustomExternalData()
-{
-       CFTypeRef result = externalize_data();
-       if (NULL == result)
-       {
-               return NULL;
-       }
-       
-       if (CFGetTypeID(result) == CFErrorGetTypeID())
-       {
-               // Ouch!  we should deal with this
-               CFRelease(result);
-               return NULL;
-       }
-       
-       if (CFGetTypeID(result) == CFDictionaryGetTypeID())
-       {
-               return (CFDictionaryRef)result;
-       }
-       
-       CFRelease(result);
-       result = NULL;
-       return (CFDictionaryRef)result;
-}
-
-
-void CustomTransform::SetCustomExternalData(CFDictionaryRef customData)
-{
-       if (NULL != customData)
-       {
-               internalize_data(customData);           
-       }
-       return;
-}
-
-CFErrorRef SecTransformSetAttributeAction(SecTransformImplementationRef ref, 
-                                                               CFStringRef action,
-                                                               SecTransformStringOrAttributeRef attribute, 
-                                                               SecTransformAttributeActionBlock newAction)                                                             
-{
-       if (NULL == ref)
-       {
-                CFErrorRef result = CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, 
-                       "SecTransformSetAttributeNotificationAction called with a NULL SecTransformImplementationRef ref");
-                       
-               return result;
-       }
-       
-       return (CFErrorRef)ref->overrideAttribute(action, attribute, newAction);
-}
-
-CFErrorRef SecTransformSetDataAction(SecTransformImplementationRef ref, 
-                                                                       CFStringRef action, 
-                                                                       SecTransformDataBlock newAction)
-{
-       if (NULL == ref)
-       {
-                CFErrorRef result = CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, 
-                       "SecTransformSetAttributeNotificationAction called with a NULL SecTransformImplementationRef ref");
-                       
-               return result;
-       }
-       
-       return (CFErrorRef)ref->overrideData(action, newAction);        
-}
-
-CFErrorRef SecTransformSetTransformAction(SecTransformImplementationRef ref,
-                                                               CFStringRef action, 
-                                                               SecTransformActionBlock newAction)
-{
-       if (NULL == ref)
-       {
-                CFErrorRef result = CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, 
-                       "SecTransformSetAttributeNotificationAction called with a NULL SecTransformImplementationRef ref");
-                       
-               return result;
-       }
-       
-       return (CFErrorRef)ref->overrideTransform(action, newAction);
-}
-
-CFTypeRef SecTranformCustomGetAttribute(SecTransformImplementationRef ref,
-                                        SecTransformStringOrAttributeRef attribute,
-                                        SecTransformMetaAttributeType type)
-{
-       if (NULL == ref)
-       {
-        CFErrorRef result = CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, 
-                                                       "SecTransformCustomGetAttribute called with a NULL SecTransformImplementationRef ref");
-        
-               return result;
-       }
-       
-       return (CFErrorRef)ref->get(attribute, type);
-}
-
-CFTypeRef SecTransformCustomSetAttribute(SecTransformImplementationRef ref,
-                                                                       SecTransformStringOrAttributeRef attribute, 
-                                                                       SecTransformMetaAttributeType type, 
-                                                                       CFTypeRef value)
-{
-       if (NULL == ref)
-       {
-                CFErrorRef result = CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, 
-                       "SecTransformCustomSetAttribute called with a NULL SecTransformImplementationRef ref");
-                       
-               return result;
-       }
-       
-       return (CFErrorRef)ref->send(attribute, type, value);
-       
-}
-
-CFTypeRef SecTransformPushbackAttribute(SecTransformImplementationRef ref,
-                                                               SecTransformStringOrAttributeRef attribute, 
-                                                               CFTypeRef value)
-{
-       if (NULL == ref)
-       {
-                CFErrorRef result = CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, 
-                       "SecTransformPushbackAttribute called with a NULL SecTransformImplementationRef ref");
-                       
-               return (CFTypeRef)result;
-       }
-       
-       return ref->pushback(attribute, value);
-}