blob: 2eff4cad516b8013e4024d798cffc6dce3632e44 [file] [log] [blame]
// Copyright 2018 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 DEVICE_FIDO_MAC_TOUCH_ID_CONTEXT_H_
#define DEVICE_FIDO_MAC_TOUCH_ID_CONTEXT_H_
#import <LocalAuthentication/LocalAuthentication.h>
#import <Security/Security.h>
#include "base/callback.h"
#include "base/component_export.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_nsobject.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
namespace device {
namespace fido {
namespace mac {
// TouchIdContext wraps a macOS Touch ID consent prompt for signing with a
// secure enclave key. It is a essentially a simpler facade for the LAContext
// class from the macOS LocalAuthentication framework (c.f.
// https://developer.apple.com/documentation/localauthentication/lacontext?language=objc).
//
// Use |Create| to instantiate a new context. Multiple instances can be created
// at the same time. However, calling |PromptTouchId| on one instance will
// cancel any other pending evaluations with an error. Deleting an instance
// will invalidate any pending evaluation prompts (i.e. the dialog will
// disappear and evaluation will fail with an error).
class COMPONENT_EXPORT(DEVICE_FIDO)
API_AVAILABLE(macosx(10.12.2)) TouchIdContext {
public:
// The callback is invoked when the Touch ID prompt completes. It receives a
// boolean indicating whether obtaining the fingerprint was successful.
using Callback = base::OnceCallback<void(bool)>;
// Factory method for instantiating a TouchIdContext.
static std::unique_ptr<TouchIdContext> Create();
// Returns whether Touch ID is supported on the current hardware and set up to
// be used.
static bool TouchIdAvailable();
virtual ~TouchIdContext();
// PromptTouchId displays a Touch ID consent prompt with the provided reason
// string to the user. On completion or error, the provided callback is
// invoked, unless the TouchIdContext instance has been destroyed in the
// meantime (in which case nothing happens).
virtual void PromptTouchId(const base::string16& reason, Callback callback);
// authentication_context returns the LAContext used for the Touch ID prompt.
LAContext* authentication_context() const { return context_; }
// access_control returns a reference to the SecAccessControl object that was
// evaluated/authorized in the Touch ID prompt.
SecAccessControlRef access_control() const { return access_control_; }
protected:
TouchIdContext();
private:
using CreateFuncPtr = decltype(&Create);
using TouchIdAvailableFuncPtr = decltype(&TouchIdAvailable);
static CreateFuncPtr g_create_;
static TouchIdAvailableFuncPtr g_touch_id_available_;
static std::unique_ptr<TouchIdContext> CreateImpl();
static bool TouchIdAvailableImpl();
void RunCallback(bool success);
base::scoped_nsobject<LAContext> context_;
base::ScopedCFTypeRef<SecAccessControlRef> access_control_;
Callback callback_;
base::WeakPtrFactory<TouchIdContext> weak_ptr_factory_;
friend class ScopedTouchIdTestEnvironment;
DISALLOW_COPY_AND_ASSIGN(TouchIdContext);
};
} // namespace mac
} // namespace fido
} // namespace device
#endif // DEVICE_FIDO_MAC_TOUCH_ID_CONTEXT_H_