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(®isteredOK, 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