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

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: Address Avi's code review: add NStoCFCast and other nits. 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
« no previous file with comments | « crypto/apple_keychain.h ('k') | crypto/apple_keychain_mac.mm » ('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 "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]);
39 CFDictionarySetValue(query, kSecAttrService,
40 base::mac::NSToCFCast(service_name_ns));
41
42 // Set the account name.
43 scoped_nsobject<NSString> account_name_ns(
44 [[NSString alloc] initWithBytes:accountName
45 length:accountNameLength
46 encoding:NSUTF8StringEncoding]);
47 CFDictionarySetValue(query, kSecAttrAccount,
48 base::mac::NSToCFCast(account_name_ns));
49
50 // Use the proper search constants, return only the data of the first match.
51 CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);
52 CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
53 return query;
54 }
55
56 // Creates a dictionary conatining the data to save into the keychain.
57 // Ownership follows the Create rule.
58 CFDictionaryRef CreateKeychainData(UInt32 serviceNameLength,
59 const char* serviceName,
60 UInt32 accountNameLength,
61 const char* accountName,
62 UInt32 passwordLength,
63 const void* passwordData,
64 KeychainAction action) {
65 CFMutableDictionaryRef keychain_data =
66 CFDictionaryCreateMutable(NULL,
67 0,
68 &kCFTypeDictionaryKeyCallBacks,
69 &kCFTypeDictionaryValueCallBacks);
70
71 // Set the password.
72 NSData* password = [NSData dataWithBytes:passwordData length:passwordLength];
73 CFDictionarySetValue(keychain_data, kSecValueData,
74 base::mac::NSToCFCast(password));
75
76 // If this is not a creation, no structural information is needed.
77 if (action != kKeychainActionCreate)
78 return keychain_data;
79
80 // Set the type of the data.
81 CFDictionarySetValue(keychain_data, kSecClass, kSecClassGenericPassword);
82
83 // Only allow access when the device has been unlocked.
84 CFDictionarySetValue(keychain_data,
85 kSecAttrAccessible,
86 kSecAttrAccessibleWhenUnlocked);
87
88 // Set the service name.
89 scoped_nsobject<NSString> service_name_ns(
90 [[NSString alloc] initWithBytes:serviceName
91 length:serviceNameLength
92 encoding:NSUTF8StringEncoding]);
93 CFDictionarySetValue(keychain_data, kSecAttrService,
94 base::mac::NSToCFCast(service_name_ns));
95
96 // Set the account name.
97 scoped_nsobject<NSString> account_name_ns(
98 [[NSString alloc] initWithBytes:accountName
99 length:accountNameLength
100 encoding:NSUTF8StringEncoding]);
101 CFDictionarySetValue(keychain_data, kSecAttrAccount,
102 base::mac::NSToCFCast(account_name_ns));
103
104 return keychain_data;
105 }
106
107 } // namespace
108
109 namespace crypto {
110
111 AppleKeychain::AppleKeychain() {}
112
113 AppleKeychain::~AppleKeychain() {}
114
115 OSStatus AppleKeychain::ItemFreeContent(SecKeychainAttributeList* attrList,
116 void* data) const {
117 free(data);
118 return noErr;
119 }
120
121 OSStatus AppleKeychain::AddGenericPassword(SecKeychainRef keychain,
122 UInt32 serviceNameLength,
123 const char* serviceName,
124 UInt32 accountNameLength,
125 const char* accountName,
126 UInt32 passwordLength,
127 const void* passwordData,
128 SecKeychainItemRef* itemRef) const {
129 base::mac::ScopedCFTypeRef<CFDictionaryRef> query(
130 CreateGenericPasswordQuery(serviceNameLength,
131 serviceName,
132 accountNameLength,
133 accountName));
134 // Check that there is not already a password.
135 OSStatus status = SecItemCopyMatching(query, NULL);
136 if (status == errSecItemNotFound) {
137 // A new entry must be created.
138 base::mac::ScopedCFTypeRef<CFDictionaryRef> keychain_data(
139 CreateKeychainData(serviceNameLength,
140 serviceName,
141 accountNameLength,
142 accountName,
143 passwordLength,
144 passwordData,
145 kKeychainActionCreate));
146 status = SecItemAdd(keychain_data, NULL);
147 } else if (status == noErr) {
148 // The entry must be updated.
149 base::mac::ScopedCFTypeRef<CFDictionaryRef> keychain_data(
150 CreateKeychainData(serviceNameLength,
151 serviceName,
152 accountNameLength,
153 accountName,
154 passwordLength,
155 passwordData,
156 kKeychainActionUpdate));
157 status = SecItemUpdate(query, keychain_data);
158 }
159
160 return status;
161 }
162
163 OSStatus AppleKeychain::FindGenericPassword(CFTypeRef keychainOrArray,
164 UInt32 serviceNameLength,
165 const char* serviceName,
166 UInt32 accountNameLength,
167 const char* accountName,
168 UInt32* passwordLength,
169 void** passwordData,
170 SecKeychainItemRef* itemRef) const {
171 DCHECK((passwordData && passwordLength) ||
172 (!passwordData && !passwordLength));
173 base::mac::ScopedCFTypeRef<CFDictionaryRef> query(
174 CreateGenericPasswordQuery(serviceNameLength,
175 serviceName,
176 accountNameLength,
177 accountName));
178
179 // Get the keychain item containing the password.
180 CFTypeRef resultRef = NULL;
181 OSStatus status = SecItemCopyMatching(query, &resultRef);
182 base::mac::ScopedCFTypeRef<CFTypeRef> result(resultRef);
183
184 if (status != noErr) {
185 if (passwordData) {
186 *passwordData = NULL;
187 *passwordLength = 0;
188 }
189 return status;
190 }
191
192 if (passwordData) {
193 CFDataRef data = base::mac::CFCast<CFDataRef>(result);
194 NSUInteger length = CFDataGetLength(data);
195 *passwordData = malloc(length * sizeof(UInt8));
196 CFDataGetBytes(data, CFRangeMake(0, length), (UInt8*)*passwordData);
197 *passwordLength = length;
198 }
199 return status;
200 }
201
202 } // namespace crypto
OLDNEW
« no previous file with comments | « crypto/apple_keychain.h ('k') | crypto/apple_keychain_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698