]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_client/aclclient.cpp
Security-179.tar.gz
[apple/security.git] / cdsa / cdsa_client / aclclient.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // keyclient
21 //
22 #include <Security/aclclient.h>
23 #include <Security/keychainacl.h>
24 #include <Security/cssmwalkers.h>
25 #include <Security/cssmdata.h>
26 #include <Security/cssmclient.h>
27
28
29 namespace Security {
30 namespace CssmClient {
31
32
33 static inline void check(CSSM_RETURN rc)
34 {
35 ObjectImpl::check(rc);
36 }
37
38
39 //
40 // AclBearer methods (trivial)
41 //
42 AclBearer::~AclBearer()
43 { }
44
45
46 //
47 // Variant forms of AclBearer implemented in terms of its canonical virtual methods
48 //
49 void AclBearer::addAcl(const AclEntryInput &input, const CSSM_ACCESS_CREDENTIALS *cred)
50 {
51 changeAcl(AclEdit(input), cred);
52 }
53
54 void AclBearer::changeAcl(CSSM_ACL_HANDLE handle, const AclEntryInput &input,
55 const CSSM_ACCESS_CREDENTIALS *cred)
56 {
57 changeAcl(AclEdit(handle, input), cred);
58 }
59
60 void AclBearer::deleteAcl(CSSM_ACL_HANDLE handle, const CSSM_ACCESS_CREDENTIALS *cred)
61 {
62 changeAcl(AclEdit(handle), cred);
63 }
64
65 void AclBearer::deleteAcl(const char *tag, const CSSM_ACCESS_CREDENTIALS *cred)
66 {
67 AutoAclEntryInfoList entries;
68 getAcl(entries, tag);
69 for (uint32 n = 0; n < entries.count(); n++)
70 deleteAcl(entries[n].handle(), cred);
71 }
72
73
74 //
75 // KeyAclBearer implementation
76 //
77 void KeyAclBearer::getAcl(AutoAclEntryInfoList &aclInfos, const char *selectionTag) const
78 {
79 aclInfos.allocator(allocator);
80 check(CSSM_GetKeyAcl(csp, &key, reinterpret_cast<const CSSM_STRING *>(selectionTag), aclInfos, aclInfos));
81 }
82
83 void KeyAclBearer::changeAcl(const CSSM_ACL_EDIT &aclEdit, const CSSM_ACCESS_CREDENTIALS *cred)
84 {
85 check(CSSM_ChangeKeyAcl(csp, AccessCredentials::needed(cred), &aclEdit, &key));
86 }
87
88 void KeyAclBearer::getOwner(AutoAclOwnerPrototype &owner) const
89 {
90 owner.allocator(allocator);
91 check(CSSM_GetKeyOwner(csp, &key, owner));
92 }
93
94 void KeyAclBearer::changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner,
95 const CSSM_ACCESS_CREDENTIALS *cred)
96 {
97 check(CSSM_ChangeKeyOwner(csp, AccessCredentials::needed(cred), &key, &newOwner));
98 }
99
100
101 //
102 // A single global structure containing pseudo-static data
103 //
104 struct Statics {
105 Statics();
106 CssmAllocator &alloc;
107
108 AutoCredentials nullCred;
109 AutoCredentials promptCred;
110 AutoCredentials unlockCred;
111 };
112
113 namespace {
114 ModuleNexus<Statics> statics;
115 }
116
117
118 //
119 // Make pseudo-statics.
120 // Note: This is an eternal object. It is not currently destroyed
121 // if the containing code is unloaded. But then, the containing
122 // code is Security.framework, which never unloads anyway.
123 //
124 Statics::Statics()
125 : alloc(CssmAllocator::standard()),
126 nullCred(alloc, 1),
127 promptCred(alloc, 2),
128 unlockCred(alloc, 1)
129 {
130 // nullCred: nothing at all
131 // contains:
132 // an empty THRESHOLD sample to match threshold subjects with "free" subjects
133 nullCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_THRESHOLD);
134
135 // promptCred: a credential permitting user prompt confirmations
136 // contains:
137 // a KEYCHAIN_PROMPT sample, both by itself and in a THRESHOLD
138 promptCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT);
139 promptCred.sample(1) = TypedList(alloc, CSSM_SAMPLE_TYPE_THRESHOLD,
140 new(alloc) ListElement(TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT)));
141
142 // unlockCred: ???
143 unlockCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
144 new(alloc) ListElement(CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT));
145 }
146
147
148 //
149 // Make and break AclFactories
150 //
151 AclFactory::AclFactory()
152 { }
153
154 AclFactory::~AclFactory()
155 { }
156
157
158 //
159 // Return basic pseudo-static values
160 //
161 const AccessCredentials *AclFactory::nullCred() const
162 { return &statics().nullCred; }
163
164 const AccessCredentials *AclFactory::promptCred() const
165 { return &statics().promptCred; }
166
167 const AccessCredentials *AclFactory::unlockCred() const
168 { return &statics().unlockCred; }
169
170
171 //
172 // Manage the (pseudo) credentials used to explicitly provide a passphrase to a keychain.
173 // Use the eternal unlockCred() for normal (protected prompt) unlocking.
174 //
175 AclFactory::KeychainCredentials::~KeychainCredentials ()
176 {
177 DataWalkers::chunkFree (mCredentials, allocator);
178 }
179
180 AclFactory::PassphraseUnlockCredentials::PassphraseUnlockCredentials (const CssmData& password,
181 CssmAllocator& allocator) : KeychainCredentials(allocator)
182 {
183 mCredentials->sample(0) = TypedList(allocator, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
184 new (allocator) ListElement (CSSM_SAMPLE_TYPE_PASSWORD),
185 new (allocator) ListElement (CssmAutoData(allocator, password).release()));
186 }
187
188
189 //
190 // Manage the (pseudo) credentials used to explicitly change a keychain's passphrase
191 //
192 AclFactory::PasswordChangeCredentials::PasswordChangeCredentials (const CssmData& password,
193 CssmAllocator& allocator) : KeychainCredentials(allocator)
194 {
195 mCredentials->sample(0) = TypedList(allocator, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK,
196 new (allocator) ListElement (CSSM_SAMPLE_TYPE_PASSWORD),
197 new (allocator) ListElement (CssmAutoData(allocator, password).release()));
198 }
199
200
201 //
202 // Create an ANY style AclEntryInput.
203 // This can be used to explicitly request wide-open authorization on a new CSSM object.
204 //
205 AclFactory::AnyResourceContext::AnyResourceContext(const CSSM_ACCESS_CREDENTIALS *cred)
206 : mAny(CSSM_ACL_SUBJECT_TYPE_ANY), mTag(CSSM_ACL_AUTHORIZATION_ANY)
207 {
208 // set up an ANY/EVERYTHING AclEntryInput
209 input().proto().subject() += &mAny;
210 AuthorizationGroup &authGroup = input().proto().authorization();
211 authGroup.NumberOfAuthTags = 1;
212 authGroup.AuthTags = &mTag;
213
214 // install the cred (not copied)
215 credentials(cred);
216 }
217
218
219 } // end namespace CssmClient
220 } // end namespace Security