]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_transform/lib/SecTransform.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / Security / libsecurity_transform / lib / SecTransform.cpp
diff --git a/Security/libsecurity_transform/lib/SecTransform.cpp b/Security/libsecurity_transform/lib/SecTransform.cpp
deleted file mode 100644 (file)
index 958d097..0000000
+++ /dev/null
@@ -1,547 +0,0 @@
-#include "SecTransform.h"
-#include "SecTransformInternal.h"
-
-#include "Transform.h"
-#include "Utilities.h"
-#include "TransformFactory.h"
-#include "GroupTransform.h"
-#include "c++utils.h"
-#include "SecCollectTransform.h"
-
-
-#include <string>
-
-using namespace std;
-
-const CFStringRef kSecTransformInputAttributeName = CFSTR("INPUT");
-const CFStringRef kSecTransformOutputAttributeName = CFSTR("OUTPUT");
-const CFStringRef kSecTransformDebugAttributeName = CFSTR("DEBUG");
-const CFStringRef kSecTransformTransformName = CFSTR("NAME");
-//const CFStringRef kSecTransformErrorTransform = CFSTR("TRANSFORM");
-const CFStringRef kSecTransformErrorDomain = CFSTR("com.apple.security.transforms.error");
-const CFStringRef kSecTransformAbortAttributeName = CFSTR("ABORT");
-
-CFErrorRef SecTransformConnectTransformsInternal(SecGroupTransformRef groupRef,
-                                                               SecTransformRef sourceTransformRef,
-                                                                       CFStringRef sourceAttributeName,
-                                                                       SecTransformRef destinationTransformRef,
-                                                                       CFStringRef destinationAttributeName)
-{
-       Transform* destination = (Transform*) CoreFoundationHolder::ObjectFromCFType(destinationTransformRef);
-       Transform* source = (Transform*) CoreFoundationHolder::ObjectFromCFType(sourceTransformRef);
-
-       GroupTransform* group = (GroupTransform*) CoreFoundationHolder::ObjectFromCFType(groupRef);
-       CFErrorRef temp = source->Connect(group, destination, destinationAttributeName, sourceAttributeName);
-       return temp;
-}
-
-
-CFErrorRef SecTransformDisconnectTransforms(SecTransformRef sourceTransformRef, CFStringRef sourceAttributeName,
-                                                                                       SecTransformRef destinationTransformRef, CFStringRef destinationAttributeName)
-{
-       Transform* destination = (Transform*) CoreFoundationHolder::ObjectFromCFType(destinationTransformRef);
-       Transform* source = (Transform*) CoreFoundationHolder::ObjectFromCFType(sourceTransformRef);
-       return source->Disconnect(destination, sourceAttributeName, destinationAttributeName);
-}
-
-SecGroupTransformRef SecTransformCreateGroupTransform()
-{
-       return (SecGroupTransformRef) GroupTransform::Make();
-}
-
-SecGroupTransformRef SecTransformConnectTransforms(SecTransformRef sourceTransformRef,
-                                                  CFStringRef sourceAttributeName,
-                                                  SecTransformRef destinationTransformRef,
-                                                  CFStringRef destinationAttributeName,
-                                                  SecGroupTransformRef group,
-                                                  CFErrorRef *error)
-{
-       if (group == NULL)
-       {
-               if (error)
-               {
-                       *error = CreateSecTransformErrorRef(kSecTransformErrorMissingParameter, "Group must not be NULL.");
-               }
-
-               return NULL;
-       }
-
-       if (destinationAttributeName == NULL)
-       {
-               destinationAttributeName = kSecTransformInputAttributeName;
-       }
-
-       if (sourceAttributeName == NULL)
-       {
-               sourceAttributeName = kSecTransformOutputAttributeName;
-       }
-
-       GroupTransform* gtr = (GroupTransform*) CoreFoundationHolder::ObjectFromCFType(group);
-
-       CFErrorRef temp = SecTransformConnectTransformsInternal(gtr->GetCFObject(),
-                       sourceTransformRef, sourceAttributeName,
-                       destinationTransformRef, destinationAttributeName);
-
-       if (error)
-       {
-               *error = temp;
-       }
-
-       if (temp) // an error happened?
-       {
-               return NULL;
-       }
-       else
-       {
-               return group;
-       }
-}
-
-
-
-Boolean SecTransformSetAttribute(SecTransformRef transformRef,
-                                                               CFStringRef key,
-                                                               CFTypeRef value,
-                                                               CFErrorRef *error)
-{
-       Boolean result = false; // Guilty until proven
-       Transform* transform = (Transform*) CoreFoundationHolder::ObjectFromCFType(transformRef);
-
-       if (CFGetTypeID(transformRef) == GroupTransform::GetCFTypeID() && !transform->getAH(key, false))
-       {
-               if (error)
-               {
-                       *error = CreateSecTransformErrorRef(kSecTransformOperationNotSupportedOnGroup, "SecTransformSetAttribute on non-exported attribute: %@ (exported attributes are: %@).", key, transform->GetAllAH());
-               }
-
-               return result;
-       }
-
-       // if the caller is setting the abort attribute, a value must be supplied
-       if (NULL == value && CFStringCompare(key, kSecTransformAbortAttributeName, 0) == kCFCompareEqualTo)
-       {
-               if (error)
-               {
-            // XXX:  "a parameter"?  It has one: NULL.  What it requires is a non-NULL value.
-                       *error = CreateSecTransformErrorRef(kSecTransformInvalidArgument, "ABORT requires a parameter.");
-               }
-
-               return result;
-       }
-
-       CFErrorRef temp = transform->ExternalSetAttribute(key, value);
-       result = (temp == NULL);
-       if (error)
-       {
-               *error = temp;
-       }
-       else
-       {
-               if (temp)
-               {
-                       CFRelease(temp);
-               }
-       }
-
-       return result;
-}
-
-
-
-CFTypeRef SecTransformGetAttribute(SecTransformRef transformRef,
-                                                                       CFStringRef key)
-{
-       // if the transform is a group, we really want to operation on its first object
-       if (CFGetTypeID(transformRef) == GroupTransform::GetCFTypeID())
-       {
-               return NULL;
-       }
-
-       Transform* transform = (Transform*) CoreFoundationHolder::ObjectFromCFType(transformRef);
-       if (transform->mIsActive) {
-               return CreateSecTransformErrorRef(kSecTransformTransformIsExecuting, "Can not get the value of attributes during execution (attempt to fetch %@/%@)", transform->GetName(), key);
-       }
-       return transform->GetAttribute(key);
-}
-
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-function"
-static inline GroupTransform* MakeGroupTransformFromTransformRef(SecTransformRef tr)
-{
-       GroupTransform* gt = (GroupTransform*) CoreFoundationHolder::ObjectFromCFType(tr);
-       return gt;
-}
-#pragma clang diagnostic pop
-
-static CFTypeRef InternalSecTransformExecute(SecTransformRef transformRef,
-                                                       CFErrorRef* errorRef,
-                                                       dispatch_queue_t deliveryQueue,
-                                                       SecMessageBlock deliveryBlock)
-{
-       if (NULL == transformRef || (deliveryBlock && !deliveryQueue))
-       {
-               CFErrorRef localError = CFErrorCreate(kCFAllocatorDefault, kSecTransformErrorDomain,
-                       kSecTransformInvalidArgument, NULL);
-
-               if (NULL != errorRef)
-               {
-                       *errorRef = localError;
-               }
-               else
-               {
-                       CFRelease(localError);
-               }
-
-               return (CFTypeRef)NULL;
-       }
-
-       // if our transform is a group, connect to its first member instead
-       if (CFGetTypeID(transformRef) == GroupTransform::GetCFTypeID())
-       {
-               GroupTransform* gtsrc = (GroupTransform*) CoreFoundationHolder::ObjectFromCFType(transformRef);
-               transformRef = gtsrc->GetAnyMember();
-       }
-
-       Transform* transform = (Transform*) CoreFoundationHolder::ObjectFromCFType(transformRef);
-       return transform->Execute(deliveryQueue, deliveryBlock, errorRef);
-}
-
-CFTypeRef SecTransformExecute(SecTransformRef transformRef, CFErrorRef* errorRef)
-{
-       if (NULL == transformRef)
-       {
-               if (errorRef)
-               {
-                       *errorRef = CreateSecTransformErrorRef(kSecTransformInvalidArgument, "NULL transform can not be executed");
-               }
-               return NULL;
-       }
-
-       Transform* transform = (Transform*) CoreFoundationHolder::ObjectFromCFType(transformRef);
-
-       // transform->Execute will check this, but by then we have attached a collector which causes all manner of issues.
-       if (transform->mIsActive)
-       {
-               if (errorRef)
-               {
-                       *errorRef = CreateSecTransformErrorRef(kSecTransformTransformIsExecuting, "The %@ transform has already executed, it may not be executed again.", transform->GetName());
-               }
-               return NULL;
-       }
-
-       SecTransformRef collectTransform = transforms_assume(SecCreateCollectTransform(errorRef));
-       SecGroupTransformRef theGroup = NULL;
-       Boolean releaseTheGroup = false;
-       GroupTransform* myGroup = NULL;
-       Boolean needConnection = true;
-
-       // Sniff the type of the transformRef to see if it is a group
-       if (SecGroupTransformGetTypeID() == CFGetTypeID(transformRef))
-       {
-               theGroup = (SecGroupTransformRef)transformRef;
-       }
-       else
-       {
-               // Ok TransformRef is a TransformRef so get's it group
-
-               myGroup = transform->mGroup;
-
-               if (NULL == myGroup)
-               {
-                       theGroup = SecTransformCreateGroupTransform();
-                       if (NULL == theGroup)
-                       {
-                               if (NULL != errorRef)
-                               {
-                                       *errorRef = GetNoMemoryErrorAndRetain();
-                               }
-
-                               return (CFTypeRef)NULL;
-
-                       }
-
-                       releaseTheGroup = true;
-
-                       SecGroupTransformRef connectResult =
-                               SecTransformConnectTransforms(transformRef,
-                                                                                 kSecTransformOutputAttributeName,
-                                                                                 collectTransform,
-                                                                                 kSecTransformInputAttributeName,
-                                                                                 theGroup, errorRef);
-
-                       if (NULL == connectResult)
-                       {
-                               return (CFTypeRef)NULL;
-                       }
-
-                       needConnection = false;
-
-               }
-               else
-               {
-                       theGroup = (SecGroupTransformRef)myGroup->GetCFObject();
-               }
-       }
-
-       if (NULL == theGroup || (SecGroupTransformGetTypeID() != CFGetTypeID(theGroup)))
-       {
-               if (NULL != errorRef)
-               {
-                       *errorRef = GetNoMemoryErrorAndRetain();
-               }
-
-               return (CFTypeRef)NULL;
-
-       }
-
-
-       if (needConnection)
-       {
-               // Connect the collectTransform to the group
-               myGroup = ((GroupTransform*)CoreFoundationHolder::ObjectFromCFType(theGroup))->GetRootGroup();
-        if (NULL == myGroup)
-        {
-            if (NULL != errorRef)
-            {
-                *errorRef = GetNoMemoryErrorAndRetain();
-            }
-
-            return (CFTypeRef)NULL;
-        }
-
-               SecTransformRef outputTransform = myGroup->FindLastTransform();
-
-               SecGroupTransformRef connectResult =
-               SecTransformConnectTransforms(outputTransform,
-                                                                         kSecTransformOutputAttributeName,
-                                                                         collectTransform,
-                                                                         kSecTransformInputAttributeName,
-                                                                         myGroup->GetCFObject(), errorRef);
-
-               if (NULL == connectResult)
-               {
-                       CFRelease(collectTransform);
-                       if (releaseTheGroup)
-                       {
-                               CFRelease(theGroup);
-                       }
-                       return (CFTypeRef)NULL;
-               }
-       }
-
-       __block CFTypeRef myResult = NULL;
-       dispatch_semaphore_t mySem = dispatch_semaphore_create(0L);
-       dispatch_queue_t myQueue = dispatch_queue_create("com.apple.security.sectransfrom.SecTransformExecute", NULL);
-       SecMessageBlock myBlock = ^(CFTypeRef message, CFErrorRef error, Boolean isFinal)
-       {
-               if (NULL != error)
-               {
-                       if (NULL != errorRef)
-                       {
-                               CFRetain(error);
-                               *errorRef = error;
-                       }
-
-                       if (NULL != myResult)
-                       {
-                               CFRelease(myResult);
-                               myResult = NULL;
-                       }
-               }
-
-               if (NULL != message)
-               {
-                       myResult = message;
-                       CFRetain(myResult);
-               }
-
-               if (isFinal)
-               {
-                       dispatch_semaphore_signal(mySem);
-               }
-       };
-
-       SecTransformExecuteAsync(theGroup, myQueue, myBlock);
-       dispatch_semaphore_wait(mySem, DISPATCH_TIME_FOREVER);
-       dispatch_release(mySem);
-       dispatch_release(myQueue);
-
-       if (releaseTheGroup)
-       {
-               CFRelease(theGroup);
-               theGroup = NULL;
-       }
-       CFRelease(collectTransform);
-
-       return myResult;
-}
-
-void SecTransformExecuteAsync(SecTransformRef transformRef,
-                                                         dispatch_queue_t deliveryQueue,
-                                                         SecMessageBlock deliveryBlock)
-{
-       CFErrorRef localError = NULL;
-       InternalSecTransformExecute(transformRef, &localError, deliveryQueue, deliveryBlock);
-
-       // if we got an error (usually a transform startup error), we must deliver it
-       if (localError != NULL)
-       {
-               // The monitor treats a NULL queue as running on it's own queue, which from an appication's point of view is
-               // the same as a default global queue.   Chances are there is no monitor at this point, so it is best to just use the
-               //  global queue for this.
-               dispatch_queue_t effectiveQueue = deliveryQueue ? deliveryQueue : dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL);
-               dispatch_async(effectiveQueue, ^{
-                       deliveryBlock(NULL, localError, true);
-               });
-       }
-}
-
-CFDictionaryRef SecTransformCopyExternalRepresentation(SecTransformRef transformRef)
-{
-
-       Transform* tr = (Transform*) CoreFoundationHolder::ObjectFromCFType(transformRef);
-       return tr->Externalize(NULL);
-}
-
-CFStringRef SecTransformDotForDebugging(SecTransformRef transformRef)
-{
-    if (CFGetTypeID(transformRef) == SecGroupTransformGetTypeID()) {
-        GroupTransform* tr = (GroupTransform*) CoreFoundationHolder::ObjectFromCFType(transformRef);
-        return tr->DotForDebugging();
-    } else {
-        return CFSTR("Can only dot debug a group");
-    }
-}
-
-SecTransformRef SecTransformCreateFromExternalRepresentation(
-                                                               CFDictionaryRef dictionary,
-                                                               CFErrorRef *error)
-{
-       // The incoming dictionary consists of a list of transforms and
-       // a list of connections.  We start by making the individual
-       // transforms and storing them in a dictionary so that we can
-       // efficiently make connections
-
-       CFArrayRef transforms = (CFArrayRef) CFDictionaryGetValue(dictionary, EXTERN_TRANSFORM_TRANSFORM_ARRAY);
-       if (transforms == NULL)
-       {
-               // The dictionary we got is massively malformed!
-               *error = CreateSecTransformErrorRef(kSecTransformErrorInvalidInputDictionary, "%@ is missing from the dictionary.  The dictionary is malformed.", EXTERN_TRANSFORM_TRANSFORM_ARRAY);
-               return NULL;
-       }
-
-       CFArrayRef connections = (CFArrayRef) CFDictionaryGetValue(dictionary, EXTERN_TRANSFORM_CONNECTION_ARRAY);
-       if (connections == NULL)
-       {
-               // The dictionary we got is massively malformed!
-               *error = CreateSecTransformErrorRef(kSecTransformErrorInvalidInputDictionary, "%@ is missing from the dictionary.  The dictionary is malformed.", EXTERN_TRANSFORM_CONNECTION_ARRAY);
-               return NULL;
-       }
-
-       CFMutableDictionaryRef transformHolder = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-       CFTypeRefHolder _(transformHolder);
-
-       CFIndex numTransforms = CFArrayGetCount(transforms);
-       CFIndex n;
-
-       SecTransformRef aTransform;
-
-       for (n = 0; n < numTransforms; ++n)
-       {
-               // get the basic info we need
-               CFDictionaryRef xTransform = (CFDictionaryRef) CFArrayGetValueAtIndex(transforms, n);
-
-               CFStringRef xName = (CFStringRef) CFDictionaryGetValue(xTransform, EXTERN_TRANSFORM_NAME);
-
-               CFStringRef xType = (CFStringRef) CFDictionaryGetValue(xTransform, EXTERN_TRANSFORM_TYPE);
-
-               // reconstruct the transform
-               aTransform = TransformFactory::MakeTransformWithType(xType, error);
-               SecTransformSetAttribute(aTransform, kSecTransformTransformName, xName, NULL);
-
-               // restore the transform state
-               Transform* tr = (Transform*) CoreFoundationHolder::ObjectFromCFType(aTransform);
-               tr->RestoreState((CFDictionaryRef) CFDictionaryGetValue(xTransform, EXTERN_TRANSFORM_STATE));
-               tr->SetCustomExternalData((CFDictionaryRef) CFDictionaryGetValue(xTransform, EXTERN_TRANSFORM_CUSTOM_EXPORTS_DICTIONARY));
-
-               CFIndex cnt = CFDictionaryGetCount(transformHolder);
-
-               // add the transform to the dictionary
-               CFDictionaryAddValue(transformHolder, xName, aTransform);
-
-               if (CFDictionaryGetCount(transformHolder) <= cnt)
-               {
-                       if (error)
-                       {
-                               *error = CreateSecTransformErrorRef(kSecTransformErrorInvalidInputDictionary,
-                                                       "Out of memory, or damaged input dictonary (duplicate label %@?)", xName);
-                       }
-                       return NULL;
-               }
-       }
-
-       CFIndex numConnections = CFArrayGetCount(connections);
-       if (numConnections == 0)
-       {
-               return aTransform;
-       }
-
-       SecGroupTransformRef gt = SecTransformCreateGroupTransform();
-
-       for (n = 0; n < numConnections; ++n)
-       {
-               CFDictionaryRef connection = (CFDictionaryRef) CFArrayGetValueAtIndex(connections, n);
-               CFStringRef fromTransformName = (CFStringRef) CFDictionaryGetValue(connection, EXTERN_TRANSFORM_FROM_NAME);
-               CFStringRef fromAttribute = (CFStringRef) CFDictionaryGetValue(connection, EXTERN_TRANSFORM_FROM_ATTRIBUTE);
-               CFStringRef toTransformName = (CFStringRef) CFDictionaryGetValue(connection, EXTERN_TRANSFORM_TO_NAME);
-               CFStringRef toAttribute = (CFStringRef) CFDictionaryGetValue(connection, EXTERN_TRANSFORM_TO_ATTRIBUTE);
-
-               SecTransformRef fromTransform = (SecTransformRef) CFDictionaryGetValue(transformHolder, fromTransformName);
-               if (!fromTransform) {
-                       if (error) {
-                               *error = CreateSecTransformErrorRef(kSecTransformErrorInvalidInputDictionary, "Can't connect %@ to %@ because %@ was not found", fromTransformName, toTransformName, fromTransformName);
-                       }
-                       return NULL;
-               }
-               SecTransformRef toTransform = (SecTransformRef) CFDictionaryGetValue(transformHolder, toTransformName);
-               if (!toTransform) {
-                       if (error) {
-                               *error = CreateSecTransformErrorRef(kSecTransformErrorInvalidInputDictionary, "Can't connect %@ to %@ because %@ was not found", fromTransformName, toTransformName, toTransformName);
-                       }
-                       return NULL;
-               }
-
-               aTransform = SecTransformConnectTransforms(fromTransform, fromAttribute, toTransform, toAttribute, gt, error);
-       }
-
-       return gt;
-}
-
-
-
-SecTransformRef SecTransformFindByName(SecTransformRef transform, CFStringRef name)
-{
-       Transform *t = (Transform*)CoreFoundationHolder::ObjectFromCFType(transform);
-    GroupTransform *g = t->GetRootGroup();
-
-    if (g) {
-        return g->FindByName(name);
-    } else {
-        // There is no group, so if transform isn't our guy nobody is.
-        return (CFStringCompare(name, t->GetName(), 0) == kCFCompareEqualTo) ? transform : NULL;
-    }
-}
-
-
-
-CFTypeID SecGroupTransformGetTypeID()
-{
-       return GroupTransform::GetCFTypeID();
-}
-
-CFTypeID SecTransformGetTypeID()
-{
-       // Obviously this is wrong (returns same CFTypeID as SecTransformGetTypeID) Needs to be fixed
-       return GroupTransform::GetCFTypeID();
-}