1/*
2 * Copyright © 2010 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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 * compliance with the License. Please obtain a copy of the License at
9 * http://www.opensource.apple.com/apsl/ and read it before using this
10 * file.
11 *
12 * The Original Code and all software distributed under the License are
13 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
17 * Please see the License for the specific language governing rights and
18 * limitations under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#ifndef _SEC_CUSTOM_TRANSFORM_H__
24#define _SEC_CUSTOM_TRANSFORM_H__
25
26#include <Security/SecTransform.h>
27
28// Blocks are required for custom transforms
29#ifdef __BLOCKS__
30
31CF_EXTERN_C_BEGIN
32
33/*!
34    @header
35
36    Custom transforms are an API that provides the ability to easily create new
37    transforms. The essential functions of a transform are created in a
38    collection of blocks. These blocks override the standard behavior of the
39    base transform; a custom transform with no overrides is a null transform
40    that merely passes through a data flow.
41
42    A new transform type is created when calling the SecTransformRegister
43    function which registers the name of the new transform and sets up its
44    overrides. The SecTransformCreate function creates a new instance of a
45    registered custom transform.
46
47    A sample custom transform is provided here, along with a basic test program.
48    This transform creates a Caesar cipher transform, one that simply adds a
49    value to every byte of the plaintext.
50
51    -----cut here-----
52<pre>
53@textblock
54//
55//  CaesarXform.c
56//
57//  Copyright 2010 Apple Inc. All rights reserved.
58//
59//
60
61#include <Security/SecCustomTransform.h>
62#include <Security/SecTransform.h>
63
64// This is the unique name for the custom transform type.
65const CFStringRef kCaesarCipher = CFSTR("com.apple.caesarcipher");
66
67// Name of the "key" attribute.
68const CFStringRef kKeyAttributeName = CFSTR("key");
69
70// Shortcut to return a CFError.
71CFErrorRef invalid_input_error(void)
72{
73    return CFErrorCreate(kCFAllocatorDefault, kSecTransformErrorDomain,
74                         kSecTransformErrorInvalidInput, NULL);
75}
76
77// =========================================================================
78//  Implementation of the Transform instance
79// =========================================================================
80static SecTransformInstanceBlock CaesarImplementation(CFStringRef name,
81                                            SecTransformRef newTransform,
82                                            SecTransformImplementationRef ref)
83{
84
85    SecTransformInstanceBlock instanceBlock =
86    ^{
87        CFErrorRef result = NULL;
88
89        // Every time a new instance of this custom transform class is
90        // created, this block is called. This behavior means that any
91        // block variables created in this block act like instance
92        // variables for the new custom transform instance.
93        __block int _key = 0;
94
95        result = SecTransformSetAttributeAction(ref,
96                                                kSecTransformActionAttributeNotification,
97                                                kKeyAttributeName,
98                                                ^(SecTransformAttributeRef name, CFTypeRef d)
99            {
100                CFNumberGetValue((CFNumberRef)d, kCFNumberIntType, &_key);
101                return d;
102            });
103
104        if (result)
105            return result;
106
107        // Create an override that will be called to process the input
108        // data into the output data
109        result = SecTransformSetDataAction(ref,
110                                           kSecTransformActionProcessData,
111                                           ^(CFTypeRef d)
112            {
113                if (NULL == d)               // End of stream?
114                    return (CFTypeRef) NULL; // Just return a null.
115
116                char *dataPtr = (char *)CFDataGetBytePtr((CFDataRef)d);
117
118                CFIndex dataLength = CFDataGetLength((CFDataRef)d);
119
120                // Do the processing in memory.  There are better ways to do
121                // this but for showing how custom transforms work this is fine.
122                char *buffer = (char *)malloc(dataLength);
123                if (NULL == buffer)
124                    return (CFTypeRef) invalid_input_error();            // Return a CFErrorRef
125
126                // Do the work of the caesar cipher (Rot(n))
127
128                CFIndex i;
129                for (i = 0; i < dataLength; i++)
130                    buffer[i] = dataPtr[i] + _key;
131
132                return (CFTypeRef)CFDataCreateWithBytesNoCopy(NULL, (UInt8 *)buffer,
133                                                              dataLength, kCFAllocatorMalloc);
134            });
135        return result;
136    };
137
138    return Block_copy(instanceBlock);
139}
140
141SecTransformRef CaesarTransformCreate(CFIndex k, CFErrorRef* error)
142{
143    SecTransformRef caesarCipher;
144    __block Boolean result = 1;
145    static dispatch_once_t registeredOK = 0;
146
147    dispatch_once(&registeredOK,
148                  ^{
149                     result = SecTransformRegister(kCaesarCipher, &CaesarImplementation, error);
150                  });
151
152    if (!result)
153        return NULL;
154
155    caesarCipher = SecTransformCreate(kCaesarCipher, error);
156    if (NULL != caesarCipher)
157    {
158        CFNumberRef keyNumber =  CFNumberCreate(kCFAllocatorDefault,
159                                                kCFNumberIntType, &k);
160        SecTransformSetAttribute(caesarCipher, kKeyAttributeName,
161                                 keyNumber, error);
162        CFRelease(keyNumber);
163    }
164
165    return caesarCipher;
166}
167
168
169// The second function shows how to use custom transform defined in the
170// previous function
171
172// =========================================================================
173//  Use a custom ROT-N (caesar cipher) transform
174// =========================================================================
175CFDataRef TestCaesar(CFDataRef theData, int rotNumber)
176{
177    CFDataRef result = NULL;
178    CFErrorRef error = NULL;
179
180    if (NULL == theData)
181        return result;
182
183    // Create an instance of the custom transform
184    SecTransformRef caesarCipher = CaesarTransformCreate(rotNumber, &error);
185    if (NULL == caesarCipher || NULL != error)
186        return result;
187
188    // Set the data to be transformed as the input to the custom transform
189    SecTransformSetAttribute(caesarCipher,
190                             kSecTransformInputAttributeName, theData, &error);
191
192    if (NULL != error)
193    {
194        CFRelease(caesarCipher);
195        return result;
196    }
197
198    // Execute the transform synchronously
199    result = (CFDataRef)SecTransformExecute(caesarCipher, &error);
200    CFRelease(caesarCipher);
201
202    return result;
203}
204
205#include <CoreFoundation/CoreFoundation.h>
206
207int main (int argc, const char *argv[])
208{
209    CFDataRef testData, testResult;
210    UInt8 bytes[26];
211    int i;
212
213    // Create some test data, a string from A-Z
214
215    for (i = 0; i < sizeof(bytes); i++)
216        bytes[i] = 'A' + i;
217
218    testData = CFDataCreate(kCFAllocatorDefault, bytes, sizeof(bytes));
219    CFRetain(testData);
220    CFShow(testData);
221
222    // Encrypt the test data
223    testResult = TestCaesar(testData, 3);
224
225    CFShow(testResult);
226    CFRelease(testData);
227    CFRelease(testResult);
228    return 0;
229}
230@/textblock
231</pre>
232
233*/
234
235/****************	Custom Transform attribute metadata   ****************/
236
237/*!
238    @enum Custom Transform Attribute Metadata
239    @discussion
240            Within a transform, each of its attributes is a collection of
241            "metadata attributes", of which name and current value are two. The
242            value is directly visible from outside; the other metadata
243            attributes direct the behavior of the transform and
244            its function within its group. Each attribute may be tailored by setting its metadata.
245
246    @const kSecTransformMetaAttributeValue
247            The actual value of the attribute. The attribute value has a default
248            value of NULL.
249
250    @const kSecTransformMetaAttributeName
251            The name of the attribute. Attribute name is read only and may
252            not be used with the SecTransformSetAttributeBlock block.
253
254    @const kSecTransformMetaAttributeRef
255            A direct reference to an attribute's value. This reference allows
256            for direct access to an attribute without having to look up the
257            attribute by name.  If a transform commonly uses an attribute, using
258            a reference speeds up the use of that attribute. Attribute
259            references are not visible or valid from outside of the particular
260            transform instance.
261
262    @const kSecTransformMetaAttributeRequired
263            Specifies if an attribute must have a non NULL value set or have an
264            incoming connection before the transform starts to execute. This
265            metadata has a default value of true for the input attribute, but
266            false for all other attributes.
267
268    @const kSecTransformMetaAttributeRequiresOutboundConnection
269            Specifies if an attribute must have an outbound connection. This
270            metadata has a default value of true for the output attribute but is
271            false for all other attributes.
272
273    @const kSecTransformMetaAttributeDeferred
274            Determines if the AttributeSetNotification notification or the
275            ProcessData blocks are deferred until SecExecuteTransform is called.
276            This metadata value has a default value of true for the input
277            attribute but is false for all other attributes.
278
279    @const kSecTransformMetaAttributeStream
280            Specifies if the attribute should expect a series of values ending
281            with a NULL to specify the end of the data stream. This metadata has
282            a default value of true for the input and output attributes, but is
283            false for all other attributes.
284
285    @const kSecTransformMetaAttributeCanCycle
286            A Transform group is a directed graph which is typically acyclic.
287            Some transforms need to work with cycles. For example, a transform
288            that emits a header and trailer around the data of another transform
289            must create a cycle. If this metadata set to true, no error is
290            returned if a cycle is detected for this attribute.
291
292    @const kSecTransformMetaAttributeExternalize
293            Specifies if this attribute should be written out when creating the
294            external representation of this transform. This metadata has a
295            default value of true.
296
297    @const kSecTransformMetaAttributeHasOutboundConnections
298            This metadata value is true if the attribute has an outbound
299            connection. This metadata is read only.
300
301    @const kSecTransformMetaAttributeHasInboundConnection
302            This metadata value is true if the attribute has an inbound
303            connection. This metadata is read only.
304*/
305
306enum
307{
308    kSecTransformMetaAttributeValue,
309    kSecTransformMetaAttributeName,
310    kSecTransformMetaAttributeRef,
311    kSecTransformMetaAttributeRequired,
312    kSecTransformMetaAttributeRequiresOutboundConnection,
313    kSecTransformMetaAttributeDeferred,
314    kSecTransformMetaAttributeStream,
315    kSecTransformMetaAttributeCanCycle,
316    kSecTransformMetaAttributeExternalize,
317    kSecTransformMetaAttributeHasOutboundConnections,
318    kSecTransformMetaAttributeHasInboundConnection
319};
320
321typedef CFIndex SecTransformMetaAttributeType;
322
323/*!
324    @typedef        SecTransformAttributeRef
325
326    @abstract       A direct reference to an attribute. Using an attribute
327                    reference speeds up using an attribute's value by removing
328                    the need to look
329    it up by name.
330*/
331typedef CFTypeRef SecTransformAttributeRef;
332
333
334/*!
335    @typedef        SecTransformStringOrAttributeRef
336
337    @abstract       This type signifies that either a CFStringRef or
338                    a SecTransformAttributeRef may be used.
339*/
340typedef CFTypeRef SecTransformStringOrAttributeRef;
341
342
343/*!
344    @typedef        SecTransformActionBlock
345
346    @abstract       A block that overrides the default behavior of a
347                    custom transform.
348
349    @result         If this block is used to overide the
350                    kSecTransformActionExternalizeExtraData action then the
351                    block should return a CFDictinaryRef of the custom
352                    items to be exported. For all of other actions the
353                    block should return NULL. If an error occurs for
354                    any action, the block should return a CFErrorRef.
355
356    @discussion     A SecTransformTransformActionBlock block is used to
357                    override
358                    the default behavior of a custom transform. This block is
359                    associated with the SecTransformOverrideTransformAction
360                    block.
361
362                    The behaviors that can be overridden are:
363
364                        kSecTransformActionCanExecute
365                            Determine if the transform has all of the data
366                            needed to run.
367
368                        kSecTransformActionStartingExecution
369                            Called just before running ProcessData.
370
371                        kSecTransformActionFinalize
372                            Called just before deleting the custom transform.
373
374                        kSecTransformActionExternalizeExtraData
375                            Called to allow for writing out custom data
376                            to be exported.
377
378                    Example:
379<pre>
380@textblock
381                    SecTransformImplementationRef ref;
382                    CFErrorRef error = NULL;
383
384                    error = SecTransformSetTransformAction(ref, kSecTransformActionStartingExecution,
385                    ^{
386                        // This is where the work to initialize any data needed
387                        // before running
388                        CFErrorRef result = DoMyInitialization();
389                        return result;
390                    });
391
392                    SecTransformTransformActionBlock actionBlock =
393                    ^{
394                        // This is where the work to clean up any existing data
395                        // before running
396                        CFErrorRef result = DoMyFinalization();
397                        return result;
398                    };
399
400                    error = SecTransformSetTransformAction(ref, kSecTransformActionFinalize,
401                        actionBlock);
402@/textblock
403</pre>
404*/
405typedef CFTypeRef (^SecTransformActionBlock)(void);
406
407/*!
408    @typedef        SecTransformAttributeActionBlock
409
410    @abstract       A block used to override the default attribute handling
411                    for when an attribute is set.
412
413    @param attribute       The attribute whose default is being overridden or NULL
414                    if this is a generic notification override
415
416    @param value    Proposed new value for the attribute.
417
418    @result         The new value of the attribute if successful. If an
419                    error occurred then a CFErrorRef is returned. If a transform
420                    needs to have a CFErrorRef as the value of an attribute,
421                    then the CFErrorRef needs to be placed into a container such
422                    as a CFArrayRef, CFDictionaryRef etc.
423
424    @discussion     See the example program in this header for more details.
425
426*/
427typedef CFTypeRef (^SecTransformAttributeActionBlock)(
428                                SecTransformAttributeRef attribute,
429                                CFTypeRef value);
430
431/*!
432    @typedef        SecTransformDataBlock
433
434    @abstract       A block used to override the default data handling
435                    for a transform.
436
437    @param data     The data to be processed. When this block is used
438                    to to implement the kSecTransformActionProcessData action,
439                    the data is the input data that is to be processed into the
440                    output data.  When this block is used to implement the
441                    kSecTransformActionInternalizeExtraData action, the data is
442                    a CFDictionaryRef that contains the data that needs to be
443                    imported.
444
445    @result         When this block is used to implment the
446                    kSecTransformActionProcessData action, the value returned
447                    is to be the data that will be passed to the output
448                    attribute.  If an error occured while processing the input
449                    data then the block should return a CFErrorRef.
450
451                    When this block is used to implement the
452                    kSecTransformActionInternalizeExtraData action then this block
453                    should return NULL or a CFErrorRef if an error occurred.
454
455    @discussion     See the example program for more details.
456*/
457typedef CFTypeRef (^SecTransformDataBlock)(CFTypeRef data);
458
459/*!
460    @typedef        SecTransformInstanceBlock
461
462    @abstract       This is the block that is returned from an
463                    implementation of a CreateTransform function.
464
465    @result         A CFErrorRef if an error occurred or NULL.
466
467    @discussion     The instance block that is returned from the
468                    developers CreateTransform function, defines
469                    the behavior of a custom attribute.  Please
470                    see the example at the head of this file.
471
472*/
473typedef CFErrorRef (^SecTransformInstanceBlock)(void);
474
475/*!
476    @typedef        SecTransformImplementationRef
477
478    @abstract       The SecTransformImplementationRef is a pointer to a block
479                    that implements an instance of a transform.
480
481*/
482typedef const struct OpaqueSecTransformImplementation* SecTransformImplementationRef;
483
484/*!
485    @function       SecTransformSetAttributeAction
486
487    @abstract       Be notified when a attribute is set. The supplied block is
488                    called when the attribute is set. This can be done for a
489                    specific named attribute or all attributes.
490
491    @param ref      A SecTransformImplementationRef that is bound to an instance
492                    of a custom transform.
493
494    @param action   The behavior to be set. This can be one of the following
495                    actions:
496
497                    kSecTransformActionAttributeNotification - add a block that
498                    is called when an attribute is set. If the name is NULL,
499                    then the supplied block is called for all set attributes
500                    except for ones that have a specific block as a handler.
501
502                    For example, if there is a handler for the attribute "foo"
503                    and for all attributes, the "foo" handler is called when the
504                    "foo" attribute is set, but all other attribute sets will
505                    call the NULL handler.
506
507                    The kSecTransformActionProcessData action is a special case
508                    of a SecTransformSetAttributeAction action.  If this is
509                    called on the input attribute then it will overwrite any
510                    kSecTransformActionProcessData that was set.
511
512                    kSecTransformActionAttributeValidation Add a block that is
513                    called to validate the input to an attribute.
514
515    @param attribute
516                    The name of the attribute that will be handled. An attribute
517                    reference may also be given here. A NULL name indicates that
518                    the supplied action is for all attributes.
519
520    @param newAction
521                    A SecTransformAttributeActionBlock which implements the
522                    behavior.
523
524    @result         A CFErrorRef if an error occured NULL otherwise.
525
526    @discussion     This function may be called multiple times for either a
527                    named attribute or for all attributes when the attribute
528                    parameter is NULL. Each time the API is called it overwrites
529                    what was there previously.
530
531*/
532CF_EXPORT
533CFErrorRef SecTransformSetAttributeAction(SecTransformImplementationRef ref,
534                                CFStringRef action,
535                                SecTransformStringOrAttributeRef attribute,
536                                SecTransformAttributeActionBlock newAction);
537/*!
538    @function       SecTransformSetDataAction
539
540    @abstract       Change the way a custom transform will do data processing.
541                    When the action parameter is kSecTransformActionProcessData
542                    The newAction block will change the way that input data is
543                    processed to become the output data. When the action
544                    parameter is kSecTransformActionInternalizeExtraData it will
545                    change the way a custom transform reads in data to be
546                    imported into the transform.
547
548    @param ref      A SecTransformImplementationRef that is bound to an instance
549                    of a custom transform.
550
551    @param action   The action being overridden.  This value should be one of the
552                    following:
553                        kSecTransformActionProcessData
554                            Change the way that input data is processed into the
555                            output data. The default behavior is to simply copy
556                            the input data to the output attribute.
557
558                            The kSecTransformActionProcessData action is really
559                            a special case of a SecTransformSetAttributeAction
560                            action. If you call this method with
561                            kSecTransformActionProcessData it would overwrite
562                            any kSecTransformActionAttributeNotification action
563                            that was set proviously
564
565                        kSecTransformActionInternalizeExtraData
566                            Change the way that custom externalized data is
567                            imported into the transform.  The default behavior
568                            is to do nothing.
569
570    @param newAction
571                    A SecTransformDataBlock which implements the behavior.
572
573                    If the action parameter is kSecTransformActionProcessData then
574                    this block will be called to process the input data into the
575                    output data.
576
577                    if the action parameter is kSecTransformActionInternalizeExtraData then
578                    this block will called to input custom data into the transform.
579
580    @result         A CFErrorRef is an error occured NULL otherwise.
581
582    @discussion      This API may be called multiple times.  Each time the API is called
583                    it overwrites what was there previously.
584
585*/
586CF_EXPORT
587CFErrorRef SecTransformSetDataAction(SecTransformImplementationRef ref,
588                                    CFStringRef action,
589                                    SecTransformDataBlock newAction);
590
591/*
592    @function       SecTransformSetTransformAction
593
594    @abstract       Change the way that transform deals with transform lifecycle
595                    behaviors.
596
597    @param ref      A SecTransformImplementationRef that is bound to an instance
598                    of a custom transform. It provides the neccessary context
599                    for making the call to modify a custom transform.
600
601    @param action   Defines what behavior will be changed.  The possible values
602                    are:
603
604                        kSecTransformActionCanExecute
605                            A CanExecute block is called before the transform
606                            starts to execute. Returning NULL indicates that the
607                            transform has all necessary parameters set up to be
608                            able to execute. If there is a condition that
609                            prevents this transform from executing, return a
610                            CFError. The default behavior is to return NULL.
611
612                        kSecTransformActionStartingExecution
613                            A StartingExecution block is called as a transform
614                            starts execution but before any input is delivered.
615                            Transform-specific initialization can be performed
616                            in this block.
617
618                        kSecTransformActionFinalize
619                            A Finalize block is called before a transform is
620                            released. Any final cleanup can be performed in this
621                            block.
622
623                        kSecTransformActionExternalizeExtraData
624                            An ExternalizeExtraData block is called before a
625                            transform is externalized. If there is any extra
626                            work that the transform needs to do (e.g. copy data
627                            from local variables to attributes) it can be
628                            performed in this block.
629
630    @param newAction
631                    A SecTransformTransformActionBlock which implements the behavior.
632
633    @result         A CFErrorRef if an error occured NULL otherwise.
634
635*/
636CF_EXPORT
637CFErrorRef SecTransformSetTransformAction(SecTransformImplementationRef ref,
638                                CFStringRef action,
639                                SecTransformActionBlock newAction);
640
641/*!
642 @function       SecTranformCustomGetAttribute
643
644 @abstract       Allow a custom transform to get an attribute value
645
646 @param ref      A SecTransformImplementationRef that is bound to an instance
647 of a custom transform.
648
649 @param attribute
650 The name or the attribute handle of the attribute whose
651 value is to be retrieved.
652
653 @param type     The type of data to be retrieved for the attribute.  See the
654 discussion on SecTransformMetaAttributeType for details.
655
656 @result         The value of the attribute.
657
658 */
659CF_EXPORT
660CFTypeRef SecTranformCustomGetAttribute(SecTransformImplementationRef ref,
661                                        SecTransformStringOrAttributeRef attribute,
662                                        SecTransformMetaAttributeType type) AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8;
663
664/*!
665 @function       SecTransformCustomGetAttribute
666
667 @abstract       Allow a custom transform to get an attribute value
668
669 @param ref      A SecTransformImplementationRef that is bound to an instance
670 of a custom transform.
671
672 @param attribute
673 The name or the attribute handle of the attribute whose
674 value is to be retrieved.
675
676 @param type     The type of data to be retrieved for the attribute.  See the
677 discussion on SecTransformMetaAttributeType for details.
678
679 @result         The value of the attribute.
680
681 */
682CF_EXPORT
683CFTypeRef SecTransformCustomGetAttribute(SecTransformImplementationRef ref,
684                                        SecTransformStringOrAttributeRef attribute,
685                                        SecTransformMetaAttributeType type) __asm__("_SecTranformCustomGetAttribute");
686
687/*!
688    @function       SecTransformCustomSetAttribute
689
690    @abstract       Allow a custom transform to set an attribute value
691
692    @param ref      A SecTransformImplementationRef that is bound to an instance
693                    of a custom transform.
694
695    @param attribute
696                    The name or the attribute handle of the attribute whose
697                    value is to be set.
698
699    @param type     The type of data to be retrieved for the attribute.  See the
700                    discussion on SecTransformMetaAttributeType for details.
701
702    @param value    The new value for the attribute
703
704    @result         A CFErrorRef if an error occured , NULL otherwise.
705
706    @discussion     Unlike the SecTransformSetAttribute API this API can set
707                    attribute values while a transform is executing.  These
708                    values are limited to the custom transform instance that
709                    is bound to the ref parameter.
710
711*/
712CF_EXPORT
713CFTypeRef SecTransformCustomSetAttribute(SecTransformImplementationRef ref,
714                                    SecTransformStringOrAttributeRef attribute,
715                                    SecTransformMetaAttributeType type,
716                                    CFTypeRef value);
717/*!
718    @function       SecTransformPushbackAttribute
719
720    @abstract       Allows for putting a single value back for a specific
721                    attribute.  This will stop the flow of data into the
722                    specified attribute until any attribute is changed for the
723                    transform instance bound to the ref parameter.
724
725    @param ref      A SecTransformImplementationRef that is bound to an instance
726                    of a custom transform.
727
728    @param attribute
729                    The name or the attribute handle of the attribute whose
730                    value is to be pushed back.
731
732    @param value    The value being pushed back.
733
734    @result         A CFErrorRef if an error occured , NULL otherwise.
735
736*/
737CF_EXPORT
738CFTypeRef SecTransformPushbackAttribute(SecTransformImplementationRef ref,
739                                SecTransformStringOrAttributeRef attribute,
740                                CFTypeRef value);
741
742/*!
743    @typedef        SecTransformCreateFP
744
745    @abstract       A function pointer to a function that will create a
746                    new instance of a custom transform.
747
748    @param name     The name of the new custom transform. This name MUST be
749                    unique.
750
751    @param newTransform
752                    The newly created transform Ref.
753
754    @param ref      A reference that is bound to an instance of a custom
755                    transform.
756
757    @result         A SecTransformInstanceBlock that is used to create a new
758                    instance of a custom transform.
759
760    @discussion      The CreateTransform function creates a new transform. The
761                    SecTransformInstanceBlock that is returned from this
762                    function provides the implementation of all of the overrides
763                    necessary to create the custom transform. This returned
764                    SecTransformInstanceBlock is also where the "instance"
765                    variables for the custom transform may be defined. See the
766                    example in the header section of this file for more detail.
767*/
768
769typedef SecTransformInstanceBlock (*SecTransformCreateFP)(CFStringRef name,
770                            SecTransformRef newTransform,
771                            SecTransformImplementationRef ref);
772
773/************** custom Transform transform override actions   **************/
774
775/*!
776    @constant  kSecTransformActionCanExecute
777                Overrides the standard behavior that checks to see if all of the
778                required attributes either have been set or are connected to
779                another transform.  When overriding the default behavior the
780                developer can decided what the necessary data is to have for a
781                transform to be considered 'ready to run'.  Returning NULL means
782                that the transform is ready to be run. If the transform is NOT
783                ready to run then the override should return a CFErrorRef
784                stipulating the error.
785 */
786CF_EXPORT const CFStringRef kSecTransformActionCanExecute;
787/*!
788    @constant  kSecTransformActionStartingExecution
789                Overrides the standard behavior that occurs just before starting
790                execution of a custom transform. This is typically overridden
791                to allow for initialization. This is used with the
792                SecTransformOverrideTransformAction block.
793 */
794CF_EXPORT const CFStringRef kSecTransformActionStartingExecution;
795
796/*!
797    @constant kSecTransformActionFinalize
798                Overrides the standard behavior that occurs just before deleting
799                a custom transform. This is typically overridden to allow for
800                memory clean up of a custom transform.  This is used with the
801                SecTransformOverrideTransformAction block.
802 */
803CF_EXPORT const CFStringRef kSecTransformActionFinalize;
804
805/*!
806
807    @constant kSecTransformActionExternalizeExtraData
808                Allows for adding to the data that is stored using an override
809                to the kSecTransformActionExternalizeExtraData block. The output
810                of this override is a dictionary that contains the custom
811                externalized data. A common use of this override is to write out
812                a version number of a custom transform.
813 */
814CF_EXPORT const CFStringRef kSecTransformActionExternalizeExtraData;
815
816/*!
817    @constant  kSecTransformActionProcessData
818                Overrides the standard data processing for an attribute. This is
819                almost exclusively used for processing the input attribute as
820                the return value of their block sets the output attribute. This
821                is used with the SecTransformOverrideAttributeAction block.
822 */
823CF_EXPORT const CFStringRef kSecTransformActionProcessData;
824
825/*!
826    @constant kSecTransformActionInternalizeExtraData
827                Overrides the standard processing that occurs when externalized
828                data is used to create a transform.  This is closely tied to the
829                kSecTransformActionExternalizeExtraData override. The 'normal'
830                attributes are read into the new transform and then this is
831                called to read in the items that were written out using
832                kSecTransformActionExternalizeExtraData override. A common use
833                of this override would be to read in the version number of the
834                externalized custom transform.
835 */
836CF_EXPORT const CFStringRef kSecTransformActionInternalizeExtraData;
837
838/*!
839    @constant SecTransformActionAttributeNotification
840                Allows a block to be called when an attribute is set.  This
841                allows for caching the value as a block variable in the instance
842                block or transmogrifying the data to be set. This action is
843                where a custom transform would be able to do processing outside
844                of processing input to output as process data does.  One the
845                data has been processed the action block can call
846                SecTransformCustomSetAttribute to update and other attribute.
847 */
848CF_EXPORT const CFStringRef kSecTransformActionAttributeNotification;
849
850/*!
851    @constant kSecTransformActionAttributeValidation
852                Allows a block to be called to validate the new value for an
853                attribute.  The default is no validation and any CFTypeRef can
854                be used as the new value.  The block should return NULL if the
855                value is ok to set on the attribute or a CFErrorRef otherwise.
856
857*/
858CF_EXPORT const CFStringRef kSecTransformActionAttributeValidation;
859
860/*!
861    @function       SecTransformRegister
862
863    @abstract       Register a new custom transform so that it may be used to
864                    process data
865
866    @param uniqueName
867                    A unique name for this custom transform.  It is recommended
868                    that a reverse DNS name be used for the name of your custom
869                    transform
870
871    @param createTransformFunction
872                    A SecTransformCreateFP function pointer. The function must
873                    return a SecTransformInstanceBlock block that block_copy has
874                    been called on before returning the block. Failure to call
875                    block_copy will cause undefined behavior.
876
877    @param error    This pointer is set if an error occurred.  This value
878                    may be NULL if you do not want an error returned.
879
880    @result         True if the custom transform was registered false otherwise
881
882*/
883CF_EXPORT
884Boolean SecTransformRegister(CFStringRef uniqueName,
885                                    SecTransformCreateFP createTransformFunction,
886                                    CFErrorRef* error)
887                            __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA);
888
889/*!
890     @function      SecTransformCreate
891
892     @abstract      Creates a transform computation object.
893
894     @param name    The type of transform to create, must have been registered
895                    by SecTransformRegister, or be a system pre-defined
896                    transform type.
897
898     @param error   A pointer to a CFErrorRef.  This pointer is set if an error
899                    occurred.  This value may be NULL if you do not want an
900                    error returned.
901
902     @result        A pointer to a SecTransformRef object.  This object must be
903                    released with CFRelease when you are done with it.  This
904                    function returns NULL if an error occurred.
905 */
906CF_EXPORT
907SecTransformRef SecTransformCreate(CFStringRef name, CFErrorRef *error)
908                            __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA);
909
910/*!
911    @Function       SecTransformNoData
912
913    @abstract       Returns back A CFTypeRef from inside a processData
914                    override that says that while no data is being returned
915                    the transform is still active and awaiting data.
916
917    @result         A 'special' value that allows that specifies that the
918                    transform is still active and awaiting data.
919
920    @discussion      The standard behavior for the ProcessData override is that
921                    it will receive a CFDataRef and it processes that data and
922                    returns a CFDataRef that contains the processed data. When
923                    there is no more data to process the ProcessData override
924                    block is called one last time with a NULL CFDataRef.  The
925                    ProcessData block should/must return the NULL CFDataRef to
926                    complete the processing.  This model does not work well for
927                    some transforms. For example a digest transform needs to see
928                    ALL of the data that is being digested before it can send
929                    out the digest value.
930
931                    If a ProcessData block has no data to return, it can return
932                    SecTransformNoData(), which informs the transform system
933                    that there is no data to pass on to the next transform.
934
935
936*/
937CF_EXPORT
938CFTypeRef SecTransformNoData(void);
939
940CF_EXTERN_C_END
941
942#endif // __BLOCKS__
943#endif // _SEC_CUSTOM_TRANSFORM_H__
944