X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_transform/lib/SecTransform.h?ds=sidebyside diff --git a/Security/libsecurity_transform/lib/SecTransform.h b/Security/libsecurity_transform/lib/SecTransform.h new file mode 100644 index 00000000..22574456 --- /dev/null +++ b/Security/libsecurity_transform/lib/SecTransform.h @@ -0,0 +1,618 @@ +/* + * 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 + +CF_EXTERN_C_BEGIN + + +/*! + @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 + + +*/ + +enum +{ + 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 +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. + +
+@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
+
+ + @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 +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 +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 +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 tthe ranforms + 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 message, CFErrorRef 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_EXTERN_C_END + +#endif /* _SEC_TRANSFORM_H__ */