15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/mac/security_wrappers.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/foundation_util.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/mac_logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OSStatus SecTrustedApplicationCopyRequirement(
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SecTrustedApplicationRef application,
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SecRequirementRef* requirement);
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // extern "C"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedSecKeychainSetUserInteractionAllowed::
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedSecKeychainSetUserInteractionAllowed(Boolean allowed) {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecKeychainGetUserInteractionAllowed(&old_allowed_);
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    old_allowed_ = TRUE;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  status = SecKeychainSetUserInteractionAllowed(allowed);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedSecKeychainSetUserInteractionAllowed::
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~ScopedSecKeychainSetUserInteractionAllowed() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecKeychainSetUserInteractionAllowed(old_allowed_);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrSKeychainItemAndAccess::CrSKeychainItemAndAccess(SecKeychainItemRef item,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   SecAccessRef access)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : item_(item),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      access_(access) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These CFRetain calls aren't leaks. They're balanced by an implicit
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CFRelease at destruction because the fields are of type ScopedCFTypeRef.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These fields are retained on construction (unlike the typical
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ScopedCFTypeRef pattern) because this class is intended for use as an STL
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // type adapter to keep two related objects together, and thus must
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // implement proper reference counting in the methods required for STL
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // container use. This class and is not intended to act as a scoper for the
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // underlying objects in user code. For that, just use ScopedCFTypeRef.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFRetain(item_);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFRetain(access_);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrSKeychainItemAndAccess::CrSKeychainItemAndAccess(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CrSKeychainItemAndAccess& that)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : item_(that.item_.get()),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      access_(that.access_.get()) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See the comment above in the two-argument constructor.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFRetain(item_);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFRetain(access_);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrSKeychainItemAndAccess::~CrSKeychainItemAndAccess() {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrSKeychainItemAndAccess::operator=(const CrSKeychainItemAndAccess& that) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See the comment above in the two-argument constructor.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFRetain(that.item_);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  item_.reset(that.item_);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFRetain(that.access_);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  access_.reset(that.access_);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrSACLSimpleContents::CrSACLSimpleContents() {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrSACLSimpleContents::~CrSACLSimpleContents() {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedSecKeychainAttributeInfo::ScopedSecKeychainAttributeInfo(
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SecKeychainAttributeInfo* attribute_info)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : attribute_info_(attribute_info) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedSecKeychainAttributeInfo::~ScopedSecKeychainAttributeInfo() {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecKeychainFreeAttributeInfo(attribute_info_);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedCrSKeychainItemAttributesAndData::ScopedCrSKeychainItemAttributesAndData(
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CrSKeychainItemAttributesAndData* attributes_and_data)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : attributes_and_data_(attributes_and_data) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedCrSKeychainItemAttributesAndData::
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~ScopedCrSKeychainItemAttributesAndData() {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (attributes_and_data_.get()) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CrSKeychainItemFreeAttributesAndData(
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        attributes_and_data_->attribute_list, attributes_and_data_->data);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SecKeychainSearchRef CrSKeychainSearchCreateFromAttributes(
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CFTypeRef keychain_or_array,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SecItemClass item_class,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SecKeychainAttributeList* attribute_list) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SecKeychainSearchRef search;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecKeychainSearchCreateFromAttributes(keychain_or_array,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          item_class,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          attribute_list,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          &search);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return search;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SecKeychainItemRef CrSKeychainSearchCopyNext(SecKeychainSearchRef search) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!search) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SecKeychainItemRef item;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecKeychainSearchCopyNext(search, &item);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != errSecItemNotFound) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OSSTATUS_LOG(ERROR, status);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return item;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrSKeychainItemFreeAttributesAndData(
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SecKeychainAttributeList* attribute_list,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* data) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecKeychainItemFreeAttributesAndData(attribute_list, data);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrSKeychainItemTestAccess(SecKeychainItemRef item) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32 length;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* data;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecKeychainItemCopyAttributesAndData(item,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         NULL,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         NULL,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         NULL,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         &length,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         &data);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != errSecAuthFailed) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OSSTATUS_LOG(ERROR, status);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CrSKeychainItemFreeAttributesAndData(NULL, data);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SecAccessRef CrSKeychainItemCopyAccess(SecKeychainItemRef item) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SecAccessRef access;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecKeychainItemCopyAccess(item, &access);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != errSecNoAccessForItem && status != errSecAuthFailed) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OSSTATUS_LOG(ERROR, status);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return access;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFArrayRef CrSAccessCopyACLList(SecAccessRef access) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!access) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFArrayRef acl_list;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecAccessCopyACLList(access, &acl_list);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return acl_list;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrSACLSimpleContents* CrSACLCopySimpleContents(SecACLRef acl) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!acl) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<CrSACLSimpleContents> acl_simple_contents(
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CrSACLSimpleContents());
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFArrayRef application_list;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFStringRef description;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status =
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SecACLCopySimpleContents(acl,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &application_list,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &description,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &acl_simple_contents->prompt_selector);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != errSecACLNotSimple) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OSSTATUS_LOG(ERROR, status);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  acl_simple_contents->application_list.reset(application_list);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  acl_simple_contents->description.reset(description);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return acl_simple_contents.release();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SecRequirementRef CrSTrustedApplicationCopyRequirement(
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SecTrustedApplicationRef application) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!application) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SecRequirementRef requirement;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecTrustedApplicationCopyRequirement(application,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         &requirement);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return requirement;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFStringRef CrSRequirementCopyString(SecRequirementRef requirement,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     SecCSFlags flags) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!requirement) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CFStringRef requirement_string;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecRequirementCopyString(requirement,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             flags,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             &requirement_string);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return requirement_string;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SecTrustedApplicationRef CrSTrustedApplicationCreateFromPath(const char* path) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SecTrustedApplicationRef application;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecTrustedApplicationCreateFromPath(path, &application);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return application;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrSACLSetSimpleContents(SecACLRef acl,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const CrSACLSimpleContents& acl_simple_contents) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status =
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SecACLSetSimpleContents(acl,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              acl_simple_contents.application_list,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              acl_simple_contents.description,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              &acl_simple_contents.prompt_selector);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SecKeychainRef CrSKeychainItemCopyKeychain(SecKeychainItemRef item) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SecKeychainRef keychain;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecKeychainItemCopyKeychain(item, &keychain);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return keychain;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SecKeychainAttributeInfo* CrSKeychainAttributeInfoForItemID(
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SecKeychainRef keychain,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UInt32 item_id) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SecKeychainAttributeInfo* attribute_info;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecKeychainAttributeInfoForItemID(keychain,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      item_id,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      &attribute_info);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return attribute_info;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrSKeychainItemAttributesAndData* CrSKeychainItemCopyAttributesAndData(
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SecKeychainRef keychain,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SecKeychainItemRef item) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedCrSKeychainItemAttributesAndData attributes_and_data(
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CrSKeychainItemAttributesAndData());
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status =
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SecKeychainItemCopyAttributesAndData(item,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           NULL,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           attributes_and_data.item_class_ptr(),
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           NULL,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           NULL,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           NULL);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This looks really weird, but it's right. See 10.7.3
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // libsecurity_keychain-55044 lib/SecItem.cpp
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // _CreateAttributesDictionaryFromKeyItem and 10.7.3 SecurityTool-55002
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // keychain_utilities.c print_keychain_item_attributes.
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32 item_id;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (attributes_and_data.item_class()) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSecInternetPasswordItemClass:
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      item_id = CSSM_DL_DB_RECORD_INTERNET_PASSWORD;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSecGenericPasswordItemClass:
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      item_id = CSSM_DL_DB_RECORD_GENERIC_PASSWORD;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // kSecInternetPasswordItemClass is marked as deprecated in the 10.9 sdk,
344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // but the files in libsecurity_keychain from 10.7 referenced above still
345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // use it. Also see rdar://14281375 /
346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // http://openradar.appspot.com/radar?id=3143412 .
347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#pragma clang diagnostic push
348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#pragma clang diagnostic ignored "-Wdeprecated-declarations"
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSecAppleSharePasswordItemClass:
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#pragma clang diagnostic pop
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      item_id = CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      item_id = attributes_and_data.item_class();
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedSecKeychainAttributeInfo attribute_info(
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CrSKeychainAttributeInfoForItemID(keychain, item_id));
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!attribute_info) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  status = SecKeychainItemCopyAttributesAndData(
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      item,
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      attribute_info,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      attributes_and_data.item_class_ptr(),
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      attributes_and_data.attribute_list_ptr(),
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      attributes_and_data.length_ptr(),
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      attributes_and_data.data_ptr());
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return attributes_and_data.release();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrSKeychainItemDelete(SecKeychainItemRef item) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = SecKeychainItemDelete(item);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SecKeychainItemRef CrSKeychainItemCreateFromContent(
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CrSKeychainItemAttributesAndData& attributes_and_data,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SecKeychainRef keychain,
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SecAccessRef access) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SecKeychainItemRef item;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status =
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SecKeychainItemCreateFromContent(attributes_and_data.item_class,
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       attributes_and_data.attribute_list,
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       attributes_and_data.length,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       attributes_and_data.data,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       keychain,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       access,
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       &item);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != errSecSuccess) {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OSSTATUS_LOG(ERROR, status);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return item;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome
411