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

Side by Side Diff: crypto/apple_keychain_ios.mm

Issue 10875029: Rename MacKeychain to AppleKeychain (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix compile error. Created 8 years, 3 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
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 "crypto/apple_keychain.h"
6
7 #import <Foundation/Foundation.h>
8
9 #include "base/mac/foundation_util.h"
10 #include "base/mac/scoped_cftyperef.h"
11 #include "base/memory/scoped_nsobject.h"
12
13 namespace {
14
15 enum KeychainAction {
16 kKeychainActionCreate,
17 kKeychainActionUpdate
18 };
19
20 // Creates a dictionary that can be used to query the keystore.
21 // Ownership follows the Create rule.
22 CFDictionaryRef CreateGenericPasswordQuery(UInt32 serviceNameLength,
23 const char* serviceName,
24 UInt32 accountNameLength,
25 const char* accountName) {
26 CFMutableDictionaryRef query =
27 CFDictionaryCreateMutable(NULL,
28 5,
29 &kCFTypeDictionaryKeyCallBacks,
30 &kCFTypeDictionaryValueCallBacks);
31 // Type of element is generic password.
32 CFDictionarySetValue(query, kSecClass, kSecClassGenericPassword);
33
34 // Set the service name.
35 scoped_nsobject<NSString> service_name_ns(
36 [[NSString alloc] initWithBytes:serviceName
37 length:serviceNameLength
38 encoding:NSUTF8StringEncoding]);
Avi (use Gerrit) 2012/08/29 17:56:21 align on colons
msarda 2012/08/30 09:43:02 Done.
39 CFDictionarySetValue(query, kSecAttrService, service_name_ns);
Avi (use Gerrit) 2012/08/29 17:56:21 When passing in an NSObject as a CFRef, a NSToCFCa
msarda 2012/08/30 09:43:02 Done.
40
41 // Set the account name.
42 scoped_nsobject<NSString> account_name_ns(
43 [[NSString alloc] initWithBytes:accountName
44 length:accountNameLength
45 encoding:NSUTF8StringEncoding]);
Avi (use Gerrit) 2012/08/29 17:56:21 align on colons
msarda 2012/08/30 09:43:02 Done.
46 CFDictionarySetValue(query, kSecAttrAccount, account_name_ns);
Avi (use Gerrit) 2012/08/29 17:56:21 NSToCFCast
msarda 2012/08/30 09:43:02 Done.
47
48 // Use the proper search constants, return only the data of the first match.
49 CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);
50 CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
51 return query;
52 }
53
54 // Creates a dictionary conatining the data to save into the keychain.
55 // Ownership follows the Create rule.
56 CFDictionaryRef CreateKeychainData(UInt32 serviceNameLength,
57 const char* serviceName,
58 UInt32 accountNameLength,
59 const char* accountName,
60 UInt32 passwordLength,
61 const void* passwordData,
62 KeychainAction action) {
63 CFMutableDictionaryRef keychain_data =
64 CFDictionaryCreateMutable(NULL,
65 0,
66 &kCFTypeDictionaryKeyCallBacks,
67 &kCFTypeDictionaryValueCallBacks);
68
69 // Set the password.
70 NSData* password = [NSData dataWithBytes:passwordData length:passwordLength];
71 CFDictionarySetValue(keychain_data, kSecValueData, password);
Avi (use Gerrit) 2012/08/29 17:56:21 NSToCFCast
msarda 2012/08/30 09:43:02 Done.
72
73 // If this is not a creation, no structural information is needed.
74 if (action != kKeychainActionCreate)
75 return keychain_data;
76
77 // Set the type of the data.
78 CFDictionarySetValue(keychain_data, kSecClass, kSecClassGenericPassword);
79
80 // Only allow access when the device has been unlocked.
81 CFDictionarySetValue(keychain_data,
82 kSecAttrAccessible,
83 kSecAttrAccessibleWhenUnlocked);
84
85 // Set the service name.
86 scoped_nsobject<NSString> service_name_ns(
87 [[NSString alloc] initWithBytes:serviceName
88 length:serviceNameLength
89 encoding:NSUTF8StringEncoding]);
Avi (use Gerrit) 2012/08/29 17:56:21 align on colons
msarda 2012/08/30 09:43:02 Done.
90 CFDictionarySetValue(keychain_data, kSecAttrService, service_name_ns);
Avi (use Gerrit) 2012/08/29 17:56:21 NSToCFCast
msarda 2012/08/30 09:43:02 Done.
91
92 // Set the account name.
93 scoped_nsobject<NSString> account_name_ns(
94 [[NSString alloc] initWithBytes:accountName
95 length:accountNameLength
96 encoding:NSUTF8StringEncoding]);
97 CFDictionarySetValue(keychain_data, kSecAttrAccount, account_name_ns);
Avi (use Gerrit) 2012/08/29 17:56:21 NSToCFCast
msarda 2012/08/30 09:43:02 Done.
98
99 return keychain_data;
100 }
101
102 } // namespace
103
104 namespace crypto {
105
106 AppleKeychain::AppleKeychain() {}
107
108 AppleKeychain::~AppleKeychain() {}
109
110 OSStatus AppleKeychain::ItemFreeContent(SecKeychainAttributeList* attrList,
111 void* data) const {
112 free(data);
113 return noErr;
114 }
115
116 OSStatus AppleKeychain::AddGenericPassword(SecKeychainRef keychain,
117 UInt32 serviceNameLength,
118 const char* serviceName,
119 UInt32 accountNameLength,
120 const char* accountName,
121 UInt32 passwordLength,
122 const void* passwordData,
123 SecKeychainItemRef* itemRef) const {
124 base::mac::ScopedCFTypeRef<CFDictionaryRef> query(
125 CreateGenericPasswordQuery(serviceNameLength,
126 serviceName,
127 accountNameLength,
128 accountName));
129 // Check that there is not already a password.
130 OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, NULL);
Avi (use Gerrit) 2012/08/29 17:56:21 Rather than relying on a cast, just do query.get()
msarda 2012/08/30 09:43:02 Done.
131 if (status == errSecItemNotFound) {
132 // A new entry must be created.
133 base::mac::ScopedCFTypeRef<CFDictionaryRef> keychain_data(
134 CreateKeychainData(serviceNameLength,
135 serviceName,
136 accountNameLength,
137 accountName,
138 passwordLength,
139 passwordData,
140 kKeychainActionCreate));
141 status = SecItemAdd(keychain_data, NULL);
142 } else if (status == noErr) {
143 // The entry must be updated.
144 base::mac::ScopedCFTypeRef<CFDictionaryRef> keychain_data(
145 CreateKeychainData(serviceNameLength,
146 serviceName,
147 accountNameLength,
148 accountName,
149 passwordLength,
150 passwordData,
151 kKeychainActionUpdate));
152 status = SecItemUpdate(query, keychain_data);
153 }
154
155 return status;
156 }
157
158 OSStatus AppleKeychain::FindGenericPassword(CFTypeRef keychainOrArray,
159 UInt32 serviceNameLength,
160 const char* serviceName,
161 UInt32 accountNameLength,
162 const char* accountName,
163 UInt32* passwordLength,
164 void** passwordData,
165 SecKeychainItemRef* itemRef) const {
166 DCHECK((passwordData && passwordLength) ||
167 (!passwordData && !passwordLength));
168 base::mac::ScopedCFTypeRef<CFDictionaryRef> query(
169 CreateGenericPasswordQuery(serviceNameLength,
170 serviceName,
171 accountNameLength,
172 accountName));
173
174 CFTypeRef result = NULL;
175 OSStatus status = SecItemCopyMatching(query, &result);
176 if (status != noErr) {
177 if (passwordData) {
178 *passwordData = NULL;
179 *passwordLength = 0;
180 }
181 return status;
182 }
183
184 if (passwordData) {
185 NSData* data = base::mac::CFToNSCast(base::mac::CFCast<CFDataRef>(result));
Avi (use Gerrit) 2012/08/29 17:56:21 Doing this cast is a bit silly. Just use CFDataGet
186 NSUInteger length = [data length];
187 *passwordData = malloc(length);
188 [data getBytes:*passwordData length:length];
189 *passwordLength = length;
190 }
191 CFRelease(result);
Avi (use Gerrit) 2012/08/29 17:56:21 Can you capture the value into a ScopedCFRef so yo
192 return status;
193 }
194
195 } // namespace crypto
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698