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

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: Created 8 years, 4 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
Ryan Sleevi 2012/08/23 22:22:58 nit: indent two spaces.
msarda 2012/08/27 14:24:07 Done.
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 = CFDictionaryCreateMutable(NULL, 5,
27 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
Ryan Sleevi 2012/08/23 22:22:58 super minor tiny nit: Because of the second param
msarda 2012/08/27 14:24:07 It does not fit (line has 81 characters). I have r
28 // Type of element is generic password.
29 CFDictionarySetValue(query, kSecClass, kSecClassGenericPassword);
30
31 // Set the service name.
32 scoped_nsobject<NSString> service_name_ns(
33 [[NSString alloc] initWithBytes:serviceName
34 length:serviceNameLength
35 encoding:NSUTF8StringEncoding]);
36 CFDictionarySetValue(query, kSecAttrService, service_name_ns);
37
38 // Set the account name.
39 scoped_nsobject<NSString> account_name_ns(
40 [[NSString alloc] initWithBytes:accountName
41 length:accountNameLength
42 encoding:NSUTF8StringEncoding]);
43 CFDictionarySetValue(query, kSecAttrAccount, account_name_ns);
44
45 // Use the proper search constants, return only the data of the first match.
46 CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);
47 CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
48 return query;
49 }
50
51 // Creates a dictionary conatining the data to save into the keychain.
52 // Ownership follows the Create rule.
53 CFDictionaryRef CreateKeychainData(UInt32 serviceNameLength,
54 const char* serviceName,
55 UInt32 accountNameLength,
56 const char* accountName,
57 UInt32 passwordLength,
58 const void* passwordData,
59 KeychainAction action) {
60 CFMutableDictionaryRef keychain_data = CFDictionaryCreateMutable(NULL, 0,
61 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
62
63 // Set the password.
64 NSData* password = [NSData dataWithBytes:passwordData length:passwordLength];
65 CFDictionarySetValue(keychain_data, kSecValueData, password);
66
67 // If this is a creation, the structural information must be defined.
68 if (action == kKeychainActionCreate) {
69 // Set the type of the data.
70 CFDictionarySetValue(keychain_data, kSecClass, kSecClassGenericPassword);
71
72 // Only allow access when the device has been unlocked.
73 CFDictionarySetValue(keychain_data,
74 kSecAttrAccessible,
75 kSecAttrAccessibleWhenUnlocked);
76
77 // Set the service name.
78 scoped_nsobject<NSString> service_name_ns(
79 [[NSString alloc] initWithBytes:serviceName
80 length:serviceNameLength
81 encoding:NSUTF8StringEncoding]);
82 CFDictionarySetValue(keychain_data, kSecAttrService, service_name_ns);
83
84 // Set the account name.
85 scoped_nsobject<NSString> account_name_ns(
86 [[NSString alloc] initWithBytes:accountName
87 length:accountNameLength
88 encoding:NSUTF8StringEncoding]);
89 CFDictionarySetValue(keychain_data, kSecAttrAccount, account_name_ns);
90 }
91
92 return keychain_data;
93 }
94
95 } // namespace
96
97 namespace crypto {
98
99 AppleKeychain::AppleKeychain() {}
100
101 AppleKeychain::~AppleKeychain() {}
102
103 OSStatus AppleKeychain::ItemFreeContent(SecKeychainAttributeList* attrList,
104 void* data) const {
105 free(data);
Ryan Sleevi 2012/08/23 22:22:58 nit? if (data) free(data)
stuartmorgan 2012/08/24 06:56:03 free is NULL-safe.
msarda 2012/08/27 14:24:07 Kept as is following on Stuart's comment. On 2012
106 return noErr;
107 }
108
109 OSStatus AppleKeychain::AddGenericPassword(SecKeychainRef keychain,
110 UInt32 serviceNameLength,
111 const char* serviceName,
112 UInt32 accountNameLength,
113 const char* accountName,
114 UInt32 passwordLength,
115 const void* passwordData,
116 SecKeychainItemRef* itemRef) const {
117 base::mac::ScopedCFTypeRef<CFDictionaryRef> query(
118 CreateGenericPasswordQuery(serviceNameLength,
119 serviceName,
120 accountNameLength,
121 accountName));
122 // Check that there is not already a password.
123 OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, NULL);
124 if (status == errSecItemNotFound) {
125 // A new entry must be created.
126 base::mac::ScopedCFTypeRef<CFDictionaryRef> keychain_data(
127 CreateKeychainData(serviceNameLength,
128 serviceName,
129 accountNameLength,
130 accountName,
131 passwordLength,
132 passwordData,
133 kKeychainActionCreate));
134 status = SecItemAdd(keychain_data, NULL);
135 } else if (status == noErr) {
136 // The entry must be updated.
137 base::mac::ScopedCFTypeRef<CFDictionaryRef> keychain_data(
138 CreateKeychainData(serviceNameLength,
139 serviceName,
140 accountNameLength,
141 accountName,
142 passwordLength,
143 passwordData,
144 kKeychainActionUpdate));
145 status = SecItemUpdate(query, keychain_data);
146 }
147
148 return status;
149 }
150
151 OSStatus AppleKeychain::FindGenericPassword(CFTypeRef keychainOrArray,
152 UInt32 serviceNameLength,
153 const char* serviceName,
154 UInt32 accountNameLength,
155 const char* accountName,
156 UInt32* passwordLength,
157 void** passwordData,
158 SecKeychainItemRef* itemRef) const {
159 base::mac::ScopedCFTypeRef<CFDictionaryRef> query(
160 CreateGenericPasswordQuery(serviceNameLength,
161 serviceName,
162 accountNameLength,
163 accountName));
164
165 CFTypeRef result = NULL;
166 OSStatus status = SecItemCopyMatching(query, &result);
167 if (status == noErr) {
168 NSData* data = base::mac::CFToNSCast(base::mac::CFCast<CFDataRef>(result));
169 NSUInteger length = [data length];
170 *passwordData = malloc(length);
Ryan Sleevi 2012/08/23 22:22:58 nit: Should you make sure to set *passwordData = N
stuartmorgan 2012/08/24 06:56:03 The docs for the function this mimics doesn't say,
msarda 2012/08/27 14:24:07 Done.
171 [data getBytes:*passwordData length:length];
172 *passwordLength = length;
173 CFRelease(result);
174 }
175 return status;
176 }
177
178 } // namespace crypto
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698