Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: chrome/browser/mac/security_wrappers.cc

Issue 10344009: Implement Keychain reauthorization (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/mac/security_wrappers.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/mac/security_wrappers.h"
6
7 #include "base/mac/foundation_util.h"
8 #include "base/mac/mac_logging.h"
9
10 #if !defined(MAC_OS_X_VERSION_10_5) || \
11 MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
12
13 enum {
14 // New Security.framework code uses errSecSuccess instead of noErr, but the
15 // constant is new in 10.6.
16 errSecSuccess = 0
17 };
18
19 // This exists on 10.5 for linking, but but because
20 // <Security/SecRequirement.h> did not ship in the SDK in that version, no
21 // declaration is present. This declaration is correct on 10.5, see
22 // 10.5.0 libsecurity_codesigning-32568/lib/SecRequirement.h.
23 extern "C" {
24 OSStatus SecRequirementCopyString(SecRequirementRef requirement,
25 SecCSFlags flags,
26 CFStringRef* text);
27 } // extern "C"
28
29 #endif
30
31 extern "C" {
32 OSStatus SecTrustedApplicationCopyRequirement(
33 SecTrustedApplicationRef application,
34 SecRequirementRef* requirement);
35 } // extern "C"
36
37 namespace chrome {
38 namespace browser {
39 namespace mac {
40
41 ScopedSecKeychainSetUserInteractionAllowed::
42 ScopedSecKeychainSetUserInteractionAllowed(Boolean allowed) {
43 OSStatus status = SecKeychainGetUserInteractionAllowed(&old_allowed_);
44 if (status != errSecSuccess) {
45 OSSTATUS_LOG(ERROR, status);
46 old_allowed_ = TRUE;
47 }
48
49 status = SecKeychainSetUserInteractionAllowed(allowed);
50 if (status != errSecSuccess) {
51 OSSTATUS_LOG(ERROR, status);
52 }
53 }
54
55 ScopedSecKeychainSetUserInteractionAllowed::
56 ~ScopedSecKeychainSetUserInteractionAllowed() {
57 OSStatus status = SecKeychainSetUserInteractionAllowed(old_allowed_);
58 if (status != errSecSuccess) {
59 OSSTATUS_LOG(ERROR, status);
60 }
61 }
62
63 CrSKeychainItemAndAccess::CrSKeychainItemAndAccess(SecKeychainItemRef item,
64 SecAccessRef access)
65 : item_(item),
66 access_(access) {
67 // These CFRetain calls aren't leaks. They're balanced by an implicit
68 // CFRelease at destruction because the fields are of type ScopedCFTypeRef.
69 // These fields are retained on construction (unlike the typical
70 // ScopedCFTypeRef pattern) because this class is intended for use as an STL
71 // type adapter to keep two related objects together, and thus must
72 // implement proper reference counting in the methods required for STL
73 // container use. This class and is not intended to act as a scoper for the
74 // underlying objects in user code. For that, just use ScopedCFTypeRef.
75 CFRetain(item_);
76 CFRetain(access_);
77 }
78
79 CrSKeychainItemAndAccess::CrSKeychainItemAndAccess(
80 const CrSKeychainItemAndAccess& that)
81 : item_(that.item_.get()),
82 access_(that.access_.get()) {
83 // See the comment above in the two-argument constructor.
84 CFRetain(item_);
85 CFRetain(access_);
86 }
87
88 CrSKeychainItemAndAccess::~CrSKeychainItemAndAccess() {
89 }
90
91 void CrSKeychainItemAndAccess::operator=(const CrSKeychainItemAndAccess& that) {
92 // See the comment above in the two-argument constructor.
93 CFRetain(that.item_);
94 item_.reset(that.item_);
95
96 CFRetain(that.access_);
97 access_.reset(that.access_);
98 }
99
100 CrSACLSimpleContents::CrSACLSimpleContents() {
101 }
102
103 CrSACLSimpleContents::~CrSACLSimpleContents() {
104 }
105
106 ScopedSecKeychainAttributeInfo::ScopedSecKeychainAttributeInfo(
107 SecKeychainAttributeInfo* attribute_info)
108 : attribute_info_(attribute_info) {
109 }
110
111 ScopedSecKeychainAttributeInfo::~ScopedSecKeychainAttributeInfo() {
112 OSStatus status = SecKeychainFreeAttributeInfo(attribute_info_);
113 if (status != errSecSuccess) {
114 OSSTATUS_LOG(ERROR, status);
115 }
116 }
117
118 ScopedCrSKeychainItemAttributesAndData::ScopedCrSKeychainItemAttributesAndData(
119 CrSKeychainItemAttributesAndData* attributes_and_data)
120 : attributes_and_data_(attributes_and_data) {
121 }
122
123 ScopedCrSKeychainItemAttributesAndData::
124 ~ScopedCrSKeychainItemAttributesAndData() {
125 if (attributes_and_data_.get()) {
126 CrSKeychainItemFreeAttributesAndData(
127 attributes_and_data_->attribute_list, attributes_and_data_->data);
128 }
129 }
130
131 SecKeychainSearchRef CrSKeychainSearchCreateFromAttributes(
132 CFTypeRef keychain_or_array,
133 SecItemClass item_class,
134 const SecKeychainAttributeList* attribute_list) {
135 SecKeychainSearchRef search;
136 OSStatus status = SecKeychainSearchCreateFromAttributes(keychain_or_array,
137 item_class,
138 attribute_list,
139 &search);
140 if (status != errSecSuccess) {
141 OSSTATUS_LOG(ERROR, status);
142 return NULL;
143 }
144
145 return search;
146 }
147
148 SecKeychainItemRef CrSKeychainSearchCopyNext(SecKeychainSearchRef search) {
149 if (!search) {
150 return NULL;
151 }
152
153 SecKeychainItemRef item;
154 OSStatus status = SecKeychainSearchCopyNext(search, &item);
155 if (status != errSecSuccess) {
156 if (status != errSecItemNotFound) {
157 OSSTATUS_LOG(ERROR, status);
158 }
159 return NULL;
160 }
161
162 return item;
163 }
164
165 void CrSKeychainItemFreeAttributesAndData(
166 SecKeychainAttributeList* attribute_list,
167 void* data) {
168 OSStatus status = SecKeychainItemFreeAttributesAndData(attribute_list, data);
169 if (status != errSecSuccess) {
170 OSSTATUS_LOG(ERROR, status);
171 }
172 }
173
174 bool CrSKeychainItemTestAccess(SecKeychainItemRef item) {
175 UInt32 length;
176 void* data;
177 OSStatus status = SecKeychainItemCopyAttributesAndData(item,
178 NULL,
179 NULL,
180 NULL,
181 &length,
182 &data);
183 if (status != errSecSuccess) {
184 if (status != errSecAuthFailed) {
185 OSSTATUS_LOG(ERROR, status);
186 }
187 return false;
188 }
189
190 CrSKeychainItemFreeAttributesAndData(NULL, data);
191
192 return true;
193 }
194
195 SecAccessRef CrSKeychainItemCopyAccess(SecKeychainItemRef item) {
196 SecAccessRef access;
197 OSStatus status = SecKeychainItemCopyAccess(item, &access);
198 if (status != errSecSuccess) {
199 if (status != errSecNoAccessForItem && status != errSecAuthFailed) {
200 OSSTATUS_LOG(ERROR, status);
201 }
202 return NULL;
203 }
204
205 return access;
206 }
207
208 CFArrayRef CrSAccessCopyACLList(SecAccessRef access) {
209 if (!access) {
210 return NULL;
211 }
212
213 CFArrayRef acl_list;
214 OSStatus status = SecAccessCopyACLList(access, &acl_list);
215 if (status != errSecSuccess) {
216 OSSTATUS_LOG(ERROR, status);
217 return NULL;
218 }
219
220 return acl_list;
221 }
222
223 CrSACLSimpleContents* CrSACLCopySimpleContents(SecACLRef acl) {
224 if (!acl) {
225 return NULL;
226 }
227
228 scoped_ptr<CrSACLSimpleContents> acl_simple_contents(
229 new CrSACLSimpleContents());
230 CFArrayRef application_list;
231 CFStringRef description;
232 OSStatus status =
233 SecACLCopySimpleContents(acl,
234 &application_list,
235 &description,
236 &acl_simple_contents->prompt_selector);
237 if (status != errSecSuccess) {
238 if (status != errSecACLNotSimple) {
239 OSSTATUS_LOG(ERROR, status);
240 }
241 return NULL;
242 }
243
244 acl_simple_contents->application_list.reset(application_list);
245 acl_simple_contents->description.reset(description);
246
247 return acl_simple_contents.release();
248 }
249
250 SecRequirementRef CrSTrustedApplicationCopyRequirement(
251 SecTrustedApplicationRef application) {
252 if (!application) {
253 return NULL;
254 }
255
256 SecRequirementRef requirement;
257 OSStatus status = SecTrustedApplicationCopyRequirement(application,
258 &requirement);
259 if (status != errSecSuccess) {
260 OSSTATUS_LOG(ERROR, status);
261 return NULL;
262 }
263
264 return requirement;
265 }
266
267 CFStringRef CrSRequirementCopyString(SecRequirementRef requirement,
268 SecCSFlags flags) {
269 if (!requirement) {
270 return NULL;
271 }
272
273 CFStringRef requirement_string;
274 OSStatus status = SecRequirementCopyString(requirement,
275 flags,
276 &requirement_string);
277 if (status != errSecSuccess) {
278 OSSTATUS_LOG(ERROR, status);
279 return NULL;
280 }
281
282 return requirement_string;
283 }
284
285 SecTrustedApplicationRef CrSTrustedApplicationCreateFromPath(const char* path) {
286 SecTrustedApplicationRef application;
287 OSStatus status = SecTrustedApplicationCreateFromPath(path, &application);
288 if (status != errSecSuccess) {
289 OSSTATUS_LOG(ERROR, status);
290 return NULL;
291 }
292
293 return application;
294 }
295
296 bool CrSACLSetSimpleContents(SecACLRef acl,
297 const CrSACLSimpleContents& acl_simple_contents) {
298 OSStatus status =
299 SecACLSetSimpleContents(acl,
300 acl_simple_contents.application_list,
301 acl_simple_contents.description,
302 &acl_simple_contents.prompt_selector);
303 if (status != errSecSuccess) {
304 OSSTATUS_LOG(ERROR, status);
305 return false;
306 }
307
308 return true;
309 }
310
311 SecKeychainRef CrSKeychainItemCopyKeychain(SecKeychainItemRef item) {
312 SecKeychainRef keychain;
313 OSStatus status = SecKeychainItemCopyKeychain(item, &keychain);
314 if (status != errSecSuccess) {
315 OSSTATUS_LOG(ERROR, status);
316 return NULL;
317 }
318
319 return keychain;
320 }
321
322 SecKeychainAttributeInfo* CrSKeychainAttributeInfoForItemID(
323 SecKeychainRef keychain,
324 UInt32 item_id) {
325 SecKeychainAttributeInfo* attribute_info;
326 OSStatus status = SecKeychainAttributeInfoForItemID(keychain,
327 item_id,
328 &attribute_info);
329 if (status != errSecSuccess) {
330 OSSTATUS_LOG(ERROR, status);
331 return NULL;
332 }
333
334 return attribute_info;
335 }
336
337 CrSKeychainItemAttributesAndData* CrSKeychainItemCopyAttributesAndData(
338 SecKeychainRef keychain,
339 SecKeychainItemRef item) {
340 ScopedCrSKeychainItemAttributesAndData attributes_and_data(
341 new CrSKeychainItemAttributesAndData());
342 OSStatus status =
343 SecKeychainItemCopyAttributesAndData(item,
344 NULL,
345 attributes_and_data.item_class_ptr(),
346 NULL,
347 NULL,
348 NULL);
349 if (status != errSecSuccess) {
350 OSSTATUS_LOG(ERROR, status);
351 return NULL;
352 }
353
354 // This looks really weird, but it's right. See 10.7.3
355 // libsecurity_keychain-55044 lib/SecItem.cpp
356 // _CreateAttributesDictionaryFromKeyItem and 10.7.3 SecurityTool-55002
357 // keychain_utilities.c print_keychain_item_attributes.
358 UInt32 item_id;
359 switch (attributes_and_data.item_class()) {
360 case kSecInternetPasswordItemClass:
361 item_id = CSSM_DL_DB_RECORD_INTERNET_PASSWORD;
362 break;
363 case kSecGenericPasswordItemClass:
364 item_id = CSSM_DL_DB_RECORD_GENERIC_PASSWORD;
365 break;
366 case kSecAppleSharePasswordItemClass:
367 item_id = CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD;
368 break;
369 default:
370 item_id = attributes_and_data.item_class();
371 break;
372 }
373
374 ScopedSecKeychainAttributeInfo attribute_info(
375 CrSKeychainAttributeInfoForItemID(keychain, item_id));
376 if (!attribute_info) {
377 return NULL;
378 }
379
380 status = SecKeychainItemCopyAttributesAndData(
381 item,
382 attribute_info,
383 attributes_and_data.item_class_ptr(),
384 attributes_and_data.attribute_list_ptr(),
385 attributes_and_data.length_ptr(),
386 attributes_and_data.data_ptr());
387 if (status != errSecSuccess) {
388 OSSTATUS_LOG(ERROR, status);
389 return NULL;
390 }
391
392 return attributes_and_data.release();
393 }
394
395 bool CrSKeychainItemDelete(SecKeychainItemRef item) {
396 OSStatus status = SecKeychainItemDelete(item);
397 if (status != errSecSuccess) {
398 OSSTATUS_LOG(ERROR, status);
399 return false;
400 }
401
402 return true;
403 }
404
405 SecKeychainItemRef CrSKeychainItemCreateFromContent(
406 const CrSKeychainItemAttributesAndData& attributes_and_data,
407 SecKeychainRef keychain,
408 SecAccessRef access) {
409 SecKeychainItemRef item;
410 OSStatus status =
411 SecKeychainItemCreateFromContent(attributes_and_data.item_class,
412 attributes_and_data.attribute_list,
413 attributes_and_data.length,
414 attributes_and_data.data,
415 keychain,
416 access,
417 &item);
418 if (status != errSecSuccess) {
419 OSSTATUS_LOG(ERROR, status);
420 return NULL;
421 }
422
423 return item;
424 }
425
426 } // namespace mac
427 } // namespace browser
428 } // namespace chrome
OLDNEW
« no previous file with comments | « chrome/browser/mac/security_wrappers.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698