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