]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 A |
1 | #include <libkern/OSAtomic.h> |
2 | ||
3 | #include "TransformFactory.h" | |
4 | #include "NullTransform.h" | |
5 | #include "Digest.h" | |
6 | #include "EncryptTransform.h" | |
7 | #include "GroupTransform.h" | |
8 | #include "Utilities.h" | |
9 | ||
10 | ||
11 | void TransformFactory::RegisterTransforms() | |
12 | { | |
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); | |
18 | } | |
19 | ||
20 | CFMutableDictionaryRef TransformFactory::gRegistered; | |
21 | dispatch_once_t TransformFactory::gSetup; | |
22 | dispatch_queue_t TransformFactory::gRegisteredQueue; | |
23 | ||
24 | bool TransformFactory::RegisterTransform_prelocked(TransformFactory* tf, CFStringRef cfname) | |
25 | { | |
26 | if (!CFDictionaryContainsKey(gRegistered, tf->mCFType)) { | |
27 | CFDictionaryAddValue(gRegistered, tf->mCFType, tf); | |
28 | if (!cfname) { | |
29 | CoreFoundationObject::RegisterObject(tf->mCFType, false); | |
30 | } else { | |
31 | if (!CoreFoundationObject::FindObjectType(cfname)) { | |
32 | CoreFoundationObject::RegisterObject(cfname, false); | |
33 | } | |
34 | } | |
35 | } | |
36 | ||
37 | return true; | |
38 | } | |
39 | ||
40 | ||
41 | void TransformFactory::RegisterTransform(TransformFactory* tf, CFStringRef cfname) | |
42 | { | |
43 | dispatch_once_f(&gSetup, NULL, Setup); | |
44 | dispatch_barrier_sync(gRegisteredQueue, ^{ | |
45 | RegisterTransform_prelocked(tf, cfname); | |
46 | }); | |
47 | } | |
48 | ||
49 | void TransformFactory::Setup(void *) | |
50 | { | |
51 | gRegisteredQueue = dispatch_queue_create("com.apple.security.TransformFactory.Registered", DISPATCH_QUEUE_CONCURRENT); | |
52 | gRegistered = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, NULL); | |
53 | RegisterTransforms(); | |
54 | } | |
55 | ||
56 | void TransformFactory::Setup() | |
57 | { | |
58 | dispatch_once_f(&gSetup, NULL, Setup); | |
59 | } | |
60 | ||
61 | TransformFactory* TransformFactory::FindTransformFactoryByType(CFStringRef name) | |
62 | { | |
63 | dispatch_once_f(&gSetup, NULL, Setup); | |
64 | __block TransformFactory *ret; | |
65 | dispatch_barrier_sync(gRegisteredQueue, ^{ | |
66 | ret = (TransformFactory*)CFDictionaryGetValue(gRegistered, name); | |
67 | }); | |
68 | return ret; | |
69 | } | |
70 | ||
71 | ||
72 | ||
73 | SecTransformRef TransformFactory::MakeTransformWithType(CFStringRef type, CFErrorRef* baseError) | |
74 | { | |
75 | TransformFactory* tf = FindTransformFactoryByType(type); | |
76 | if (!tf) | |
77 | { | |
78 | if (baseError != NULL) | |
79 | { | |
80 | #if 0 | |
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 | |
84 | // to run. | |
85 | dispatch_barrier_sync(gRegisteredQueue, ^(void) { | |
86 | CFMutableStringRef transformNames = CFStringCreateMutable(NULL, 0); | |
87 | CFIndex numberRegistered = CFDictionaryGetCount(gRegistered); | |
88 | CFStringRef names[numberRegistered]; | |
89 | CFDictionaryGetKeysAndValues(gRegistered, (const void**)names, NULL); | |
90 | for(int i = 0; i < numberRegistered; i++) { | |
91 | if (i != 0) { | |
92 | CFStringAppend(transformNames, CFSTR(", ")); | |
93 | } | |
94 | CFStringAppend(transformNames, names[i]); | |
95 | } | |
96 | ||
97 | *baseError = CreateSecTransformErrorRef(kSecTransformTransformIsNotRegistered, | |
98 | "The %s transform is not registered, choose from: %@", type,transformNames); | |
99 | ||
100 | }); | |
101 | #else | |
102 | *baseError = CreateSecTransformErrorRef(kSecTransformTransformIsNotRegistered, | |
103 | "The %s transform is not registered", type); | |
104 | #endif | |
105 | } | |
106 | ||
107 | return NULL; | |
108 | } | |
109 | else | |
110 | { | |
111 | return tf->Make(); | |
112 | } | |
113 | } | |
114 | ||
115 | ||
116 | ||
117 | TransformFactory::TransformFactory(CFStringRef type, bool registerGlobally, CFStringRef cftype) : mCFType(type) | |
118 | { | |
119 | if (registerGlobally) | |
120 | { | |
121 | CoreFoundationObject::RegisterObject(cftype ? cftype : type, false); | |
122 | } | |
123 | } |