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#ifndef CHROME_BROWSER_MAC_SECURITY_WRAPPERS_H_
6#define CHROME_BROWSER_MAC_SECURITY_WRAPPERS_H_
7
8#include <Security/Security.h>
9#include <Security/SecRequirement.h>
10
11#include "base/basictypes.h"
12#include "base/mac/scoped_cftyperef.h"
13#include "base/memory/scoped_ptr.h"
14
15namespace chrome {
16
17// Wraps SecKeychainSetUserInteractionAllowed, restoring the previous setting
18// on destruction.
19class ScopedSecKeychainSetUserInteractionAllowed {
20 public:
21  explicit ScopedSecKeychainSetUserInteractionAllowed(Boolean allowed);
22  ~ScopedSecKeychainSetUserInteractionAllowed();
23
24 private:
25  Boolean old_allowed_;
26
27  DISALLOW_COPY_AND_ASSIGN(ScopedSecKeychainSetUserInteractionAllowed);
28};
29
30// Holds a paired SecKeychainItemRef and SecAccessRef, maintaining the
31// association between the two, and managing their ownership by retaining
32// the SecKeychainItemRef and SecAccessRef elements placed into a
33// CrSKeychainItemAndAccess object. Suitable for use
34// in standard C++ containers.
35class CrSKeychainItemAndAccess {
36 public:
37  CrSKeychainItemAndAccess(SecKeychainItemRef item, SecAccessRef access);
38  CrSKeychainItemAndAccess(const CrSKeychainItemAndAccess& that);
39
40  ~CrSKeychainItemAndAccess();
41
42  void operator=(const CrSKeychainItemAndAccess& that);
43
44  SecKeychainItemRef item() const { return item_; }
45  SecAccessRef access() const { return access_; }
46
47 private:
48  base::ScopedCFTypeRef<SecKeychainItemRef> item_;
49  base::ScopedCFTypeRef<SecAccessRef> access_;
50};
51
52// Holds the return value from CrSACLCopySimpleContents and an argument to
53// CrSACLSetSimpleContents, managing ownership. Used in those wrappers to keep
54// logically grouped data together.
55struct CrSACLSimpleContents {
56  CrSACLSimpleContents();
57  ~CrSACLSimpleContents();
58
59  base::ScopedCFTypeRef<CFArrayRef> application_list;
60  base::ScopedCFTypeRef<CFStringRef> description;
61  CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR prompt_selector;
62};
63
64// Holds a SecKeychainAttributeInfo*, calling SecKeychainFreeAttributeInfo on
65// destruction.
66class ScopedSecKeychainAttributeInfo {
67 public:
68  explicit ScopedSecKeychainAttributeInfo(
69      SecKeychainAttributeInfo* attribute_info);
70  ~ScopedSecKeychainAttributeInfo();
71
72  operator SecKeychainAttributeInfo*() const {
73    return attribute_info_;
74  }
75
76 private:
77  SecKeychainAttributeInfo* attribute_info_;
78};
79
80// Holds the return value from CrSKeychainItemCopyAttributesAndData and an
81// argument to CrSKeychainItemCreateFromContent. Used in those wrappers to
82// keep logically grouped data together.
83struct CrSKeychainItemAttributesAndData {
84  SecItemClass item_class;
85  SecKeychainAttributeList* attribute_list;
86  UInt32 length;
87  void* data;
88};
89
90// Holds a CrSKeychainItemAttributesAndData*, calling
91// CrSKeychainItemFreeAttributesAndData and freeing the owned
92// CrSKeychainItemAttributesAndData* on destruction.
93class ScopedCrSKeychainItemAttributesAndData {
94 public:
95  ScopedCrSKeychainItemAttributesAndData(
96      CrSKeychainItemAttributesAndData* attributes_and_data);
97  ~ScopedCrSKeychainItemAttributesAndData();
98
99  CrSKeychainItemAttributesAndData* get() const {
100    return attributes_and_data_.get();
101  }
102
103  CrSKeychainItemAttributesAndData* release() {
104    return attributes_and_data_.release();
105  }
106
107  SecItemClass item_class() const {
108    return attributes_and_data_->item_class;
109  }
110
111  SecItemClass* item_class_ptr() const {
112    return &attributes_and_data_->item_class;
113  }
114
115  SecKeychainAttributeList* attribute_list() const {
116    return attributes_and_data_->attribute_list;
117  }
118
119  SecKeychainAttributeList** attribute_list_ptr() const {
120    return &attributes_and_data_->attribute_list;
121  }
122
123  UInt32 length() const {
124    return attributes_and_data_->length;
125  }
126
127  UInt32* length_ptr() const {
128    return &attributes_and_data_->length;
129  }
130
131  void* data() const {
132    return attributes_and_data_->data;
133  }
134
135  void** data_ptr() const {
136    return &attributes_and_data_->data;
137  }
138
139 private:
140  scoped_ptr<CrSKeychainItemAttributesAndData> attributes_and_data_;
141};
142
143// Wraps SecKeychainSearchCreateFromAttributes, returning NULL on error and a
144// SecKeychainSearchRef owned by the caller on success.
145SecKeychainSearchRef CrSKeychainSearchCreateFromAttributes(
146    CFTypeRef keychain_or_array,
147    SecItemClass item_class,
148    const SecKeychainAttributeList* attribute_list);
149
150// Wraps SecKeychainSearchCopyNext, tolerating a NULL argument (resulting in
151// a NULL return value but nothing logged), returning NULL on error and a
152// SecKeychainItemRef owned by the caller on success.
153SecKeychainItemRef CrSKeychainSearchCopyNext(SecKeychainSearchRef search);
154
155// Wraps SecKeychainItemFreeAttributesAndData.
156void CrSKeychainItemFreeAttributesAndData(
157    SecKeychainAttributeList* attribute_list,
158    void* data);
159
160// Tests access to |item| by calling SecKeychainItemCopyAttributesAndData,
161// taking care to properly free any returned data. Returns true if access to
162// |item| is authorized. errSecAuthFailed is considered an "expected" error
163// for which nothing will be logged, although false will be returned.
164bool CrSKeychainItemTestAccess(SecKeychainItemRef item);
165
166// Wraps SecKeychainItemCopyAccess, returning NULL on error and a SecAccessRef
167// owned by the caller on success. errSecNoAccessForItem and errSecAuthFailed
168// are considered "expected" errors for which nothing will be logged, although
169// NULL will be returned.
170SecAccessRef CrSKeychainItemCopyAccess(SecKeychainItemRef item);
171
172// Wraps SecAccessCopyACLList, returning NULL on error and a CFArrayRef owned
173// by the caller on success.
174CFArrayRef CrSAccessCopyACLList(SecAccessRef access);
175
176// Wraps SecACLCopySimpleContents, returning NULL on error and a
177// CrSACLSimpleContents* owned by the caller on success. errSecACLNotSimple is
178// considered an "expected" error for which nothing will be logged, although
179// NULL will be returned.
180CrSACLSimpleContents* CrSACLCopySimpleContents(SecACLRef acl);
181
182// Wraps SecTrustedApplicationCopyRequirement, tolerating a NULL argument
183// (resulting in a NULL return value but nothing logged) and returning NULL on
184// error or a SecRequirementRef owned by the caller on success.
185SecRequirementRef CrSTrustedApplicationCopyRequirement(
186    SecTrustedApplicationRef application);
187
188// Wraps SecRequirementCopyString, tolerating a NULL argument (resulting in
189// a NULL return value but nothing logged) and returning NULL on error or a
190// CFStringRef owned by the caller on success.
191CFStringRef CrSRequirementCopyString(SecRequirementRef requirement,
192                                     SecCSFlags flags);
193
194// Wraps SecTrustedApplicationCreateFromPath, returning NULL on error or a
195// SecTrustedApplicationRef owned by the caller on success.
196SecTrustedApplicationRef CrSTrustedApplicationCreateFromPath(const char* path);
197
198// Wraps SecACLSetSimpleContents, adapting it to the CrSACLSimpleContents
199// argument, returning false on error or true on success.
200bool CrSACLSetSimpleContents(SecACLRef acl,
201                             const CrSACLSimpleContents& acl_simple_contents);
202
203// Wraps SecKeychainItemCopyKeychain, returning NULL on error or a
204// SecKeychainRef owned by the caller on success.
205SecKeychainRef CrSKeychainItemCopyKeychain(SecKeychainItemRef item);
206
207// Wraps SecKeychainAttributeInfoForItemID, returning NULL on error or a
208// SecKeychainAttributeInfo* owned by the caller on success.
209SecKeychainAttributeInfo* CrSKeychainAttributeInfoForItemID(
210    SecKeychainRef keychain,
211    UInt32 item_id);
212
213// Wraps SecKeychainItemCopyAttributesAndData, returning NULL on error or a
214// CrSKeychainItemAttributesAndData* owned by the caller on success.
215CrSKeychainItemAttributesAndData* CrSKeychainItemCopyAttributesAndData(
216    SecKeychainRef keychain,
217    SecKeychainItemRef item);
218
219// Wraps SecKeychainItemDelete, returning false on error or true on success.
220bool CrSKeychainItemDelete(SecKeychainItemRef item);
221
222// Wraps SecKeychainItemCreateFromContent, adapting it to the
223// CrSKeychainItemAttributesAndData argument, returning NULL on error or a
224// SecKeychainItemRef owned by the caller on success.
225SecKeychainItemRef CrSKeychainItemCreateFromContent(
226    const CrSKeychainItemAttributesAndData& attributes_and_data,
227    SecKeychainRef keychain,
228    SecAccessRef access);
229
230}  // namespace chrome
231
232#endif  // CHROME_BROWSER_MAC_SECURITY_WRAPPERS_H_
233