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

Side by Side Diff: remoting/client/ios/keychain_wrapper.mm

Issue 2871993003: Moving the iOS directory to be remoting top level. (Closed)
Patch Set: //remoting/ios was the old landing target for the internal iOS application. Fix. Created 3 years, 7 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 | « remoting/client/ios/keychain_wrapper.h ('k') | remoting/client/ios/session/BUILD.gn » ('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 2017 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 #if !defined(__has_feature) || !__has_feature(objc_arc)
6 #error "This file requires ARC support."
7 #endif
8
9 #import "remoting/client/ios/keychain_wrapper.h"
10
11 #import "remoting/client/ios/domain/host_info.h"
12
13 static const UInt8 kKeychainItemIdentifier[] = "org.chromium.RemoteDesktop\0";
14
15 @interface KeychainWrapper () {
16 NSMutableDictionary* _keychainData;
17 NSMutableDictionary* _userInfoQuery;
18 }
19 @end
20
21 @implementation KeychainWrapper
22
23 - (id)init {
24 if ((self = [super init])) {
25 OSStatus keychainErr = noErr;
26 _userInfoQuery = [[NSMutableDictionary alloc] init];
27 [_userInfoQuery setObject:(__bridge id)kSecClassGenericPassword
28 forKey:(__bridge id)kSecClass];
29 NSData* keychainItemID =
30 [NSData dataWithBytes:kKeychainItemIdentifier
31 length:strlen((const char*)kKeychainItemIdentifier)];
32 [_userInfoQuery setObject:keychainItemID
33 forKey:(__bridge id)kSecAttrGeneric];
34 [_userInfoQuery setObject:(__bridge id)kSecMatchLimitOne
35 forKey:(__bridge id)kSecMatchLimit];
36 [_userInfoQuery setObject:(__bridge id)kCFBooleanTrue
37 forKey:(__bridge id)kSecReturnAttributes];
38
39 CFMutableDictionaryRef outDictionary = nil;
40 keychainErr = SecItemCopyMatching((__bridge CFDictionaryRef)_userInfoQuery,
41 (CFTypeRef*)&outDictionary);
42 if (keychainErr == noErr) {
43 _keychainData = [self
44 secItemFormatToDictionary:(__bridge_transfer NSMutableDictionary*)
45 outDictionary];
46 } else if (keychainErr == errSecItemNotFound) {
47 [self resetKeychainItem];
48
49 if (outDictionary) {
50 CFRelease(outDictionary);
51 _keychainData = nil;
52 }
53 } else {
54 NSLog(@"Serious error.");
55 if (outDictionary) {
56 CFRelease(outDictionary);
57 _keychainData = nil;
58 }
59 }
60 }
61 return self;
62 }
63
64 - (void)setRefreshToken:(NSString*)refreshToken {
65 [self setObject:refreshToken forKey:(__bridge id)kSecValueData];
66 }
67
68 - (NSString*)refreshToken {
69 return [self objectForKey:(__bridge id)kSecValueData];
70 }
71
72 // Implement the mySetObject:forKey method, which writes attributes to the
73 // keychain:
74 - (void)setObject:(id)inObject forKey:(id)key {
75 if (inObject == nil)
76 return;
77 id currentObject = [_keychainData objectForKey:key];
78 if (![currentObject isEqual:inObject]) {
79 [_keychainData setObject:inObject forKey:key];
80 [self writeToKeychain];
81 }
82 }
83
84 // Implement the myObjectForKey: method, which reads an attribute value from a
85 // dictionary:
86 - (id)objectForKey:(id)key {
87 return [_keychainData objectForKey:key];
88 }
89
90 - (void)resetKeychainItem {
91 if (!_keychainData) {
92 _keychainData = [[NSMutableDictionary alloc] init];
93 } else if (_keychainData) {
94 NSMutableDictionary* tmpDictionary =
95 [self dictionaryToSecItemFormat:_keychainData];
96 OSStatus errorcode = SecItemDelete((__bridge CFDictionaryRef)tmpDictionary);
97 if (errorcode == errSecItemNotFound) {
98 // this is ok.
99 } else if (errorcode != noErr) {
100 NSLog(@"Problem deleting current keychain item.");
101 }
102 }
103
104 [_keychainData setObject:@"gaia_refresh_token"
105 forKey:(__bridge id)kSecAttrLabel];
106 [_keychainData setObject:@"Gaia fresh token"
107 forKey:(__bridge id)kSecAttrDescription];
108 [_keychainData setObject:@"" forKey:(__bridge id)kSecValueData];
109 }
110
111 - (NSMutableDictionary*)dictionaryToSecItemFormat:
112 (NSDictionary*)dictionaryToConvert {
113 NSMutableDictionary* returnDictionary =
114 [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert];
115
116 NSData* keychainItemID =
117 [NSData dataWithBytes:kKeychainItemIdentifier
118 length:strlen((const char*)kKeychainItemIdentifier)];
119 [returnDictionary setObject:keychainItemID
120 forKey:(__bridge id)kSecAttrGeneric];
121 [returnDictionary setObject:(__bridge id)kSecClassGenericPassword
122 forKey:(__bridge id)kSecClass];
123
124 NSString* passwordString =
125 [dictionaryToConvert objectForKey:(__bridge id)kSecValueData];
126 [returnDictionary
127 setObject:[passwordString dataUsingEncoding:NSUTF8StringEncoding]
128 forKey:(__bridge id)kSecValueData];
129 return returnDictionary;
130 }
131
132 - (NSMutableDictionary*)secItemFormatToDictionary:
133 (NSDictionary*)dictionaryToConvert {
134 NSMutableDictionary* returnDictionary =
135 [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert];
136
137 [returnDictionary setObject:(__bridge id)kCFBooleanTrue
138 forKey:(__bridge id)kSecReturnData];
139 [returnDictionary setObject:(__bridge id)kSecClassGenericPassword
140 forKey:(__bridge id)kSecClass];
141
142 CFDataRef passwordData = NULL;
143 OSStatus keychainError = noErr;
144 keychainError = SecItemCopyMatching(
145 (__bridge CFDictionaryRef)returnDictionary, (CFTypeRef*)&passwordData);
146 if (keychainError == noErr) {
147 [returnDictionary removeObjectForKey:(__bridge id)kSecReturnData];
148
149 NSString* password = [[NSString alloc]
150 initWithBytes:[(__bridge_transfer NSData*)passwordData bytes]
151 length:[(__bridge NSData*)passwordData length]
152 encoding:NSUTF8StringEncoding];
153 [returnDictionary setObject:password forKey:(__bridge id)kSecValueData];
154 } else if (keychainError == errSecItemNotFound) {
155 NSLog(@"Nothing was found in the keychain.");
156 if (passwordData) {
157 CFRelease(passwordData);
158 passwordData = nil;
159 }
160 } else {
161 NSLog(@"Serious error.\n");
162 if (passwordData) {
163 CFRelease(passwordData);
164 passwordData = nil;
165 }
166 }
167 return returnDictionary;
168 }
169
170 - (void)writeToKeychain {
171 CFDictionaryRef attributes = nil;
172 NSMutableDictionary* updateItem = nil;
173
174 if (SecItemCopyMatching((__bridge CFDictionaryRef)_userInfoQuery,
175 (CFTypeRef*)&attributes) == noErr) {
176 updateItem = [NSMutableDictionary
177 dictionaryWithDictionary:(__bridge_transfer NSDictionary*)attributes];
178
179 [updateItem setObject:[_userInfoQuery objectForKey:(__bridge id)kSecClass]
180 forKey:(__bridge id)kSecClass];
181
182 NSMutableDictionary* tempCheck =
183 [self dictionaryToSecItemFormat:_keychainData];
184 [tempCheck removeObjectForKey:(__bridge id)kSecClass];
185
186 OSStatus errorcode = SecItemUpdate((__bridge CFDictionaryRef)updateItem,
187 (__bridge CFDictionaryRef)tempCheck);
188 if (errorcode != noErr) {
189 NSLog(@"Couldn't update the Keychain Item. %d", (int)errorcode);
190 }
191 } else {
192 OSStatus errorcode =
193 SecItemAdd((__bridge CFDictionaryRef)
194 [self dictionaryToSecItemFormat:_keychainData],
195 NULL);
196 if (errorcode != noErr) {
197 NSLog(@"Couldn't add the Keychain Item. %d", (int)errorcode);
198 }
199 if (attributes) {
200 CFRelease(attributes);
201 attributes = nil;
202 }
203 }
204 }
205
206 @end
OLDNEW
« no previous file with comments | « remoting/client/ios/keychain_wrapper.h ('k') | remoting/client/ios/session/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698