tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsKeychainMigrationUtils.mm (2589B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "nsKeychainMigrationUtils.h"
      6 
      7 #include <Security/Security.h>
      8 
      9 #include "mozilla/Logging.h"
     10 
     11 #include "nsCocoaUtils.h"
     12 #include "nsString.h"
     13 
     14 using namespace mozilla;
     15 
     16 LazyLogModule gKeychainUtilsLog("keychainmigrationutils");
     17 
     18 NS_IMPL_ISUPPORTS(nsKeychainMigrationUtils, nsIKeychainMigrationUtils)
     19 
     20 NS_IMETHODIMP
     21 nsKeychainMigrationUtils::GetGenericPassword(const nsACString& aServiceName,
     22                                             const nsACString& aAccountName,
     23                                             nsACString& aKey) {
     24  // To retrieve a secret, we create a CFDictionary of the form:
     25  // { class: generic password,
     26  //   service: the given service name
     27  //   account: the given account name,
     28  //   match limit: match one,
     29  //   return attributes: true,
     30  //   return data: true }
     31  // This searches for and returns the attributes and data for the secret
     32  // matching the given service and account names. We then extract the data
     33  // (i.e. the secret) and return it.
     34  NSDictionary* searchDictionary = @{
     35    (__bridge NSString*)
     36    kSecClass : (__bridge NSString*)kSecClassGenericPassword,
     37    (__bridge NSString*)
     38    kSecAttrService : nsCocoaUtils::ToNSString(aServiceName),
     39    (__bridge NSString*)
     40    kSecAttrAccount : nsCocoaUtils::ToNSString(aAccountName),
     41    (__bridge NSString*)kSecMatchLimit : (__bridge NSString*)kSecMatchLimitOne,
     42    (__bridge NSString*)kSecReturnAttributes : @YES,
     43    (__bridge NSString*)kSecReturnData : @YES
     44  };
     45 
     46  CFTypeRef item;
     47  // https://developer.apple.com/documentation/security/1398306-secitemcopymatching
     48  OSStatus rv =
     49      SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary, &item);
     50  if (rv != errSecSuccess) {
     51    MOZ_LOG(gKeychainUtilsLog, LogLevel::Debug,
     52            ("SecItemCopyMatching failed: %d", rv));
     53    return NS_ERROR_FAILURE;
     54  }
     55  NSDictionary* resultDict = [(__bridge NSDictionary*)item autorelease];
     56  NSData* secret = [resultDict objectForKey:(__bridge NSString*)kSecValueData];
     57  if (!secret) {
     58    MOZ_LOG(gKeychainUtilsLog, LogLevel::Debug, ("objectForKey failed"));
     59    return NS_ERROR_FAILURE;
     60  }
     61  if ([secret length] != 0) {
     62    // We assume that the data is UTF-8 encoded since that seems to be common
     63    // and Keychain Access shows it with that encoding.
     64    aKey.Assign(reinterpret_cast<const char*>([secret bytes]), [secret length]);
     65  }
     66 
     67  return NS_OK;
     68 }