forked from mirrors/gecko-dev
		
	 9331b9fb07
			
		
	
	
		9331b9fb07
		
	
	
	
	
		
			
			For some reason, its value in the Google style we use is 80... except for Objective-C, where it's 100, which led to things like: https://hg.mozilla.org/mozilla-central/rev/31bf68247e6e https://hg.mozilla.org/mozilla-central/rev/64ceb33533a4. There's probably a discussion to have about whether 80 is the right limit, but since it's what's used for everything except ObjC, let's roll with it. # ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D187409
		
			
				
	
	
		
			68 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			68 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 | |
|  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "nsKeychainMigrationUtils.h"
 | |
| 
 | |
| #include <Security/Security.h>
 | |
| 
 | |
| #include "mozilla/Logging.h"
 | |
| 
 | |
| #include "nsCocoaUtils.h"
 | |
| #include "nsString.h"
 | |
| 
 | |
| using namespace mozilla;
 | |
| 
 | |
| LazyLogModule gKeychainUtilsLog("keychainmigrationutils");
 | |
| 
 | |
| NS_IMPL_ISUPPORTS(nsKeychainMigrationUtils, nsIKeychainMigrationUtils)
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| nsKeychainMigrationUtils::GetGenericPassword(const nsACString& aServiceName,
 | |
|                                              const nsACString& aAccountName,
 | |
|                                              nsACString& aKey) {
 | |
|   // To retrieve a secret, we create a CFDictionary of the form:
 | |
|   // { class: generic password,
 | |
|   //   service: the given service name
 | |
|   //   account: the given account name,
 | |
|   //   match limit: match one,
 | |
|   //   return attributes: true,
 | |
|   //   return data: true }
 | |
|   // This searches for and returns the attributes and data for the secret
 | |
|   // matching the given service and account names. We then extract the data
 | |
|   // (i.e. the secret) and return it.
 | |
|   NSDictionary* searchDictionary = @{
 | |
|     (__bridge NSString*)
 | |
|     kSecClass : (__bridge NSString*)kSecClassGenericPassword,
 | |
|     (__bridge NSString*)
 | |
|     kSecAttrService : nsCocoaUtils::ToNSString(aServiceName),
 | |
|     (__bridge NSString*)
 | |
|     kSecAttrAccount : nsCocoaUtils::ToNSString(aAccountName),
 | |
|     (__bridge NSString*)kSecMatchLimit : (__bridge NSString*)kSecMatchLimitOne,
 | |
|     (__bridge NSString*)kSecReturnAttributes : @YES,
 | |
|     (__bridge NSString*)kSecReturnData : @YES
 | |
|   };
 | |
| 
 | |
|   CFTypeRef item;
 | |
|   // https://developer.apple.com/documentation/security/1398306-secitemcopymatching
 | |
|   OSStatus rv =
 | |
|       SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary, &item);
 | |
|   if (rv != errSecSuccess) {
 | |
|     MOZ_LOG(gKeychainUtilsLog, LogLevel::Debug,
 | |
|             ("SecItemCopyMatching failed: %d", rv));
 | |
|     return NS_ERROR_FAILURE;
 | |
|   }
 | |
|   NSDictionary* resultDict = [(__bridge NSDictionary*)item autorelease];
 | |
|   NSData* secret = [resultDict objectForKey:(__bridge NSString*)kSecValueData];
 | |
|   if (!secret) {
 | |
|     MOZ_LOG(gKeychainUtilsLog, LogLevel::Debug, ("objectForKey failed"));
 | |
|     return NS_ERROR_FAILURE;
 | |
|   }
 | |
|   if ([secret length] != 0) {
 | |
|     // We assume that the data is UTF-8 encoded since that seems to be common
 | |
|     // and Keychain Access shows it with that encoding.
 | |
|     aKey.Assign(reinterpret_cast<const char*>([secret bytes]), [secret length]);
 | |
|   }
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 |