2 * Copyright (c) 2010-2012 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>
30 CF_ASSUME_NONNULL_BEGIN
31 CF_IMPLICIT_BRIDGING_ENABLED
36 To better follow this header, you should understand the following
39 Transform A transform converts data from one form to another.
40 Digests, encryption and decryption are all examples
41 of transforms. Each transform performs a single
44 Group A transform group is a directed (typically) acyclic
45 graph of transforms. Results from a transform flow
46 to the next Transform in the graph, and so on until
47 the end of the graph is reached.
49 Attribute Transforms may have one or more attributes. These
50 attributes are parameters for the transforms and
51 may affect the operation of the transform. The value
52 of an attribute may be set with static data or from
53 the value of an attribute in another transform
54 by connecting the attributes using the
55 SecTransformConnectTransforms API.
58 Representation Transforms may be created programmatically or from
59 an external representation. External representations
60 may be created from existing transforms.
62 There are many types of transforms available. These are documented
63 in their own headers. The functions in this header are applicable
70 @constant kSecTransformErrorDomain
71 The domain for CFErrorRefs created by Transforms
73 CF_EXPORT
const CFStringRef kSecTransformErrorDomain
;
76 @constant kSecTransformPreviousErrorKey
77 If multiple errors occurred, the CFErrorRef that
78 is returned from a Transfo]rm API will have a userInfo
79 dictionary and that dictionary will have the previous
80 error keyed by the kSecTransformPreviousErrorKey.
82 CF_EXPORT
const CFStringRef kSecTransformPreviousErrorKey
;
85 @constant kSecTransformAbortOriginatorKey
86 The value of this key will be the transform that caused
87 the transform chain to abort.
89 CF_EXPORT
const CFStringRef kSecTransformAbortOriginatorKey
;
92 /**************** Transform Error Codes ****************/
94 @enum Security Transform Error Codes
96 @const kSecTransformErrorAttributeNotFound
97 The attribute was not found.
99 @const kSecTransformErrorInvalidOperation
100 An invalid operation was attempted.
102 @const kSecTransformErrorNotInitializedCorrectly
103 A required initialization is missing. It
104 is most likely a missing required attribute.
106 @const kSecTransformErrorMoreThanOneOutput
107 A transform has an internal routing error
108 that has caused multiple outputs instead
109 of a single discrete output. This will
110 occur if SecTransformExecute has already
113 @const kSecTransformErrorInvalidInputDictionary
114 A dictionary given to
115 SecTransformCreateFromExternalRepresentation has invalid data.
117 @const kSecTransformErrorInvalidAlgorithm
118 A transform that needs an algorithm as an attribute
119 i.e the Sign and Verify transforms, received an invalid
122 @const kSecTransformErrorInvalidLength
123 A transform that needs a length such as a digest
124 transform has been given an invalid length.
126 @const kSecTransformErrorInvalidType
127 An invalid type has been set on an attribute.
129 @const kSecTransformErrorInvalidInput
130 The input set on a transform is invalid. This can
131 occur if the data set for an attribute does not
132 meet certain requirements such as correct key
133 usage for signing data.
135 @const kSecTransformErrorNameAlreadyRegistered
136 A custom transform of a particular name has already
139 @const kSecTransformErrorUnsupportedAttribute
140 An illegal action such as setting a read only
141 attribute has occurred.
143 @const kSecTransformOperationNotSupportedOnGroup
144 An illegal action on a group transform such as
145 trying to call SecTransformSetAttribute has occurred.
147 @const kSecTransformErrorMissingParameter
148 A transform is missing a required attribute.
150 @const kSecTransformErrorInvalidConnection
151 A SecTransformConnectTransforms was called with
152 transforms in different groups.
154 @const kSecTransformTransformIsExecuting
155 An illegal operation was called on a Transform
156 while it was executing. Please see the sequencing documentation
157 in the discussion area of the SecTransformExecute API
159 @const kSecTransformInvalidOverride
160 An illegal override was given to a custom transform
162 @const kSecTransformTransformIsNotRegistered
163 A custom transform was asked to be created but the transform
164 has not been registered.
166 @const kSecTransformErrorAbortInProgress
167 The abort attribute has been set and the transform is in the
168 process of shutting down
170 @const kSecTransformErrorAborted
171 The transform was aborted.
173 @const kSecTransformInvalidArgument
174 An invalid argument was given to a Transform API
181 kSecTransformErrorAttributeNotFound
= 1,
182 kSecTransformErrorInvalidOperation
= 2,
183 kSecTransformErrorNotInitializedCorrectly
= 3,
184 kSecTransformErrorMoreThanOneOutput
= 4,
185 kSecTransformErrorInvalidInputDictionary
= 5,
186 kSecTransformErrorInvalidAlgorithm
= 6,
187 kSecTransformErrorInvalidLength
= 7,
188 kSecTransformErrorInvalidType
= 8,
189 kSecTransformErrorInvalidInput
= 10,
190 kSecTransformErrorNameAlreadyRegistered
= 11,
191 kSecTransformErrorUnsupportedAttribute
= 12,
192 kSecTransformOperationNotSupportedOnGroup
= 13,
193 kSecTransformErrorMissingParameter
= 14,
194 kSecTransformErrorInvalidConnection
= 15,
195 kSecTransformTransformIsExecuting
= 16,
196 kSecTransformInvalidOverride
= 17,
197 kSecTransformTransformIsNotRegistered
= 18,
198 kSecTransformErrorAbortInProgress
= 19,
199 kSecTransformErrorAborted
= 20,
200 kSecTransformInvalidArgument
= 21
204 typedef CFTypeRef SecTransformRef
;
205 typedef CFTypeRef SecGroupTransformRef
;
208 @function SecTransformGetTypeID
209 @abstract Return the CFTypeID for a SecTransform.
213 CF_EXPORT CFTypeID
SecTransformGetTypeID(void);
216 @function SecGroupTransformGetTypeID
217 @abstract Return the CFTypeID for a SecTransformGroup.
222 CF_EXPORT CFTypeID
SecGroupTransformGetTypeID(void);
225 /**************** Transform Attribute Names ****************/
227 @constant kSecTransformInputAttributeName
228 The name of the input attribute.
230 CF_EXPORT
const CFStringRef kSecTransformInputAttributeName
__OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
233 @constant kSecTransformOutputAttributeName
234 The name of the output attribute.
236 CF_EXPORT
const CFStringRef kSecTransformOutputAttributeName
__OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
239 @constant kSecTransformDebugAttributeName
240 Set this attribute to a CFWriteStream.
241 This will signal the transform to write debugging
242 information to the stream.
243 If this attribute is set to kCFBooleanTrue then
244 the debugging data will be written out to
247 CF_EXPORT
const CFStringRef kSecTransformDebugAttributeName
__OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
250 @constant kSecTransformTransformName
251 The name of the transform.
253 CF_EXPORT
const CFStringRef kSecTransformTransformName
__OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
256 @constant kSecTransformAbortAttributeName
257 The name of the abort attribute.
259 CF_EXPORT
const CFStringRef kSecTransformAbortAttributeName
__OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
262 @function SecTransformCreateFromExternalRepresentation
264 @abstract Creates a transform instance from a CFDictionary of
267 @param dictionary The dictionary of parameters.
269 @param error An optional pointer to a CFErrorRef. This value is
270 set if an error occurred. If not NULL the caller is
271 responsible for releasing the CFErrorRef.
273 @result A pointer to a SecTransformRef object. You
274 must release the object with CFRelease when you are done
275 with it. A NULL will be returned if an error occurred during
276 initialization, and if the error parameter
277 is non-null, it contains the specific error data.
281 SecTransformRef
SecTransformCreateFromExternalRepresentation(
282 CFDictionaryRef dictionary
,
284 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
287 @function SecTransformCopyExternalRepresentation
289 @abstract Create a CFDictionaryRef that contains enough
290 information to be able to recreate a transform.
292 @param transformRef The transformRef to be externalized.
294 @discussion This function returns a CFDictionaryRef that contains
295 sufficient information to be able to recreate this
296 transform. You can pass this CFDictionaryRef to
297 SecTransformCreateFromExternalRepresentation
298 to be able to recreate the transform. The dictionary
299 can also be written out to disk using the techniques
302 http://developer.apple.com/mac/library/documentation/CoreFoundation/Conceptual/CFPropertyLists/Articles/Saving.html
306 CFDictionaryRef
SecTransformCopyExternalRepresentation(
307 SecTransformRef transformRef
)
308 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
311 @function SecTransformCreateGroupTransform
313 @abstract Create a SecGroupTransformRef that acts as a
314 container for a set of connected transforms.
316 @result A reference to a SecGroupTransform.
318 @discussion A SecGroupTransformRef is a container for all of
319 the transforms that are in a directed graph.
320 A SecGroupTransformRef can be used with
321 SecTransformExecute, SecTransformExecuteAsync
322 and SecTransformCopyExternalRepresentation
323 APIs. While the intention is that a
324 SecGroupTransformRef willwork just like a S
325 SecTransformRef that is currently not the case.
326 Using a SecGroupTransformRef with the
327 SecTransformConnectTransforms,
328 SecTransformSetAttribute and
329 SecTransformGetAttribute is undefined.
332 SecGroupTransformRef
SecTransformCreateGroupTransform(void);
335 @function SecTransformConnectTransforms
337 @abstract Pipe fitting for transforms.
339 @param sourceTransformRef
340 The transform that sends the data to the
341 destinationTransformRef.
343 @param sourceAttributeName
344 The name of the attribute in the sourceTransformRef that
345 supplies the data to the destinationTransformRef.
346 Any attribute of the transform may be used as a source.
348 @param destinationTransformRef
349 The transform that has one of its attributes
350 be set with the data from the sourceTransformRef
353 @param destinationAttributeName
354 The name of the attribute within the
355 destinationTransformRef whose data is set with the
356 data from the sourceTransformRef sourceAttributeName
357 attribute. Any attribute of the transform may be set.
360 @param group In order to ensure referential integrity, transforms
361 are chained together into a directed graph and
362 placed into a group. Each transform that makes up the
363 graph must be placed into the same group. After
364 a SecTransformRef has been placed into a group by
365 calling the SecTransformConnectTransforms it may be
366 released as the group will retain the transform.
367 CFRelease the group after you execute
368 it, or when you determine you will never execute it.
370 In the example below, the output of trans1 is
371 set to be the input of trans2. The output of trans2
372 is set to be the input of trans3. Since the
373 same group was used for the connections, the three
374 transforms are in the same group.
378 SecGroupTransformRef group =SecTransformCreateGroupTransform();
379 CFErrorRef error = NULL;
381 SecTransformRef trans1; // previously created using a
382 // Transform construction API
383 // like SecEncryptTransformCreate
385 SecTransformRef trans2; // previously created using a
386 // Transform construction API
387 // like SecEncryptTransformCreate
389 SecTransformRef trans3; // previously created using a
390 // Transform construction API
391 // like SecEncryptTransformCreate
394 SecTransformConnectTransforms(trans1, kSecTransformOutputAttributeName,
395 trans2, kSecTransformInputAttributeName,
398 SecTransformConnectTransforms(trans2, kSecTransformOutputAttributeName,
399 trans3, kSecTransformInputAttributeName.
405 CFDataRef = (CFDataRef)SecTransformExecute(group, &error, NULL, NULL);
410 @param error An optional pointer to a CFErrorRef. This value
411 is set if an error occurred. If not NULL, the caller
412 is responsible for releasing the CFErrorRef.
414 @result The value returned is SecGroupTransformRef parameter.
415 This will allow for chaining calls to
416 SecTransformConnectTransforms.
418 @discussion This function places transforms into a group by attaching
419 the value of an attribute of one transform to the
420 attribute of another transform. Typically the attribute
421 supplying the data is the kSecTransformAttrOutput
422 attribute but that is not a requirement. It can be used to
423 set an attribute like Salt with the output attribute of
424 a random number transform. This function returns an
425 error and the named attribute will not be changed if
426 SecTransformExecute had previously been called on the
431 SecGroupTransformRef
SecTransformConnectTransforms(SecTransformRef sourceTransformRef
,
432 CFStringRef sourceAttributeName
,
433 SecTransformRef destinationTransformRef
,
434 CFStringRef destinationAttributeName
,
435 SecGroupTransformRef group
,
437 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
440 @function SecTransformSetAttribute
442 @abstract Set a static value as the value of an attribute in a
443 transform. This is useful for things like iteration
444 counts and other non-changing values.
446 @param transformRef The transform whose attribute is to be set.
448 @param key The name of the attribute to be set.
450 @param value The static value to set for the named attribute.
452 @param error An optional pointer to a CFErrorRef. This value
453 is set if an error occurred. If not NULL the caller
454 is responsible for releasing the CFErrorRef.
456 @result Returns true if the call succeeded. If an error occurred,
457 the error parameter has more information
458 about the failure case.
460 @discussion This API allows for setting static data into an
461 attribute for a transform. This is in contrast to
462 the SecTransformConnectTransforms function which sets derived
463 data. This function will return an error and the
464 named attribute will not be changed if SecTransformExecute
465 has been called on the transform.
469 Boolean
SecTransformSetAttribute(SecTransformRef transformRef
,
473 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
476 @function SecTransformGetAttribute
478 @abstract Get the current value of a transform attribute.
480 @param transformRef The transform whose attribute value will be retrieved.
482 @param key The name of the attribute to retrieve.
484 @result The value of an attribute. If this attribute
485 is being set as the output of another transform
486 and SecTransformExecute has not been called on the
487 transform or if the attribute does not exists
488 then NULL will be returned.
490 @discussion This may be called after SecTransformExecute.
494 CFTypeRef
SecTransformGetAttribute(SecTransformRef transformRef
,
496 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
499 @function SecTransformFindByName
501 @abstract Finds a member of a transform group by its name.
503 @param transform The transform group to be searched.
505 @param name The name of the transform to be found.
507 @discussion When a transform instance is created it will be given a
508 unique name. This name can be used to find that instance
509 in a group. While it is possible to change this unique
510 name using the SecTransformSetAttribute API, developers
511 should not do so. This allows
512 SecTransformFindTransformByName to work correctly.
514 @result The transform group member, or NULL if the member
519 SecTransformRef
SecTransformFindByName(SecGroupTransformRef transform
,
521 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
524 @function SecTransformExecute
526 @abstract Executes a Transform or transform group synchronously.
528 @param transformRef The transform to execute.
530 @param errorRef An optional pointer to a CFErrorRef. This value
531 will be set if an error occurred during
532 initialization or execution of the transform or group.
533 If not NULL the caller will be responsible for releasing
534 the returned CFErrorRef.
536 @result This is the result of the transform. The specific value
537 is determined by the transform being executed.
539 @discussion There are two phases that occur when executing a
540 transform. The first phase checks to see if the tranforms
541 have all of their required attributes set.
542 If a GroupTransform is being executed, then a required
543 attribute for a transform is valid if it is connected
544 to another attribute that supplies the required value.
545 If any of the required attributes are not set or connected
546 then SecTransformExecute will not run the transform but will
547 return NULL and the apporiate error is placed in the
548 error parameter if it is not NULL.
550 The second phase is the actual execution of the transform.
551 SecTransformExecute executes the transform or
552 GroupTransform and when all of the processing is completed
553 it returns the result. If an error occurs during
554 execution, then all processing will stop and NULL will be
555 returned and the appropriate error will be placed in the
556 error parameter if it is not NULL.
559 CF_EXPORT CF_RETURNS_RETAINED
560 CFTypeRef
SecTransformExecute(SecTransformRef transformRef
, CFErrorRef
* errorRef
)
561 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
) CF_RETURNS_RETAINED
;
564 @typedef SecMessageBlock
566 @abstract A SecMessageBlock is used by a transform instance to
567 deliver messages during asynchronous operations.
569 @param message A CFType containing the message. This is where
570 either intermediate or final results are returned.
572 @param error If an error occurred, this will contain a CFErrorRef,
573 otherwise this will be NULL. If not NULL the caller
574 is responsible for releasing the CFErrorRef.
576 @param isFinal If set the message returned is the final result
577 otherwise it is an intermediate result.
580 typedef void (^SecMessageBlock
)(CFTypeRef __nullable message
, CFErrorRef __nullable error
,
584 @function SecTransformExecuteAsync
586 @abstract Executes Transform or transform group asynchronously.
589 @param transformRef The transform to execute.
592 A dispatch queue on which to deliver the results of
596 A SecMessageBlock to asynchronously receive the
597 results of the transform.
599 @discussion SecTransformExecuteAsync works just like the
600 SecTransformExecute API except that it
601 returns results to the deliveryBlock. There
602 may be multple results depending on the transform.
603 The block knows that the processing is complete
604 when the isFinal parameter is set to true. If an
605 error occurs the block's error parameter is
606 set and the isFinal parameter will be set to
611 void SecTransformExecuteAsync(SecTransformRef transformRef
,
612 dispatch_queue_t deliveryQueue
,
613 SecMessageBlock deliveryBlock
)
614 __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_NA
);
616 CF_IMPLICIT_BRIDGING_DISABLED
617 CF_ASSUME_NONNULL_END
620 #endif /* _SEC_TRANSFORM_H__ */