// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CRYPTO_MOCK_KEYCHAIN_MAC_H_
#define CRYPTO_MOCK_KEYCHAIN_MAC_H_

#include <stdint.h>

#include <map>
#include <set>
#include <string>
#include <vector>

#include "base/compiler_specific.h"
#include "crypto/apple_keychain.h"

namespace crypto {

// Mock Keychain wrapper for testing code that interacts with the OS X
// Keychain.  Implemented by storing SecKeychainAttributeList and
// KeychainPasswordData values in separate mutable containers and
// mapping them to integer keys.
//
// Note that "const" is pretty much meaningless for this class; the const-ness
// of AppleKeychain doesn't apply to the actual keychain data, so all of the
// Mock data is mutable; don't assume that it won't change over the life of
// tests.
class CRYPTO_EXPORT MockAppleKeychain : public AppleKeychain {
 public:
  MockAppleKeychain();
  ~MockAppleKeychain() override;

  // AppleKeychain implementation.
  OSStatus FindGenericPassword(CFTypeRef keychainOrArray,
                               UInt32 serviceNameLength,
                               const char* serviceName,
                               UInt32 accountNameLength,
                               const char* accountName,
                               UInt32* passwordLength,
                               void** passwordData,
                               SecKeychainItemRef* itemRef) const override;
  OSStatus ItemFreeContent(SecKeychainAttributeList* attrList,
                           void* data) const override;
  OSStatus AddGenericPassword(SecKeychainRef keychain,
                              UInt32 serviceNameLength,
                              const char* serviceName,
                              UInt32 accountNameLength,
                              const char* accountName,
                              UInt32 passwordLength,
                              const void* passwordData,
                              SecKeychainItemRef* itemRef) const override;

  // Returns the password that OSCrypt uses to generate its encryption key.
  std::string GetEncryptionPassword() const;

#if !defined(OS_IOS)
  OSStatus ItemCopyAttributesAndData(SecKeychainItemRef itemRef,
                                     SecKeychainAttributeInfo* info,
                                     SecItemClass* itemClass,
                                     SecKeychainAttributeList** attrList,
                                     UInt32* length,
                                     void** outData) const override;
  // Pass "fail_me" as the data to get errSecAuthFailed.
  OSStatus ItemModifyAttributesAndData(SecKeychainItemRef itemRef,
                                       const SecKeychainAttributeList* attrList,
                                       UInt32 length,
                                       const void* data) const override;
  OSStatus ItemFreeAttributesAndData(SecKeychainAttributeList* attrList,
                                     void* data) const override;
  OSStatus ItemDelete(SecKeychainItemRef itemRef) const override;
  OSStatus SearchCreateFromAttributes(
      CFTypeRef keychainOrArray,
      SecItemClass itemClass,
      const SecKeychainAttributeList* attrList,
      SecKeychainSearchRef* searchRef) const override;
  OSStatus SearchCopyNext(SecKeychainSearchRef searchRef,
                          SecKeychainItemRef* itemRef) const override;
  // Pass "some.domain.com" as the serverName to get errSecDuplicateItem.
  OSStatus AddInternetPassword(SecKeychainRef keychain,
                               UInt32 serverNameLength,
                               const char* serverName,
                               UInt32 securityDomainLength,
                               const char* securityDomain,
                               UInt32 accountNameLength,
                               const char* accountName,
                               UInt32 pathLength,
                               const char* path,
                               UInt16 port,
                               SecProtocolType protocol,
                               SecAuthenticationType authenticationType,
                               UInt32 passwordLength,
                               const void* passwordData,
                               SecKeychainItemRef* itemRef) const override;
  void Free(CFTypeRef ref) const override;

  // Return the counts of objects returned by Create/Copy functions but never
  // Free'd as they should have been.
  int UnfreedSearchCount() const;
  int UnfreedKeychainItemCount() const;
  int UnfreedAttributeDataCount() const;

  // Returns true if all items added with AddInternetPassword have a creator
  // code set.
  bool CreatorCodesSetForAddedItems() const;

  struct KeychainTestData {
    const SecAuthenticationType auth_type;
    const char* server;
    const SecProtocolType protocol;
    const char* path;
    const UInt32 port;
    const char* security_domain;
    const char* creation_date;
    const char* username;
    const char* password;
    const bool negative_item;
  };
  // Adds a keychain item with the given info to the test set.
  void AddTestItem(const KeychainTestData& item_data);
#endif  // !defined(OS_IOS)

  // |FindGenericPassword()| can return different results depending on user
  // interaction with the system Keychain.  For mocking purposes we allow the
  // user of this class to specify the result code of the
  // |FindGenericPassword()| call so we can simulate the result of different
  // user interactions.
  void set_find_generic_result(OSStatus result) {
    find_generic_result_ = result;
  }

  // Returns the true if |AddGenericPassword()| was called.
  bool called_add_generic() const { return called_add_generic_; }

  // Returns the value of the password set when |AddGenericPassword()| was
  // called.
  std::string add_generic_password() const { return add_generic_password_; }

  // Returns the number of allocations - deallocations for password data.
  int password_data_count() const { return password_data_count_; }

 private:
  // Type used for the keys in the std::map(s) and MockAppleKeychain items.
  typedef uintptr_t MockKeychainItemType;

  // Type of the map holding the mock keychain attributes.
  typedef std::map<MockKeychainItemType, SecKeychainAttributeList>
      MockKeychainAttributesMap;

#if !defined(OS_IOS)
  // Returns true if the keychain already contains a password that matches the
  // attributes provided.
  bool AlreadyContainsInternetPassword(
      UInt32 serverNameLength,
      const char* serverName,
      UInt32 securityDomainLength,
      const char* securityDomain,
      UInt32 accountNameLength,
      const char* accountName,
      UInt32 pathLength,
      const char* path,
      UInt16 port,
      SecProtocolType protocol,
      SecAuthenticationType authenticationType) const;
  // Initializes storage for keychain data at |key|.
  void InitializeKeychainData(MockKeychainItemType key) const;
  // Sets the data and length of |tag| in the item-th test item.
  void SetTestDataBytes(
      MockKeychainItemType item,
      UInt32 tag,
      const void* data,
      size_t length);
  // Sets the data and length of |tag| in the item-th test item based on
  // |value|. The null-terminator will not be included; the Keychain Services
  // docs don't indicate whether it is or not, so clients should not assume
  // that it will be.
  void SetTestDataString(MockKeychainItemType item,
                         UInt32 tag,
                         const char* value);
  // Sets the data of the corresponding attribute of the item-th test item to
  // |value|. Assumes that the space has alread been allocated, and the length
  // set.
  void SetTestDataPort(MockKeychainItemType item, UInt32 value);
  void SetTestDataProtocol(MockKeychainItemType item, SecProtocolType value);
  void SetTestDataAuthType(MockKeychainItemType item,
                           SecAuthenticationType value);
  void SetTestDataNegativeItem(MockKeychainItemType item, Boolean value);
  void SetTestDataCreator(MockKeychainItemType item, OSType value);
  // Sets the password data and length for the item-th test item.
  void SetTestDataPasswordBytes(MockKeychainItemType item,
                                const void* data,
                                size_t length);
  // Sets the password for the item-th test item. As with SetTestDataString,
  // the data will not be null-terminated.
  void SetTestDataPasswordString(MockKeychainItemType item, const char* value);

  // Returns the address of the attribute in attribute_list with tag |tag|.
  static SecKeychainAttribute* AttributeWithTag(
      const SecKeychainAttributeList& attribute_list,
      UInt32 tag);

  static const SecKeychainSearchRef kDummySearchRef;

  typedef struct KeychainPasswordData {
    KeychainPasswordData() : data(NULL), length(0) {}
    void* data;
    UInt32 length;
  } KeychainPasswordData;

  // Mutable because the MockAppleKeychain API requires its internal keychain
  // storage to be modifiable by users of this class.
  mutable MockKeychainAttributesMap keychain_attr_list_;
  mutable std::map<MockKeychainItemType,
                   KeychainPasswordData> keychain_data_;
  mutable MockKeychainItemType next_item_key_;

  // Tracks the items that should be returned in subsequent calls to
  // SearchCopyNext, based on the last call to SearchCreateFromAttributes.
  // We can't handle multiple active searches, since we don't track the search
  // ref we return, but we don't need to for our mocking.
  mutable std::vector<MockKeychainItemType> remaining_search_results_;

  // Track copies and releases to make sure they balance. Really these should
  // be maps to track per item, but this should be good enough to catch
  // real mistakes.
  mutable int search_copy_count_;
  mutable int keychain_item_copy_count_;
  mutable int attribute_data_copy_count_;

  // Tracks which items (by key) were added with AddInternetPassword.
  mutable std::set<MockKeychainItemType> added_via_api_;
#endif  // !defined(OS_IOS)

  // Result code for the |FindGenericPassword()| method.
  OSStatus find_generic_result_;

  // Records whether |AddGenericPassword()| gets called.
  mutable bool called_add_generic_;

  // Tracks the allocations and frees of password data in |FindGenericPassword|
  // and |ItemFreeContent|.
  mutable int password_data_count_;

  // Records the password being set when |AddGenericPassword()| gets called.
  mutable std::string add_generic_password_;
};

}  // namespace crypto

#endif  // CRYPTO_MOCK_KEYCHAIN_MAC_H_
