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.
620 lines
21 KiB
620 lines
21 KiB
/* |
|
* Copyright (c) 2010-2012 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_TRANSFORM_H__ |
|
#define _SEC_TRANSFORM_H__ |
|
|
|
#include <CoreFoundation/CoreFoundation.h> |
|
|
|
CF_EXTERN_C_BEGIN |
|
CF_ASSUME_NONNULL_BEGIN |
|
CF_IMPLICIT_BRIDGING_ENABLED |
|
|
|
/*! |
|
@header |
|
|
|
To better follow this header, you should understand the following |
|
terms: |
|
|
|
Transform A transform converts data from one form to another. |
|
Digests, encryption and decryption are all examples |
|
of transforms. Each transform performs a single |
|
operation. |
|
Transform |
|
Group A transform group is a directed (typically) acyclic |
|
graph of transforms. Results from a transform flow |
|
to the next Transform in the graph, and so on until |
|
the end of the graph is reached. |
|
|
|
Attribute Transforms may have one or more attributes. These |
|
attributes are parameters for the transforms and |
|
may affect the operation of the transform. The value |
|
of an attribute may be set with static data or from |
|
the value of an attribute in another transform |
|
by connecting the attributes using the |
|
SecTransformConnectTransforms API. |
|
|
|
External |
|
Representation Transforms may be created programmatically or from |
|
an external representation. External representations |
|
may be created from existing transforms. |
|
|
|
There are many types of transforms available. These are documented |
|
in their own headers. The functions in this header are applicable |
|
to all transforms. |
|
|
|
*/ |
|
|
|
|
|
/*! |
|
@constant kSecTransformErrorDomain |
|
The domain for CFErrorRefs created by Transforms |
|
*/ |
|
CF_EXPORT const CFStringRef kSecTransformErrorDomain; |
|
|
|
/*! |
|
@constant kSecTransformPreviousErrorKey |
|
If multiple errors occurred, the CFErrorRef that |
|
is returned from a Transfo]rm API will have a userInfo |
|
dictionary and that dictionary will have the previous |
|
error keyed by the kSecTransformPreviousErrorKey. |
|
*/ |
|
CF_EXPORT const CFStringRef kSecTransformPreviousErrorKey; |
|
|
|
/*! |
|
@constant kSecTransformAbortOriginatorKey |
|
The value of this key will be the transform that caused |
|
the transform chain to abort. |
|
*/ |
|
CF_EXPORT const CFStringRef kSecTransformAbortOriginatorKey; |
|
|
|
|
|
/**************** Transform Error Codes ****************/ |
|
/*! |
|
@enum Security Transform Error Codes |
|
@discussion |
|
@const kSecTransformErrorAttributeNotFound |
|
The attribute was not found. |
|
|
|
@const kSecTransformErrorInvalidOperation |
|
An invalid operation was attempted. |
|
|
|
@const kSecTransformErrorNotInitializedCorrectly |
|
A required initialization is missing. It |
|
is most likely a missing required attribute. |
|
|
|
@const kSecTransformErrorMoreThanOneOutput |
|
A transform has an internal routing error |
|
that has caused multiple outputs instead |
|
of a single discrete output. This will |
|
occur if SecTransformExecute has already |
|
been called. |
|
|
|
@const kSecTransformErrorInvalidInputDictionary |
|
A dictionary given to |
|
SecTransformCreateFromExternalRepresentation has invalid data. |
|
|
|
@const kSecTransformErrorInvalidAlgorithm |
|
A transform that needs an algorithm as an attribute |
|
i.e the Sign and Verify transforms, received an invalid |
|
algorithm. |
|
|
|
@const kSecTransformErrorInvalidLength |
|
A transform that needs a length such as a digest |
|
transform has been given an invalid length. |
|
|
|
@const kSecTransformErrorInvalidType |
|
An invalid type has been set on an attribute. |
|
|
|
@const kSecTransformErrorInvalidInput |
|
The input set on a transform is invalid. This can |
|
occur if the data set for an attribute does not |
|
meet certain requirements such as correct key |
|
usage for signing data. |
|
|
|
@const kSecTransformErrorNameAlreadyRegistered |
|
A custom transform of a particular name has already |
|
been registered. |
|
|
|
@const kSecTransformErrorUnsupportedAttribute |
|
An illegal action such as setting a read only |
|
attribute has occurred. |
|
|
|
@const kSecTransformOperationNotSupportedOnGroup |
|
An illegal action on a group transform such as |
|
trying to call SecTransformSetAttribute has occurred. |
|
|
|
@const kSecTransformErrorMissingParameter |
|
A transform is missing a required attribute. |
|
|
|
@const kSecTransformErrorInvalidConnection |
|
A SecTransformConnectTransforms was called with |
|
transforms in different groups. |
|
|
|
@const kSecTransformTransformIsExecuting |
|
An illegal operation was called on a Transform |
|
while it was executing. Please see the sequencing documentation |
|
in the discussion area of the SecTransformExecute API |
|
|
|
@const kSecTransformInvalidOverride |
|
An illegal override was given to a custom transform |
|
|
|
@const kSecTransformTransformIsNotRegistered |
|
A custom transform was asked to be created but the transform |
|
has not been registered. |
|
|
|
@const kSecTransformErrorAbortInProgress |
|
The abort attribute has been set and the transform is in the |
|
process of shutting down |
|
|
|
@const kSecTransformErrorAborted |
|
The transform was aborted. |
|
|
|
@const kSecTransformInvalidArgument |
|
An invalid argument was given to a Transform API |
|
|
|
|
|
*/ |
|
|
|
CF_ENUM(CFIndex) |
|
{ |
|
kSecTransformErrorAttributeNotFound = 1, |
|
kSecTransformErrorInvalidOperation = 2, |
|
kSecTransformErrorNotInitializedCorrectly = 3, |
|
kSecTransformErrorMoreThanOneOutput = 4, |
|
kSecTransformErrorInvalidInputDictionary = 5, |
|
kSecTransformErrorInvalidAlgorithm = 6, |
|
kSecTransformErrorInvalidLength = 7, |
|
kSecTransformErrorInvalidType = 8, |
|
kSecTransformErrorInvalidInput = 10, |
|
kSecTransformErrorNameAlreadyRegistered = 11, |
|
kSecTransformErrorUnsupportedAttribute = 12, |
|
kSecTransformOperationNotSupportedOnGroup = 13, |
|
kSecTransformErrorMissingParameter = 14, |
|
kSecTransformErrorInvalidConnection = 15, |
|
kSecTransformTransformIsExecuting = 16, |
|
kSecTransformInvalidOverride = 17, |
|
kSecTransformTransformIsNotRegistered = 18, |
|
kSecTransformErrorAbortInProgress = 19, |
|
kSecTransformErrorAborted = 20, |
|
kSecTransformInvalidArgument = 21 |
|
|
|
}; |
|
|
|
typedef CFTypeRef SecTransformRef; |
|
typedef CFTypeRef SecGroupTransformRef; |
|
|
|
/*! |
|
@function SecTransformGetTypeID |
|
@abstract Return the CFTypeID for a SecTransform. |
|
@result The CFTypeID |
|
*/ |
|
|
|
CF_EXPORT CFTypeID SecTransformGetTypeID(void); |
|
|
|
/*! |
|
@function SecGroupTransformGetTypeID |
|
@abstract Return the CFTypeID for a SecTransformGroup. |
|
@result The CFTypeID |
|
*/ |
|
|
|
|
|
CF_EXPORT CFTypeID SecGroupTransformGetTypeID(void); |
|
|
|
|
|
/**************** Transform Attribute Names ****************/ |
|
/*! |
|
@constant kSecTransformInputAttributeName |
|
The name of the input attribute. |
|
*/ |
|
CF_EXPORT const CFStringRef kSecTransformInputAttributeName __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
/*! |
|
@constant kSecTransformOutputAttributeName |
|
The name of the output attribute. |
|
*/ |
|
CF_EXPORT const CFStringRef kSecTransformOutputAttributeName __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
/*! |
|
@constant kSecTransformDebugAttributeName |
|
Set this attribute to a CFWriteStream. |
|
This will signal the transform to write debugging |
|
information to the stream. |
|
If this attribute is set to kCFBooleanTrue then |
|
the debugging data will be written out to |
|
stderr. |
|
*/ |
|
CF_EXPORT const CFStringRef kSecTransformDebugAttributeName __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
/*! |
|
@constant kSecTransformTransformName |
|
The name of the transform. |
|
*/ |
|
CF_EXPORT const CFStringRef kSecTransformTransformName __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
/*! |
|
@constant kSecTransformAbortAttributeName |
|
The name of the abort attribute. |
|
*/ |
|
CF_EXPORT const CFStringRef kSecTransformAbortAttributeName __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
/*! |
|
@function SecTransformCreateFromExternalRepresentation |
|
|
|
@abstract Creates a transform instance from a CFDictionary of |
|
parameters. |
|
|
|
@param dictionary The dictionary of parameters. |
|
|
|
@param error An optional pointer to a CFErrorRef. This value is |
|
set if an error occurred. If not NULL the caller is |
|
responsible for releasing the CFErrorRef. |
|
|
|
@result A pointer to a SecTransformRef object. You |
|
must release the object with CFRelease when you are done |
|
with it. A NULL will be returned if an error occurred during |
|
initialization, and if the error parameter |
|
is non-null, it contains the specific error data. |
|
|
|
*/ |
|
CF_EXPORT __nullable |
|
SecTransformRef SecTransformCreateFromExternalRepresentation( |
|
CFDictionaryRef dictionary, |
|
CFErrorRef *error) |
|
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
/*! |
|
@function SecTransformCopyExternalRepresentation |
|
|
|
@abstract Create a CFDictionaryRef that contains enough |
|
information to be able to recreate a transform. |
|
|
|
@param transformRef The transformRef to be externalized. |
|
|
|
@discussion This function returns a CFDictionaryRef that contains |
|
sufficient information to be able to recreate this |
|
transform. You can pass this CFDictionaryRef to |
|
SecTransformCreateFromExternalRepresentation |
|
to be able to recreate the transform. The dictionary |
|
can also be written out to disk using the techniques |
|
described here. |
|
|
|
http://developer.apple.com/mac/library/documentation/CoreFoundation/Conceptual/CFPropertyLists/Articles/Saving.html |
|
*/ |
|
|
|
CF_EXPORT |
|
CFDictionaryRef SecTransformCopyExternalRepresentation( |
|
SecTransformRef transformRef) |
|
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
/*! |
|
@function SecTransformCreateGroupTransform |
|
|
|
@abstract Create a SecGroupTransformRef that acts as a |
|
container for a set of connected transforms. |
|
|
|
@result A reference to a SecGroupTransform. |
|
|
|
@discussion A SecGroupTransformRef is a container for all of |
|
the transforms that are in a directed graph. |
|
A SecGroupTransformRef can be used with |
|
SecTransformExecute, SecTransformExecuteAsync |
|
and SecTransformCopyExternalRepresentation |
|
APIs. While the intention is that a |
|
SecGroupTransformRef willwork just like a S |
|
SecTransformRef that is currently not the case. |
|
Using a SecGroupTransformRef with the |
|
SecTransformConnectTransforms, |
|
SecTransformSetAttribute and |
|
SecTransformGetAttribute is undefined. |
|
*/ |
|
CF_EXPORT |
|
SecGroupTransformRef SecTransformCreateGroupTransform(void); |
|
|
|
/*! |
|
@function SecTransformConnectTransforms |
|
|
|
@abstract Pipe fitting for transforms. |
|
|
|
@param sourceTransformRef |
|
The transform that sends the data to the |
|
destinationTransformRef. |
|
|
|
@param sourceAttributeName |
|
The name of the attribute in the sourceTransformRef that |
|
supplies the data to the destinationTransformRef. |
|
Any attribute of the transform may be used as a source. |
|
|
|
@param destinationTransformRef |
|
The transform that has one of its attributes |
|
be set with the data from the sourceTransformRef |
|
parameter. |
|
|
|
@param destinationAttributeName |
|
The name of the attribute within the |
|
destinationTransformRef whose data is set with the |
|
data from the sourceTransformRef sourceAttributeName |
|
attribute. Any attribute of the transform may be set. |
|
|
|
|
|
@param group In order to ensure referential integrity, transforms |
|
are chained together into a directed graph and |
|
placed into a group. Each transform that makes up the |
|
graph must be placed into the same group. After |
|
a SecTransformRef has been placed into a group by |
|
calling the SecTransformConnectTransforms it may be |
|
released as the group will retain the transform. |
|
CFRelease the group after you execute |
|
it, or when you determine you will never execute it. |
|
|
|
In the example below, the output of trans1 is |
|
set to be the input of trans2. The output of trans2 |
|
is set to be the input of trans3. Since the |
|
same group was used for the connections, the three |
|
transforms are in the same group. |
|
|
|
<pre> |
|
@textblock |
|
SecGroupTransformRef group =SecTransformCreateGroupTransform(); |
|
CFErrorRef error = NULL; |
|
|
|
SecTransformRef trans1; // previously created using a |
|
// Transform construction API |
|
// like SecEncryptTransformCreate |
|
|
|
SecTransformRef trans2; // previously created using a |
|
// Transform construction API |
|
// like SecEncryptTransformCreate |
|
|
|
SecTransformRef trans3; // previously created using a |
|
// Transform construction API |
|
// like SecEncryptTransformCreate |
|
|
|
|
|
SecTransformConnectTransforms(trans1, kSecTransformOutputAttributeName, |
|
trans2, kSecTransformInputAttributeName, |
|
group, &error); |
|
|
|
SecTransformConnectTransforms(trans2, kSecTransformOutputAttributeName, |
|
trans3, kSecTransformInputAttributeName. |
|
group, &error); |
|
CFRelease(trans1); |
|
CFRelease(trans2); |
|
CFRelease(trans3); |
|
|
|
CFDataRef = (CFDataRef)SecTransformExecute(group, &error, NULL, NULL); |
|
CFRelease(group); |
|
@/textblock |
|
</pre> |
|
|
|
@param error An optional pointer to a CFErrorRef. This value |
|
is set if an error occurred. If not NULL, the caller |
|
is responsible for releasing the CFErrorRef. |
|
|
|
@result The value returned is SecGroupTransformRef parameter. |
|
This will allow for chaining calls to |
|
SecTransformConnectTransforms. |
|
|
|
@discussion This function places transforms into a group by attaching |
|
the value of an attribute of one transform to the |
|
attribute of another transform. Typically the attribute |
|
supplying the data is the kSecTransformAttrOutput |
|
attribute but that is not a requirement. It can be used to |
|
set an attribute like Salt with the output attribute of |
|
a random number transform. This function returns an |
|
error and the named attribute will not be changed if |
|
SecTransformExecute had previously been called on the |
|
transform. |
|
*/ |
|
|
|
CF_EXPORT __nullable |
|
SecGroupTransformRef SecTransformConnectTransforms(SecTransformRef sourceTransformRef, |
|
CFStringRef sourceAttributeName, |
|
SecTransformRef destinationTransformRef, |
|
CFStringRef destinationAttributeName, |
|
SecGroupTransformRef group, |
|
CFErrorRef *error) |
|
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
/*! |
|
@function SecTransformSetAttribute |
|
|
|
@abstract Set a static value as the value of an attribute in a |
|
transform. This is useful for things like iteration |
|
counts and other non-changing values. |
|
|
|
@param transformRef The transform whose attribute is to be set. |
|
|
|
@param key The name of the attribute to be set. |
|
|
|
@param value The static value to set for the named attribute. |
|
|
|
@param error An optional pointer to a CFErrorRef. This value |
|
is set if an error occurred. If not NULL the caller |
|
is responsible for releasing the CFErrorRef. |
|
|
|
@result Returns true if the call succeeded. If an error occurred, |
|
the error parameter has more information |
|
about the failure case. |
|
|
|
@discussion This API allows for setting static data into an |
|
attribute for a transform. This is in contrast to |
|
the SecTransformConnectTransforms function which sets derived |
|
data. This function will return an error and the |
|
named attribute will not be changed if SecTransformExecute |
|
has been called on the transform. |
|
*/ |
|
|
|
CF_EXPORT |
|
Boolean SecTransformSetAttribute(SecTransformRef transformRef, |
|
CFStringRef key, |
|
CFTypeRef value, |
|
CFErrorRef *error) |
|
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
/*! |
|
@function SecTransformGetAttribute |
|
|
|
@abstract Get the current value of a transform attribute. |
|
|
|
@param transformRef The transform whose attribute value will be retrieved. |
|
|
|
@param key The name of the attribute to retrieve. |
|
|
|
@result The value of an attribute. If this attribute |
|
is being set as the output of another transform |
|
and SecTransformExecute has not been called on the |
|
transform or if the attribute does not exists |
|
then NULL will be returned. |
|
|
|
@discussion This may be called after SecTransformExecute. |
|
*/ |
|
|
|
CF_EXPORT __nullable |
|
CFTypeRef SecTransformGetAttribute(SecTransformRef transformRef, |
|
CFStringRef key) |
|
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
/*! |
|
@function SecTransformFindByName |
|
|
|
@abstract Finds a member of a transform group by its name. |
|
|
|
@param transform The transform group to be searched. |
|
|
|
@param name The name of the transform to be found. |
|
|
|
@discussion When a transform instance is created it will be given a |
|
unique name. This name can be used to find that instance |
|
in a group. While it is possible to change this unique |
|
name using the SecTransformSetAttribute API, developers |
|
should not do so. This allows |
|
SecTransformFindTransformByName to work correctly. |
|
|
|
@result The transform group member, or NULL if the member |
|
was not found. |
|
*/ |
|
|
|
CF_EXPORT __nullable |
|
SecTransformRef SecTransformFindByName(SecGroupTransformRef transform, |
|
CFStringRef name) |
|
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
/*! |
|
@function SecTransformExecute |
|
|
|
@abstract Executes a Transform or transform group synchronously. |
|
|
|
@param transformRef The transform to execute. |
|
|
|
@param errorRef An optional pointer to a CFErrorRef. This value |
|
will be set if an error occurred during |
|
initialization or execution of the transform or group. |
|
If not NULL the caller will be responsible for releasing |
|
the returned CFErrorRef. |
|
|
|
@result This is the result of the transform. The specific value |
|
is determined by the transform being executed. |
|
|
|
@discussion There are two phases that occur when executing a |
|
transform. The first phase checks to see if the tranforms |
|
have all of their required attributes set. |
|
If a GroupTransform is being executed, then a required |
|
attribute for a transform is valid if it is connected |
|
to another attribute that supplies the required value. |
|
If any of the required attributes are not set or connected |
|
then SecTransformExecute will not run the transform but will |
|
return NULL and the apporiate error is placed in the |
|
error parameter if it is not NULL. |
|
|
|
The second phase is the actual execution of the transform. |
|
SecTransformExecute executes the transform or |
|
GroupTransform and when all of the processing is completed |
|
it returns the result. If an error occurs during |
|
execution, then all processing will stop and NULL will be |
|
returned and the appropriate error will be placed in the |
|
error parameter if it is not NULL. |
|
*/ |
|
|
|
CF_EXPORT CF_RETURNS_RETAINED |
|
CFTypeRef SecTransformExecute(SecTransformRef transformRef, CFErrorRef* errorRef) |
|
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA) CF_RETURNS_RETAINED; |
|
|
|
/*! |
|
@typedef SecMessageBlock |
|
|
|
@abstract A SecMessageBlock is used by a transform instance to |
|
deliver messages during asynchronous operations. |
|
|
|
@param message A CFType containing the message. This is where |
|
either intermediate or final results are returned. |
|
|
|
@param error If an error occurred, this will contain a CFErrorRef, |
|
otherwise this will be NULL. If not NULL the caller |
|
is responsible for releasing the CFErrorRef. |
|
|
|
@param isFinal If set the message returned is the final result |
|
otherwise it is an intermediate result. |
|
*/ |
|
|
|
typedef void (^SecMessageBlock)(CFTypeRef __nullable message, CFErrorRef __nullable error, |
|
Boolean isFinal); |
|
|
|
/*! |
|
@function SecTransformExecuteAsync |
|
|
|
@abstract Executes Transform or transform group asynchronously. |
|
|
|
|
|
@param transformRef The transform to execute. |
|
|
|
@param deliveryQueue |
|
A dispatch queue on which to deliver the results of |
|
this transform. |
|
|
|
@param deliveryBlock |
|
A SecMessageBlock to asynchronously receive the |
|
results of the transform. |
|
|
|
@discussion SecTransformExecuteAsync works just like the |
|
SecTransformExecute API except that it |
|
returns results to the deliveryBlock. There |
|
may be multple results depending on the transform. |
|
The block knows that the processing is complete |
|
when the isFinal parameter is set to true. If an |
|
error occurs the block's error parameter is |
|
set and the isFinal parameter will be set to |
|
true. |
|
*/ |
|
|
|
CF_EXPORT |
|
void SecTransformExecuteAsync(SecTransformRef transformRef, |
|
dispatch_queue_t deliveryQueue, |
|
SecMessageBlock deliveryBlock) |
|
__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); |
|
|
|
CF_IMPLICIT_BRIDGING_DISABLED |
|
CF_ASSUME_NONNULL_END |
|
CF_EXTERN_C_END |
|
|
|
#endif /* _SEC_TRANSFORM_H__ */
|
|
|