// 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 <stddef.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);

  void set_locked(bool locked) { locked_ = locked; }
#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;

  // Simulates the state when the user refuses to unclock the Keychain.
  // If true, reading and modifying a password value result in errSecAuthFailed.
  bool locked_;

  typedef struct KeychainPasswordData {
    KeychainPasswordData() : data(nullptr), 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_
