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.
949 lines
39 KiB
949 lines
39 KiB
9 years ago
|
/*
|
||
|
* 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__
|