2 * Copyright © 2010 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #ifndef _SEC_TRANSFORM_H__
25 #define _SEC_TRANSFORM_H__
27 #include <CoreFoundation/CoreFoundation.h>
35 To better follow this header, you should understand the following
38 Transform A transform converts data from one form to another.
39 Digests, encryption and decryption are all examples
40 of transforms. Each transform performs a single
43 Group A transform group is a directed (typically) acyclic
44 graph of transforms. Results from a transform flow
45 to the next Transform in the graph, and so on until
46 the end of the graph is reached.
48 Attribute Transforms may have one or more attributes. These
49 attributes are parameters for the transforms and
50 may affect the operation of the transform. The value
51 of an attribute may be set with static data or from
52 the value of an attribute in another transform
53 by connecting the attributes using the
54 SecTransformConnectTransforms API.
57 Representation Transforms may be created programmatically or from
58 an external representation. External representations
59 may be created from existing transforms.
61 There are many types of transforms available. These are documented
62 in their own headers. The functions in this header are applicable
69 @constant kSecTransformErrorDomain
70 The domain for CFErrorRefs created by Transforms
72 CF_EXPORT
const CFStringRef kSecTransformErrorDomain
;
75 @constant kSecTransformPreviousErrorKey
76 If multiple errors occurred, the CFErrorRef that
77 is returned from a Transfo]rm API will have a userInfo
78 dictionary and that dictionary will have the previous
79 error keyed by the kSecTransformPreviousErrorKey.
81 CF_EXPORT
const CFStringRef kSecTransformPreviousErrorKey
;
84 @constant kSecTransformAbortOriginatorKey
85 The value of this key will be the transform that caused
86 the transform chain to abort.
88 CF_EXPORT
const CFStringRef kSecTransformAbortOriginatorKey
;
91 /**************** Transform Error Codes ****************/
93 @enum Security Transform Error Codes
95 @const kSecTransformErrorAttributeNotFound
96 The attribute was not found.
98 @const kSecTransformErrorInvalidOperation
99 An invalid operation was attempted.
101 @const kSecTransformErrorNotInitializedCorrectly
102 A required initialization is missing. It
103 is most likely a missing required attribute.
105 @const kSecTransformErrorMoreThanOneOutput
106 A transform has an internal routing error
107 that has caused multiple outputs instead
108 of a single discrete output. This will
109 occur if SecTransformExecute has already
112 @const kSecTransformErrorInvalidInputDictionary
113 A dictionary given to
114 SecTransformCreateFromExternalRepresentation has invalid data.
116 @const kSecTransformErrorInvalidAlgorithm
117 A transform that needs an algorithm as an attribute
118 i.e the Sign and Verify transforms, received an invalid
121 @const kSecTransformErrorInvalidLength
122 A transform that needs a length such as a digest
123 transform has been given an invalid length.
125 @const kSecTransformErrorInvalidType
126 An invalid type has been set on an attribute.
128 @const kSecTransformErrorInvalidInput
129 The input set on a transform is invalid. This can
130 occur if the data set for an attribute does not
131 meet certain requirements such as correct key
132 usage for signing data.
134 @const kSecTransformErrorNameAlreadyRegistered
135 A custom transform of a particular name has already
138 @const kSecTransformErrorUnsupportedAttribute
139 An illegal action such as setting a read only
140 attribute has occurred.
142 @const kSecTransformOperationNotSupportedOnGroup
143 An illegal action on a group transform such as
144 trying to call SecTransformSetAttribute has occurred.
146 @const kSecTransformErrorMissingParameter
147 A transform is missing a required attribute.
149 @const kSecTransformErrorInvalidConnection
150 A SecTransformConnectTransforms was called with
151 transforms in different groups.
153 @const kSecTransformTransformIsExecuting
154 An illegal operation was called on a Transform
155 while it was executing. Please see the sequencing documentation
156 in the discussion area of the SecTransformExecute API
158 @const kSecTransformInvalidOverride
159 An illegal override was given to a custom transform
161 @const kSecTransformTransformIsNotRegistered
162 A custom transform was asked to be created but the transform
163 has not been registered.
165 @const kSecTransformErrorAbortInProgress
166 The abort attribute has been set and the transform is in the
167 process of shutting down
169 @const kSecTransformErrorAborted
170 The transform was aborted.
172 @const kSecTransformInvalidArgument
173 An invalid argument was given to a Transform API
180 kSecTransformErrorAttributeNotFound
= 1,
181 kSecTransformErrorInvalidOperation
= 2,
182 kSecTransformErrorNotInitializedCorrectly
= 3,
183 kSecTransformErrorMoreThanOneOutput
= 4,
184 kSecTransformErrorInvalidInputDictionary
= 5,
185 kSecTransformErrorInvalidAlgorithm
= 6,
186 kSecTransformErrorInvalidLength
= 7,
187 kSecTransformErrorInvalidType
= 8,
188 kSecTransformErrorInvalidInput
= 10,
189 kSecTransformErrorNameAlreadyRegistered
= 11,
190 kSecTransformErrorUnsupportedAttribute
= 12,
191 kSecTransformOperationNotSupportedOnGroup
= 13,
192 kSecTransformErrorMissingParameter
= 14,
193 kSecTransformErrorInvalidConnection
= 15,
194 kSecTransformTransformIsExecuting
= 16,
195 kSecTransformInvalidOverride
= 17,
196 kSecTransformTransformIsNotRegistered
= 18,
197 kSecTransformErrorAbortInProgress
= 19,
198 kSecTransformErrorAborted
= 20,
199 kSecTransformInvalidArgument
= 21
203 typedef CFTypeRef SecTransformRef
;
204 typedef CFTypeRef SecGroupTransformRef
;
207 @function SecTransformGetTypeID
208 @abstract Return the CFTypeID for a SecTransform.
212 CF_EXPORT CFTypeID
SecTransformGetTypeID(void);
215 @function SecGroupTransformGetTypeID
216 @abstract Return the CFTypeID for a SecTransformGroup.
221 CF_EXPORT CFTypeID
SecGroupTransformGetTypeID(void);
224 /**************** Transform Attribute Names ****************/
226 @constant kSecTransformInputAttributeName
227 The name of the input attribute.
229 CF_EXPORT
const CFStringRef kSecTransformInputAttributeName
__OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
232 @constant kSecTransformOutputAttributeName
233 The name of the output attribute.
235 CF_EXPORT
const CFStringRef kSecTransformOutputAttributeName
__OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
238 @constant kSecTransformDebugAttributeName
239 Set this attribute to a CFWriteStream.
240 This will signal the transform to write debugging
241 information to the stream.
242 If this attribute is set to kCFBooleanTrue then
243 the debugging data will be written out to
246 CF_EXPORT
const CFStringRef kSecTransformDebugAttributeName
__OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
249 @constant kSecTransformTransformName
250 The name of the transform.
252 CF_EXPORT
const CFStringRef kSecTransformTransformName
__OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
255 @constant kSecTransformAbortAttributeName
256 The name of the abort attribute.
258 CF_EXPORT
const CFStringRef kSecTransformAbortAttributeName
__OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
261 @function SecTransformCreateFromExternalRepresentation
263 @abstract Creates a transform instance from a CFDictionary of
266 @param dictionary The dictionary of parameters.
268 @param error An optional pointer to a CFErrorRef. This value is
269 set if an error occurred. If not NULL the caller is
270 responsible for releasing the CFErrorRef.
272 @result A pointer to a SecTransformRef object. You
273 must release the object with CFRelease when you are done
274 with it. A NULL will be returned if an error occurred during
275 initialization, and if the error parameter
276 is non-null, it contains the specific error data.
280 SecTransformRef
SecTransformCreateFromExternalRepresentation(
281 CFDictionaryRef dictionary
,
283 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
286 @function SecTransformCopyExternalRepresentation
288 @abstract Create a CFDictionaryRef that contains enough
289 information to be able to recreate a transform.
291 @param transformRef The transformRef to be externalized.
293 @discussion This function returns a CFDictionaryRef that contains
294 sufficient information to be able to recreate this
295 transform. You can pass this CFDictionaryRef to
296 SecTransformCreateFromExternalRepresentation
297 to be able to recreate the transform. The dictionary
298 can also be written out to disk using the techniques
301 http://developer.apple.com/mac/library/documentation/CoreFoundation/Conceptual/CFPropertyLists/Articles/Saving.html
305 CFDictionaryRef
SecTransformCopyExternalRepresentation(
306 SecTransformRef transformRef
)
307 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
310 @function SecTransformCreateGroupTransform
312 @abstract Create a SecGroupTransformRef that acts as a
313 container for a set of connected transforms.
315 @result A reference to a SecGroupTransform.
317 @discussion A SecGroupTransformRef is a container for all of
318 the transforms that are in a directed graph.
319 A SecGroupTransformRef can be used with
320 SecTransformExecute, SecTransformExecuteAsync
321 and SecTransformCopyExternalRepresentation
322 APIs. While the intention is that a
323 SecGroupTransformRef willwork just like a S
324 SecTransformRef that is currently not the case.
325 Using a SecGroupTransformRef with the
326 SecTransformConnectTransforms,
327 SecTransformSetAttribute and
328 SecTransformGetAttribute is undefined.
331 SecGroupTransformRef
SecTransformCreateGroupTransform(void);
334 @function SecTransformConnectTransforms
336 @abstract Pipe fitting for transforms.
338 @param sourceTransformRef
339 The transform that sends the data to the
340 destinationTransformRef.
342 @param sourceAttributeName
343 The name of the attribute in the sourceTransformRef that
344 supplies the data to the destinationTransformRef.
345 Any attribute of the transform may be used as a source.
347 @param destinationTransformRef
348 The transform that has one of its attributes
349 be set with the data from the sourceTransformRef
352 @param destinationAttributeName
353 The name of the attribute within the
354 destinationTransformRef whose data is set with the
355 data from the sourceTransformRef sourceAttributeName
356 attribute. Any attribute of the transform may be set.
359 @param group In order to ensure referential integrity, transforms
360 are chained together into a directed graph and
361 placed into a group. Each transform that makes up the
362 graph must be placed into the same group. After
363 a SecTransformRef has been placed into a group by
364 calling the SecTransformConnectTransforms it may be
365 released as the group will retain the transform.
366 CFRelease the group after you execute
367 it, or when you determine you will never execute it.
369 In the example below, the output of trans1 is
370 set to be the input of trans2. The output of trans2
371 is set to be the input of trans3. Since the
372 same group was used for the connections, the three
373 transforms are in the same group.
377 SecGroupTransformRef group =SecTransformCreateGroupTransform();
378 CFErrorRef error = NULL;
380 SecTransformRef trans1; // previously created using a
381 // Transform construction API
382 // like SecEncryptTransformCreate
384 SecTransformRef trans2; // previously created using a
385 // Transform construction API
386 // like SecEncryptTransformCreate
388 SecTransformRef trans3; // previously created using a
389 // Transform construction API
390 // like SecEncryptTransformCreate
393 SecTransformConnectTransforms(trans1, kSecTransformOutputAttributeName,
394 trans2, kSecTransformInputAttributeName,
397 SecTransformConnectTransforms(trans2, kSecTransformOutputAttributeName,
398 trans3, kSecTransformInputAttributeName.
404 CFDataRef = (CFDataRef)SecTransformExecute(group, &error, NULL, NULL);
409 @param error An optional pointer to a CFErrorRef. This value
410 is set if an error occurred. If not NULL, the caller
411 is responsible for releasing the CFErrorRef.
413 @result The value returned is SecGroupTransformRef parameter.
414 This will allow for chaining calls to
415 SecTransformConnectTransforms.
417 @discussion This function places transforms into a group by attaching
418 the value of an attribute of one transform to the
419 attribute of another transform. Typically the attribute
420 supplying the data is the kSecTransformAttrOutput
421 attribute but that is not a requirement. It can be used to
422 set an attribute like Salt with the output attribute of
423 a random number transform. This function returns an
424 error and the named attribute will not be changed if
425 SecTransformExecute had previously been called on the
430 SecGroupTransformRef
SecTransformConnectTransforms(SecTransformRef sourceTransformRef
,
431 CFStringRef sourceAttributeName
,
432 SecTransformRef destinationTransformRef
,
433 CFStringRef destinationAttributeName
,
434 SecGroupTransformRef group
,
436 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
439 @function SecTransformSetAttribute
441 @abstract Set a static value as the value of an attribute in a
442 transform. This is useful for things like iteration
443 counts and other non-changing values.
445 @param transformRef The transform whose attribute is to be set.
447 @param key The name of the attribute to be set.
449 @param value The static value to set for the named attribute.
451 @param error An optional pointer to a CFErrorRef. This value
452 is set if an error occurred. If not NULL the caller
453 is responsible for releasing the CFErrorRef.
455 @result Returns true if the call succeeded. If an error occurred,
456 the error parameter has more information
457 about the failure case.
459 @discussion This API allows for setting static data into an
460 attribute for a transform. This is in contrast to
461 the SecTransformConnectTransforms function which sets derived
462 data. This function will return an error and the
463 named attribute will not be changed if SecTransformExecute
464 has been called on the transform.
468 Boolean
SecTransformSetAttribute(SecTransformRef transformRef
,
472 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
475 @function SecTransformGetAttribute
477 @abstract Get the current value of a transform attribute.
479 @param transformRef The transform whose attribute value will be retrieved.
481 @param key The name of the attribute to retrieve.
483 @result The value of an attribute. If this attribute
484 is being set as the output of another transform
485 and SecTransformExecute has not been called on the
486 transform or if the attribute does not exists
487 then NULL will be returned.
489 @discussion This may be called after SecTransformExecute.
493 CFTypeRef
SecTransformGetAttribute(SecTransformRef transformRef
,
495 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
498 @function SecTransformFindByName
500 @abstract Finds a member of a transform group by its name.
502 @param transform The transform group to be searched.
504 @param name The name of the transform to be found.
506 @discussion When a transform instance is created it will be given a
507 unique name. This name can be used to find that instance
508 in a group. While it is possible to change this unique
509 name using the SecTransformSetAttribute API, developers
510 should not do so. This allows
511 SecTransformFindTransformByName to work correctly.
513 @result The transform group member, or NULL if the member
518 SecTransformRef
SecTransformFindByName(SecGroupTransformRef transform
,
520 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
523 @function SecTransformExecute
525 @abstract Executes a Transform or transform group synchronously.
527 @param transformRef The transform to execute.
529 @param errorRef An optional pointer to a CFErrorRef. This value
530 will be set if an error occurred during
531 initialization or execution of the transform or group.
532 If not NULL the caller will be responsible for releasing
533 the returned CFErrorRef.
535 @result This is the result of the transform. The specific value
536 is determined by the transform being executed.
538 @discussion There are two phases that occur when executing a
539 transform. The first phase checks to see if tthe ranforms
540 have all of their required attributes set.
541 If a GroupTransform is being executed, then a required
542 attribute for a transform is valid if it is connected
543 to another attribute that supplies the required value.
544 If any of the required attributes are not set or connected
545 then SecTransformExecute will not run the transform but will
546 return NULL and the apporiate error is placed in the
547 error parameter if it is not NULL.
549 The second phase is the actual execution of the transform.
550 SecTransformExecute executes the transform or
551 GroupTransform and when all of the processing is completed
552 it returns the result. If an error occurs during
553 execution, then all processing will stop and NULL will be
554 returned and the appropriate error will be placed in the
555 error parameter if it is not NULL.
558 CF_EXPORT CF_RETURNS_RETAINED
559 CFTypeRef
SecTransformExecute(SecTransformRef transformRef
, CFErrorRef
* errorRef
)
560 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
) CF_RETURNS_RETAINED
;
563 @typedef SecMessageBlock
565 @abstract A SecMessageBlock is used by a transform instance to
566 deliver messages during asynchronous operations.
568 @param message A CFType containing the message. This is where
569 either intermediate or final results are returned.
571 @param error If an error occurred, this will contain a CFErrorRef,
572 otherwise this will be NULL. If not NULL the caller
573 is responsible for releasing the CFErrorRef.
575 @param isFinal If set the message returned is the final result
576 otherwise it is an intermediate result.
579 typedef void (^SecMessageBlock
)(CFTypeRef message
, CFErrorRef error
,
583 @function SecTransformExecuteAsync
585 @abstract Executes Transform or transform group asynchronously.
588 @param transformRef The transform to execute.
591 A dispatch queue on which to deliver the results of
595 A SecMessageBlock to asynchronously receive the
596 results of the transform.
598 @discussion SecTransformExecuteAsync works just like the
599 SecTransformExecute API except that it
600 returns results to the deliveryBlock. There
601 may be multple results depending on the transform.
602 The block knows that the processing is complete
603 when the isFinal parameter is set to true. If an
604 error occurs the block's error parameter is
605 set and the isFinal parameter will be set to
610 void SecTransformExecuteAsync(SecTransformRef transformRef
,
611 dispatch_queue_t deliveryQueue
,
612 SecMessageBlock deliveryBlock
)
613 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
618 #endif /* _SEC_TRANSFORM_H__ */