You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
948 lines
39 KiB
948 lines
39 KiB
/* |
|
* 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 |
|
|
|
CF_ASSUME_NONNULL_BEGIN |
|
CF_IMPLICIT_BRIDGING_ENABLED |
|
|
|
/*! |
|
@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(®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 <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. |
|
*/ |
|
|
|
typedef CF_ENUM(CFIndex, SecTransformMetaAttributeType) |
|
{ |
|
kSecTransformMetaAttributeValue, |
|
kSecTransformMetaAttributeName, |
|
kSecTransformMetaAttributeRef, |
|
kSecTransformMetaAttributeRequired, |
|
kSecTransformMetaAttributeRequiresOutboundConnection, |
|
kSecTransformMetaAttributeDeferred, |
|
kSecTransformMetaAttributeStream, |
|
kSecTransformMetaAttributeCanCycle, |
|
kSecTransformMetaAttributeExternalize, |
|
kSecTransformMetaAttributeHasOutboundConnections, |
|
kSecTransformMetaAttributeHasInboundConnection |
|
}; |
|
|
|
/*! |
|
@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 __nullable (^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 __nullable (^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 __nullable (^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 __nullable (^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 __nullable |
|
CFErrorRef SecTransformSetAttributeAction(SecTransformImplementationRef ref, |
|
CFStringRef action, |
|
SecTransformStringOrAttributeRef __nullable 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 __nullable |
|
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 __nullable |
|
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 __nullable |
|
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 __nullable |
|
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 __nullable |
|
CFTypeRef SecTransformCustomSetAttribute(SecTransformImplementationRef ref, |
|
SecTransformStringOrAttributeRef attribute, |
|
SecTransformMetaAttributeType type, |
|
CFTypeRef __nullable 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 __nullable |
|
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 __nonnull (*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 __nullable |
|
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_IMPLICIT_BRIDGING_DISABLED |
|
CF_ASSUME_NONNULL_END |
|
|
|
CF_EXTERN_C_END |
|
|
|
#endif // __BLOCKS__ |
|
#endif // _SEC_CUSTOM_TRANSFORM_H__
|
|
|