1 #include <libkern/OSAtomic.h>
3 #include "TransformFactory.h"
4 #include "NullTransform.h"
6 #include "EncryptTransform.h"
7 #include "GroupTransform.h"
11 void TransformFactory::RegisterTransforms()
13 RegisterTransform_prelocked(NullTransform::MakeTransformFactory(), NULL
);
14 RegisterTransform_prelocked(DigestTransform::MakeTransformFactory(), NULL
);
15 RegisterTransform_prelocked(EncryptTransform::MakeTransformFactory(), NULL
);
16 RegisterTransform_prelocked(DecryptTransform::MakeTransformFactory(), NULL
);
17 RegisterTransform_prelocked(GroupTransform::MakeTransformFactory(), NULL
);
20 CFMutableDictionaryRef
TransformFactory::gRegistered
;
21 dispatch_once_t
TransformFactory::gSetup
;
22 dispatch_queue_t
TransformFactory::gRegisteredQueue
;
24 bool TransformFactory::RegisterTransform_prelocked(TransformFactory
* tf
, CFStringRef cfname
)
26 if (!CFDictionaryContainsKey(gRegistered
, tf
->mCFType
)) {
27 CFDictionaryAddValue(gRegistered
, tf
->mCFType
, tf
);
29 CoreFoundationObject::RegisterObject(tf
->mCFType
, false);
31 if (!CoreFoundationObject::FindObjectType(cfname
)) {
32 CoreFoundationObject::RegisterObject(cfname
, false);
41 void TransformFactory::RegisterTransform(TransformFactory
* tf
, CFStringRef cfname
)
43 dispatch_once_f(&gSetup
, NULL
, Setup
);
44 dispatch_barrier_sync(gRegisteredQueue
, ^{
45 RegisterTransform_prelocked(tf
, cfname
);
49 void TransformFactory::Setup(void *)
51 gRegisteredQueue
= dispatch_queue_create("com.apple.security.TransformFactory.Registered", DISPATCH_QUEUE_CONCURRENT
);
52 gRegistered
= CFDictionaryCreateMutable(NULL
, 0, &kCFCopyStringDictionaryKeyCallBacks
, NULL
);
56 void TransformFactory::Setup()
58 dispatch_once_f(&gSetup
, NULL
, Setup
);
61 TransformFactory
* TransformFactory::FindTransformFactoryByType(CFStringRef name
)
63 dispatch_once_f(&gSetup
, NULL
, Setup
);
64 __block TransformFactory
*ret
;
65 dispatch_barrier_sync(gRegisteredQueue
, ^{
66 ret
= (TransformFactory
*)CFDictionaryGetValue(gRegistered
, name
);
73 SecTransformRef
TransformFactory::MakeTransformWithType(CFStringRef type
, CFErrorRef
* baseError
) CF_RETURNS_RETAINED
75 TransformFactory
* tf
= FindTransformFactoryByType(type
);
78 if (baseError
!= NULL
)
81 // This version lists out all regestered transform types.
82 // It is useful more for debugging then for anything else,
83 // so it is great to keep around, but normally not so good
85 dispatch_barrier_sync(gRegisteredQueue
, ^(void) {
86 CFMutableStringRef transformNames
= CFStringCreateMutable(NULL
, 0);
87 CFIndex numberRegistered
= CFDictionaryGetCount(gRegistered
);
88 CFStringRef
*names
= (CFStringRef
*)malloc(numberRegistered
* sizeof(CFStringRef
));
90 *baseError
= CreateSecTransformErrorRef(errSecMemoryError
,
91 "The %s transform names can't be allocated.", type
);
95 CFDictionaryGetKeysAndValues(gRegistered
, (const void**)names
, NULL
);
96 for(int i
= 0; i
< numberRegistered
; i
++) {
98 CFStringAppend(transformNames
, CFSTR(", "));
100 CFStringAppend(transformNames
, names
[i
]);
105 *baseError
= CreateSecTransformErrorRef(kSecTransformTransformIsNotRegistered
,
106 "The %s transform is not registered, choose from: %@", type
,transformNames
);
110 *baseError
= CreateSecTransformErrorRef(kSecTransformTransformIsNotRegistered
,
111 "The %s transform is not registered", type
);
125 TransformFactory::TransformFactory(CFStringRef type
, bool registerGlobally
, CFStringRef cftype
) : mCFType(type
)
127 if (registerGlobally
)
129 CoreFoundationObject::RegisterObject(cftype
? cftype
: type
, false);