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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/mac/security_wrappers.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/mac/security_wrappers.cc
===================================================================
--- chrome/browser/mac/security_wrappers.cc (revision 0)
+++ chrome/browser/mac/security_wrappers.cc (revision 0)
@@ -0,0 +1,428 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/mac/security_wrappers.h"
+
+#include "base/mac/foundation_util.h"
+#include "base/mac/mac_logging.h"
+
+#if !defined(MAC_OS_X_VERSION_10_5) || \
+ MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
+
+enum {
+ // New Security.framework code uses errSecSuccess instead of noErr, but the
+ // constant is new in 10.6.
+ errSecSuccess = 0
+};
+
+// This exists on 10.5 for linking, but but because
+// <Security/SecRequirement.h> did not ship in the SDK in that version, no
+// declaration is present. This declaration is correct on 10.5, see
+// 10.5.0 libsecurity_codesigning-32568/lib/SecRequirement.h.
+extern "C" {
+OSStatus SecRequirementCopyString(SecRequirementRef requirement,
+ SecCSFlags flags,
+ CFStringRef* text);
+} // extern "C"
+
+#endif
+
+extern "C" {
+OSStatus SecTrustedApplicationCopyRequirement(
+ SecTrustedApplicationRef application,
+ SecRequirementRef* requirement);
+} // extern "C"
+
+namespace chrome {
+namespace browser {
+namespace mac {
+
+ScopedSecKeychainSetUserInteractionAllowed::
+ ScopedSecKeychainSetUserInteractionAllowed(Boolean allowed) {
+ OSStatus status = SecKeychainGetUserInteractionAllowed(&old_allowed_);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ old_allowed_ = TRUE;
+ }
+
+ status = SecKeychainSetUserInteractionAllowed(allowed);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ }
+}
+
+ScopedSecKeychainSetUserInteractionAllowed::
+ ~ScopedSecKeychainSetUserInteractionAllowed() {
+ OSStatus status = SecKeychainSetUserInteractionAllowed(old_allowed_);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ }
+}
+
+CrSKeychainItemAndAccess::CrSKeychainItemAndAccess(SecKeychainItemRef item,
+ SecAccessRef access)
+ : item_(item),
+ access_(access) {
+ // These CFRetain calls aren't leaks. They're balanced by an implicit
+ // CFRelease at destruction because the fields are of type ScopedCFTypeRef.
+ // These fields are retained on construction (unlike the typical
+ // ScopedCFTypeRef pattern) because this class is intended for use as an STL
+ // type adapter to keep two related objects together, and thus must
+ // implement proper reference counting in the methods required for STL
+ // container use. This class and is not intended to act as a scoper for the
+ // underlying objects in user code. For that, just use ScopedCFTypeRef.
+ CFRetain(item_);
+ CFRetain(access_);
+}
+
+CrSKeychainItemAndAccess::CrSKeychainItemAndAccess(
+ const CrSKeychainItemAndAccess& that)
+ : item_(that.item_.get()),
+ access_(that.access_.get()) {
+ // See the comment above in the two-argument constructor.
+ CFRetain(item_);
+ CFRetain(access_);
+}
+
+CrSKeychainItemAndAccess::~CrSKeychainItemAndAccess() {
+}
+
+void CrSKeychainItemAndAccess::operator=(const CrSKeychainItemAndAccess& that) {
+ // See the comment above in the two-argument constructor.
+ CFRetain(that.item_);
+ item_.reset(that.item_);
+
+ CFRetain(that.access_);
+ access_.reset(that.access_);
+}
+
+CrSACLSimpleContents::CrSACLSimpleContents() {
+}
+
+CrSACLSimpleContents::~CrSACLSimpleContents() {
+}
+
+ScopedSecKeychainAttributeInfo::ScopedSecKeychainAttributeInfo(
+ SecKeychainAttributeInfo* attribute_info)
+ : attribute_info_(attribute_info) {
+}
+
+ScopedSecKeychainAttributeInfo::~ScopedSecKeychainAttributeInfo() {
+ OSStatus status = SecKeychainFreeAttributeInfo(attribute_info_);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ }
+}
+
+ScopedCrSKeychainItemAttributesAndData::ScopedCrSKeychainItemAttributesAndData(
+ CrSKeychainItemAttributesAndData* attributes_and_data)
+ : attributes_and_data_(attributes_and_data) {
+}
+
+ScopedCrSKeychainItemAttributesAndData::
+ ~ScopedCrSKeychainItemAttributesAndData() {
+ if (attributes_and_data_.get()) {
+ CrSKeychainItemFreeAttributesAndData(
+ attributes_and_data_->attribute_list, attributes_and_data_->data);
+ }
+}
+
+SecKeychainSearchRef CrSKeychainSearchCreateFromAttributes(
+ CFTypeRef keychain_or_array,
+ SecItemClass item_class,
+ const SecKeychainAttributeList* attribute_list) {
+ SecKeychainSearchRef search;
+ OSStatus status = SecKeychainSearchCreateFromAttributes(keychain_or_array,
+ item_class,
+ attribute_list,
+ &search);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return NULL;
+ }
+
+ return search;
+}
+
+SecKeychainItemRef CrSKeychainSearchCopyNext(SecKeychainSearchRef search) {
+ if (!search) {
+ return NULL;
+ }
+
+ SecKeychainItemRef item;
+ OSStatus status = SecKeychainSearchCopyNext(search, &item);
+ if (status != errSecSuccess) {
+ if (status != errSecItemNotFound) {
+ OSSTATUS_LOG(ERROR, status);
+ }
+ return NULL;
+ }
+
+ return item;
+}
+
+void CrSKeychainItemFreeAttributesAndData(
+ SecKeychainAttributeList* attribute_list,
+ void* data) {
+ OSStatus status = SecKeychainItemFreeAttributesAndData(attribute_list, data);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ }
+}
+
+bool CrSKeychainItemTestAccess(SecKeychainItemRef item) {
+ UInt32 length;
+ void* data;
+ OSStatus status = SecKeychainItemCopyAttributesAndData(item,
+ NULL,
+ NULL,
+ NULL,
+ &length,
+ &data);
+ if (status != errSecSuccess) {
+ if (status != errSecAuthFailed) {
+ OSSTATUS_LOG(ERROR, status);
+ }
+ return false;
+ }
+
+ CrSKeychainItemFreeAttributesAndData(NULL, data);
+
+ return true;
+}
+
+SecAccessRef CrSKeychainItemCopyAccess(SecKeychainItemRef item) {
+ SecAccessRef access;
+ OSStatus status = SecKeychainItemCopyAccess(item, &access);
+ if (status != errSecSuccess) {
+ if (status != errSecNoAccessForItem && status != errSecAuthFailed) {
+ OSSTATUS_LOG(ERROR, status);
+ }
+ return NULL;
+ }
+
+ return access;
+}
+
+CFArrayRef CrSAccessCopyACLList(SecAccessRef access) {
+ if (!access) {
+ return NULL;
+ }
+
+ CFArrayRef acl_list;
+ OSStatus status = SecAccessCopyACLList(access, &acl_list);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return NULL;
+ }
+
+ return acl_list;
+}
+
+CrSACLSimpleContents* CrSACLCopySimpleContents(SecACLRef acl) {
+ if (!acl) {
+ return NULL;
+ }
+
+ scoped_ptr<CrSACLSimpleContents> acl_simple_contents(
+ new CrSACLSimpleContents());
+ CFArrayRef application_list;
+ CFStringRef description;
+ OSStatus status =
+ SecACLCopySimpleContents(acl,
+ &application_list,
+ &description,
+ &acl_simple_contents->prompt_selector);
+ if (status != errSecSuccess) {
+ if (status != errSecACLNotSimple) {
+ OSSTATUS_LOG(ERROR, status);
+ }
+ return NULL;
+ }
+
+ acl_simple_contents->application_list.reset(application_list);
+ acl_simple_contents->description.reset(description);
+
+ return acl_simple_contents.release();
+}
+
+SecRequirementRef CrSTrustedApplicationCopyRequirement(
+ SecTrustedApplicationRef application) {
+ if (!application) {
+ return NULL;
+ }
+
+ SecRequirementRef requirement;
+ OSStatus status = SecTrustedApplicationCopyRequirement(application,
+ &requirement);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return NULL;
+ }
+
+ return requirement;
+}
+
+CFStringRef CrSRequirementCopyString(SecRequirementRef requirement,
+ SecCSFlags flags) {
+ if (!requirement) {
+ return NULL;
+ }
+
+ CFStringRef requirement_string;
+ OSStatus status = SecRequirementCopyString(requirement,
+ flags,
+ &requirement_string);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return NULL;
+ }
+
+ return requirement_string;
+}
+
+SecTrustedApplicationRef CrSTrustedApplicationCreateFromPath(const char* path) {
+ SecTrustedApplicationRef application;
+ OSStatus status = SecTrustedApplicationCreateFromPath(path, &application);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return NULL;
+ }
+
+ return application;
+}
+
+bool CrSACLSetSimpleContents(SecACLRef acl,
+ const CrSACLSimpleContents& acl_simple_contents) {
+ OSStatus status =
+ SecACLSetSimpleContents(acl,
+ acl_simple_contents.application_list,
+ acl_simple_contents.description,
+ &acl_simple_contents.prompt_selector);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return false;
+ }
+
+ return true;
+}
+
+SecKeychainRef CrSKeychainItemCopyKeychain(SecKeychainItemRef item) {
+ SecKeychainRef keychain;
+ OSStatus status = SecKeychainItemCopyKeychain(item, &keychain);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return NULL;
+ }
+
+ return keychain;
+}
+
+SecKeychainAttributeInfo* CrSKeychainAttributeInfoForItemID(
+ SecKeychainRef keychain,
+ UInt32 item_id) {
+ SecKeychainAttributeInfo* attribute_info;
+ OSStatus status = SecKeychainAttributeInfoForItemID(keychain,
+ item_id,
+ &attribute_info);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return NULL;
+ }
+
+ return attribute_info;
+}
+
+CrSKeychainItemAttributesAndData* CrSKeychainItemCopyAttributesAndData(
+ SecKeychainRef keychain,
+ SecKeychainItemRef item) {
+ ScopedCrSKeychainItemAttributesAndData attributes_and_data(
+ new CrSKeychainItemAttributesAndData());
+ OSStatus status =
+ SecKeychainItemCopyAttributesAndData(item,
+ NULL,
+ attributes_and_data.item_class_ptr(),
+ NULL,
+ NULL,
+ NULL);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return NULL;
+ }
+
+ // This looks really weird, but it's right. See 10.7.3
+ // libsecurity_keychain-55044 lib/SecItem.cpp
+ // _CreateAttributesDictionaryFromKeyItem and 10.7.3 SecurityTool-55002
+ // keychain_utilities.c print_keychain_item_attributes.
+ UInt32 item_id;
+ switch (attributes_and_data.item_class()) {
+ case kSecInternetPasswordItemClass:
+ item_id = CSSM_DL_DB_RECORD_INTERNET_PASSWORD;
+ break;
+ case kSecGenericPasswordItemClass:
+ item_id = CSSM_DL_DB_RECORD_GENERIC_PASSWORD;
+ break;
+ case kSecAppleSharePasswordItemClass:
+ item_id = CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD;
+ break;
+ default:
+ item_id = attributes_and_data.item_class();
+ break;
+ }
+
+ ScopedSecKeychainAttributeInfo attribute_info(
+ CrSKeychainAttributeInfoForItemID(keychain, item_id));
+ if (!attribute_info) {
+ return NULL;
+ }
+
+ status = SecKeychainItemCopyAttributesAndData(
+ item,
+ attribute_info,
+ attributes_and_data.item_class_ptr(),
+ attributes_and_data.attribute_list_ptr(),
+ attributes_and_data.length_ptr(),
+ attributes_and_data.data_ptr());
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return NULL;
+ }
+
+ return attributes_and_data.release();
+}
+
+bool CrSKeychainItemDelete(SecKeychainItemRef item) {
+ OSStatus status = SecKeychainItemDelete(item);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return false;
+ }
+
+ return true;
+}
+
+SecKeychainItemRef CrSKeychainItemCreateFromContent(
+ const CrSKeychainItemAttributesAndData& attributes_and_data,
+ SecKeychainRef keychain,
+ SecAccessRef access) {
+ SecKeychainItemRef item;
+ OSStatus status =
+ SecKeychainItemCreateFromContent(attributes_and_data.item_class,
+ attributes_and_data.attribute_list,
+ attributes_and_data.length,
+ attributes_and_data.data,
+ keychain,
+ access,
+ &item);
+ if (status != errSecSuccess) {
+ OSSTATUS_LOG(ERROR, status);
+ return NULL;
+ }
+
+ return item;
+}
+
+} // namespace mac
+} // namespace browser
+} // namespace chrome
« 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