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